@@ -11,6 +11,7 @@ module Idris.Elab.Utils where
1111import Idris.AbsSyntax
1212import Idris.Core.Elaborate hiding (Tactic(..))
1313import Idris.Core.Evaluate
14+import Idris.Core.WHNF
1415import Idris.Core.TT
1516import Idris.Core.Typecheck
1617import Idris.DeepSeq
@@ -184,8 +185,8 @@ decorateid decorate (PClauses f o n cs)
184185
185186-- if 't' is an interface application, assume its arguments are injective
186187pbinds :: IState -> Term -> ElabD ()
187−pbinds i (Bind n (PVar _ t) sc)
188− = do attack; patbind n
188+pbinds i (Bind n (PVar rig t) sc)
189+ = do attack; patbind n rig
189190 env <- get_env
190191 case unApply (normalise (tt_ctxt i) env t) of
191192 (P _ c _, args) -> case lookupCtxt c (idris_interfaces i) of
@@ -571,3 +572,28 @@ hasEmptyPat :: Context -> Ctxt TypeInfo -> Term -> Bool
571572hasEmptyPat ctxt tyctxt (Bind n (PVar _ ty) sc)
572573 = isEmpty ctxt tyctxt ty || hasEmptyPat ctxt tyctxt sc
573574hasEmptyPat ctxt tyctxt _ = False
575+
576+-- Find names which are applied to a function in a Rig1 position
577+findLinear :: IState -> [Name] -> Term -> [Name]
578+findLinear ist env tm | (P _ f _, args) <- unApply tm,
579+ f `notElem` env,
580+ Just ty_in <- lookupTyExact f (tt_ctxt ist)
581+ = let ty = whnfArgs (tt_ctxt ist) [] ty_in in
582+ nub $ concatMap (findLinear ist env) args ++ findLinArg ty args
583+ where
584+ findLinArg (Bind n (Pi c _ _ _) sc) (P _ a _ : as)
585+ | Rig1 <- c = a : findLinArg sc as
586+ findLinArg (Bind n (Pi _ _ _ _) sc) (a : as) = findLinArg sc as
587+ findLinArg _ _ = []
588+findLinear ist env (App _ f a)
589+ = nub $ findLinear ist env f ++ findLinear ist env a
590+findLinear ist env (Bind n b sc) = findLinear ist (n : env) sc
591+findLinear ist _ _ = []
592+
593+setLinear :: [Name] -> Term -> Term
594+setLinear ns (Bind n b@(PVar r t) sc)
595+ | n `elem` ns = Bind n (PVar Rig1 t) (setLinear ns sc)
596+ | otherwise = Bind n b (setLinear ns sc)
597+setLinear ns tm = tm
598+
599+