Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix duplicate label issue, include index for duplicate effect labels #513

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from

Conversation

TimWhiting
Copy link
Collaborator

@TimWhiting TimWhiting commented May 3, 2024

Fixes #511

@daanx, I understand if you would like to redo this yourself to make it cleaner, but this should illustrate the issue / solution.

Specifically @evv-index does not include an index for duplicate labels. This is fine for most effect expressions, since the effect row is incrementally adjusted. However, for the general open case where you use a vector of indices and there are multiple labels of the same kind, we get invalid offsets. This would happen with or without the code in Simplify.hs which turns them into constant offsets.

In general I think the types for effect rows need to represent duplicate label indices more explicitly (when extracting the ordered effect), so I defaulted to including the count of duplicate labels (pseudo index) in extractOrderedEffect. However, the indices aren't really important till after type checking, so there are a lot of places where I needed to discard the indices. I don't know if you would rather do something to represent this invariant more explicitly in the type, or if you would rather create another function for when you don't care about indices, since there are only a few places that do.

In particular the issue is illustrated by the following short code snippet from the core output. (from the example in #511)

(std/core/hnd/@open1(
                        (std/core/vector/unvlist(
                       // Here is the problem both of these indices are the same!!!!
                        (std/core/types/Cons((std/core/types/@make-ssize_t(0)), 
                        (std/core/types/Cons((std/core/types/@make-ssize_t(0)), 
                        std/core/types/Nil)))))

if labelName l1 == labelName l2
then numbered ((i+1,l2):(i, l1):acc) labs
else numbered ((0,l2):(i, l1):acc) labs
numbered acc [] = reverse acc
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is where I number the duplicate labels (they are presorted, so labels with the same name will already be next to each other).

let coreMask = coreExprFromNameInfo maskQName maskInfo
coreIndex= Core.App (Core.TypeApp (coreExprFromNameInfo evvIndexQName evvIndexInfo) [effTo])
[coreHTag]
[(makeInt32 0), coreHTag]
Copy link
Collaborator Author

@TimWhiting TimWhiting May 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about this one, this is in inference of Inject creating the core statement @inject-effect. I assumed the new effect will be the first one of that tag, but I'm not sure if I understand this part of inference that well currently.

findMatch :: Integer -> Name -> [Type] -> Integer
findMatch i lname (l:ls) = if (labelName l == lname) then i else findMatch (i+1) lname ls
findMatch :: Integer -> (Int, Name) -> [(Int, Type)] -> Integer
findMatch i (off, lname) ((ol,l):ls) = if (labelName l == lname) && off == ol then i else findMatch (i+1) (off, lname) ls
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This changes to find the label with the correct name at the correct count of the label name.

bottomUp (App (TypeApp (Var evvIndex _) [effTp,hndTp]) [htag]) | getName evvIndex == nameEvvIndex && isEffectFixed effTp
= makeEvIndex (effectOffset (effectLabelFromHandler hndTp) effTp)
bottomUp (App (TypeApp (Var evvIndex _) [effTp,hndTp]) [App _ [Lit (LitInt i)], htag]) | getName evvIndex == nameEvvIndex && isEffectFixed effTp
= makeEvIndex (effectOffset ((fromIntegral i), (effectLabelFromHandler hndTp)) effTp)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course simplification has to take into account the new parameter

= let (htagTp,hndTp)
= let (name,_,tpArgs) = labelNameEx l
hndCon = TCon (TypeCon name -- (toHandlerName name)
(kindFunN (map getKind tpArgs ++ [kindEffect,kindStar]) kindStar))
in (makeTypeApp (resolve (toEffectTagName name)) tpArgs, typeApp hndCon tpArgs)
in App (makeTypeApp (resolve nameEvvIndex) [effTo,hndTp]) [htagTp]
in App (makeTypeApp (resolve nameEvvIndex) [effTo,hndTp]) [makeInt32 (fromIntegral i), htagTp]
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the only change to open resolve. Adding in the name's count.

if (kk_string_cmp_borrow(htag.tagname,ev->htag.tagname,ctx) <= 0) return i; // break on insertion point
if (kk_string_cmp_borrow(htag.tagname,ev->htag.tagname,ctx) <= 0) {
if (off == 0) return i; // break on insertion point
off--; // adjust for duplicate label
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is the main change in the runtime. We get the handler with the correct name at the correct offset.

@@ -540,7 +541,7 @@ inferIsolated contextRange range body inf
Nothing -> return res
Just vrng -> do seff <- subst ieff
let (ls,tl) = extractOrderedEffect seff
case filter (\l -> labelName l == nameTpLocal) ls of
case filter (\l -> labelName l == nameTpLocal) (map snd ls) of
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All other changes just look like this essentially (getting the result of extractOrderedEffect as it was previously.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Mask is ignored when adding exn effect
1 participant