1-- | Preprocess 'Agda.Syntax.Concrete.Declaration's, producing 'NiceDeclaration's.
2--
3-- * Attach fixity and syntax declarations to the definition they refer to.
4--
5-- * Distribute the following attributes to the individual definitions:
6-- @abstract@,
7-- @instance@,
8-- @postulate@,
9-- @primitive@,
10-- @private@,
11-- termination pragmas.
12--
13-- * Gather the function clauses belonging to one function definition.
14--
15-- * Expand ellipsis @...@ in function clauses following @with@.
16--
17-- * Infer mutual blocks.
18-- A block starts when a lone signature is encountered, and ends when
19-- all lone signatures have seen their definition.
20--
21-- * Handle interleaved mutual blocks.
22-- In an `interleaved mutual' block we:
23-- * leave the data and fun sigs in place
24-- * classify signatures in `constructor' block based on their return type
25-- and group them all as a data def at the position in the block where the
26-- first constructor for the data sig in question occured
27-- * classify fun clauses based on the declared function used and group them
28-- all as a fundef at the position in the block where the first such fun
29-- clause appeared
30--
31-- * Report basic well-formedness error,
32-- when one of the above transformation fails.
33-- When possible, errors should be deferred to the scope checking phase
34-- (ConcreteToAbstract), where we are in the TCM and can produce more
35-- informative error messages.
36
37
38module Agda.Syntax.Concrete.Definitions
39 ( NiceDeclaration(..)
40 , NiceConstructor, NiceTypeSignature
41 , Clause(..)
42 , DeclarationException(..)
43 , DeclarationWarning(..), DeclarationWarning'(..), unsafeDeclarationWarning
44 , Nice, NiceEnv(..), runNice
45 , niceDeclarations
46 , notSoNiceDeclarations
47 , niceHasAbstract
48 , Measure
49 , declarationWarningName
50 ) where
51
52
53import Prelude hiding (null)
54
55import Control.Monad ( forM, guard, unless, void, when )
56import Control.Monad.Except ( )
57import Control.Monad.Reader ( asks )
58import Control.Monad.State ( MonadState(..), gets, StateT, runStateT )
59import Control.Monad.Trans ( lift )
60
61import Data.Bifunctor
62import Data.Either (isLeft, isRight)
63import Data.Function (on)
64import qualified Data.Map as Map
65import Data.Map (Map)
66import Data.Maybe
67import Data.Semigroup ( Semigroup(..) )
68import qualified Data.List as List
69import qualified Data.Foldable as Fold
70import qualified Data.Traversable as Trav
71
72import Agda.Syntax.Concrete
73import Agda.Syntax.Concrete.Pattern
74import Agda.Syntax.Common hiding (TerminationCheck())
75import qualified Agda.Syntax.Common as Common
76import Agda.Syntax.Position
77import Agda.Syntax.Notation
78import Agda.Syntax.Concrete.Pretty () --instance only
79import Agda.Syntax.Concrete.Fixity
80import Agda.Syntax.Common.Pretty
81
82import Agda.Syntax.Concrete.Definitions.Errors
83import Agda.Syntax.Concrete.Definitions.Monad
84import Agda.Syntax.Concrete.Definitions.Types
85
86import Agda.Utils.AffineHole
87import Agda.Utils.CallStack ( CallStack, HasCallStack, withCallerCallStack )
88import Agda.Utils.Functor
89import Agda.Utils.Lens
90import Agda.Utils.List (isSublistOf, spanJust)
91import Agda.Utils.List1 (List1, pattern (:|), (<|))
92import qualified Agda.Utils.List1 as List1
93import Agda.Utils.Maybe
94import Agda.Utils.Monad
95import Agda.Utils.Null
96import Agda.Utils.Singleton
97import Agda.Utils.Three
98import Agda.Utils.Tuple
99import Agda.Utils.Update
100
101import Agda.Utils.Impossible
102
103{--------------------------------------------------------------------------
104 The niceifier
105 --------------------------------------------------------------------------}
106
107-- | Check that declarations in a mutual block are consistently
108-- equipped with MEASURE pragmas, or whether there is a
109-- NO_TERMINATION_CHECK pragma.
110combineTerminationChecks :: Range -> [TerminationCheck] -> Nice TerminationCheck
111combineTerminationChecks r = loop
112 where
113 loop :: [TerminationCheck] -> Nice TerminationCheck
114 loop [] = return TerminationCheck
115 loop (tc : tcs) = do
116 tc' <- loop tcs
117 case (tc, tc') of
118 (TerminationCheck , tc' ) -> return tc'
119 (tc , TerminationCheck ) -> return tc
120 (NonTerminating , NonTerminating ) -> return NonTerminating
121 (NoTerminationCheck , NoTerminationCheck ) -> return NoTerminationCheck
122 (NoTerminationCheck , Terminating ) -> return Terminating
123 (Terminating , NoTerminationCheck ) -> return Terminating
124 (Terminating , Terminating ) -> return Terminating
125 (TerminationMeasure{} , TerminationMeasure{} ) -> return tc
126 (TerminationMeasure r _, NoTerminationCheck ) -> failure r
127 (TerminationMeasure r _, Terminating ) -> failure r
128 (NoTerminationCheck , TerminationMeasure r _) -> failure r
129 (Terminating , TerminationMeasure r _) -> failure r
130 (TerminationMeasure r _, NonTerminating ) -> failure r
131 (NonTerminating , TerminationMeasure r _) -> failure r
132 (NoTerminationCheck , NonTerminating ) -> failure r
133 (Terminating , NonTerminating ) -> failure r
134 (NonTerminating , NoTerminationCheck ) -> failure r
135 (NonTerminating , Terminating ) -> failure r
136 failure r = declarationException $ InvalidMeasureMutual r
137
138combineCoverageChecks :: [CoverageCheck] -> CoverageCheck
139combineCoverageChecks = Fold.fold
140
141combinePositivityChecks :: [PositivityCheck] -> PositivityCheck
142combinePositivityChecks = Fold.fold
143
144data DeclKind
145 = LoneSigDecl Range DataRecOrFun Name
146 | LoneDefs DataRecOrFun [Name]
147 | OtherDecl
148 deriving (Eq, Show)
149
150declKind :: NiceDeclaration -> DeclKind
151declKind (FunSig r _ _ _ _ _ tc cc x _) = LoneSigDecl r (FunName tc cc) x
152declKind (NiceRecSig r _ _ _ pc uc x _ _) = LoneSigDecl r (RecName pc uc) x
153declKind (NiceDataSig r _ _ _ pc uc x _ _) = LoneSigDecl r (DataName pc uc) x
154declKind (FunDef r _ abs ins tc cc x _) = LoneDefs (FunName tc cc) [x]
155declKind (NiceDataDef _ _ _ pc uc x pars _) = LoneDefs (DataName pc uc) [x]
156declKind (NiceUnquoteData _ _ _ pc uc x _ _) = LoneDefs (DataName pc uc) [x]
157declKind (NiceRecDef _ _ _ pc uc x _ pars _) = LoneDefs (RecName pc uc) [x]
158declKind (NiceUnquoteDef _ _ _ tc cc xs _) = LoneDefs (FunName tc cc) xs
159declKind Axiom{} = OtherDecl
160declKind NiceField{} = OtherDecl
161declKind PrimitiveFunction{} = OtherDecl
162declKind NiceMutual{} = OtherDecl
163declKind NiceModule{} = OtherDecl
164declKind NiceModuleMacro{} = OtherDecl
165declKind NiceOpen{} = OtherDecl
166declKind NiceImport{} = OtherDecl
167declKind NicePragma{} = OtherDecl
168declKind NiceFunClause{} = OtherDecl
169declKind NicePatternSyn{} = OtherDecl
170declKind NiceGeneralize{} = OtherDecl
171declKind NiceUnquoteDecl{} = OtherDecl
172declKind NiceLoneConstructor{} = OtherDecl
173declKind NiceOpaque{} = OtherDecl
174
175-- | Replace (Data/Rec/Fun)Sigs with Axioms for postulated names
176-- The first argument is a list of axioms only.
177replaceSigs
178 :: LoneSigs -- ^ Lone signatures to be turned into Axioms
179 -> [NiceDeclaration] -- ^ Declarations containing them
180 -> [NiceDeclaration] -- ^ In the output, everything should be defined
181replaceSigs ps = if Map.null ps then id else \case
182 [] -> __IMPOSSIBLE__
183 (d:ds) ->
184 case replaceable d of
185 -- If declaration d of x is mentioned in the map of lone signatures then replace
186 -- it with an axiom
187 Just (x, axiom)
188 | (Just (LoneSig _ x' _), ps') <- Map.updateLookupWithKey (\ _ _ -> Nothing) x ps
189 , getRange x == getRange x'
190 -- Use the range as UID to ensure we do not replace the wrong signature.
191 -- This could happen if the user wrote a duplicate definition.
192 -> axiom : replaceSigs ps' ds
193 _ -> d : replaceSigs ps ds
194
195 where
196
197 -- A @replaceable@ declaration is a signature. It has a name and we can make an
198 -- @Axiom@ out of it.
199 replaceable :: NiceDeclaration -> Maybe (Name, NiceDeclaration)
200 replaceable = \case
201 FunSig r acc abst inst _ argi _ _ x' e ->
202 -- #4881: Don't use the unique NameId for NoName lookups.
203 let x = if isNoName x' then noName (nameRange x') else x' in
204 Just (x, Axiom r acc abst inst argi x' e)
205 NiceRecSig r erased acc abst _ _ x pars t ->
206 let e = Generalized $ makePi (lamBindingsToTelescope r pars) t in
207 Just (x, Axiom r acc abst NotInstanceDef
208 (setQuantity (asQuantity erased) defaultArgInfo) x e)
209 NiceDataSig r erased acc abst _ _ x pars t ->
210 let e = Generalized $ makePi (lamBindingsToTelescope r pars) t in
211 Just (x, Axiom r acc abst NotInstanceDef
212 (setQuantity (asQuantity erased) defaultArgInfo) x e)
213 _ -> Nothing
214
215-- | Main. Fixities (or more precisely syntax declarations) are needed when
216-- grouping function clauses.
217niceDeclarations :: Fixities -> [Declaration] -> Nice [NiceDeclaration]
218niceDeclarations fixs ds = do
219
220 -- Run the nicifier in an initial environment. But keep the warnings.
221 st <- get
222 put $ initNiceState { niceWarn = niceWarn st }
223 nds <- nice ds
224
225 -- Check that every signature got its definition.
226 ps <- use loneSigs
227 checkLoneSigs ps
228 -- We postulate the missing ones and insert them in place of the corresponding @FunSig@
229 let ds = replaceSigs ps nds
230
231 -- Note that loneSigs is ensured to be empty.
232 -- (Important, since inferMutualBlocks also uses loneSigs state).
233 res <- inferMutualBlocks ds
234
235 -- Restore the old state, but keep the warnings.
236 warns <- gets niceWarn
237 put $ st { niceWarn = warns }
238 return res
239
240 where
241
242 inferMutualBlocks :: [NiceDeclaration] -> Nice [NiceDeclaration]
243 inferMutualBlocks [] = return []
244 inferMutualBlocks (d : ds) =
245 case declKind d of
246 OtherDecl -> (d :) <$> inferMutualBlocks ds
247 LoneDefs{} -> (d :) <$> inferMutualBlocks ds -- Andreas, 2017-10-09, issue #2576: report error in ConcreteToAbstract
248 LoneSigDecl r k x -> do
249 _ <- addLoneSig r x k
250 InferredMutual checks nds0 ds1 <- untilAllDefined (mutualChecks k) ds
251 -- If we still have lone signatures without any accompanying definition,
252 -- we postulate the definition and substitute the axiom for the lone signature
253 ps <- use loneSigs
254 checkLoneSigs ps
255 let ds0 = replaceSigs ps (d : nds0) -- NB: don't forget the LoneSig the block started with!
256 -- We then keep processing the rest of the block
257 tc <- combineTerminationChecks (getRange d) (mutualTermination checks)
258 let cc = combineCoverageChecks (mutualCoverage checks)
259 let pc = combinePositivityChecks (mutualPositivity checks)
260 (NiceMutual empty tc cc pc ds0 :) <$> inferMutualBlocks ds1
261 where
262 untilAllDefined :: MutualChecks -> [NiceDeclaration] -> Nice InferredMutual
263 untilAllDefined checks ds = do
264 done <- noLoneSigs
265 if done then return (InferredMutual checks [] ds) else
266 case ds of
267 [] -> return (InferredMutual checks [] ds)
268 d : ds -> case declKind d of
269 LoneSigDecl r k x -> do
270 void $ addLoneSig r x k
271 extendInferredBlock d <$> untilAllDefined (mutualChecks k <> checks) ds
272 LoneDefs k xs -> do
273 mapM_ removeLoneSig xs
274 extendInferredBlock d <$> untilAllDefined (mutualChecks k <> checks) ds
275 OtherDecl -> extendInferredBlock d <$> untilAllDefined checks ds
276
277 nice :: [Declaration] -> Nice [NiceDeclaration]
278 nice [] = return []
279 nice ds = do
280 (xs , ys) <- nice1 ds
281 (xs ++) <$> nice ys
282
283 nice1 :: [Declaration] -> Nice ([NiceDeclaration], [Declaration])
284 nice1 [] = return ([], []) -- Andreas, 2017-09-16, issue #2759: no longer __IMPOSSIBLE__
285 nice1 (d:ds) = do
286 let justWarning :: HasCallStack => DeclarationWarning' -> Nice ([NiceDeclaration], [Declaration])
287 justWarning w = do
288 -- NOTE: This is the location of the invoker of justWarning, not here.
289 withCallerCallStack $ declarationWarning' w
290 nice1 ds
291
292 case d of
293
294 TypeSig info _tac x t -> do
295 termCheck <- use terminationCheckPragma
296 covCheck <- use coverageCheckPragma
297 -- Andreas, 2020-09-28, issue #4950: take only range of identifier,
298 -- since parser expands type signatures with several identifiers
299 -- (like @x y z : A@) into several type signatures (with imprecise ranges).
300 let r = getRange x
301 -- register x as lone type signature, to recognize clauses later
302 x' <- addLoneSig r x $ FunName termCheck covCheck
303 return ([FunSig r PublicAccess ConcreteDef NotInstanceDef NotMacroDef info termCheck covCheck x' t] , ds)
304
305 -- Should not show up: all FieldSig are part of a Field block
306 FieldSig{} -> __IMPOSSIBLE__
307
308 Generalize r [] -> justWarning $ EmptyGeneralize r
309 Generalize _ sigs -> do
310 gs <- forM sigs $ \case
311 sig@(TypeSig info tac x t) -> do
312 -- Andreas, 2022-03-25, issue #5850:
313 -- Warn about @variable {x} : A@ which is equivalent to @variable x : A@.
314 when (getHiding info == Hidden) $
315 declarationWarning $ HiddenGeneralize $ getRange x
316 return $ NiceGeneralize (getRange sig) PublicAccess info tac x t
317 _ -> __IMPOSSIBLE__
318 return (gs, ds)
319
320 (FunClause lhs _ _ _) -> do
321 termCheck <- use terminationCheckPragma
322 covCheck <- use coverageCheckPragma
323 catchall <- popCatchallPragma
324 xs <- loneFuns <$> use loneSigs
325 -- for each type signature 'x' waiting for clauses, we try
326 -- if we have some clauses for 'x'
327 case [ (x, (x', fits, rest))
328 | (x, x') <- xs
329 , let (fits, rest) =
330 -- Anonymous declarations only have 1 clause each!
331 if isNoName x then ([d], ds)
332 else span (couldBeFunClauseOf (Map.lookup x fixs) x) (d : ds)
333 , not (null fits)
334 ] of
335
336 -- case: clauses match none of the sigs
337 [] -> case lhs of
338 -- Subcase: The lhs is single identifier (potentially anonymous).
339 -- Treat it as a function clause without a type signature.
340 LHS p [] [] | Just x <- isSingleIdentifierP p -> do
341 d <- mkFunDef (setOrigin Inserted defaultArgInfo) termCheck covCheck x Nothing [d] -- fun def without type signature is relevant
342 return (d , ds)
343 -- Subcase: The lhs is a proper pattern.
344 -- This could be a let-pattern binding. Pass it on.
345 -- A missing type signature error might be raise in ConcreteToAbstract
346 _ -> do
347 return ([NiceFunClause (getRange d) PublicAccess ConcreteDef termCheck covCheck catchall d] , ds)
348
349 -- case: clauses match exactly one of the sigs
350 [(x,(x',fits,rest))] -> do
351 -- The x'@NoName{} is the unique version of x@NoName{}.
352 removeLoneSig x
353 ds <- expandEllipsis fits
354 cs <- mkClauses x' ds False
355 return ([FunDef (getRange fits) fits ConcreteDef NotInstanceDef termCheck covCheck x' cs] , rest)
356
357 -- case: clauses match more than one sigs (ambiguity)
358 xf:xfs -> declarationException $ AmbiguousFunClauses lhs $ List1.reverse $ fmap fst $ xf :| xfs
359 -- "ambiguous function clause; cannot assign it uniquely to one type signature"
360
361 Field r [] -> justWarning $ EmptyField r
362 Field _ fs -> (,ds) <$> niceAxioms FieldBlock fs
363
364 DataSig r erased x tel t -> do
365 pc <- use positivityCheckPragma
366 uc <- use universeCheckPragma
367 _ <- addLoneSig r x $ DataName pc uc
368 (,ds) <$> dataOrRec pc uc NiceDataDef
369 (flip NiceDataSig erased) (niceAxioms DataBlock) r
370 x (Just (tel, t)) Nothing
371
372 Data r erased x tel t cs -> do
373 pc <- use positivityCheckPragma
374 -- Andreas, 2018-10-27, issue #3327
375 -- Propagate {-# NO_UNIVERSE_CHECK #-} pragma from signature to definition.
376 -- Universe check is performed if both the current value of
377 -- 'universeCheckPragma' AND the one from the signature say so.
378 uc <- use universeCheckPragma
379 uc <- if uc == NoUniverseCheck then return uc else getUniverseCheckFromSig x
380 mt <- defaultTypeSig (DataName pc uc) x (Just t)
381 (,ds) <$> dataOrRec pc uc NiceDataDef
382 (flip NiceDataSig erased) (niceAxioms DataBlock) r
383 x ((tel,) <$> mt) (Just (tel, cs))
384
385 DataDef r x tel cs -> do
386 pc <- use positivityCheckPragma
387 -- Andreas, 2018-10-27, issue #3327
388 -- Propagate {-# NO_UNIVERSE_CHECK #-} pragma from signature to definition.
389 -- Universe check is performed if both the current value of
390 -- 'universeCheckPragma' AND the one from the signature say so.
391 uc <- use universeCheckPragma
392 uc <- if uc == NoUniverseCheck then return uc else getUniverseCheckFromSig x
393 mt <- defaultTypeSig (DataName pc uc) x Nothing
394 (,ds) <$> dataOrRec pc uc NiceDataDef
395 (flip NiceDataSig defaultErased)
396 (niceAxioms DataBlock) r x ((tel,) <$> mt)
397 (Just (tel, cs))
398
399 RecordSig r erased x tel t -> do
400 pc <- use positivityCheckPragma
401 uc <- use universeCheckPragma
402 _ <- addLoneSig r x $ RecName pc uc
403 return ( [NiceRecSig r erased PublicAccess ConcreteDef pc uc x
404 tel t]
405 , ds
406 )
407
408 Record r erased x dir tel t cs -> do
409 pc <- use positivityCheckPragma
410 -- Andreas, 2018-10-27, issue #3327
411 -- Propagate {-# NO_UNIVERSE_CHECK #-} pragma from signature to definition.
412 -- Universe check is performed if both the current value of
413 -- 'universeCheckPragma' AND the one from the signature say so.
414 uc <- use universeCheckPragma
415 uc <- if uc == NoUniverseCheck then return uc else getUniverseCheckFromSig x
416 mt <- defaultTypeSig (RecName pc uc) x (Just t)
417 (,ds) <$> dataOrRec pc uc
418 (\r o a pc uc x tel cs ->
419 NiceRecDef r o a pc uc x dir tel cs)
420 (flip NiceRecSig erased) return r x
421 ((tel,) <$> mt) (Just (tel, cs))
422
423 RecordDef r x dir tel cs -> do
424 pc <- use positivityCheckPragma
425 -- Andreas, 2018-10-27, issue #3327
426 -- Propagate {-# NO_UNIVERSE_CHECK #-} pragma from signature to definition.
427 -- Universe check is performed if both the current value of
428 -- 'universeCheckPragma' AND the one from the signature say so.
429 uc <- use universeCheckPragma
430 uc <- if uc == NoUniverseCheck then return uc else getUniverseCheckFromSig x
431 mt <- defaultTypeSig (RecName pc uc) x Nothing
432 (,ds) <$> dataOrRec pc uc
433 (\r o a pc uc x tel cs ->
434 NiceRecDef r o a pc uc x dir tel cs)
435 (flip NiceRecSig defaultErased) return r x
436 ((tel,) <$> mt) (Just (tel, cs))
437
438 Mutual r ds' -> do
439 -- The lone signatures encountered so far are not in scope
440 -- for the mutual definition
441 breakImplicitMutualBlock r "`mutual` blocks"
442 case ds' of
443 [] -> justWarning $ EmptyMutual r
444 _ -> (,ds) <$> (singleton <$> (mkOldMutual r =<< nice ds'))
445
446 InterleavedMutual r ds' -> do
447 -- The lone signatures encountered so far are not in scope
448 -- for the mutual definition
449 breakImplicitMutualBlock r "`interleaved mutual` blocks"
450 case ds' of
451 [] -> justWarning $ EmptyMutual r
452 _ -> (,ds) <$> (singleton <$> (mkInterleavedMutual r =<< nice ds'))
453
454 LoneConstructor r [] -> justWarning $ EmptyConstructor r
455 LoneConstructor r ds' ->
456 ((,ds) . singleton . NiceLoneConstructor r) <$> niceAxioms ConstructorBlock ds'
457
458
459 Abstract r [] -> justWarning $ EmptyAbstract r
460 Abstract r ds' ->
461 (,ds) <$> (abstractBlock r =<< nice ds')
462
463 Private r UserWritten [] -> justWarning $ EmptyPrivate r
464 Private r o ds' ->
465 (,ds) <$> (privateBlock r o =<< nice ds')
466
467 InstanceB r [] -> justWarning $ EmptyInstance r
468 InstanceB r ds' ->
469 (,ds) <$> (instanceBlock r =<< nice ds')
470
471 Macro r [] -> justWarning $ EmptyMacro r
472 Macro r ds' ->
473 (,ds) <$> (macroBlock r =<< nice ds')
474
475 Postulate r [] -> justWarning $ EmptyPostulate r
476 Postulate _ ds' ->
477 (,ds) <$> niceAxioms PostulateBlock ds'
478
479 Primitive r [] -> justWarning $ EmptyPrimitive r
480 Primitive _ ds' -> (,ds) <$> (map toPrim <$> niceAxioms PrimitiveBlock ds')
481
482 Module r erased x tel ds' -> return $
483 ([NiceModule r PublicAccess ConcreteDef erased x tel ds'], ds)
484
485 ModuleMacro r erased x modapp op is -> return $
486 ([NiceModuleMacro r PublicAccess erased x modapp op is], ds)
487
488 -- Fixity and syntax declarations and polarity pragmas have
489 -- already been processed.
490 Infix _ _ -> return ([], ds)
491 Syntax _ _ -> return ([], ds)
492
493 PatternSyn r n as p -> do
494 return ([NicePatternSyn r PublicAccess n as p] , ds)
495 Open r x is -> return ([NiceOpen r x is] , ds)
496 Import r x as op is -> return ([NiceImport r x as op is] , ds)
497
498 UnquoteDecl r xs e -> do
499 tc <- use terminationCheckPragma
500 cc <- use coverageCheckPragma
501 return ([NiceUnquoteDecl r PublicAccess ConcreteDef NotInstanceDef tc cc xs e] , ds)
502
503 UnquoteDef r xs e -> do
504 sigs <- map fst . loneFuns <$> use loneSigs
505 List1.ifNotNull (filter (`notElem` sigs) xs)
506 {-then-} (declarationException . UnquoteDefRequiresSignature)
507 {-else-} $ do
508 mapM_ removeLoneSig xs
509 return ([NiceUnquoteDef r PublicAccess ConcreteDef TerminationCheck YesCoverageCheck xs e] , ds)
510
511 UnquoteData r xs cs e -> do
512 pc <- use positivityCheckPragma
513 uc <- use universeCheckPragma
514 return ([NiceUnquoteData r PublicAccess ConcreteDef pc uc xs cs e], ds)
515
516 Pragma p -> do
517 -- Warn about unsafe pragmas unless we are in a builtin module.
518 whenM (asks safeButNotBuiltin) $
519 whenJust (unsafePragma p) $ \ w ->
520 declarationWarning w
521 nicePragma p ds
522
523 Opaque r ds' -> do
524 breakImplicitMutualBlock r "`opaque` blocks"
525
526 -- Split the enclosed declarations into an initial run of
527 -- 'unfolding' statements and the rest of the body.
528 let
529 (unfoldings, body) = flip spanMaybe ds' $ \case
530 Unfolding _ ns -> pure ns
531 _ -> Nothing
532
533 -- The body of an 'opaque' definition can have mutual
534 -- recursion by interleaving type signatures and definitions,
535 -- just like the body of a module.
536 decls0 <- nice body
537 ps <- use loneSigs
538 checkLoneSigs ps
539 let decls = replaceSigs ps decls0
540 body <- inferMutualBlocks decls
541 pure ([NiceOpaque r (concat unfoldings) body], ds)
542
543 Unfolding r _ -> declarationException $ UnfoldingOutsideOpaque r
544
545 nicePragma :: Pragma -> [Declaration] -> Nice ([NiceDeclaration], [Declaration])
546
547 nicePragma (TerminationCheckPragma r (TerminationMeasure _ x)) ds =
548 if canHaveTerminationMeasure ds then
549 withTerminationCheckPragma (TerminationMeasure r x) $ nice1 ds
550 else do
551 declarationWarning $ InvalidTerminationCheckPragma r
552 nice1 ds
553
554 nicePragma (TerminationCheckPragma r NoTerminationCheck) ds = do
555 -- This PRAGMA has been deprecated in favour of (NON_)TERMINATING
556 -- We warn the user about it and then assume the function is NON_TERMINATING.
557 declarationWarning $ PragmaNoTerminationCheck r
558 nicePragma (TerminationCheckPragma r NonTerminating) ds
559
560 nicePragma (TerminationCheckPragma r tc) ds =
561 if canHaveTerminationCheckPragma ds then
562 withTerminationCheckPragma tc $ nice1 ds
563 else do
564 declarationWarning $ InvalidTerminationCheckPragma r
565 nice1 ds
566
567 nicePragma (NoCoverageCheckPragma r) ds =
568 if canHaveCoverageCheckPragma ds then
569 withCoverageCheckPragma NoCoverageCheck $ nice1 ds
570 else do
571 declarationWarning $ InvalidCoverageCheckPragma r
572 nice1 ds
573
574 nicePragma (CatchallPragma r) ds =
575 if canHaveCatchallPragma ds then
576 withCatchallPragma True $ nice1 ds
577 else do
578 declarationWarning $ InvalidCatchallPragma r
579 nice1 ds
580
581 nicePragma (NoPositivityCheckPragma r) ds =
582 if canHaveNoPositivityCheckPragma ds then
583 withPositivityCheckPragma NoPositivityCheck $ nice1 ds
584 else do
585 declarationWarning $ InvalidNoPositivityCheckPragma r
586 nice1 ds
587
588 nicePragma (NoUniverseCheckPragma r) ds =
589 if canHaveNoUniverseCheckPragma ds then
590 withUniverseCheckPragma NoUniverseCheck $ nice1 ds
591 else do
592 declarationWarning $ InvalidNoUniverseCheckPragma r
593 nice1 ds
594
595 nicePragma p@CompilePragma{} ds = do
596 return ([NicePragma (getRange p) p], ds)
597
598 nicePragma (PolarityPragma{}) ds = return ([], ds)
599
600 nicePragma (BuiltinPragma r str qn@(QName x)) ds = do
601 return ([NicePragma r (BuiltinPragma r str qn)], ds)
602
603 nicePragma p@RewritePragma{} ds = return ([NicePragma (getRange p) p], ds)
604 nicePragma p ds = return ([NicePragma (getRange p) p], ds)
605
606 canHaveTerminationMeasure :: [Declaration] -> Bool
607 canHaveTerminationMeasure [] = False
608 canHaveTerminationMeasure (d:ds) = case d of
609 TypeSig{} -> True
610 (Pragma p) | isAttachedPragma p -> canHaveTerminationMeasure ds
611 _ -> False
612
613 canHaveTerminationCheckPragma :: [Declaration] -> Bool
614 canHaveTerminationCheckPragma [] = False
615 canHaveTerminationCheckPragma (d:ds) = case d of
616 Mutual _ ds -> any (canHaveTerminationCheckPragma . singleton) ds
617 TypeSig{} -> True
618 FunClause{} -> True
619 UnquoteDecl{} -> True
620 (Pragma p) | isAttachedPragma p -> canHaveTerminationCheckPragma ds
621 _ -> False
622
623 canHaveCoverageCheckPragma :: [Declaration] -> Bool
624 canHaveCoverageCheckPragma = canHaveTerminationCheckPragma
625
626 canHaveCatchallPragma :: [Declaration] -> Bool
627 canHaveCatchallPragma [] = False
628 canHaveCatchallPragma (d:ds) = case d of
629 FunClause{} -> True
630 (Pragma p) | isAttachedPragma p -> canHaveCatchallPragma ds
631 _ -> False
632
633 canHaveNoPositivityCheckPragma :: [Declaration] -> Bool
634 canHaveNoPositivityCheckPragma [] = False
635 canHaveNoPositivityCheckPragma (d:ds) = case d of
636 Mutual _ ds -> any (canHaveNoPositivityCheckPragma . singleton) ds
637 Data{} -> True
638 DataSig{} -> True
639 DataDef{} -> True
640 Record{} -> True
641 RecordSig{} -> True
642 RecordDef{} -> True
643 Pragma p | isAttachedPragma p -> canHaveNoPositivityCheckPragma ds
644 _ -> False
645
646 canHaveNoUniverseCheckPragma :: [Declaration] -> Bool
647 canHaveNoUniverseCheckPragma [] = False
648 canHaveNoUniverseCheckPragma (d:ds) = case d of
649 Data{} -> True
650 DataSig{} -> True
651 DataDef{} -> True
652 Record{} -> True
653 RecordSig{} -> True
654 RecordDef{} -> True
655 Pragma p | isAttachedPragma p -> canHaveNoPositivityCheckPragma ds
656 _ -> False
657
658 -- Pragma that attaches to the following declaration.
659 isAttachedPragma :: Pragma -> Bool
660 isAttachedPragma = \case
661 TerminationCheckPragma{} -> True
662 CatchallPragma{} -> True
663 NoPositivityCheckPragma{} -> True
664 NoUniverseCheckPragma{} -> True
665 _ -> False
666
667 -- We could add a default type signature here, but at the moment we can't
668 -- infer the type of a record or datatype, so better to just fail here.
669 defaultTypeSig :: DataRecOrFun -> Name -> Maybe Expr -> Nice (Maybe Expr)
670 defaultTypeSig k x t@Just{} = return t
671 defaultTypeSig k x Nothing = do
672 caseMaybeM (getSig x) (return Nothing) $ \ k' -> do
673 unless (sameKind k k') $ declarationException $ WrongDefinition x k' k
674 Nothing <$ removeLoneSig x
675
676 dataOrRec
677 :: forall a decl
678 . PositivityCheck
679 -> UniverseCheck
680 -> (Range -> Origin -> IsAbstract -> PositivityCheck -> UniverseCheck -> Name -> [LamBinding] -> [decl] -> NiceDeclaration)
681 -- Construct definition.
682 -> (Range -> Access -> IsAbstract -> PositivityCheck -> UniverseCheck -> Name -> [LamBinding] -> Expr -> NiceDeclaration)
683 -- Construct signature.
684 -> ([a] -> Nice [decl]) -- Constructor checking.
685 -> Range
686 -> Name -- Data/record type name.
687 -> Maybe ([LamBinding], Expr) -- Parameters and type. If not @Nothing@ a signature is created.
688 -> Maybe ([LamBinding], [a]) -- Parameters and constructors. If not @Nothing@, a definition body is created.
689 -> Nice [NiceDeclaration]
690 dataOrRec pc uc mkDef mkSig niceD r x mt mcs = do
691 mds <- Trav.forM mcs $ \ (tel, cs) -> (tel,) <$> niceD cs
692 -- We set origin to UserWritten if the user split the data/rec herself,
693 -- and to Inserted if the she wrote a single declaration that we're
694 -- splitting up here. We distinguish these because the scoping rules for
695 -- generalizable variables differ in these cases.
696 let o | isJust mt && isJust mcs = Inserted
697 | otherwise = UserWritten
698 return $ catMaybes $
699 [ mt <&> \ (tel, t) -> mkSig (fuseRange x t) PublicAccess ConcreteDef pc uc x tel t
700 , mds <&> \ (tel, ds) -> mkDef r o ConcreteDef pc uc x (caseMaybe mt tel $ const $ concatMap dropTypeAndModality tel) ds
701 -- If a type is given (mt /= Nothing), we have to delete the types in @tel@
702 -- for the data definition, lest we duplicate them. And also drop modalities (#1886).
703 ]
704 -- Translate axioms
705 niceAxioms :: KindOfBlock -> [TypeSignatureOrInstanceBlock] -> Nice [NiceDeclaration]
706 niceAxioms b ds = List.concat <$> mapM (niceAxiom b) ds
707
708 niceAxiom :: KindOfBlock -> TypeSignatureOrInstanceBlock -> Nice [NiceDeclaration]
709 niceAxiom b = \case
710 d@(TypeSig rel _tac x t) -> do
711 return [ Axiom (getRange d) PublicAccess ConcreteDef NotInstanceDef rel x t ]
712 d@(FieldSig i tac x argt) | b == FieldBlock -> do
713 return [ NiceField (getRange d) PublicAccess ConcreteDef i tac x argt ]
714 InstanceB r decls -> do
715 instanceBlock r =<< niceAxioms InstanceBlock decls
716 Private r o decls | PostulateBlock <- b -> do
717 privateBlock r o =<< niceAxioms b decls
718 Pragma p@(RewritePragma r _ _) -> return [ NicePragma r p ]
719 Pragma p@(OverlapPragma r _ _) -> return [ NicePragma r p ]
720 d -> declarationException $ WrongContentBlock b $ getRange d
721
722 toPrim :: NiceDeclaration -> NiceDeclaration
723 toPrim (Axiom r p a i rel x t) = PrimitiveFunction r p a x (Arg rel t)
724 toPrim _ = __IMPOSSIBLE__
725
726 -- Create a function definition.
727 mkFunDef info termCheck covCheck x mt ds0 = do
728 ds <- expandEllipsis ds0
729 cs <- mkClauses x ds False
730 return [ FunSig (fuseRange x t) PublicAccess ConcreteDef NotInstanceDef NotMacroDef info termCheck covCheck x t
731 , FunDef (getRange ds0) ds0 ConcreteDef NotInstanceDef termCheck covCheck x cs ]
732 where
733 t = fromMaybe (underscore (getRange x)) mt
734
735 underscore r = Underscore r Nothing
736
737
738 expandEllipsis :: [Declaration] -> Nice [Declaration]
739 expandEllipsis [] = return []
740 expandEllipsis (d@(FunClause lhs@(LHS p _ _) _ _ _) : ds)
741 | hasEllipsis p = (d :) <$> expandEllipsis ds
742 | otherwise = (d :) <$> expand (killRange p) ds
743 where
744 expand :: Pattern -> [Declaration] -> Nice [Declaration]
745 expand _ [] = return []
746 expand p (d : ds) = do
747 case d of
748 Pragma (CatchallPragma _) -> do
749 (d :) <$> expand p ds
750 FunClause (LHS p0 eqs es) rhs wh ca -> do
751 case hasEllipsis' p0 of
752 ManyHoles -> declarationException $ MultipleEllipses p0
753 OneHole cxt ~(EllipsisP r Nothing) -> do
754 -- Replace the ellipsis by @p@.
755 let p1 = cxt $ EllipsisP r $ Just $ setRange r p
756 let d' = FunClause (LHS p1 eqs es) rhs wh ca
757 -- If we have with-expressions (es /= []) then the following
758 -- ellipses also get the additional patterns in p0.
759 (d' :) <$> expand (if null es then p else killRange p1) ds
760 ZeroHoles _ -> do
761 -- We can have ellipses after a fun clause without.
762 -- They refer to the last clause that introduced new with-expressions.
763 -- Same here: If we have new with-expressions, the next ellipses will
764 -- refer to us.
765 -- Andreas, Jesper, 2017-05-13, issue #2578
766 -- Need to update the range also on the next with-patterns.
767 (d :) <$> expand (if null es then p else killRange p0) ds
768 _ -> __IMPOSSIBLE__
769 expandEllipsis _ = __IMPOSSIBLE__
770
771 -- Turn function clauses into nice function clauses.
772 mkClauses :: Name -> [Declaration] -> Catchall -> Nice [Clause]
773 mkClauses _ [] _ = return []
774 mkClauses x (Pragma (CatchallPragma r) : cs) True = do
775 declarationWarning $ InvalidCatchallPragma r
776 mkClauses x cs True
777 mkClauses x (Pragma (CatchallPragma r) : cs) False = do
778 when (null cs) $ declarationWarning $ InvalidCatchallPragma r
779 mkClauses x cs True
780
781 mkClauses x (FunClause lhs rhs wh ca : cs) catchall
782 | null (lhsWithExpr lhs) || hasEllipsis lhs =
783 (Clause x (ca || catchall) lhs rhs wh [] :) <$> mkClauses x cs False -- Will result in an error later.
784
785 mkClauses x (FunClause lhs rhs wh ca : cs) catchall = do
786 when (null withClauses) $ declarationException $ MissingWithClauses x lhs
787 wcs <- mkClauses x withClauses False
788 (Clause x (ca || catchall) lhs rhs wh wcs :) <$> mkClauses x cs' False
789 where
790 (withClauses, cs') = subClauses cs
791
792 -- A clause is a subclause if the number of with-patterns is
793 -- greater or equal to the current number of with-patterns plus the
794 -- number of with arguments.
795 numWith = numberOfWithPatterns p + length (filter visible es) where LHS p _ es = lhs
796
797 subClauses :: [Declaration] -> ([Declaration],[Declaration])
798 subClauses (c@(FunClause (LHS p0 _ _) _ _ _) : cs)
799 | isEllipsis p0 ||
800 numberOfWithPatterns p0 >= numWith = mapFst (c:) (subClauses cs)
801 | otherwise = ([], c:cs)
802 subClauses (c@(Pragma (CatchallPragma r)) : cs) = case subClauses cs of
803 ([], cs') -> ([], c:cs')
804 (cs, cs') -> (c:cs, cs')
805 subClauses [] = ([],[])
806 subClauses _ = __IMPOSSIBLE__
807 mkClauses _ _ _ = __IMPOSSIBLE__
808
809 couldBeCallOf :: Maybe Fixity' -> Name -> Pattern -> Bool
810 couldBeCallOf mFixity x p =
811 let
812 pns = patternNames p
813 xStrings = nameStringParts x
814 patStrings = concatMap nameStringParts pns
815 in
816-- trace ("x = " ++ prettyShow x) $
817-- trace ("pns = " ++ show pns) $
818-- trace ("xStrings = " ++ show xStrings) $
819-- trace ("patStrings = " ++ show patStrings) $
820-- trace ("mFixity = " ++ show mFixity) $
821 case (listToMaybe pns, mFixity) of
822 -- first identifier in the patterns is the fun.symbol?
823 (Just y, _) | x == y -> True -- trace ("couldBe since y = " ++ prettyShow y) $ True
824 -- are the parts of x contained in p
825 _ | xStrings `isSublistOf` patStrings -> True -- trace ("couldBe since isSublistOf") $ True
826 -- looking for a mixfix fun.symb
827 (_, Just fix) -> -- also matches in case of a postfix
828 let notStrings = stringParts (theNotation fix)
829 in -- trace ("notStrings = " ++ show notStrings) $
830 -- trace ("patStrings = " ++ show patStrings) $
831 not (null notStrings) && (notStrings `isSublistOf` patStrings)
832 -- not a notation, not first id: give up
833 _ -> False -- trace ("couldBe not (case default)") $ False
834
835
836 -- for finding nice clauses for a type sig in mutual blocks
837 couldBeNiceFunClauseOf :: Maybe Fixity' -> Name -> NiceDeclaration
838 -> Maybe (MutualChecks, Declaration)
839 couldBeNiceFunClauseOf mf n (NiceFunClause _ _ _ tc cc _ d)
840 = (MutualChecks [tc] [cc] [], d) <$ guard (couldBeFunClauseOf mf n d)
841 couldBeNiceFunClauseOf _ _ _ = Nothing
842
843 -- for finding clauses for a type sig in mutual blocks
844 couldBeFunClauseOf :: Maybe Fixity' -> Name -> Declaration -> Bool
845 couldBeFunClauseOf mFixity x (Pragma (CatchallPragma{})) = True
846 couldBeFunClauseOf mFixity x (FunClause (LHS p _ _) _ _ _) =
847 hasEllipsis p || couldBeCallOf mFixity x p
848 couldBeFunClauseOf _ _ _ = False -- trace ("couldBe not (fun default)") $ False
849
850 -- Turn a new style `interleaved mutual' block into a new style mutual block
851 -- by grouping the declarations in blocks.
852 mkInterleavedMutual
853 :: KwRange -- Range of the @interleaved mutual@ keywords.
854 -> [NiceDeclaration] -- Declarations inside the block.
855 -> Nice NiceDeclaration -- Returns a 'NiceMutual'.
856 mkInterleavedMutual kwr ds' = do
857 (other, (m, checks, _)) <- runStateT (groupByBlocks kwr ds') (empty, mempty, 0)
858 let idecls = other ++ concatMap (uncurry interleavedDecl) (Map.toList m)
859 let decls0 = map snd $ List.sortBy (compare `on` fst) idecls
860 ps <- use loneSigs
861 checkLoneSigs ps
862 let decls = replaceSigs ps decls0
863 -- process the checks
864 let r = fuseRange kwr ds'
865 tc <- combineTerminationChecks r (mutualTermination checks)
866 let cc = combineCoverageChecks (mutualCoverage checks)
867 let pc = combinePositivityChecks (mutualPositivity checks)
868 pure $ NiceMutual kwr tc cc pc decls
869
870 where
871
872 ------------------------------------------------------------------------------
873 -- Adding Signatures
874 addType :: Name -> (DeclNum -> a) -> MutualChecks
875 -> StateT (Map Name a, MutualChecks, DeclNum) Nice ()
876 addType n c mc = do
877 (m, checks, i) <- get
878 when (isJust $ Map.lookup n m) $ lift $ declarationException $ DuplicateDefinition n
879 put (Map.insert n (c i) m, mc <> checks, i + 1)
880
881 addFunType d@(FunSig _ _ _ _ _ _ tc cc n _) = do
882 let checks = MutualChecks [tc] [cc] []
883 addType n (\ i -> InterleavedFun i d Nothing) checks
884 addFunType _ = __IMPOSSIBLE__
885
886 addDataType d@(NiceDataSig _ _ _ _ pc uc n _ _) = do
887 let checks = MutualChecks [] [] [pc]
888 addType n (\ i -> InterleavedData i d Nothing) checks
889 addDataType _ = __IMPOSSIBLE__
890
891 ------------------------------------------------------------------------------
892 -- Adding constructors & clauses
893
894 addDataConstructors :: Maybe Range -- Range of the `data A where` (if any)
895 -> Maybe Name -- Data type the constructors belong to
896 -> [NiceConstructor] -- Constructors to add
897 -> StateT (InterleavedMutual, MutualChecks, DeclNum) Nice ()
898 -- if we know the type's name, we can go ahead
899 addDataConstructors mr (Just n) ds = do
900 (m, checks, i) <- get
901 case Map.lookup n m of
902 Just (InterleavedData i0 sig cs) -> do
903 lift $ removeLoneSig n
904 -- add the constructors to the existing ones (if any)
905 let (cs', i') = case cs of
906 Nothing -> ((i , ds :| [] ), i + 1)
907 Just (i1, ds1) -> ((i1, ds <| ds1), i)
908 put (Map.insert n (InterleavedData i0 sig (Just cs')) m, checks, i')
909 _ -> lift $ declarationWarning $ MissingDeclarations $ case mr of
910 Just r -> [(n, r)]
911 Nothing -> flip foldMap ds $ \case
912 Axiom r _ _ _ _ n _ -> [(n, r)]
913 _ -> __IMPOSSIBLE__
914
915 addDataConstructors mr Nothing [] = pure ()
916
917 -- Otherwise we try to guess which datasig the constructor is referring to
918 addDataConstructors mr Nothing (d : ds) = do
919 -- get the candidate data types that are in this interleaved mutual block
920 (m, _, _) <- get
921 let sigs = mapMaybe (\ (n, d) -> n <$ isInterleavedData d) $ Map.toList m
922 -- check whether this constructor matches any of them
923 case isConstructor sigs d of
924 Right n -> do
925 -- if so grab the whole block that may work and add them
926 let (ds0, ds1) = span (isRight . isConstructor [n]) ds
927 addDataConstructors Nothing (Just n) (d : ds0)
928 -- and then repeat the process for the rest of the block
929 addDataConstructors Nothing Nothing ds1
930 Left (n, ns) -> lift $ declarationException $ AmbiguousConstructor (getRange d) n ns
931
932 addFunDef :: NiceDeclaration -> StateT (InterleavedMutual, MutualChecks, DeclNum) Nice ()
933 addFunDef (FunDef _ ds _ _ tc cc n cs) = do
934 let check = MutualChecks [tc] [cc] []
935 (m, checks, i) <- get
936 case Map.lookup n m of
937 Just (InterleavedFun i0 sig cs0) -> do
938 let (cs', i') = case cs0 of
939 Nothing -> ((i, (ds, cs) :| [] ), i + 1)
940 Just (i1, cs1) -> ((i1, (ds, cs) <| cs1), i)
941 put (Map.insert n (InterleavedFun i0 sig (Just cs')) m, check <> checks, i')
942 _ -> __IMPOSSIBLE__ -- A FunDef always come after an existing FunSig!
943 addFunDef _ = __IMPOSSIBLE__
944
945 addFunClauses ::
946 KwRange
947 -> [NiceDeclaration]
948 -> StateT (InterleavedMutual, MutualChecks, DeclNum) Nice [(DeclNum, NiceDeclaration)]
949 addFunClauses r (nd@(NiceFunClause _ _ _ tc cc _ d@(FunClause lhs _ _ _)) : ds) = do
950 -- get the candidate functions that are in this interleaved mutual block
951 (m, checks, i) <- get
952 let sigs = mapMaybe (\ (n, d) -> n <$ isInterleavedFun d) $ Map.toList m
953 -- find the funsig candidates for the funclause of interest
954 case [ (x, fits, rest)
955 | x <- sigs
956 , let (fits, rest) = spanJust (couldBeNiceFunClauseOf (Map.lookup x fixs) x) (nd : ds)
957 , not (null fits)
958 ] of
959 -- no candidate: keep the isolated fun clause, we'll complain about it later
960 [] -> do
961 let check = MutualChecks [tc] [cc] []
962 put (m, check <> checks, i + 1)
963 ((i,nd) :) <$> groupByBlocks r ds
964 -- exactly one candidate: attach the funclause to the definition
965 [(n, fits0, rest)] -> do
966 let (checkss, fits) = unzip fits0
967 ds <- lift $ expandEllipsis fits
968 cs <- lift $ mkClauses n ds False
969 case Map.lookup n m of
970 Just (InterleavedFun i0 sig cs0) -> do
971 let (cs', i') = case cs0 of
972 Nothing -> ((i, (fits,cs) :| [] ), i + 1)
973 Just (i1, cs1) -> ((i1, (fits,cs) <| cs1), i)
974 let checks' = Fold.fold checkss
975 put (Map.insert n (InterleavedFun i0 sig (Just cs')) m, checks' <> checks, i')
976 _ -> __IMPOSSIBLE__
977 groupByBlocks r rest
978 -- more than one candidate: fail, complaining about the ambiguity!
979 xf:xfs -> lift $ declarationException
980 $ AmbiguousFunClauses lhs
981 $ List1.reverse $ fmap (\ (a,_,_) -> a) $ xf :| xfs
982 addFunClauses _ _ = __IMPOSSIBLE__
983
984 groupByBlocks ::
985 KwRange
986 -> [NiceDeclaration]
987 -> StateT (InterleavedMutual, MutualChecks, DeclNum) Nice [(DeclNum, NiceDeclaration)]
988 groupByBlocks kwr [] = pure []
989 groupByBlocks kwr (d : ds) = do
990 -- for most branches we deal with the one declaration and move on
991 let oneOff act = act >>= \ ns -> (ns ++) <$> groupByBlocks kwr ds
992 case d of
993 NiceDataSig{} -> oneOff $ [] <$ addDataType d
994 NiceDataDef r _ _ _ _ n _ ds -> oneOff $ [] <$ addDataConstructors (Just r) (Just n) ds
995 NiceLoneConstructor _ ds -> oneOff $ [] <$ addDataConstructors Nothing Nothing ds
996 FunSig{} -> oneOff $ [] <$ addFunType d
997 FunDef _ _ _ _ _ _ n cs
998 | not (isNoName n) -> oneOff $ [] <$ addFunDef d
999 -- It's a bit different for fun clauses because we may need to grab a lot
1000 -- of clauses to handle ellipses properly.
1001 NiceFunClause{} -> addFunClauses kwr (d:ds)
1002 -- We do not need to worry about RecSig vs. RecDef: we know there's exactly one
1003 -- of each for record definitions and leaving them in place should be enough!
1004 _ -> oneOff $ do
1005 (m, c, i) <- get -- TODO: grab checks from c?
1006 put (m, c, i + 1)
1007 pure [(i,d)]
1008
1009 -- Extract the name of the return type (if any) of a potential constructor.
1010 -- In case of failure return the name of the constructor and the list of candidates
1011 -- for the return type.
1012 -- A `constructor' block should only contain NiceConstructors so we crash with
1013 -- an IMPOSSIBLE otherwise
1014 isConstructor :: [Name] -> NiceDeclaration -> Either (Name, [Name]) Name
1015 isConstructor ns (Axiom _ _ _ _ _ n e)
1016 -- extract the return type & see it as an LHS-style pattern
1017 | Just p <- exprToPatternWithHoles <$> returnExpr e =
1018 case [ x | x <- ns
1019 , couldBeCallOf (Map.lookup x fixs) x p
1020 ] of
1021 [x] -> Right x
1022 xs -> Left (n, xs)
1023 -- which may fail (e.g. if the "return type" is a hole
1024 | otherwise = Left (n, [])
1025 isConstructor _ _ = __IMPOSSIBLE__
1026
1027 -- Turn an old-style mutual block into a new style mutual block
1028 -- by pushing the definitions to the end.
1029 mkOldMutual
1030 :: KwRange -- Range of the @mutual@ keyword (if any).
1031 -> [NiceDeclaration] -- Declarations inside the block.
1032 -> Nice NiceDeclaration -- Returns a 'NiceMutual'.
1033 mkOldMutual kwr ds' = do
1034 -- Postulate the missing definitions
1035 let ps = loneSigsFromLoneNames loneNames
1036 checkLoneSigs ps
1037 let ds = replaceSigs ps ds'
1038
1039 -- -- Remove the declarations that aren't allowed in old style mutual blocks
1040 -- ds <- fmap catMaybes $ forM ds $ \ d -> let success = pure (Just d) in case d of
1041 -- -- Andreas, 2013-11-23 allow postulates in mutual blocks
1042 -- Axiom{} -> success
1043 -- -- Andreas, 2017-10-09, issue #2576, raise error about missing type signature
1044 -- -- in ConcreteToAbstract rather than here.
1045 -- NiceFunClause{} -> success
1046 -- -- Andreas, 2018-05-11, issue #3052, allow pat.syn.s in mutual blocks
1047 -- NicePatternSyn{} -> success
1048 -- -- Otherwise, only categorized signatures and definitions are allowed:
1049 -- -- Data, Record, Fun
1050 -- _ -> if (declKind d /= OtherDecl) then success
1051 -- else Nothing <$ declarationWarning (NotAllowedInMutual (getRange d) $ declName d)
1052 -- Sort the declarations in the mutual block.
1053 -- Declarations of names go to the top. (Includes module definitions.)
1054 -- Definitions of names go to the bottom.
1055 -- Some declarations are forbidden, as their positioning could confuse
1056 -- the user.
1057 (top, bottom, invalid) <- forEither3M ds $ \ d -> do
1058 let top = return (In1 d)
1059 bottom = return (In2 d)
1060 invalid s = In3 d <$ do declarationWarning $ NotAllowedInMutual (getRange d) s
1061 case d of
1062 -- Andreas, 2013-11-23 allow postulates in mutual blocks
1063 Axiom{} -> top
1064 NiceField{} -> top
1065 PrimitiveFunction{} -> top
1066 -- Andreas, 2019-07-23 issue #3932:
1067 -- Nested mutual blocks are not supported.
1068 NiceMutual{} -> invalid "mutual blocks"
1069 -- Andreas, 2018-10-29, issue #3246
1070 -- We could allow modules (top), but this is potentially confusing.
1071 NiceModule{} -> invalid "Module definitions"
1072 -- Lone constructors are only allowed in new-style mutual blocks
1073 NiceLoneConstructor{} -> invalid "Lone constructors"
1074 NiceModuleMacro{} -> top
1075 NiceOpen{} -> top
1076 NiceImport{} -> top
1077 NiceRecSig{} -> top
1078 NiceDataSig{} -> top
1079 -- Andreas, 2017-10-09, issue #2576, raise error about missing type signature
1080 -- in ConcreteToAbstract rather than here.
1081 NiceFunClause{} -> bottom
1082 FunSig{} -> top
1083 FunDef{} -> bottom
1084 NiceDataDef{} -> bottom
1085 NiceRecDef{} -> bottom
1086 -- Andreas, 2018-05-11, issue #3051, allow pat.syn.s in mutual blocks
1087 -- Andreas, 2018-10-29: We shift pattern synonyms to the bottom
1088 -- since they might refer to constructors defined in a data types
1089 -- just above them.
1090 NicePatternSyn{} -> bottom
1091 NiceGeneralize{} -> top
1092 NiceUnquoteDecl{} -> top
1093 NiceUnquoteDef{} -> bottom
1094 NiceUnquoteData{} -> top
1095
1096 -- Opaque blocks can not participate in old-style mutual
1097 -- recursion. If some of the definitions are opaque then
1098 -- they all need to be.
1099 NiceOpaque r _ _ ->
1100 In3 d <$ do declarationException $ OpaqueInMutual r
1101 NicePragma r pragma -> case pragma of
1102
1103 OptionsPragma{} -> top -- error thrown in the type checker
1104
1105 -- Some builtins require a definition, and they affect type checking
1106 -- Thus, we do not handle BUILTINs in mutual blocks (at least for now).
1107 BuiltinPragma{} -> invalid "BUILTIN pragmas"
1108
1109 -- The REWRITE pragma behaves differently before or after the def.
1110 -- and affects type checking. Thus, we refuse it here.
1111 RewritePragma{} -> invalid "REWRITE pragmas"
1112
1113 -- Compiler pragmas are not needed for type checking, thus,
1114 -- can go to the bottom.
1115 ForeignPragma{} -> bottom
1116 CompilePragma{} -> bottom
1117
1118 StaticPragma{} -> bottom
1119 InlinePragma{} -> bottom
1120 NotProjectionLikePragma{} -> bottom
1121
1122 OverlapPragma{} -> top
1123
1124 ImpossiblePragma{} -> top -- error thrown in scope checker
1125 EtaPragma{} -> bottom -- needs record definition
1126 WarningOnUsage{} -> top
1127 WarningOnImport{} -> top
1128 InjectivePragma{} -> top -- only needs name, not definition
1129 InjectiveForInferencePragma{} -> top
1130 DisplayPragma{} -> top -- only for printing
1131
1132 -- The attached pragmas have already been handled at this point.
1133 CatchallPragma{} -> __IMPOSSIBLE__
1134 TerminationCheckPragma{} -> __IMPOSSIBLE__
1135 NoPositivityCheckPragma{} -> __IMPOSSIBLE__
1136 PolarityPragma{} -> __IMPOSSIBLE__
1137 NoUniverseCheckPragma{} -> __IMPOSSIBLE__
1138 NoCoverageCheckPragma{} -> __IMPOSSIBLE__
1139
1140
1141 -- -- Pull type signatures to the top
1142 -- let (sigs, other) = List.partition isTypeSig ds
1143
1144 -- -- Push definitions to the bottom
1145 -- let (other, defs) = flip List.partition ds $ \case
1146 -- FunDef{} -> False
1147 -- NiceDataDef{} -> False
1148 -- NiceRecDef{} -> False
1149 -- NiceFunClause{} -> False
1150 -- NicePatternSyn{} -> False
1151 -- NiceUnquoteDef{} -> False
1152 -- _ -> True
1153
1154 -- Compute termination checking flag for mutual block
1155 tc0 <- use terminationCheckPragma
1156 let tcs = map termCheck ds
1157 let r = fuseRange kwr ds'
1158 tc <- combineTerminationChecks r (tc0:tcs)
1159
1160 -- Compute coverage checking flag for mutual block
1161 cc0 <- use coverageCheckPragma
1162 let ccs = map covCheck ds
1163 let cc = combineCoverageChecks (cc0:ccs)
1164
1165 -- Compute positivity checking flag for mutual block
1166 pc0 <- use positivityCheckPragma
1167 let pcs = map positivityCheckOldMutual ds
1168 let pc = combinePositivityChecks (pc0:pcs)
1169
1170 return $ NiceMutual kwr tc cc pc $ top ++ bottom
1171
1172 where
1173 sigNames = [ (r, x, k) | LoneSigDecl r k x <- map declKind ds' ]
1174 defNames = [ (x, k) | LoneDefs k xs <- map declKind ds', x <- xs ]
1175 -- compute the set difference with equality just on names
1176 loneNames = [ (r, x, k) | (r, x, k) <- sigNames, List.all ((x /=) . fst) defNames ]
1177
1178 termCheck :: NiceDeclaration -> TerminationCheck
1179 -- Andreas, 2013-02-28 (issue 804):
1180 -- do not termination check a mutual block if any of its
1181 -- inner declarations comes with a {-# NO_TERMINATION_CHECK #-}
1182 termCheck (FunSig _ _ _ _ _ _ tc _ _ _) = tc
1183 termCheck (FunDef _ _ _ _ tc _ _ _) = tc
1184 -- ASR (28 December 2015): Is this equation necessary?
1185 termCheck (NiceMutual _ tc _ _ _) = tc
1186 termCheck (NiceUnquoteDecl _ _ _ _ tc _ _ _) = tc
1187 termCheck (NiceUnquoteDef _ _ _ tc _ _ _) = tc
1188 termCheck Axiom{} = TerminationCheck
1189 termCheck NiceField{} = TerminationCheck
1190 termCheck PrimitiveFunction{} = TerminationCheck
1191 termCheck NiceModule{} = TerminationCheck
1192 termCheck NiceModuleMacro{} = TerminationCheck
1193 termCheck NiceOpen{} = TerminationCheck
1194 termCheck NiceImport{} = TerminationCheck
1195 termCheck NicePragma{} = TerminationCheck
1196 termCheck NiceRecSig{} = TerminationCheck
1197 termCheck NiceDataSig{} = TerminationCheck
1198 termCheck NiceFunClause{} = TerminationCheck
1199 termCheck NiceDataDef{} = TerminationCheck
1200 termCheck NiceRecDef{} = TerminationCheck
1201 termCheck NicePatternSyn{} = TerminationCheck
1202 termCheck NiceGeneralize{} = TerminationCheck
1203 termCheck NiceLoneConstructor{} = TerminationCheck
1204 termCheck NiceUnquoteData{} = TerminationCheck
1205 termCheck NiceOpaque{} = TerminationCheck
1206
1207 covCheck :: NiceDeclaration -> CoverageCheck
1208 covCheck (FunSig _ _ _ _ _ _ _ cc _ _) = cc
1209 covCheck (FunDef _ _ _ _ _ cc _ _) = cc
1210 -- ASR (28 December 2015): Is this equation necessary?
1211 covCheck (NiceMutual _ _ cc _ _) = cc
1212 covCheck (NiceUnquoteDecl _ _ _ _ _ cc _ _) = cc
1213 covCheck (NiceUnquoteDef _ _ _ _ cc _ _) = cc
1214 covCheck Axiom{} = YesCoverageCheck
1215 covCheck NiceField{} = YesCoverageCheck
1216 covCheck PrimitiveFunction{} = YesCoverageCheck
1217 covCheck NiceModule{} = YesCoverageCheck
1218 covCheck NiceModuleMacro{} = YesCoverageCheck
1219 covCheck NiceOpen{} = YesCoverageCheck
1220 covCheck NiceImport{} = YesCoverageCheck
1221 covCheck NicePragma{} = YesCoverageCheck
1222 covCheck NiceRecSig{} = YesCoverageCheck
1223 covCheck NiceDataSig{} = YesCoverageCheck
1224 covCheck NiceFunClause{} = YesCoverageCheck
1225 covCheck NiceDataDef{} = YesCoverageCheck
1226 covCheck NiceRecDef{} = YesCoverageCheck
1227 covCheck NicePatternSyn{} = YesCoverageCheck
1228 covCheck NiceGeneralize{} = YesCoverageCheck
1229 covCheck NiceLoneConstructor{} = YesCoverageCheck
1230 covCheck NiceUnquoteData{} = YesCoverageCheck
1231 covCheck NiceOpaque{} = YesCoverageCheck
1232
1233 -- ASR (26 December 2015): Do not positivity check a mutual
1234 -- block if any of its inner declarations comes with a
1235 -- NO_POSITIVITY_CHECK pragma. See Issue 1614.
1236 positivityCheckOldMutual :: NiceDeclaration -> PositivityCheck
1237 positivityCheckOldMutual (NiceDataDef _ _ _ pc _ _ _ _) = pc
1238 positivityCheckOldMutual (NiceDataSig _ _ _ _ pc _ _ _ _) = pc
1239 positivityCheckOldMutual (NiceMutual _ _ _ pc _) = pc
1240 positivityCheckOldMutual (NiceRecSig _ _ _ _ pc _ _ _ _) = pc
1241 positivityCheckOldMutual (NiceRecDef _ _ _ pc _ _ _ _ _) = pc
1242 positivityCheckOldMutual _ = YesPositivityCheck
1243
1244 -- A mutual block cannot have a measure,
1245 -- but it can skip termination check.
1246
1247 abstractBlock
1248 :: KwRange -- Range of @abstract@ keyword.
1249 -> [NiceDeclaration]
1250 -> Nice [NiceDeclaration]
1251 abstractBlock r ds = do
1252 (ds', anyChange) <- runChangeT $ mkAbstract ds
1253 let inherited = null r
1254 if anyChange then return ds' else do
1255 -- hack to avoid failing on inherited abstract blocks in where clauses
1256 unless inherited $ declarationWarning $ UselessAbstract r
1257 return ds -- no change!
1258
1259 privateBlock
1260 :: KwRange -- Range of @private@ keyword.
1261 -> Origin -- Origin of the private block.
1262 -> [NiceDeclaration]
1263 -> Nice [NiceDeclaration]
1264 privateBlock r o ds = do
1265 (ds', anyChange) <- runChangeT $ mkPrivate r o ds
1266 if anyChange then return ds' else do
1267 when (o == UserWritten) $ declarationWarning $ UselessPrivate r
1268 return ds -- no change!
1269
1270 instanceBlock
1271 :: KwRange -- Range of @instance@ keyword.
1272 -> [NiceDeclaration]
1273 -> Nice [NiceDeclaration]
1274 instanceBlock r ds = do
1275 let (ds', anyChange) = runChange $ mapM (mkInstance r) ds
1276 if anyChange then return ds' else do
1277 declarationWarning $ UselessInstance r
1278 return ds -- no change!
1279
1280 -- Make a declaration eligible for instance search.
1281 mkInstance
1282 :: KwRange -- Range of @instance@ keyword.
1283 -> Updater NiceDeclaration
1284 mkInstance r0 = \case
1285 Axiom r p a i rel x e -> (\ i -> Axiom r p a i rel x e) <$> setInstance r0 i
1286 FunSig r p a i m rel tc cc x e -> (\ i -> FunSig r p a i m rel tc cc x e) <$> setInstance r0 i
1287 NiceUnquoteDecl r p a i tc cc x e -> (\ i -> NiceUnquoteDecl r p a i tc cc x e) <$> setInstance r0 i
1288 NiceMutual r tc cc pc ds -> NiceMutual r tc cc pc <$> mapM (mkInstance r0) ds
1289 NiceLoneConstructor r ds -> NiceLoneConstructor r <$> mapM (mkInstance r0) ds
1290 d@NiceFunClause{} -> return d
1291 FunDef r ds a i tc cc x cs -> (\ i -> FunDef r ds a i tc cc x cs) <$> setInstance r0 i
1292 NiceOpaque r ns i -> (\ i -> NiceOpaque r ns i) <$> traverse (mkInstance r0) i
1293 d@NiceField{} -> return d -- Field instance are handled by the parser
1294 d@PrimitiveFunction{} -> return d
1295 d@NiceUnquoteDef{} -> return d
1296 d@NiceRecSig{} -> return d
1297 d@NiceDataSig{} -> return d
1298 d@NiceModuleMacro{} -> return d
1299 d@NiceModule{} -> return d
1300 d@NicePragma{} -> return d
1301 d@NiceOpen{} -> return d
1302 d@NiceImport{} -> return d
1303 d@NiceDataDef{} -> return d
1304 d@NiceRecDef{} -> return d
1305 d@NicePatternSyn{} -> return d
1306 d@NiceGeneralize{} -> return d
1307 d@NiceUnquoteData{} -> return d
1308
1309 setInstance
1310 :: KwRange -- Range of @instance@ keyword.
1311 -> Updater IsInstance
1312 setInstance r0 = \case
1313 i@InstanceDef{} -> return i
1314 _ -> dirty $ InstanceDef r0
1315
1316 macroBlock
1317 :: KwRange -- Range of @macro@ keyword.
1318 -> [NiceDeclaration]
1319 -> Nice [NiceDeclaration]
1320 macroBlock r ds = do
1321 (ds', anyChange) <- runChangeT $ mkMacro ds
1322 if anyChange then return ds' else do
1323 declarationWarning $ UselessMacro r
1324 return ds -- no change!
1325
1326class MakeMacro a where
1327 mkMacro :: UpdaterT Nice a
1328
1329 default mkMacro :: (Traversable f, MakeMacro a', a ~ f a') => UpdaterT Nice a
1330 mkMacro = traverse mkMacro
1331
1332instance MakeMacro a => MakeMacro [a]
1333
1334instance MakeMacro NiceDeclaration where
1335 mkMacro = \case
1336 FunSig r p a i _ rel tc cc x e -> dirty $ FunSig r p a i MacroDef rel tc cc x e
1337 d@FunDef{} -> return d
1338 d -> lift $ declarationException $ BadMacroDef d
1339
1340-- | Make a declaration abstract.
1341--
1342-- Mark computation as 'dirty' if there was a declaration that could be made abstract.
1343-- If no abstraction is taking place, we want to complain about 'UselessAbstract'.
1344--
1345-- Alternatively, we could only flag 'dirty' if a non-abstract thing was abstracted.
1346-- Then, nested @abstract@s would sometimes also be complained about.
1347
1348class MakeAbstract a where
1349 mkAbstract :: UpdaterT Nice a
1350
1351 default mkAbstract :: (Traversable f, MakeAbstract a', a ~ f a') => UpdaterT Nice a
1352 mkAbstract = traverse mkAbstract
1353
1354instance MakeAbstract a => MakeAbstract [a]
1355
1356-- Leads to overlap with 'WhereClause':
1357-- instance (Traversable f, MakeAbstract a) => MakeAbstract (f a) where
1358-- mkAbstract = traverse mkAbstract
1359
1360instance MakeAbstract IsAbstract where
1361 mkAbstract = \case
1362 a@AbstractDef -> return a
1363 ConcreteDef -> dirty $ AbstractDef
1364
1365instance MakeAbstract NiceDeclaration where
1366 mkAbstract = \case
1367 NiceMutual r termCheck cc pc ds -> NiceMutual r termCheck cc pc <$> mkAbstract ds
1368 NiceLoneConstructor r ds -> NiceLoneConstructor r <$> mkAbstract ds
1369 FunDef r ds a i tc cc x cs -> (\ a -> FunDef r ds a i tc cc x) <$> mkAbstract a <*> mkAbstract cs
1370 NiceDataDef r o a pc uc x ps cs -> (\ a -> NiceDataDef r o a pc uc x ps) <$> mkAbstract a <*> mkAbstract cs
1371 NiceRecDef r o a pc uc x dir ps cs -> (\ a -> NiceRecDef r o a pc uc x dir ps cs) <$> mkAbstract a
1372 NiceFunClause r p a tc cc catchall d -> (\ a -> NiceFunClause r p a tc cc catchall d) <$> mkAbstract a
1373 -- The following declarations have an @InAbstract@ field
1374 -- but are not really definitions, so we do count them into
1375 -- the declarations which can be made abstract
1376 -- (thus, do not notify progress with @dirty@).
1377 Axiom r p a i rel x e -> return $ Axiom r p AbstractDef i rel x e
1378 FunSig r p a i m rel tc cc x e -> return $ FunSig r p AbstractDef i m rel tc cc x e
1379 NiceRecSig r er p a pc uc x ls t -> return $ NiceRecSig r er p AbstractDef pc uc x ls t
1380 NiceDataSig r er p a pc uc x ls t -> return $ NiceDataSig r er p AbstractDef pc uc x ls t
1381 NiceField r p _ i tac x e -> return $ NiceField r p AbstractDef i tac x e
1382 PrimitiveFunction r p _ x e -> return $ PrimitiveFunction r p AbstractDef x e
1383 -- Andreas, 2016-07-17 it does have effect on unquoted defs.
1384 -- Need to set updater state to dirty!
1385 NiceUnquoteDecl r p _ i tc cc x e -> tellDirty $> NiceUnquoteDecl r p AbstractDef i tc cc x e
1386 NiceUnquoteDef r p _ tc cc x e -> tellDirty $> NiceUnquoteDef r p AbstractDef tc cc x e
1387 NiceUnquoteData r p _ tc cc x xs e -> tellDirty $> NiceUnquoteData r p AbstractDef tc cc x xs e
1388 d@NiceModule{} -> return d
1389 d@NiceModuleMacro{} -> return d
1390 d@NicePragma{} -> return d
1391 d@(NiceOpen _ _ directives) -> do
1392 whenJust (publicOpen directives) $ lift . declarationWarning . OpenPublicAbstract
1393 return d
1394 d@NiceImport{} -> return d
1395 d@NicePatternSyn{} -> return d
1396 d@NiceGeneralize{} -> return d
1397 NiceOpaque r ns ds -> NiceOpaque r ns <$> mkAbstract ds
1398
1399instance MakeAbstract Clause where
1400 mkAbstract (Clause x catchall lhs rhs wh with) = do
1401 Clause x catchall lhs rhs <$> mkAbstract wh <*> mkAbstract with
1402
1403-- | Contents of a @where@ clause are abstract if the parent is.
1404--
1405-- These are inherited 'Abstract' blocks, indicated by an empty range
1406-- for the @abstract@ keyword.
1407instance MakeAbstract WhereClause where
1408 mkAbstract NoWhere = return $ NoWhere
1409 mkAbstract (AnyWhere r ds) = dirty $ AnyWhere r
1410 [Abstract empty ds]
1411 mkAbstract (SomeWhere r e m a ds) = dirty $ SomeWhere r e m a
1412 [Abstract empty ds]
1413
1414-- | Make a declaration private.
1415--
1416-- Andreas, 2012-11-17:
1417-- Mark computation as 'dirty' if there was a declaration that could be privatized.
1418-- If no privatization is taking place, we want to complain about 'UselessPrivate'.
1419--
1420-- Alternatively, we could only flag 'dirty' if a non-private thing was privatized.
1421-- Then, nested @private@s would sometimes also be complained about.
1422
1423class MakePrivate a where
1424 mkPrivate :: KwRange -> Origin -> UpdaterT Nice a
1425
1426 default mkPrivate :: (Traversable f, MakePrivate a', a ~ f a') => KwRange -> Origin -> UpdaterT Nice a
1427 mkPrivate kwr o = traverse $ mkPrivate kwr o
1428
1429instance MakePrivate a => MakePrivate [a]
1430
1431-- Leads to overlap with 'WhereClause':
1432-- instance (Traversable f, MakePrivate a) => MakePrivate (f a) where
1433-- mkPrivate = traverse mkPrivate
1434
1435instance MakePrivate Access where
1436 mkPrivate kwr o = \case
1437 p@PrivateAccess{} -> return p -- OR? return $ PrivateAccess o
1438 _ -> dirty $ PrivateAccess kwr o
1439
1440instance MakePrivate NiceDeclaration where
1441 mkPrivate kwr o = \case
1442 Axiom r p a i rel x e -> (\ p -> Axiom r p a i rel x e) <$> mkPrivate kwr o p
1443 NiceField r p a i tac x e -> (\ p -> NiceField r p a i tac x e) <$> mkPrivate kwr o p
1444 PrimitiveFunction r p a x e -> (\ p -> PrimitiveFunction r p a x e) <$> mkPrivate kwr o p
1445 NiceMutual r tc cc pc ds -> (\ ds-> NiceMutual r tc cc pc ds) <$> mkPrivate kwr o ds
1446 NiceLoneConstructor r ds -> NiceLoneConstructor r <$> mkPrivate kwr o ds
1447 NiceModule r p a e x tel ds -> (\ p -> NiceModule r p a e x tel ds) <$> mkPrivate kwr o p
1448 NiceModuleMacro r p e x ma op is -> (\ p -> NiceModuleMacro r p e x ma op is) <$> mkPrivate kwr o p
1449 FunSig r p a i m rel tc cc x e -> (\ p -> FunSig r p a i m rel tc cc x e) <$> mkPrivate kwr o p
1450 NiceRecSig r er p a pc uc x ls t -> (\ p -> NiceRecSig r er p a pc uc x ls t) <$> mkPrivate kwr o p
1451 NiceDataSig r er p a pc uc x ls t -> (\ p -> NiceDataSig r er p a pc uc x ls t) <$> mkPrivate kwr o p
1452 NiceFunClause r p a tc cc catchall d -> (\ p -> NiceFunClause r p a tc cc catchall d) <$> mkPrivate kwr o p
1453 NiceUnquoteDecl r p a i tc cc x e -> (\ p -> NiceUnquoteDecl r p a i tc cc x e) <$> mkPrivate kwr o p
1454 NiceUnquoteDef r p a tc cc x e -> (\ p -> NiceUnquoteDef r p a tc cc x e) <$> mkPrivate kwr o p
1455 NicePatternSyn r p x xs p' -> (\ p -> NicePatternSyn r p x xs p') <$> mkPrivate kwr o p
1456 NiceGeneralize r p i tac x t -> (\ p -> NiceGeneralize r p i tac x t) <$> mkPrivate kwr o p
1457 NiceOpaque r ns ds -> (\ p -> NiceOpaque r ns p) <$> mkPrivate kwr o ds
1458 d@NicePragma{} -> return d
1459 d@(NiceOpen _ _ directives) -> do
1460 whenJust (publicOpen directives) $ lift . declarationWarning . OpenPublicPrivate
1461 return d
1462 d@NiceImport{} -> return d
1463 -- Andreas, 2016-07-08, issue #2089
1464 -- we need to propagate 'private' to the named where modules
1465 FunDef r ds a i tc cc x cls -> FunDef r ds a i tc cc x <$> mkPrivate kwr o cls
1466 d@NiceDataDef{} -> return d
1467 d@NiceRecDef{} -> return d
1468 d@NiceUnquoteData{} -> return d
1469
1470instance MakePrivate Clause where
1471 mkPrivate kwr o (Clause x catchall lhs rhs wh with) = do
1472 Clause x catchall lhs rhs <$> mkPrivate kwr o wh <*> mkPrivate kwr o with
1473
1474instance MakePrivate WhereClause where
1475 mkPrivate kwr o = \case
1476 d@NoWhere -> return d
1477 -- @where@-declarations are protected behind an anonymous module,
1478 -- thus, they are effectively private by default.
1479 d@AnyWhere{} -> return d
1480 -- Andreas, 2016-07-08
1481 -- A @where@-module is private if the parent function is private.
1482 -- The contents of this module are not private, unless declared so!
1483 -- Thus, we do not recurse into the @ds@ (could not anyway).
1484 SomeWhere r e m a ds ->
1485 mkPrivate kwr o a <&> \a' -> SomeWhere r e m a' ds
1486
1487-- The following function is (at the time of writing) only used three
1488-- times: for building Lets, and for printing error messages.
1489
1490-- | (Approximately) convert a 'NiceDeclaration' back to a list of
1491-- 'Declaration's.
1492notSoNiceDeclarations :: NiceDeclaration -> [Declaration]
1493notSoNiceDeclarations = \case
1494 Axiom _ _ _ i rel x e -> inst i [TypeSig rel empty x e]
1495 NiceField _ _ _ i tac x argt -> [FieldSig i tac x argt]
1496 PrimitiveFunction _ _ _ x e -> [Primitive empty [TypeSig (argInfo e) empty x (unArg e)]]
1497 NiceMutual r _ _ _ ds -> [Mutual r $ concatMap notSoNiceDeclarations ds]
1498 NiceLoneConstructor r ds -> [LoneConstructor r $ concatMap notSoNiceDeclarations ds]
1499 NiceModule r _ _ e x tel ds -> [Module r e x tel ds]
1500 NiceModuleMacro r _ e x ma o dir
1501 -> [ModuleMacro r e x ma o dir]
1502 NiceOpen r x dir -> [Open r x dir]
1503 NiceImport r x as o dir -> [Import r x as o dir]
1504 NicePragma _ p -> [Pragma p]
1505 NiceRecSig r er _ _ _ _ x bs e -> [RecordSig r er x bs e]
1506 NiceDataSig r er _ _ _ _ x bs e -> [DataSig r er x bs e]
1507 NiceFunClause _ _ _ _ _ _ d -> [d]
1508 FunSig _ _ _ i _ rel _ _ x e -> inst i [TypeSig rel empty x e]
1509 FunDef _ ds _ _ _ _ _ _ -> ds
1510 NiceDataDef r _ _ _ _ x bs cs -> [DataDef r x bs $ concatMap notSoNiceDeclarations cs]
1511 NiceRecDef r _ _ _ _ x dir bs ds -> [RecordDef r x dir bs ds]
1512 NicePatternSyn r _ n as p -> [PatternSyn r n as p]
1513 NiceGeneralize _ _ i tac n e -> [Generalize empty [TypeSig i tac n e]]
1514 NiceUnquoteDecl r _ _ i _ _ x e -> inst i [UnquoteDecl r x e]
1515 NiceUnquoteDef r _ _ _ _ x e -> [UnquoteDef r x e]
1516 NiceUnquoteData r _ _ _ _ x xs e -> [UnquoteData r x xs e]
1517 NiceOpaque r ns ds -> [Opaque r (Unfolding r ns:concatMap notSoNiceDeclarations ds)]
1518 where
1519 inst (InstanceDef r) ds = [InstanceB r ds]
1520 inst NotInstanceDef ds = ds
1521
1522-- | Has the 'NiceDeclaration' a field of type 'IsAbstract'?
1523niceHasAbstract :: NiceDeclaration -> Maybe IsAbstract
1524niceHasAbstract = \case
1525 Axiom{} -> Nothing
1526 NiceField _ _ a _ _ _ _ -> Just a
1527 PrimitiveFunction _ _ a _ _ -> Just a
1528 NiceMutual{} -> Nothing
1529 NiceLoneConstructor{} -> Nothing
1530 NiceModule _ _ a _ _ _ _ -> Just a
1531 NiceModuleMacro{} -> Nothing
1532 NiceOpen{} -> Nothing
1533 NiceImport{} -> Nothing
1534 NicePragma{} -> Nothing
1535 NiceRecSig{} -> Nothing
1536 NiceDataSig{} -> Nothing
1537 NiceFunClause _ _ a _ _ _ _ -> Just a
1538 FunSig{} -> Nothing
1539 FunDef _ _ a _ _ _ _ _ -> Just a
1540 NiceDataDef _ _ a _ _ _ _ _ -> Just a
1541 NiceRecDef _ _ a _ _ _ _ _ _ -> Just a
1542 NicePatternSyn{} -> Nothing
1543 NiceGeneralize{} -> Nothing
1544 NiceUnquoteDecl _ _ a _ _ _ _ _ -> Just a
1545 NiceUnquoteDef _ _ a _ _ _ _ -> Just a
1546 NiceUnquoteData _ _ a _ _ _ _ _ -> Just a
1547 NiceOpaque{} -> Nothing