2Module : Idris.Elab.Type
3Description : Code to elaborate types.
6Maintainer : The Idris Community.
8{-# LANGUAGE PatternGuards #-}
9module Idris.Elab.Type (
10 buildType, elabType, elabType'
11 , elabPostulate, elabExtern
16import Idris.Core.Elaborate hiding (Tactic(..))
17import Idris.Core.Evaluate
19import Idris.Docstrings (Docstring)
21import Idris.Elab.Utils
22import Idris.Elab.Value
25import Idris.Output (sendHighlighting)
27import Prelude hiding (id, (.))
29import Control.Category
31import qualified Data.Set as S
39 -> Idris (Type, Type, PTerm, [(Int, Name)])
40buildType info syn fc opts n ty' = do
44 logElab 2 $ show n ++ " pre-type " ++ showTmImpls ty' ++ show (no_imp syn)
45 ty' <- addUsingConstraints syn fc ty'
46 ty' <- addUsingImpls syn n fc ty'
47 let ty = addImpl (imp_methods syn) i ty'
49 logElab 5 $ show n ++ " type pre-addimpl " ++ showTmImpls ty'
50 logElab 5 $ "with methods " ++ show (imp_methods syn)
51 logElab 2 $ show n ++ " type " ++ show (using syn) ++ "\n" ++ showTmImpls ty
53 ((ElabResult tyT' defer is ctxt' newDecls highlights newGName, est), log) <-
54 tclift $ elaborate (constraintNS info) ctxt (idris_datatypes i) (idris_name i) n (TType (UVal 0)) initEState
55 (errAt "type of " n Nothing
56 (erunAux fc (build i info ETyDecl [] n ty)))
60 processTacticDecls info newDecls
61 sendHighlighting highlights
62 updateIState $ \i -> i { idris_name = newGName }
64 let tyT = patToImp tyT'
66 logElab 3 $ show ty ++ "\nElaborated: " ++ show tyT'
68 ds <- checkAddDef True False info fc iderr True defer
69 -- if the type is not complete, note that we'll need to infer
70 -- things later (for solving metavariables)
71 when (length ds > length is) -- more deferred than case blocks
74 mapM_ (elabCaseBlock info opts) is
76 logElab 5 "Rechecking"
78 logElab 10 $ "Elaborated to " ++ showEnvDbg [] tyT
79 (cty, ckind) <- recheckC (constraintNS info) fc id [] tyT
81 -- record the implicit and inaccessible arguments
83 let (inaccData, impls) = unzip $ getUnboundImplicits i cty ty
84 let inacc = inaccessibleImps 0 cty inaccData
85 logElab 3 $ show n ++ ": inaccessible arguments: " ++ show inacc ++
86 " from " ++ show cty ++ "\n" ++ showTmImpls ty
88 putIState $ i { idris_implicits = addDef n impls (idris_implicits i) }
89 logElab 3 ("Implicit " ++ show n ++ " " ++ show impls)
92 -- Add the names referenced to the call graph, and check we're not
93 -- referring to anything less visible
94 -- In particular, a public/export type can not refer to anything
95 -- private, but can refer to any public/export
96 let refs = freeNames cty
97 nvis <- getFromHideList n
100 Just acc -> mapM_ (checkVisibility fc n (max Frozen acc) acc) refs
104 when (Constructor `notElem` opts) $ do
105 let pnames = getParamsInType i [] impls cty
106 let fninfo = FnInfo (param_pos 0 pnames cty)
108 addIBC (IBCFnInfo n fninfo)
110 return (cty, ckind, ty, inacc)
112 patToImp (Bind n (PVar rig t) sc) = Bind n (Pi rig Nothing t (TType (UVar [] 0))) (patToImp sc)
113 patToImp (Bind n b sc) = Bind n b (patToImp sc)
116 param_pos i ns (Bind n (Pi _ _ t _) sc)
117 | n `elem` ns = i : param_pos (i + 1) ns sc
118 | otherwise = param_pos (i + 1) ns sc
119 param_pos i ns t = []
121-- | Elaborate a top-level type declaration - for example, "foo : Int -> Int".
124 -> Docstring (Either Err PTerm)
125 -> [(Name, Docstring (Either Err PTerm))]
129 -> FC -- ^ The precise location of the name
132elabType = elabType' False
134elabType' :: Bool -- normalise it
137 -> Docstring (Either Err PTerm)
138 -> [(Name, Docstring (Either Err PTerm))]
145elabType' norm info syn doc argDocs fc opts n nfc ty' = {- let ty' = piBind (params info) ty_in
146 n = liftname info n_in in -}
147 do checkUndefined fc n
148 (cty, _, ty, inacc) <- buildType info syn fc opts n ty'
151 let nty = cty -- normalise ctxt [] cty
152 -- if the return type is something coinductive, freeze the definition
154 logElab 2 $ "Rechecked to " ++ show nty
155 let nty' = normalise ctxt [] nty
156 logElab 2 $ "Rechecked to " ++ show nty'
158 -- Add function name to internals (used for making :addclause know
159 -- the name unambiguously)
163 addInternalApp (fc_fname fc) (fst . fc_start $ fc) (PTyped (PRef fc [] n) ty') -- (mergeTy ty' (delab i nty')) -- TODO: Should use span instead of line and filename?
164 addIBC (IBCLineApp (fc_fname fc) (fst . fc_start $ fc) (PTyped (PRef fc [] n) ty')) -- (mergeTy ty' (delab i nty')))
166 let (fam, _) = unApply (getRetTy nty')
167 -- Productivity checking now via checking for guarded 'Delay'
168 let opts' = opts -- if corec then (Coinductive : opts) else opts
169 let usety = if norm then nty' else nty
170 ds <- checkDef info fc iderr True [(n, (-1, Nothing, usety, []))]
173 let ds' = map (\(n, (i, top, fam, ns)) -> (n, (i, top, fam, ns, True, True))) ds
176 checkDocs fc argDocs ty
177 doc' <- elabDocTerms info doc
178 argDocs' <- mapM (\(n, d) -> do d' <- elabDocTerms info d
179 return (n, d')) argDocs
180 addDocStr n doc' argDocs'
183 fputState (opt_inaccessible . ist_optimisation n) inacc
185 when (Implicit `elem` opts') $ do addCoercion n
186 addIBC (IBCCoercion n)
187 when (AutoHint `elem` opts') $
189 P _ tyn _ -> do addAutoHint tyn n
190 addIBC (IBCAutoHint tyn n)
191 t -> ifail "Hints must return a data or record type"
193 -- If the function is declared as an error handler and the language
194 -- extension is enabled, then add it to the list of error handlers.
195 errorReflection <- fmap (elem ErrorReflection . idris_language_extensions) getIState
196 when (ErrorHandler `elem` opts) $ do
199 -- Check that the declared type is the correct type for an error handler:
200 -- handler : List (TTName, TT) -> Err -> ErrorReport - for now no ctxt
202 then do i <- getIState
203 putIState $ i { idris_errorhandlers = idris_errorhandlers i ++ [n] }
204 addIBC (IBCErrorHandler n)
205 else ifail $ "The type " ++ show nty' ++ " is invalid for an error handler"
206 else ifail "Error handlers can only be defined when the ErrorReflection language extension is enabled."
207 -- Send highlighting information about the name being declared
208 sendHighlighting $ S.fromList [(FC' nfc, AnnName n Nothing Nothing Nothing)]
209 -- if it's an export list type, make a note of it
210 case (unApply usety) of
212 | ut == ffiexport -> do addIBC (IBCExport n)
217 ffiexport = sNS (sUN "FFI_Export") ["FFI_Export"]
222 errrep = txt "ErrorReportPart"
224 tyIsHandler (Bind _ (Pi _ _ (P _ (NS (UN e) ns1) _) _)
225 (App _ (P _ (NS (UN m) ns2) _)
226 (App _ (P _ (NS (UN l) ns3) _)
227 (P _ (NS (UN r) ns4) _))))
228 | e == err && m == maybe && l == lst && r == errrep
229 , ns1 == map txt ["Errors","Reflection","Language"]
230 , ns2 == map txt ["Maybe", "Prelude"]
231 , ns3 == map txt ["List", "Prelude"]
232 , ns4 == map txt ["Reflection","Language"] = True
233 tyIsHandler _ = False
235elabPostulate :: ElabInfo -> SyntaxInfo -> Docstring (Either Err PTerm) ->
236 FC -> FC -> FnOpts -> Name -> PTerm -> Idris ()
237elabPostulate info syn doc fc nfc opts n ty = do
238 elabType info syn doc [] fc opts n NoFC ty
239 putIState . (\ist -> ist{ idris_postulates = S.insert n (idris_postulates ist) }) =<< getIState
240 addIBC (IBCPostulate n)
241 sendHighlighting $ S.fromList [(FC' nfc, AnnName n (Just PostulateOutput) Nothing Nothing)]
243 -- remove it from the deferred definitions list
246elabExtern :: ElabInfo -> SyntaxInfo -> Docstring (Either Err PTerm) ->
247 FC -> FC -> FnOpts -> Name -> PTerm -> Idris ()
248elabExtern info syn doc fc nfc opts n ty = do
249 cty <- elabType info syn doc [] fc opts n NoFC ty
251 let arity = length (getArgTys (normalise (tt_ctxt ist) [] cty))
253 putIState . (\ist -> ist{ idris_externs = S.insert (n, arity) (idris_externs ist) }) =<< getIState
254 addIBC (IBCExtern (n, arity))
256 -- remove it from the deferred definitions list
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list