-
Notifications
You must be signed in to change notification settings - Fork 9
New fixes in type inference / specialization for ABI encoding library #464
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
Merged
Merged
Changes from all commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
4c13415
Fixing specialization and type inference for ABI encoding.
rodrigogribeiro d8964a5
Ormulu
rodrigogribeiro 76effcf
fix trailing comma in Generic.solc
mbenke 50e2227
Adding instance environment and matching in specialization
rodrigogribeiro 437915e
Merge remote-tracking branch 'refs/remotes/origin/new-infer-specializ…
rodrigogribeiro 4c1a05e
Adding more tests
rodrigogribeiro d2103a7
Minor fixes on instance imports and adds more tests
rodrigogribeiro dc4271c
Adding minor changes
rodrigogribeiro d1d6e57
adding encoding lib as a test case
rodrigogribeiro 873a2b5
Ormolu formatting
mbenke 69a95cb
Update test/SpecialiseTests.hs
rodrigogribeiro File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -753,15 +753,83 @@ elabFunDef :: | |||||||||||||||||||||||||||||||||||||||||||||||||
| Scheme -> -- function infered type | ||||||||||||||||||||||||||||||||||||||||||||||||||
| Scheme -> -- function annotated type | ||||||||||||||||||||||||||||||||||||||||||||||||||
| TcM (FunDef Id) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| elabFunDef isPub vs sig bdy (Forall _ (_ :=> tinf)) ann@(Forall _ (_ :=> tann)) = | ||||||||||||||||||||||||||||||||||||||||||||||||||
| elabFunDef isPub vs sig bdy (Forall _ (pinf :=> tinf)) ann@(Forall _ (pann :=> tann)) = | ||||||||||||||||||||||||||||||||||||||||||||||||||
| do | ||||||||||||||||||||||||||||||||||||||||||||||||||
| let tinf' = everywhere (mkT toMeta) tinf | ||||||||||||||||||||||||||||||||||||||||||||||||||
| tann' = everywhere (mkT toMeta) tann | ||||||||||||||||||||||||||||||||||||||||||||||||||
| s <- unify tinf' tann' | ||||||||||||||||||||||||||||||||||||||||||||||||||
| -- Find bindings for phantom predicate variables (those appearing only in | ||||||||||||||||||||||||||||||||||||||||||||||||||
| -- predicates, not in the function type). sig2's context uses annotation | ||||||||||||||||||||||||||||||||||||||||||||||||||
| -- TyVars (e.g. "rep"), but the body uses body TyVars (e.g. "$106550"). | ||||||||||||||||||||||||||||||||||||||||||||||||||
| -- Build a TyVar-level renaming from the delta and patch sig2's context. | ||||||||||||||||||||||||||||||||||||||||||||||||||
| phantomDelta <- findPhantomPredBindings pann pinf | ||||||||||||||||||||||||||||||||||||||||||||||||||
| let tvs = [(gvar mv', gen ty) | (mv', ty) <- phantomDelta] | ||||||||||||||||||||||||||||||||||||||||||||||||||
| substTVPhantom t@(TyVar v) = fromMaybe t (lookup v tvs) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| substTVPhantom t = t | ||||||||||||||||||||||||||||||||||||||||||||||||||
| sig2 <- elabSignature vs sig ann | ||||||||||||||||||||||||||||||||||||||||||||||||||
| let fd2 = everywhere (mkT (apply @Ty s)) (FunDef isPub sig2 bdy) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| let sig2' = everywhere (mkT substTVPhantom) sig2 | ||||||||||||||||||||||||||||||||||||||||||||||||||
| let fd2 = everywhere (mkT (apply @Ty s)) (FunDef isPub sig2' bdy) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| pure (everywhere (mkT gen) fd2) | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| -- Unify annotation predicates against inferred predicates locally to discover | ||||||||||||||||||||||||||||||||||||||||||||||||||
| -- mappings for phantom type variables (those absent from the function type). | ||||||||||||||||||||||||||||||||||||||||||||||||||
| -- Returns new (annotation_meta -> body_meta) bindings for phantom variables, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| -- then restores the global substitution to its state on entry. | ||||||||||||||||||||||||||||||||||||||||||||||||||
| -- | ||||||||||||||||||||||||||||||||||||||||||||||||||
| -- Soundness: it is correct for this function to leave some phantom variables | ||||||||||||||||||||||||||||||||||||||||||||||||||
| -- without a binding. A variable like rep2 in | ||||||||||||||||||||||||||||||||||||||||||||||||||
| -- forall a b rep1 rep2 . a:Tag(rep1), b:Tag(rep2) => f : a -> b -> rep1 | ||||||||||||||||||||||||||||||||||||||||||||||||||
| -- never appears in the function body, so type-checking the body produces no | ||||||||||||||||||||||||||||||||||||||||||||||||||
| -- inferred constraint that mentions it; the returned delta simply says nothing | ||||||||||||||||||||||||||||||||||||||||||||||||||
| -- about rep2. This is safe because the specialiser resolves phantom variables | ||||||||||||||||||||||||||||||||||||||||||||||||||
| -- later, at each concrete call site: when b is instantiated to TypeB, instance | ||||||||||||||||||||||||||||||||||||||||||||||||||
| -- resolution against TypeB:Tag(TagB) immediately yields rep2 = TagB without | ||||||||||||||||||||||||||||||||||||||||||||||||||
| -- any information from this phase. | ||||||||||||||||||||||||||||||||||||||||||||||||||
| -- What would be unsound is a spurious unification of distinct type variables | ||||||||||||||||||||||||||||||||||||||||||||||||||
| -- (e.g. a ≡ b) produced by mismatched predicate pairing, because that would | ||||||||||||||||||||||||||||||||||||||||||||||||||
| -- corrupt the elaborated function signature and make specialisation impossible. | ||||||||||||||||||||||||||||||||||||||||||||||||||
| -- The guards in phantomMatchingPreds prevent exactly that. | ||||||||||||||||||||||||||||||||||||||||||||||||||
| findPhantomPredBindings :: [Pred] -> [Pred] -> TcM [(MetaTv, Ty)] | ||||||||||||||||||||||||||||||||||||||||||||||||||
| findPhantomPredBindings pann pinf = do | ||||||||||||||||||||||||||||||||||||||||||||||||||
| s0 <- getSubst | ||||||||||||||||||||||||||||||||||||||||||||||||||
| -- Apply s0 to BOTH sides so that fresh metas in pinf (e.g. "$94361") are | ||||||||||||||||||||||||||||||||||||||||||||||||||
| -- substituted to their source-named counterparts (e.g. Meta "a"), matching the | ||||||||||||||||||||||||||||||||||||||||||||||||||
| -- source-named metas in pann. Phantom extras (e.g. "$94362" for "rep") remain | ||||||||||||||||||||||||||||||||||||||||||||||||||
| -- free in s0 and stay as fresh metas in pinf', making them identifiable. | ||||||||||||||||||||||||||||||||||||||||||||||||||
| let pann' = apply s0 (everywhere (mkT toMeta) pann) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| pinf' = apply s0 (everywhere (mkT toMeta) pinf) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| dom_s0 = map fst (unSubst s0) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| forM_ (phantomMatchingPreds dom_s0 pann' pinf') $ \(pa, pi_) -> | ||||||||||||||||||||||||||||||||||||||||||||||||||
| catchError (unifyPredExtras pa pi_) (\_ -> return ()) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| s_full <- getSubst | ||||||||||||||||||||||||||||||||||||||||||||||||||
| let delta = filter (\(v, _) -> v `notElem` dom_s0) (unSubst s_full) | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+792
to
+805
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| putSubst s0 -- restore global subst | ||||||||||||||||||||||||||||||||||||||||||||||||||
| return delta | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| -- Match annotation preds against inferred preds, keeping only pairs where the | ||||||||||||||||||||||||||||||||||||||||||||||||||
| -- inferred pred contains at least one meta that is NOT in dom_s0 (i.e. phantom). | ||||||||||||||||||||||||||||||||||||||||||||||||||
| -- This avoids cross-product pairings for predicates with the same class name where | ||||||||||||||||||||||||||||||||||||||||||||||||||
| -- the body metas are already bound (non-phantom). | ||||||||||||||||||||||||||||||||||||||||||||||||||
| phantomMatchingPreds :: [MetaTv] -> [Pred] -> [Pred] -> [(Pred, Pred)] | ||||||||||||||||||||||||||||||||||||||||||||||||||
| phantomMatchingPreds dom_s0 pann pinf = | ||||||||||||||||||||||||||||||||||||||||||||||||||
| [ (pa, pi_) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| | pa@(InCls cls mt_a _) <- pann, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| hasPhantomMeta pa, -- skip annotation preds already fully resolved in s0 | ||||||||||||||||||||||||||||||||||||||||||||||||||
| pi_@(InCls cls' mt_i _) <- pinf, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| cls == cls', | ||||||||||||||||||||||||||||||||||||||||||||||||||
| hasPhantomMeta pi_, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| mt_a == mt_i -- self-types must agree to avoid cross-pairing same-class constraints | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ] | ||||||||||||||||||||||||||||||||||||||||||||||||||
| where | ||||||||||||||||||||||||||||||||||||||||||||||||||
| hasPhantomMeta (InCls _ mt exts) = any (`notElem` dom_s0) (mv mt `union` mv exts) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| hasPhantomMeta _ = False | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| unifyPredExtras :: Pred -> Pred -> TcM () | ||||||||||||||||||||||||||||||||||||||||||||||||||
| unifyPredExtras (InCls _ mt1 exts1) (InCls _ mt2 exts2) = do | ||||||||||||||||||||||||||||||||||||||||||||||||||
| void $ unify mt1 mt2 | ||||||||||||||||||||||||||||||||||||||||||||||||||
| zipWithM_ (\e1 e2 -> void $ unify e1 e2) exts1 exts2 | ||||||||||||||||||||||||||||||||||||||||||||||||||
| unifyPredExtras _ _ = return () | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| toMeta :: Ty -> Ty | ||||||||||||||||||||||||||||||||||||||||||||||||||
| toMeta (TyVar (TVar n)) = Meta (MetaTv n) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| toMeta (TyCon n ts) = TyCon n (map toMeta ts) | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
compute the set of metavariables that occur in the function type (funMetas = mv tinf' ∪ mv tann') and exclude them from delta, keeping only genuinely phantom variables (present in predicates, absent from the function type) - also requires changing
findPhantomPredBindings