on master help sign in
Merge pull request #3118 from jfdm/fragile-directive

Fragile directive

commitc6c47aefc368d3cf7ef5cec761d6c7bcd265beaa authorJan de Muijnck-Hughes <jfdm@users.noreply.github.com> dateTue 26 Apr 2016, 09:06 (10 years ago) parentbe8079c6b64e74
12 files changed+229−110
CHANGELOG.md+4 idris.cabal+5−1 src/Idris/AbsSyntax.hs+25−12 src/Idris/AbsSyntaxTree.hs+25−22 src/Idris/DeepSeq.hs+3−2 src/Idris/Directives.hs+75−59 src/Idris/Elab/Utils.hs+24−7 src/Idris/IBC.hs+13−4 src/Idris/Parser.hs+9−3 test/directives001/directives001.idr+28 test/directives001/expected+14 test/directives001/run+4
CHANGELOG.md+4
@@ -26,6 +26,10 @@
2626 be called directly, so the recursive structure of `SnocList` can direct the
2727 recursion structure of `my_reverse`.
2828
29+* Added `%fragile` directive, which gives a warning and a message when a
30+ fragile name is referenced. For use in detailing fragile APIs.
31+
32+
2933## Library updates
3034
3135* `Control.WellFounded` module removed, and added to the Prelude as
idris.cabal+5−1
@@ -91,7 +91,7 @@ Extra-source-files:
9191 config.mk
9292 stack.yaml
9393 man/idris.1
94−
94+
9595 rts/*.c
9696 rts/*.h
9797 rts/arduino/*.c
@@ -409,6 +409,10 @@ Extra-source-files:
409409 test/corecords002/run
410410 test/corecords002/expected
411411
412+ test/directives001/*.idr
413+ test/directives001/run
414+ test/directives001/expected
415+
412416 test/delab001/*.idr
413417 test/delab001/run
414418 test/delab001/expected
src/Idris/AbsSyntax.hs+25−12
@@ -381,12 +381,25 @@ getNameHints i n =
381381 _ -> []
382382
383383addDeprecated :: Name -> String -> Idris ()
384−addDeprecated n reason = do i <- getIState
385− putIState $ i { idris_deprecated = addDef n reason (idris_deprecated i) }
384+addDeprecated n reason = do
385+ i <- getIState
386+ putIState $ i { idris_deprecated = addDef n reason (idris_deprecated i) }
386387
387388getDeprecated :: Name -> Idris (Maybe String)
388−getDeprecated n = do i <- getIState
389− return $ lookupCtxtExact n (idris_deprecated i)
389+getDeprecated n = do
390+ i <- getIState
391+ return $ lookupCtxtExact n (idris_deprecated i)
392+
393+
394+addFragile :: Name -> String -> Idris ()
395+addFragile n reason = do
396+ i <- getIState
397+ putIState $ i { idris_fragile = addDef n reason (idris_fragile i) }
398+
399+getFragile :: Name -> Idris (Maybe String)
400+getFragile n = do
401+ i <- getIState
402+ return $ lookupCtxtExact n (idris_fragile i)
390403
391404push_estack :: Name -> Bool -> Idris ()
392405push_estack n inst
@@ -658,7 +671,7 @@ addDeferred' nt ns
658671 = do mapM_ (\(n, (i, _, t, _, _, _)) -> updateContext (addTyDecl n nt (tidyNames S.empty t))) ns
659672 mapM_ (\(n, _) -> when (not (n `elem` primDefs)) $ addIBC (IBCMetavar n)) ns
660673 i <- getIState
661− putIState $ i { idris_metavars = map (\(n, (i, top, _, ns, isTopLevel, isDefinable)) ->
674+ putIState $ i { idris_metavars = map (\(n, (i, top, _, ns, isTopLevel, isDefinable)) ->
662675 (n, (top, i, ns, isTopLevel, isDefinable))) ns ++
663676 idris_metavars i }
664677 where
@@ -673,7 +686,7 @@ addDeferred' nt ns
673686 tidyNames used b = b
674687
675688solveDeferred :: FC -> Name -> Idris ()
676−solveDeferred fc n
689+solveDeferred fc n
677690 = do i <- getIState
678691 case lookup n (idris_metavars i) of
679692 Just (_, _, _, _, False) ->
@@ -1701,7 +1714,7 @@ addImpl' inpat env infns imp_meths ist ptm
17011714 ai :: Bool -> Bool -> [(Name, Maybe PTerm)] -> [[T.Text]] -> PTerm -> PTerm
17021715 ai inpat qq env ds (PRef fc fcs f)
17031716 | f `elem` infns = PInferRef fc fcs f
1704− | not (f `elem` map fst env) = handleErr $ aiFn topname inpat inpat qq imp_meths ist fc f fc ds []
1717+ | not (f `elem` map fst env) = handleErr $ aiFn topname inpat inpat qq imp_meths ist fc f fc ds []
17051718 ai inpat qq env ds (PHidden (PRef fc hl f))
17061719 | not (f `elem` map fst env) = PHidden (handleErr $ aiFn topname inpat False qq imp_meths ist fc f fc ds [])
17071720 ai inpat qq env ds (PRewrite fc by l r g)
@@ -1742,7 +1755,7 @@ addImpl' inpat env infns imp_meths ist ptm
17421755 = let f' = ai inpat qq env ds f
17431756 as' = map (fmap (ai inpat qq env ds)) as in
17441757 mkPApp fc 1 f' as'
1745− ai inpat qq env ds (PWithApp fc f a)
1758+ ai inpat qq env ds (PWithApp fc f a)
17461759 = PWithApp fc (ai inpat qq env ds f) (ai inpat qq env ds a)
17471760 ai inpat qq env ds (PCase fc c os)
17481761 = let c' = ai inpat qq env ds c in
@@ -1750,7 +1763,7 @@ addImpl' inpat env infns imp_meths ist ptm
17501763 -- definition which is passed through addImpl again
17511764 PCase fc c' (map aiCase os)
17521765 where
1753− aiCase (lhs, rhs)
1766+ aiCase (lhs, rhs)
17541767 = (lhs, ai inpat qq (env ++ patnames lhs) ds rhs)
17551768
17561769 -- Anything beginning with a lower case letter, not applied,
@@ -1853,9 +1866,9 @@ aiFn topname inpat True qq imp_meths ist fc f ffc ds []
18531866 vname (UN n) = True -- non qualified
18541867 vname _ = False
18551868
1856−aiFn topname inpat expat qq imp_meths ist fc f ffc ds as
1869+aiFn topname inpat expat qq imp_meths ist fc f ffc ds as
18571870 | f `elem` primNames = Right $ PApp fc (PRef ffc [ffc] f) as
1858−aiFn topname inpat expat qq imp_meths ist fc f ffc ds as
1871+aiFn topname inpat expat qq imp_meths ist fc f ffc ds as
18591872 -- This is where namespaces get resolved by adding PAlternative
18601873 = do let ns = lookupCtxtName f (idris_implicits ist)
18611874 let nh = filter (\(n, _) -> notHidden n) ns
@@ -1919,7 +1932,7 @@ aiFn topname inpat expat qq imp_meths ist fc f ffc ds as
19191932 case find n imps [] of
19201933 Just (tm, imps') ->
19211934 PImp p False l n tm : insImpAcc (M.insert n tm pnas) ps given imps'
1922− Nothing ->
1935+ Nothing ->
19231936 PImp p True l n Placeholder :
19241937 insImpAcc (M.insert n Placeholder pnas) ps given imps
19251938 insImpAcc pnas (PTacImplicit p l n sc' ty : ps) given imps =
src/Idris/AbsSyntaxTree.hs+25−22
@@ -60,7 +60,7 @@ data ElabInfo = EInfo { params :: [(Name, PTerm)],
6060 namespace :: Maybe [String],
6161 elabFC :: Maybe FC,
6262 -- We may, recursively, collect transformations to
63− -- do on the rhs, e.g. rewriting recursive calls to
63+ -- do on the rhs, e.g. rewriting recursive calls to
6464 -- functions defined by 'with'
6565 rhs_trans :: PTerm -> PTerm,
6666 rec_elabDecl :: ElabWhat -> ElabInfo -> PDecl ->
@@ -271,7 +271,8 @@ data IState = IState {
271271 idris_parserHighlights :: [(FC, OutputAnnotation)], -- ^ Highlighting information from the parser
272272 idris_deprecated :: Ctxt String, -- ^ Deprecated names and explanation
273273 idris_inmodule :: S.Set Name, -- ^ Names defined in current module
274− idris_ttstats :: M.Map Term (Int, Term)
274+ idris_ttstats :: M.Map Term (Int, Term),
275+ idris_fragile :: Ctxt String -- ^ Fragile names and explanation.
275276 }
276277
277278-- Required for parsers library, and therefore trifecta
@@ -347,6 +348,7 @@ data IBCWrite = IBCFix FixDecl
347348 | IBCExport Name
348349 | IBCAutoHint Name Name
349350 | IBCDeprecate Name String
351+ | IBCFragile Name String
350352 deriving Show
351353
352354-- | The initial state for the compiler
@@ -361,7 +363,7 @@ idrisInit = IState initContext S.empty []
361363 [] [] Nothing [] Nothing [] [] Nothing Nothing emptyContext Private False [] Nothing [] []
362364 (RawOutput stdout) True defaultTheme [] (0, emptyContext) emptyContext M.empty
363365 AutomaticWidth S.empty S.empty [] Nothing Nothing [] [] M.empty [] [] []
364− emptyContext S.empty M.empty
366+ emptyContext S.empty M.empty emptyContext
365367
366368
367369-- | The monad for the main REPL - reading and processing files and updating
@@ -758,22 +760,23 @@ deriving instance NFData PDecl'
758760!-}
759761
760762-- | The set of source directives
761−data Directive = DLib Codegen String |
762− DLink Codegen String |
763− DFlag Codegen String |
764− DInclude Codegen String |
765− DHide Name |
766− DFreeze Name |
767− DAccess Accessibility |
768− DDefault Bool |
769− DLogging Integer |
770− DDynamicLibs [String] |
771− DNameHint Name FC [(Name, FC)] |
772− DErrorHandlers Name FC Name FC [(Name, FC)] |
773− DLanguage LanguageExt |
774− DDeprecate Name String |
775− DAutoImplicits Bool |
776− DUsed FC Name Name
763+data Directive = DLib Codegen String
764+ | DLink Codegen String
765+ | DFlag Codegen String
766+ | DInclude Codegen String
767+ | DHide Name
768+ | DFreeze Name
769+ | DAccess Accessibility
770+ | DDefault Bool
771+ | DLogging Integer
772+ | DDynamicLibs [String]
773+ | DNameHint Name FC [(Name, FC)]
774+ | DErrorHandlers Name FC Name FC [(Name, FC)]
775+ | DLanguage LanguageExt
776+ | DDeprecate Name String
777+ | DFragile Name String
778+ | DAutoImplicits Bool
779+ | DUsed FC Name Name
777780
778781-- | A set of instructions for things that need to happen in IState
779782-- after a term elaboration when there's been reflected elaboration.
@@ -1016,7 +1019,7 @@ data PTerm = PQuote Raw -- ^ Inclusion of a core term into the high-level langua
10161019 | PLet FC Name FC PTerm PTerm PTerm -- ^ A let binding (second FC is precise name location)
10171020 | PTyped PTerm PTerm -- ^ Term with explicit type
10181021 | PApp FC PTerm [PArg] -- ^ e.g. IO (), List Char, length x
1019− | PWithApp FC PTerm PTerm -- ^ Application plus a 'with' argument
1022+ | PWithApp FC PTerm PTerm -- ^ Application plus a 'with' argument
10201023 | PAppImpl PTerm [ImplicitInfo] -- ^ Implicit argument application (introduced during elaboration only)
10211024 | PAppBind FC PTerm [PArg] -- ^ implicitly bound application
10221025 | PMatchApp FC Name -- ^ Make an application by type matching
@@ -1024,7 +1027,7 @@ data PTerm = PQuote Raw -- ^ Inclusion of a core term into the high-level langua
10241027 | PCase FC PTerm [(PTerm, PTerm)] -- ^ A case expression. Args are source location, scrutinee, and a list of pattern/RHS pairs
10251028 | PTrue FC PunInfo -- ^ Unit type..?
10261029 | PResolveTC FC -- ^ Solve this dictionary by type class resolution
1027− | PRewrite FC (Maybe Name) PTerm PTerm (Maybe PTerm)
1030+ | PRewrite FC (Maybe Name) PTerm PTerm (Maybe PTerm)
10281031 -- ^ "rewrite" syntax, with optional rewriting function
10291032 -- and optional result type
10301033 | PPair FC [FC] PunInfo PTerm PTerm -- ^ A pair (a, b) and whether it's a product type or a pair (solved by elaboration). The list of FCs is its punctuation.
@@ -1886,7 +1889,7 @@ pprintPTerm ppo bnd docArgs infixes = prettySe (ppopt_depth ppo) startPrec bnd
18861889 prettySe d p bnd (PTrue _ TypeOrTerm) = text "()"
18871890 prettySe d p bnd (PRewrite _ by l r _) =
18881891 depth d . bracket p startPrec $
1889− text "rewrite" <+> prettySe (decD d) (startPrec + 1) bnd l
1892+ text "rewrite" <+> prettySe (decD d) (startPrec + 1) bnd l
18901893 <+> (case by of
18911894 Nothing -> empty
18921895 Just fn -> text "using" <+>
src/Idris/DeepSeq.hs+3−2
@@ -306,6 +306,7 @@ instance NFData IBCWrite where
306306 rnf (IBCAutoHint n1 n2) = rnf n1 `seq` rnf n2 `seq` ()
307307 rnf (IBCDeprecate n1 n2) = rnf n1 `seq` rnf n2 `seq` ()
308308 rnf (IBCRecord x) = rnf x `seq` ()
309+ rnf (IBCFragile n1 n2) = rnf n1 `seq` rnf n2 `seq` ()
309310
310311
311312instance NFData a => NFData (D.Block a) where
@@ -698,8 +699,8 @@ instance NFData IState where
698699 rnf (IState x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x17 x18 x19 x20
699700 x21 x22 x23 x24 x25 x26 x27 x28 x29 x30 x31 x32 x33 x34 x35 x36 x37 x38 x39 x40
700701 x41 x42 x43 x44 x45 x46 x47 x48 x49 x50 x51 x52 x53 x54 x55 x56 x57 x58 x59 x60
701− x61 x62 x63 x64 x65 x66 x67 x68 x69 x70 x71 x72 x73 x74 x75)
702+ x61 x62 x63 x64 x65 x66 x67 x68 x69 x70 x71 x72 x73 x74 x75 x76)
702703 = rnf x1 `seq` rnf x2 `seq` rnf x3 `seq` rnf x4 `seq` rnf x5 `seq` rnf x6 `seq` rnf x7 `seq` rnf x8 `seq` rnf x9 `seq` rnf x10 `seq` () `seq` rnf x11 `seq` rnf x12 `seq` rnf x13 `seq` rnf x14 `seq` rnf x15 `seq` rnf x16 `seq` rnf x17 `seq` rnf x18 `seq` rnf x19 `seq` rnf x20 `seq`
703704 rnf x21 `seq` rnf x22 `seq` rnf x23 `seq` rnf x24 `seq` rnf x25 `seq` rnf x26 `seq` rnf x27 `seq` rnf x28 `seq` rnf x29 `seq` rnf x30 `seq` rnf x31 `seq` rnf x32 `seq` rnf x33 `seq` rnf x34 `seq` rnf x35 `seq` rnf x36 `seq` rnf x37 `seq` rnf x38 `seq` rnf x39 `seq` rnf x40 `seq`
704705 rnf x41 `seq` rnf x42 `seq` rnf x43 `seq` rnf x44 `seq` rnf x45 `seq` rnf x46 `seq` rnf x47 `seq` rnf x48 `seq` rnf x49 `seq` rnf x50 `seq` rnf x51 `seq` rnf x52 `seq` rnf x53 `seq` rnf x54 `seq` rnf x55 `seq` rnf x56 `seq` rnf x57 `seq` rnf x58 `seq` rnf x59 `seq` rnf x60 `seq`
705− rnf x61 `seq` rnf x62 `seq` rnf x63 `seq` rnf x64 `seq` rnf x65 `seq` rnf x66 `seq` rnf x67 `seq` rnf x68 `seq` rnf x69 `seq` rnf x70 `seq` rnf x71 `seq` rnf x72 `seq` rnf x73 `seq` rnf x74 `seq` rnf x75 `seq` ()
706+ rnf x61 `seq` rnf x62 `seq` rnf x63 `seq` rnf x64 `seq` rnf x65 `seq` rnf x66 `seq` rnf x67 `seq` rnf x68 `seq` rnf x69 `seq` rnf x70 `seq` rnf x71 `seq` rnf x72 `seq` rnf x73 `seq` rnf x74 `seq` rnf x75 `seq` rnf x76 `seq` ()
src/Idris/Directives.hs+75−59
@@ -13,28 +13,35 @@ import Util.DynamicLinker
1313
1414-- | Run the action corresponding to a directive
1515directiveAction :: Directive -> Idris ()
16−directiveAction (DLib cgn lib) = do addLib cgn lib
17− addIBC (IBCLib cgn lib)
16+directiveAction (DLib cgn lib) = do
17+ addLib cgn lib
18+ addIBC (IBCLib cgn lib)
1819
19−directiveAction (DLink cgn obj) = do dirs <- allImportDirs
20− o <- runIO $ findInPath dirs obj
21− addIBC (IBCObj cgn obj) -- just name, search on loading ibc
22− addObjectFile cgn o
20+directiveAction (DLink cgn obj) = do
21+ dirs <- allImportDirs
22+ o <- runIO $ findInPath dirs obj
23+ addIBC (IBCObj cgn obj) -- just name, search on loading ibc
24+ addObjectFile cgn o
2325
2426directiveAction (DFlag cgn flag) = do
25− let flags = words flag
26− mapM_ (\f -> addIBC (IBCCGFlag cgn f)) flags
27− mapM_ (addFlag cgn) flags
28−
29−directiveAction (DInclude cgn hdr) = do addHdr cgn hdr
30− addIBC (IBCHeader cgn hdr)
31−
32−directiveAction (DHide n') = do ns <- allNamespaces n'
33− mapM_ (\n -> do setAccessibility n Hidden
34− addIBC (IBCAccess n Hidden)) ns
35−directiveAction (DFreeze n') = do ns <- allNamespaces n'
36− mapM_ (\n -> do setAccessibility n Frozen
37− addIBC (IBCAccess n Frozen)) ns
27+ let flags = words flag
28+ mapM_ (\f -> addIBC (IBCCGFlag cgn f)) flags
29+ mapM_ (addFlag cgn) flags
30+
31+directiveAction (DInclude cgn hdr) = do
32+ addHdr cgn hdr
33+ addIBC (IBCHeader cgn hdr)
34+
35+directiveAction (DHide n') = do
36+ ns <- allNamespaces n'
37+ mapM_ (\n -> do
38+ setAccessibility n Hidden
39+ addIBC (IBCAccess n Hidden)) ns
40+directiveAction (DFreeze n') = do
41+ ns <- allNamespaces n'
42+ mapM_ (\n -> do
43+ setAccessibility n Frozen
44+ addIBC (IBCAccess n Frozen)) ns
3845
3946directiveAction (DAccess acc) = do updateIState (\i -> i { default_access = acc })
4047
@@ -42,49 +49,58 @@ directiveAction (DDefault tot) = do updateIState (\i -> i { default_total = tot
4249
4350directiveAction (DLogging lvl) = setLogLevel (fromInteger lvl)
4451
45−directiveAction (DDynamicLibs libs) = do added <- addDyLib libs
46− case added of
47− Left lib -> addIBC (IBCDyLib (lib_name lib))
48− Right msg -> fail $ msg
49−
50−directiveAction (DNameHint ty tyFC ns) = do ty' <- disambiguate ty
51− mapM_ (addNameHint ty' . fst) ns
52− mapM_ (\n -> addIBC (IBCNameHint (ty', fst n))) ns
53− sendHighlighting $
54− [(tyFC, AnnName ty' Nothing Nothing Nothing)] ++
55− map (\(n, fc) -> (fc, AnnBoundName n False)) ns
56−
57−directiveAction (DErrorHandlers fn nfc arg afc ns) =
58− do fn' <- disambiguate fn
59− ns' <- mapM (\(n, fc) -> do n' <- disambiguate n
60− return (n', fc)) ns
61− addFunctionErrorHandlers fn' arg (map fst ns')
62− mapM_ (addIBC .
63− IBCFunctionErrorHandler fn' arg . fst) ns'
64− sendHighlighting $
65− [(nfc, AnnName fn' Nothing Nothing Nothing),
66− (afc, AnnBoundName arg False)] ++
67− map (\(n, fc) -> (fc, AnnName n Nothing Nothing Nothing)) ns'
52+directiveAction (DDynamicLibs libs) = do
53+ added <- addDyLib libs
54+ case added of
55+ Left lib -> addIBC (IBCDyLib (lib_name lib))
56+ Right msg -> fail $ msg
57+
58+directiveAction (DNameHint ty tyFC ns) = do
59+ ty' <- disambiguate ty
60+ mapM_ (addNameHint ty' . fst) ns
61+ mapM_ (\n -> addIBC (IBCNameHint (ty', fst n))) ns
62+ sendHighlighting $ [(tyFC, AnnName ty' Nothing Nothing Nothing)] ++ map (\(n, fc) -> (fc, AnnBoundName n False)) ns
63+
64+directiveAction (DErrorHandlers fn nfc arg afc ns) = do
65+ fn' <- disambiguate fn
66+ ns' <- mapM (\(n, fc) -> do
67+ n' <- disambiguate n
68+ return (n', fc)) ns
69+ addFunctionErrorHandlers fn' arg (map fst ns')
70+ mapM_ (addIBC . IBCFunctionErrorHandler fn' arg . fst) ns'
71+ sendHighlighting $
72+ [ (nfc, AnnName fn' Nothing Nothing Nothing)
73+ , (afc, AnnBoundName arg False)
74+ ] ++ map (\(n, fc) -> (fc, AnnName n Nothing Nothing Nothing)) ns'
6875
6976directiveAction (DLanguage ext) = addLangExt ext
70−directiveAction (DDeprecate n reason)
71− = do n' <- disambiguate n
72− addDeprecated n' reason
73− addIBC (IBCDeprecate n' reason)
74−directiveAction (DAutoImplicits b)
75− = setAutoImpls b
76−directiveAction (DUsed fc fn arg) = addUsedName fc fn arg
77+
78+directiveAction (DDeprecate n reason) = do
79+ n' <- disambiguate n
80+ addDeprecated n' reason
81+ addIBC (IBCDeprecate n' reason)
82+
83+directiveAction (DFragile n reason) = do
84+ n' <- disambiguate n
85+ addFragile n' reason
86+ addIBC (IBCFragile n' reason)
87+
88+directiveAction (DAutoImplicits b) = setAutoImpls b
89+directiveAction (DUsed fc fn arg) = addUsedName fc fn arg
7790
7891disambiguate :: Name -> Idris Name
79−disambiguate n = do i <- getIState
80− case lookupCtxtName n (idris_implicits i) of
81− [(n', _)] -> return n'
82− [] -> throwError (NoSuchVariable n)
83− more -> throwError (CantResolveAlts (map fst more))
92+disambiguate n = do
93+ i <- getIState
94+ case lookupCtxtName n (idris_implicits i) of
95+ [(n', _)] -> return n'
96+ [] -> throwError (NoSuchVariable n)
97+ more -> throwError (CantResolveAlts (map fst more))
98+
8499
85100allNamespaces :: Name -> Idris [Name]
86−allNamespaces n = do i <- getIState
87− case lookupCtxtName n (idris_implicits i) of
88− [(n', _)] -> return [n']
89− [] -> throwError (NoSuchVariable n)
90− more -> return (map fst more)
101+allNamespaces n = do
102+ i <- getIState
103+ case lookupCtxtName n (idris_implicits i) of
104+ [(n', _)] -> return [n']
105+ [] -> throwError (NoSuchVariable n)
106+ more -> return (map fst more)
src/Idris/Elab/Utils.hs+24−7
@@ -41,6 +41,9 @@ recheckC_borrowing uniq_check addConstrs bs fc mkerr env t
4141 when addConstrs $ addConstraints fc cs
4242 mapM_ (checkDeprecated fc) (allTTNames tm)
4343 mapM_ (checkDeprecated fc) (allTTNames ty)
44+ mapM_ (checkFragile fc) (allTTNames tm)
45+ mapM_ (checkFragile fc) (allTTNames ty)
46+
4447 return (tm, ty)
4548
4649checkDeprecated :: FC -> Name -> Idris ()
@@ -53,6 +56,20 @@ checkDeprecated fc n
5356 "" -> Util.Pretty.empty
5457 _ -> line <> text r
5558
59+
60+checkFragile :: FC -> Name -> Idris ()
61+checkFragile fc n = do
62+ r <- getFragile n
63+ case r of
64+ Nothing -> return ()
65+ Just r -> do
66+ iWarn fc $ text "Use of a fragile construct "
67+ <> annName n
68+ <> case r of
69+ "" -> Util.Pretty.empty
70+ _ -> line <> text r
71+
72+
5673iderr :: Name -> Err -> Err
5774iderr _ e = e
5875
@@ -319,14 +336,14 @@ mkStaticTy ns t = t
319336
320337-- Check that a name has the minimum required accessibility
321338checkVisibility :: FC -> Name -> Accessibility -> Accessibility -> Name -> Idris ()
322−checkVisibility fc n minAcc acc ref
339+checkVisibility fc n minAcc acc ref
323340 = do nvis <- getFromHideList ref
324341 case nvis of
325342 Nothing -> return ()
326− Just acc' -> if acc' > minAcc
327− then tclift $ tfail (At fc
328− (Msg $ show acc ++ " " ++ show n ++
329− " can't refer to " ++
343+ Just acc' -> if acc' > minAcc
344+ then tclift $ tfail (At fc
345+ (Msg $ show acc ++ " " ++ show n ++
346+ " can't refer to " ++
330347 show acc' ++ " " ++ show ref))
331348 else return ()
332349
@@ -397,10 +414,10 @@ setDetaggable n = do
397414 _ -> putIState ist { idris_optimisation = addDef n (Optimise [] True) opt }
398415
399416displayWarnings :: EState -> Idris ()
400−displayWarnings est
417+displayWarnings est
401418 = mapM_ displayImpWarning (implicit_warnings est)
402419 where
403420 displayImpWarning :: (FC, Name) -> Idris ()
404− displayImpWarning (fc, n) =
421+ displayImpWarning (fc, n) =
405422 iputStrLn $ show fc ++ ":WARNING: " ++ show (nsroot n) ++ " is bound as an implicit\n"
406423 ++ "\tDid you mean to refer to " ++ show n ++ "?"
src/Idris/IBC.hs+13−4
@@ -40,7 +40,7 @@ import System.Directory
4040import Codec.Archive.Zip
4141
4242ibcVersion :: Word16
43−ibcVersion = 137
43+ibcVersion = 138
4444
4545-- When IBC is being loaded - we'll load different things (and omit different
4646-- structures/definitions) depending on which phase we're in
@@ -95,7 +95,8 @@ data IBCFile = IBCFile { ver :: Word16,
9595 ibc_deprecated :: ![(Name, String)],
9696 ibc_defs :: ![(Name, Def)],
9797 ibc_total :: ![(Name, Totality)],
98− ibc_access :: ![(Name, Accessibility)]
98+ ibc_access :: ![(Name, Accessibility)],
99+ ibc_fragile :: ![(Name, String)]
99100 }
100101 deriving Show
101102{-!
@@ -103,7 +104,7 @@ deriving instance Binary IBCFile
103104!-}
104105
105106initIBC :: IBCFile
106−initIBC = IBCFile ibcVersion "" [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] Nothing [] [] [] [] [] [] []
107+initIBC = IBCFile ibcVersion "" [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] Nothing [] [] [] [] [] [] [] []
107108
108109hasValidIBCVersion :: FilePath -> Idris Bool
109110hasValidIBCVersion fp = do
@@ -196,7 +197,8 @@ entries i = catMaybes [Just $ toEntry "ver" 0 (encode $ ver i),
196197 makeEntry "ibc_deprecated" (ibc_deprecated i),
197198 makeEntry "ibc_defs" (ibc_defs i),
198199 makeEntry "ibc_total" (ibc_total i),
199− makeEntry "ibc_access" (ibc_access i)]
200+ makeEntry "ibc_access" (ibc_access i),
201+ makeEntry "ibc_fragile" (ibc_fragile i)]
200202
201203writeArchive :: FilePath -> IBCFile -> Idris ()
202204writeArchive fp i = do let a = L.foldl (\x y -> addEntryToArchive y x) emptyArchive (entries i)
@@ -323,6 +325,7 @@ ibc i (IBCUsage n) f = return f { ibc_usage = n : ibc_usage f }
323325ibc i (IBCExport n) f = return f { ibc_exports = n : ibc_exports f }
324326ibc i (IBCAutoHint n h) f = return f { ibc_autohints = (n, h) : ibc_autohints f }
325327ibc i (IBCDeprecate n r) f = return f { ibc_deprecated = (n, r) : ibc_deprecated f }
328+ibc i (IBCFragile n r) f = return f { ibc_fragile = (n,r) : ibc_fragile f }
326329
327330getEntry :: (Binary b, NFData b) => b -> FilePath -> Archive -> Idris b
328331getEntry alt f a = case findEntryByPath f a of
@@ -392,6 +395,7 @@ process reexp phase archive fn = do
392395 processDefs archive
393396 processTotal archive
394397 processAccess reexp phase archive
398+ processFragile archive
395399
396400timestampOlder :: FilePath -> FilePath -> Idris ()
397401timestampOlder src ibc = do
@@ -441,6 +445,11 @@ processDeprecate ar = do
441445 ns <- getEntry [] "ibc_deprecated" ar
442446 mapM_ (\(n,reason) -> addDeprecated n reason) ns
443447
448+processFragile :: Archive -> Idris ()
449+processFragile ar = do
450+ ns <- getEntry [] "ibc_fragile" ar
451+ mapM_ (\(n,reason) -> addFragile n reason) ns
452+
444453processImportDirs :: Archive -> Idris ()
445454processImportDirs ar = do
446455 fs <- getEntry [] "ibc_importdirs" ar
src/Idris/Parser.hs+9−3
@@ -535,7 +535,7 @@ syntaxRule syn
535535 flip PQuasiquote goal <$> fixBind (q + 1) rens tm
536536 fixBind q rens (PUnquote tm) =
537537 PUnquote <$> fixBind (q - 1) rens tm
538−
538+
539539 fixBind q rens x = descendM (fixBind q rens) x
540540
541541 gensym :: Name -> IdrisParser Name
@@ -923,11 +923,11 @@ instance_ kwopt syn
923923 then [TotalFn]
924924 else []
925925
926− (doc, argDocs) <- docstring syn
926+ (doc, argDocs) <- docstring syn
927927 opts <- fnOpts initOpts
928928 acc <- accessibility
929929 opts' <- fnOpts opts
930−
930+
931931 if kwopt then optional instanceKeyword
932932 else do instanceKeyword
933933 return (Just ())
@@ -1319,6 +1319,8 @@ Directive' ::= 'lib' CodeGen String_t
13191319 | 'error_handlers' Name NameList
13201320 | 'language' 'TypeProviders'
13211321 | 'language' 'ErrorReflection'
1322+ | 'deprecated' Name String
1323+ | 'fragile' Name Reason
13221324 ;
13231325@
13241326-}
@@ -1371,6 +1373,10 @@ directive syn = do try (lchar '%' *> reserved "lib")
13711373 n <- fst <$> fnName
13721374 alt <- option "" (fst <$> stringLiteral)
13731375 return [PDirective (DDeprecate n alt)]
1376+ <|> do try (lchar '%' *> reserved "fragile")
1377+ n <- fst <$> fnName
1378+ alt <- option "" (fst <$> stringLiteral)
1379+ return [PDirective (DFragile n alt)]
13741380 <|> do fc <- getFC
13751381 try (lchar '%' *> reserved "used")
13761382 fn <- fst <$> fnName
test/directives001/directives001.idrnew file+28
@@ -0,0 +1,28 @@
1+module directives001
2+
3+%access export
4+
5+
6+data Foo = MkFoo String
7+
8+%deprecate Foo "To be replaced with `Bar`."
9+
10+data Bar : Type where
11+ MkBar : Nat -> Nat -> Bar
12+
13+
14+mkFoo : String -> Foo
15+mkFoo = MkFoo
16+
17+%deprecate mkFoo "To be replaced with `mkBar`."
18+
19+mkBar : Nat -> Bar
20+mkBar a = MkBar a a
21+
22+%fragile mkBar "How `Bar`s are to be created is still being discussed, `mkBar` is subject to change."
23+
24+namespace Main
25+ main : IO ()
26+ main = do
27+ let b = mkBar 1
28+ putStrLn $ "Hello World"
test/directives001/expectednew file+14
@@ -0,0 +1,14 @@
1+directives001.idr:14:7:Use of deprecated name directives001.Foo
2+To be replaced with `Bar`.
3+directives001.idr:14:7:Use of deprecated name directives001.Foo
4+To be replaced with `Bar`.
5+directives001.idr:15:7:Use of deprecated name directives001.Foo
6+To be replaced with `Bar`.
7+directives001.idr:15:7:Use of deprecated name directives001.Foo
8+To be replaced with `Bar`.
9+directives001.idr:26:8:
10+Use of a fragile construct directives001.mkBar
11+How `Bar`s are to be created is still being discussed, `mkBar` is subject to change.
12+directives001.idr:26:8:
13+Use of a fragile construct directives001.mkBar
14+How `Bar`s are to be created is still being discussed, `mkBar` is subject to change.
test/directives001/runnew file+4
@@ -0,0 +1,4 @@
1+#!/usr/bin/env bash
2+${IDRIS:-idris} $@ directives001.idr --check --nocolour
3+
4+rm -f directives001 *.ibc