@@ -101,6 +101,7 @@ elabInstance info syn doc argDocs what fc cs acc opts n nfc ps t expn ds = do
101101 ist <- getIState
102102 let pnames = nub $ map pname (concat (nub wparams)) ++
103103 concatMap (namesIn [] ist) ps
104+
104105 let superclassInstances = map (substInstance ips pnames) (class_default_superclasses ci)
105106 undefinedSuperclassInstances <- filterM (fmap not . isOverlapping ist) superclassInstances
106107 mapM_ (rec_elabDecl info EAll info) undefinedSuperclassInstances
@@ -128,29 +129,48 @@ elabInstance info syn doc argDocs what fc cs acc opts n nfc ps t expn ds = do
128129 logElab 3 $ "Instance is " ++ show ps ++ " implicits " ++
129130 show (concat (nub wparams))
130131
131− -- Bring variables in instance head into scope
132− let headVars = nub $ mapMaybe (\p -> case p of
133− PRef _ _ n ->
134− case lookupTy n (tt_ctxt ist) of
135− [] -> Just n
136− _ -> Nothing
137− _ -> Nothing) ps
138−-- let lhs = PRef fc iname
139− let lhs = PApp fc (PRef fc [] iname)
140− (map (\n -> pimp n (PRef fc [] n) True) headVars)
132+ -- Bring variables in instance head into scope when building the
133+ -- dictionary
134+ let headVars = nub $ concatMap getHeadVars ps
135+
136+ let lhsImps = map (\n -> pimp n (PRef fc [] n) True) headVars
137+
138+ let lhs = PApp fc (PRef fc [] iname) lhsImps
141139 let rhs = PApp fc (PRef fc [] (instanceCtorName ci))
142− (map (pexp . mkMethApp) mtys)
140+ (map (pexp . (mkMethApp lhsImps)) mtys)
143141
144− logElab 5 $ "Instance LHS " ++ show totopts ++ "\n" ++ show lhs ++ " " ++ show headVars
142+ logElab 5 $ "Instance LHS " ++ show totopts ++ "\n" ++ showTmImpls lhs ++ " " ++ show headVars
145143 logElab 5 $ "Instance RHS " ++ show rhs
146144
147− let idecls = [PClauses fc totopts iname
148− [PClause fc iname lhs [] rhs wb]]
149− logElab 1 (show idecls)
150145 push_estack iname True
146+ logElab 3 ("Method types: " ++ show wbTys)
147+ logElab 3 ("Method bodies: " ++ show wbVals)
148+
149+ let idecls = [PClauses fc totopts iname
150+ [PClause fc iname lhs [] rhs []]]
151+
152+ mapM_ (rec_elabDecl info EAll info) (map (impBind headVars) wbTys)
151153 mapM_ (rec_elabDecl info EAll info) idecls
154+
155+ ctxt <- getContext
156+ let ifn_ty = case lookupTyExact iname ctxt of
157+ Just t -> t
158+ Nothing -> error "Can't happen (interface constructor)"
159+ let ifn_is = case lookupCtxtExact iname (idris_implicits ist) of
160+ Just t -> t
161+ Nothing -> []
162+ let prop_params = getParamsInType ist [] ifn_is ifn_ty
163+
164+ logElab 3 $ "Propagating parameters to methods: "
165+ ++ show (iname, prop_params)
166+
167+ let wbVals' = map (addParams prop_params) wbVals
168+
169+ mapM_ (rec_elabDecl info EAll info) wbVals'
170+
152171 pop_estack
153− ist <- getIState
172+-- totalityCheckBlock
173+
154174 checkInjectiveArgs fc n (class_determiners ci) (lookupTyExact iname (tt_ctxt ist))
155175 addIBC (IBCInstance intInst (isNothing expn) n iname)
156176
@@ -226,8 +246,9 @@ elabInstance info syn doc argDocs what fc cs acc opts n nfc ps t expn ds = do
226246 map snd (filter (\(i, _) -> i `elem` dets) a')
227247 keepDets dets t = t
228248
229− mkMethApp (n, _, _, ty)
230− = lamBind 0 ty (papp fc (PRef fc [] n) (methArgs 0 ty))
249+ mkMethApp ps (n, _, _, ty)
250+ = lamBind 0 ty (papp fc (PRef fc [] n)
251+ (ps ++ methArgs 0 ty))
231252 lamBind i (PPi (Constraint _ _) _ _ _ sc) sc'
232253 = PLam fc (sMN i "meth") NoFC Placeholder (lamBind (i+1) sc sc')
233254 lamBind i (PPi _ n _ ty sc) sc'
@@ -254,8 +275,10 @@ elabInstance info syn doc argDocs what fc cs acc opts n nfc ps t expn ds = do
254275 _ -> return ps'
255276 getWParams (_ : ps) = getWParams ps
256277
257− decorate ns iname (UN n) = NS (SN (MethodN (UN n))) ns
258− decorate ns iname (NS (UN n) s) = NS (SN (MethodN (UN n))) ns
278+ decorate ns iname (UN nm)
279+ = NS (SN (WhereN 0 iname (SN (MethodN (UN nm))))) ns
280+ decorate ns iname (NS (UN nm) s)
281+ = NS (SN (WhereN 0 iname (SN (MethodN (UN nm))))) ns
259282
260283 mkTyDecl (n, op, t, _)
261284 = PTy emptyDocstring [] syn fc op n NoFC
@@ -314,6 +337,61 @@ elabInstance info syn doc argDocs what fc cs acc opts n nfc ps t expn ds = do
314337 clauseFor m iname ns (PClauses _ _ m' _)
315338 = decorate ns iname m == decorate ns iname m'
316339 clauseFor m iname ns _ = False
340+
341+getHeadVars :: PTerm -> [Name]
342+getHeadVars (PRef _ _ n) | implicitable n = [n]
343+getHeadVars (PApp _ _ args) = concatMap getHeadVars (map getTm args)
344+getHeadVars (PPair _ _ _ l r) = getHeadVars l ++ getHeadVars r
345+getHeadVars (PDPair _ _ _ l t r) = getHeadVars l ++ getHeadVars t ++ getHeadVars t
346+getHeadVars _ = []
347+
348+-- Implicitly bind variables from the instance head in method types
349+impBind :: [Name] -> PDecl -> PDecl
350+impBind vs (PTy d ds syn fc opts n fc' t)
351+ = PTy d ds syn fc opts n fc' (doImpBind (vs \\ boundIn t) t)
352+ where
353+ doImpBind [] ty = ty
354+ doImpBind (n : ns) ty = PPi impl n NoFC Placeholder (doImpBind ns ty)
355+
356+ boundIn (PPi _ n _ _ sc) = n : boundIn sc
357+ boundIn _ = []
358+
359+
360+-- Propagate class parameters to method bodies, if they're not already
361+-- there
362+addParams :: [Name] -> PDecl -> PDecl
363+addParams ps (PClauses fc opts n cs) = PClauses fc opts n (map addCParams cs)
364+ where
365+ addCParams (PClause fc n lhs ws rhs wb)
366+ = PClause fc n (addTmParams (dropPs (allNamesIn lhs) ps) lhs) ws rhs wb
367+ addCParams (PWith fc n lhs ws sc pn ds)
368+ = PWith fc n (addTmParams (dropPs (allNamesIn lhs) ps) lhs) ws sc pn
369+ (map (addParams ps) ds)
370+ addCParams c = c
371+
372+ addTmParams ps (PRef fc hls n) = PApp fc (PRef fc hls n) (map toImp ps)
373+ addTmParams ps (PApp fc ap@(PRef fc' hls n) args)
374+ = PApp fc ap (mergePs (map toImp ps) args)
375+ addTmParams ps tm = tm
376+
377+ toImp n = pimp n (PRef fc [] n) True
378+
379+ mergePs [] args = args
380+ mergePs (p : ps) args
381+ | isImplicit p,
382+ pname p `notElem` map pname args
383+ = p : mergePs ps args
384+ where
385+ isImplicit (PExp{}) = False
386+ isImplicit _ = True
387+ mergePs (p : ps) args
388+ = mergePs ps args
389+
390+ -- Don't propagate a parameter if the name is rebound explicitly
391+ dropPs :: [Name] -> [Name] -> [Name]
392+ dropPs ns = filter (\x -> x `notElem` ns)
393+
394+addParams ps d = d
317395
318396checkInjectiveArgs :: FC -> Name -> [Int] -> Maybe Type -> Idris ()
319397checkInjectiveArgs fc n ds Nothing = return ()