-
Notifications
You must be signed in to change notification settings - Fork 381
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 #3474 ] Fix implicit arguments in interface methods #3475
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -191,17 +191,22 @@ getMethToplevel {vars} env vis iname cname constraints allmeths params sig | |
(MkImpTy vfc cn ty_imp)) | ||
let conapp = apply (IVar vfc cname) | ||
(map (IBindVar EmptyFC) (map bindName allmeths)) | ||
let argns = getExplicitArgs 0 sig.type | ||
-- eta expand the RHS so that we put implicits in the right place | ||
let fnclause = PatClause vfc | ||
(INamedApp vfc | ||
(IVar cn.fc cn.val) -- See #3409 | ||
(UN $ Basic "__con") | ||
conapp | ||
) | ||
(mkLam argns | ||
(apply (IVar EmptyFC (methName sig.name.val)) | ||
(map (IVar EmptyFC) argns))) | ||
|
||
let lhs = INamedApp vfc | ||
(IVar cn.fc cn.val) -- See #3409 | ||
(UN $ Basic "__con") | ||
conapp | ||
let rhs = IVar EmptyFC (methName sig.name.val) | ||
|
||
-- EtaExpand implicits on both sides: | ||
-- First, obtain all the implicit names in the prefix of | ||
let piNames = collectImplicitNames sig.type | ||
-- Then apply names for each argument to the lhs | ||
let lhs = namesToRawImp True piNames lhs | ||
-- Do the same for the rhs | ||
let rhs = namesToRawImp False piNames rhs | ||
|
||
let fnclause = PatClause vfc lhs rhs | ||
let fndef = IDef vfc cn.val [fnclause] | ||
pure [tydecl, fndef] | ||
where | ||
|
@@ -219,17 +224,6 @@ getMethToplevel {vars} env vis iname cname constraints allmeths params sig | |
applyCon n = let name = UN (Basic "__con") in | ||
(n, INamedApp vfc (IVar vfc n) name (IVar vfc name)) | ||
|
||
getExplicitArgs : Int -> RawImp -> List Name | ||
getExplicitArgs i (IPi _ _ Explicit n _ sc) | ||
= MN "arg" i :: getExplicitArgs (i + 1) sc | ||
getExplicitArgs i (IPi _ _ _ n _ sc) = getExplicitArgs i sc | ||
getExplicitArgs i tm = [] | ||
|
||
mkLam : List Name -> RawImp -> RawImp | ||
mkLam [] tm = tm | ||
mkLam (x :: xs) tm | ||
= ILam EmptyFC top Explicit (Just x) (Implicit vfc False) (mkLam xs tm) | ||
|
||
bindName : Name -> String | ||
bindName (UN n) = "__bind_" ++ displayUserName n | ||
bindName (NS _ n) = bindName n | ||
|
@@ -238,6 +232,20 @@ getMethToplevel {vars} env vis iname cname constraints allmeths params sig | |
methName : Name -> Name | ||
methName n = UN (Basic $ bindName n) | ||
|
||
collectImplicitNames : RawImp -> List Name | ||
collectImplicitNames (IPi _ _ Explicit _ _ ty) = [] | ||
collectImplicitNames (IPi _ _ _ (Just n) _ ty) = n :: collectImplicitNames ty | ||
collectImplicitNames (IPi _ _ _ Nothing _ ty) = collectImplicitNames ty | ||
collectImplicitNames _ = [] | ||
|
||
namesToRawImp : Bool -> List Name -> RawImp -> RawImp | ||
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. This function is based on a similar function from 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. In |
||
namesToRawImp bind (nm@(UN{}) :: xs) fn = | ||
namesToRawImp bind xs $ INamedApp vfc fn nm $ | ||
if bind | ||
then IBindVar vfc $ nameRoot nm | ||
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.
To avoid a name conflict, I'd like to use machine generated names, but |
||
else IVar vfc nm | ||
namesToRawImp _ _ fn = fn | ||
|
||
-- Get the function for chasing a constraint. This is one of the | ||
-- arguments to the record, appearing before the method arguments. | ||
getConstraintHint : {vars : _} -> | ||
|
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.
Skipping implicit arguments without names can cause an error, but I'm not sure how to handle them properly
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.
Example with an error:
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.
As far as I know, an implicit argument without a name cannot be passed. It might be useful to add a “disable implicits” mode as suggested in Discord and use it this. It could also be useful in user code