-
Notifications
You must be signed in to change notification settings - Fork 337
/
Base.hs
4774 lines (4080 loc) · 187 KB
/
Base.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
{-# LANGUAGE CPP #-}
-- {-# LANGUAGE UndecidableInstances #-} -- ghc >= 8.2, GeneralizedNewtypeDeriving MonadTransControl BlockT
module Agda.TypeChecking.Monad.Base
( module Agda.TypeChecking.Monad.Base
, HasOptions (..)
) where
import Prelude hiding (null)
import Control.Applicative hiding (empty)
import qualified Control.Concurrent as C
import Control.DeepSeq
import qualified Control.Exception as E
import qualified Control.Monad.Fail as Fail
import Control.Monad.Except
import Control.Monad.State
import Control.Monad.Reader
import Control.Monad.Writer hiding ((<>))
import Control.Monad.Trans ( MonadTrans(..), lift )
import Control.Monad.Trans.Control ( MonadTransControl(..), liftThrough )
import Control.Monad.Trans.Identity
import Control.Monad.Trans.Maybe
import Control.Parallel ( pseq )
import Data.Array (Ix)
import Data.Function
import Data.Int
import Data.IntMap (IntMap)
import qualified Data.IntMap as IntMap
import qualified Data.List as List
import Data.Maybe
import Data.Map (Map)
import qualified Data.Map as Map -- hiding (singleton, null, empty)
import Data.Sequence (Seq)
import Data.Set (Set)
import qualified Data.Set as Set -- hiding (singleton, null, empty)
import Data.HashMap.Strict (HashMap)
import qualified Data.HashMap.Strict as HMap
import Data.Semigroup ( Semigroup, (<>)) --, Any(..) )
import Data.Data (Data)
import Data.String
import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Text.Lazy as TL
import Data.IORef
import GHC.Generics (Generic)
import Agda.Benchmarking (Benchmark, Phase)
import Agda.Syntax.Concrete (TopLevelModuleName)
import Agda.Syntax.Common
import qualified Agda.Syntax.Concrete as C
import Agda.Syntax.Concrete.Definitions
(NiceDeclaration, DeclarationWarning, dwWarning, declarationWarningName)
import qualified Agda.Syntax.Abstract as A
import Agda.Syntax.Internal as I
import Agda.Syntax.Internal.MetaVars
import Agda.Syntax.Internal.Generic (TermLike(..))
import Agda.Syntax.Parser (ParseWarning)
import Agda.Syntax.Parser.Monad (parseWarningName)
import Agda.Syntax.Treeless (Compiled)
import Agda.Syntax.Notation
import Agda.Syntax.Position
import Agda.Syntax.Scope.Base
import qualified Agda.Syntax.Info as Info
import Agda.TypeChecking.CompiledClause
import Agda.TypeChecking.Coverage.SplitTree
import Agda.TypeChecking.Positivity.Occurrence
import Agda.TypeChecking.Free.Lazy (Free(freeVars'), underBinder', underBinder)
-- Args, defined in Agda.Syntax.Treeless and exported from Agda.Compiler.Backend
-- conflicts with Args, defined in Agda.Syntax.Internal and also imported here.
-- This only matters when interpreted in ghci, which sees all of the module's
-- exported symbols, not just the ones defined in the `.hs-boot`. See the
-- comment in ../../Compiler/Backend.hs-boot
import {-# SOURCE #-} Agda.Compiler.Backend hiding (Args)
import Agda.Interaction.Options
import Agda.Interaction.Options.Warnings
import {-# SOURCE #-} Agda.Interaction.Response
(InteractionOutputCallback, defaultInteractionOutputCallback)
import Agda.Interaction.Highlighting.Precise
(HighlightingInfo, NameKind)
import Agda.Interaction.Library
import Agda.Utils.Benchmark (MonadBench(..))
import Agda.Utils.BiMap (BiMap, HasTag(..))
import qualified Agda.Utils.BiMap as BiMap
import Agda.Utils.CallStack ( CallStack, HasCallStack, withCallerCallStack )
import Agda.Utils.FileName
import Agda.Utils.Functor
import Agda.Utils.Hash
import Agda.Utils.Lens
import Agda.Utils.List
import Agda.Utils.ListT
import Agda.Utils.List1 (List1, pattern (:|))
import Agda.Utils.List2 (List2, pattern List2)
import qualified Agda.Utils.List1 as List1
import qualified Agda.Utils.Maybe.Strict as Strict
import Agda.Utils.Monad
import Agda.Utils.Null
import Agda.Utils.Permutation
import Agda.Utils.Pretty
import Agda.Utils.Singleton
import Agda.Utils.SmallSet (SmallSet)
import qualified Agda.Utils.SmallSet as SmallSet
import Agda.Utils.Update
import Agda.Utils.WithDefault ( collapseDefault )
import Agda.Utils.Impossible
---------------------------------------------------------------------------
-- * Type checking state
---------------------------------------------------------------------------
data TCState = TCSt
{ stPreScopeState :: !PreScopeState
-- ^ The state which is frozen after scope checking.
, stPostScopeState :: !PostScopeState
-- ^ The state which is modified after scope checking.
, stPersistentState :: !PersistentTCState
-- ^ State which is forever, like a diamond.
}
deriving Generic
class Monad m => ReadTCState m where
getTCState :: m TCState
locallyTCState :: Lens' a TCState -> (a -> a) -> m b -> m b
withTCState :: (TCState -> TCState) -> m a -> m a
withTCState = locallyTCState id
default getTCState :: (MonadTrans t, ReadTCState n, t n ~ m) => m TCState
getTCState = lift getTCState
default locallyTCState
:: (MonadTransControl t, ReadTCState n, t n ~ m)
=> Lens' a TCState -> (a -> a) -> m b -> m b
locallyTCState l = liftThrough . locallyTCState l
instance ReadTCState m => ReadTCState (ListT m) where
locallyTCState l = mapListT . locallyTCState l
instance ReadTCState m => ReadTCState (ChangeT m)
instance ReadTCState m => ReadTCState (ExceptT err m)
instance ReadTCState m => ReadTCState (IdentityT m)
instance ReadTCState m => ReadTCState (MaybeT m)
instance ReadTCState m => ReadTCState (ReaderT r m)
instance ReadTCState m => ReadTCState (StateT s m)
instance (Monoid w, ReadTCState m) => ReadTCState (WriterT w m)
instance Show TCState where
show _ = "TCSt{}"
data PreScopeState = PreScopeState
{ stPreTokens :: !HighlightingInfo
-- ^ Highlighting info for tokens and Happy parser warnings (but
-- not for those tokens/warnings for which highlighting exists in
-- 'stPostSyntaxInfo').
, stPreImports :: !Signature -- XX populated by scope checker
-- ^ Imported declared identifiers.
-- Those most not be serialized!
, stPreImportedModules :: !(Set ModuleName) -- imports logic
, stPreModuleToSource :: !ModuleToSource -- imports
, stPreVisitedModules :: !VisitedModules -- imports
, stPreScope :: !ScopeInfo
-- generated by scope checker, current file:
-- which modules you have, public definitions, current file, maps concrete names to abstract names.
, stPrePatternSyns :: !A.PatternSynDefns
-- ^ Pattern synonyms of the current file. Serialized.
, stPrePatternSynImports :: !A.PatternSynDefns
-- ^ Imported pattern synonyms. Must not be serialized!
, stPreGeneralizedVars :: !(Strict.Maybe (Set QName))
-- ^ Collected generalizable variables; used during scope checking of terms
, stPrePragmaOptions :: !PragmaOptions
-- ^ Options applying to the current file. @OPTIONS@
-- pragmas only affect this field.
, stPreImportedBuiltins :: !(BuiltinThings PrimFun)
, stPreImportedDisplayForms :: !DisplayForms
-- ^ Display forms added by someone else to imported identifiers
, stPreImportedInstanceDefs :: !InstanceTable
, stPreForeignCode :: !(Map BackendName [ForeignCode])
-- ^ @{-\# FOREIGN \#-}@ code that should be included in the compiled output.
-- Does not include code for imported modules.
, stPreFreshInteractionId :: !InteractionId
, stPreImportedUserWarnings :: !(Map A.QName Text)
-- ^ Imported @UserWarning@s, not to be stored in the @Interface@
, stPreLocalUserWarnings :: !(Map A.QName Text)
-- ^ Locally defined @UserWarning@s, to be stored in the @Interface@
, stPreWarningOnImport :: !(Strict.Maybe Text)
-- ^ Whether the current module should raise a warning when opened
, stPreImportedPartialDefs :: !(Set QName)
-- ^ Imported partial definitions, not to be stored in the @Interface@
, stPreProjectConfigs :: !(Map FilePath ProjectConfig)
-- ^ Map from directories to paths of closest enclosing .agda-lib
-- files (or @Nothing@ if there are none).
, stPreAgdaLibFiles :: !(Map FilePath AgdaLibFile)
-- ^ Contents of .agda-lib files that have already been parsed.
, stPreModuleNameHashes :: !(Map ModuleNameHash C.QName)
-- ^ Module name hashes that have been used so far. Used to detect
-- hash collisions.
}
deriving Generic
-- | Name disambiguation for the sake of highlighting.
data DisambiguatedName = DisambiguatedName NameKind A.QName
deriving Generic
type DisambiguatedNames = IntMap DisambiguatedName
type ConcreteNames = Map Name [C.Name]
data PostScopeState = PostScopeState
{ stPostSyntaxInfo :: !HighlightingInfo
-- ^ Highlighting info.
, stPostDisambiguatedNames :: !DisambiguatedNames
-- ^ Disambiguation carried out by the type checker.
-- Maps position of first name character to disambiguated @'A.QName'@
-- for each @'A.AmbiguousQName'@ already passed by the type checker.
, stPostMetaStore :: !MetaStore
, stPostInteractionPoints :: !InteractionPoints -- scope checker first
, stPostAwakeConstraints :: !Constraints
, stPostSleepingConstraints :: !Constraints
, stPostDirty :: !Bool -- local
-- ^ Dirty when a constraint is added, used to prevent pointer update.
-- Currently unused.
, stPostOccursCheckDefs :: !(Set QName) -- local
-- ^ Definitions to be considered during occurs check.
-- Initialized to the current mutual block before the check.
-- During occurs check, we remove definitions from this set
-- as soon we have checked them.
, stPostSignature :: !Signature
-- ^ Declared identifiers of the current file.
-- These will be serialized after successful type checking.
, stPostModuleCheckpoints :: !(Map ModuleName CheckpointId)
-- ^ For each module remember the checkpoint corresponding to the orignal
-- context of the module parameters.
, stPostImportsDisplayForms :: !DisplayForms
-- ^ Display forms we add for imported identifiers
, stPostCurrentModule :: !(Strict.Maybe ModuleName)
-- ^ The current module is available after it has been type
-- checked.
, stPostInstanceDefs :: !TempInstanceTable
, stPostConcreteNames :: !ConcreteNames
-- ^ Map keeping track of concrete names assigned to each abstract name
-- (can be more than one name in case the first one is shadowed)
, stPostUsedNames :: !(Map RawName [RawName])
-- ^ Map keeping track for each name root (= name w/o numeric
-- suffixes) what names with the same root have been used during a
-- TC computation. This information is used to build the
-- @ShadowingNames@ map.
, stPostShadowingNames :: !(Map Name [RawName])
-- ^ Map keeping track for each (abstract) name the list of all
-- (raw) names that it could maybe be shadowed by.
, stPostStatistics :: !Statistics
-- ^ Counters to collect various statistics about meta variables etc.
-- Only for current file.
, stPostTCWarnings :: ![TCWarning]
, stPostMutualBlocks :: !(Map MutualId MutualBlock)
, stPostLocalBuiltins :: !(BuiltinThings PrimFun)
, stPostFreshMetaId :: !MetaId
, stPostFreshMutualId :: !MutualId
, stPostFreshProblemId :: !ProblemId
, stPostFreshCheckpointId :: !CheckpointId
, stPostFreshInt :: !Int
, stPostFreshNameId :: !NameId
, stPostAreWeCaching :: !Bool
, stPostPostponeInstanceSearch :: !Bool
, stPostConsideringInstance :: !Bool
, stPostInstantiateBlocking :: !Bool
-- ^ Should we instantiate away blocking metas?
-- This can produce ill-typed terms but they are often more readable. See issue #3606.
-- Best set to True only for calls to pretty*/reify to limit unwanted reductions.
, stPostLocalPartialDefs :: !(Set QName)
-- ^ Local partial definitions, to be stored in the @Interface@
}
deriving (Generic)
-- | A mutual block of names in the signature.
data MutualBlock = MutualBlock
{ mutualInfo :: Info.MutualInfo
-- ^ The original info of the mutual block.
, mutualNames :: Set QName
} deriving (Show, Eq, Generic)
instance Null MutualBlock where
empty = MutualBlock empty empty
-- | A part of the state which is not reverted when an error is thrown
-- or the state is reset.
data PersistentTCState = PersistentTCSt
{ stDecodedModules :: !DecodedModules
, stPersistentOptions :: CommandLineOptions
, stInteractionOutputCallback :: InteractionOutputCallback
-- ^ Callback function to call when there is a response
-- to give to the interactive frontend.
-- See the documentation of 'InteractionOutputCallback'.
, stBenchmark :: !Benchmark
-- ^ Structure to track how much CPU time was spent on which Agda phase.
-- Needs to be a strict field to avoid space leaks!
, stAccumStatistics :: !Statistics
-- ^ Should be strict field.
, stPersistLoadedFileCache :: !(Strict.Maybe LoadedFileCache)
-- ^ Cached typechecking state from the last loaded file.
-- Should be @Nothing@ when checking imports.
, stPersistBackends :: [Backend]
-- ^ Current backends with their options
}
deriving Generic
data LoadedFileCache = LoadedFileCache
{ lfcCached :: !CachedTypeCheckLog
, lfcCurrent :: !CurrentTypeCheckLog
}
deriving Generic
-- | A log of what the type checker does and states after the action is
-- completed. The cached version is stored first executed action first.
type CachedTypeCheckLog = [(TypeCheckAction, PostScopeState)]
-- | Like 'CachedTypeCheckLog', but storing the log for an ongoing type
-- checking of a module. Stored in reverse order (last performed action
-- first).
type CurrentTypeCheckLog = [(TypeCheckAction, PostScopeState)]
-- | A complete log for a module will look like this:
--
-- * 'Pragmas'
--
-- * 'EnterSection', entering the main module.
--
-- * 'Decl'/'EnterSection'/'LeaveSection', for declarations and nested
-- modules
--
-- * 'LeaveSection', leaving the main module.
data TypeCheckAction
= EnterSection !ModuleName !A.Telescope
| LeaveSection !ModuleName
| Decl !A.Declaration
-- ^ Never a Section or ScopeDecl
| Pragmas !PragmaOptions
deriving (Generic)
-- | Empty persistent state.
initPersistentState :: PersistentTCState
initPersistentState = PersistentTCSt
{ stPersistentOptions = defaultOptions
, stDecodedModules = Map.empty
, stInteractionOutputCallback = defaultInteractionOutputCallback
, stBenchmark = empty
, stAccumStatistics = Map.empty
, stPersistLoadedFileCache = empty
, stPersistBackends = []
}
-- | Empty state of type checker.
initPreScopeState :: PreScopeState
initPreScopeState = PreScopeState
{ stPreTokens = mempty
, stPreImports = emptySignature
, stPreImportedModules = Set.empty
, stPreModuleToSource = Map.empty
, stPreVisitedModules = Map.empty
, stPreScope = emptyScopeInfo
, stPrePatternSyns = Map.empty
, stPrePatternSynImports = Map.empty
, stPreGeneralizedVars = mempty
, stPrePragmaOptions = defaultInteractionOptions
, stPreImportedBuiltins = Map.empty
, stPreImportedDisplayForms = HMap.empty
, stPreImportedInstanceDefs = Map.empty
, stPreForeignCode = Map.empty
, stPreFreshInteractionId = 0
, stPreImportedUserWarnings = Map.empty
, stPreLocalUserWarnings = Map.empty
, stPreWarningOnImport = empty
, stPreImportedPartialDefs = Set.empty
, stPreProjectConfigs = Map.empty
, stPreAgdaLibFiles = Map.empty
, stPreModuleNameHashes = Map.singleton noModuleNameHash (C.QName C.noName_)
-- We should get a hash collision if the hash of any actual module
-- name is noModuleNameHash.
}
initPostScopeState :: PostScopeState
initPostScopeState = PostScopeState
{ stPostSyntaxInfo = mempty
, stPostDisambiguatedNames = IntMap.empty
, stPostMetaStore = IntMap.empty
, stPostInteractionPoints = empty
, stPostAwakeConstraints = []
, stPostSleepingConstraints = []
, stPostDirty = False
, stPostOccursCheckDefs = Set.empty
, stPostSignature = emptySignature
, stPostModuleCheckpoints = Map.empty
, stPostImportsDisplayForms = HMap.empty
, stPostCurrentModule = empty
, stPostInstanceDefs = (Map.empty , Set.empty)
, stPostConcreteNames = Map.empty
, stPostUsedNames = Map.empty
, stPostShadowingNames = Map.empty
, stPostStatistics = Map.empty
, stPostTCWarnings = []
, stPostMutualBlocks = Map.empty
, stPostLocalBuiltins = Map.empty
, stPostFreshMetaId = 0
, stPostFreshMutualId = 0
, stPostFreshProblemId = 1
, stPostFreshCheckpointId = 1
, stPostFreshInt = 0
, stPostFreshNameId = NameId 0 noModuleNameHash
, stPostAreWeCaching = False
, stPostPostponeInstanceSearch = False
, stPostConsideringInstance = False
, stPostInstantiateBlocking = False
, stPostLocalPartialDefs = Set.empty
}
initState :: TCState
initState = TCSt
{ stPreScopeState = initPreScopeState
, stPostScopeState = initPostScopeState
, stPersistentState = initPersistentState
}
-- * st-prefixed lenses
------------------------------------------------------------------------
stTokens :: Lens' HighlightingInfo TCState
stTokens f s =
f (stPreTokens (stPreScopeState s)) <&>
\x -> s {stPreScopeState = (stPreScopeState s) {stPreTokens = x}}
stImports :: Lens' Signature TCState
stImports f s =
f (stPreImports (stPreScopeState s)) <&>
\x -> s {stPreScopeState = (stPreScopeState s) {stPreImports = x}}
stImportedModules :: Lens' (Set ModuleName) TCState
stImportedModules f s =
f (stPreImportedModules (stPreScopeState s)) <&>
\x -> s {stPreScopeState = (stPreScopeState s) {stPreImportedModules = x}}
stModuleToSource :: Lens' ModuleToSource TCState
stModuleToSource f s =
f (stPreModuleToSource (stPreScopeState s)) <&>
\x -> s {stPreScopeState = (stPreScopeState s) {stPreModuleToSource = x}}
stVisitedModules :: Lens' VisitedModules TCState
stVisitedModules f s =
f (stPreVisitedModules (stPreScopeState s)) <&>
\x -> s {stPreScopeState = (stPreScopeState s) {stPreVisitedModules = x}}
stScope :: Lens' ScopeInfo TCState
stScope f s =
f (stPreScope (stPreScopeState s)) <&>
\x -> s {stPreScopeState = (stPreScopeState s) {stPreScope = x}}
stPatternSyns :: Lens' A.PatternSynDefns TCState
stPatternSyns f s =
f (stPrePatternSyns (stPreScopeState s)) <&>
\x -> s {stPreScopeState = (stPreScopeState s) {stPrePatternSyns = x}}
stPatternSynImports :: Lens' A.PatternSynDefns TCState
stPatternSynImports f s =
f (stPrePatternSynImports (stPreScopeState s)) <&>
\x -> s {stPreScopeState = (stPreScopeState s) {stPrePatternSynImports = x}}
stGeneralizedVars :: Lens' (Maybe (Set QName)) TCState
stGeneralizedVars f s =
f (Strict.toLazy $ stPreGeneralizedVars (stPreScopeState s)) <&>
\x -> s {stPreScopeState = (stPreScopeState s) {stPreGeneralizedVars = Strict.toStrict x}}
stPragmaOptions :: Lens' PragmaOptions TCState
stPragmaOptions f s =
f (stPrePragmaOptions (stPreScopeState s)) <&>
\x -> s {stPreScopeState = (stPreScopeState s) {stPrePragmaOptions = x}}
stImportedBuiltins :: Lens' (BuiltinThings PrimFun) TCState
stImportedBuiltins f s =
f (stPreImportedBuiltins (stPreScopeState s)) <&>
\x -> s {stPreScopeState = (stPreScopeState s) {stPreImportedBuiltins = x}}
stForeignCode :: Lens' (Map BackendName [ForeignCode]) TCState
stForeignCode f s =
f (stPreForeignCode (stPreScopeState s)) <&>
\x -> s {stPreScopeState = (stPreScopeState s) {stPreForeignCode = x}}
stFreshInteractionId :: Lens' InteractionId TCState
stFreshInteractionId f s =
f (stPreFreshInteractionId (stPreScopeState s)) <&>
\x -> s {stPreScopeState = (stPreScopeState s) {stPreFreshInteractionId = x}}
stImportedUserWarnings :: Lens' (Map A.QName Text) TCState
stImportedUserWarnings f s =
f (stPreImportedUserWarnings (stPreScopeState s)) <&>
\ x -> s {stPreScopeState = (stPreScopeState s) {stPreImportedUserWarnings = x}}
stLocalUserWarnings :: Lens' (Map A.QName Text) TCState
stLocalUserWarnings f s =
f (stPreLocalUserWarnings (stPreScopeState s)) <&>
\ x -> s {stPreScopeState = (stPreScopeState s) {stPreLocalUserWarnings = x}}
getUserWarnings :: ReadTCState m => m (Map A.QName Text)
getUserWarnings = do
iuw <- useR stImportedUserWarnings
luw <- useR stLocalUserWarnings
return $ iuw `Map.union` luw
stWarningOnImport :: Lens' (Maybe Text) TCState
stWarningOnImport f s =
f (Strict.toLazy $ stPreWarningOnImport (stPreScopeState s)) <&>
\ x -> s {stPreScopeState = (stPreScopeState s) {stPreWarningOnImport = Strict.toStrict x}}
stImportedPartialDefs :: Lens' (Set QName) TCState
stImportedPartialDefs f s =
f (stPreImportedPartialDefs (stPreScopeState s)) <&>
\ x -> s {stPreScopeState = (stPreScopeState s) {stPreImportedPartialDefs = x}}
stLocalPartialDefs :: Lens' (Set QName) TCState
stLocalPartialDefs f s =
f (stPostLocalPartialDefs (stPostScopeState s)) <&>
\ x -> s {stPostScopeState = (stPostScopeState s) {stPostLocalPartialDefs = x}}
getPartialDefs :: ReadTCState m => m (Set QName)
getPartialDefs = do
ipd <- useR stImportedPartialDefs
lpd <- useR stLocalPartialDefs
return $ ipd `Set.union` lpd
stLoadedFileCache :: Lens' (Maybe LoadedFileCache) TCState
stLoadedFileCache f s =
f (Strict.toLazy $ stPersistLoadedFileCache (stPersistentState s)) <&>
\x -> s {stPersistentState = (stPersistentState s) {stPersistLoadedFileCache = Strict.toStrict x}}
stBackends :: Lens' [Backend] TCState
stBackends f s =
f (stPersistBackends (stPersistentState s)) <&>
\x -> s {stPersistentState = (stPersistentState s) {stPersistBackends = x}}
stProjectConfigs :: Lens' (Map FilePath ProjectConfig) TCState
stProjectConfigs f s =
f (stPreProjectConfigs (stPreScopeState s)) <&>
\ x -> s {stPreScopeState = (stPreScopeState s) {stPreProjectConfigs = x}}
stAgdaLibFiles :: Lens' (Map FilePath AgdaLibFile) TCState
stAgdaLibFiles f s =
f (stPreAgdaLibFiles (stPreScopeState s)) <&>
\ x -> s {stPreScopeState = (stPreScopeState s) {stPreAgdaLibFiles = x}}
stModuleNameHashes :: Lens' (Map ModuleNameHash C.QName) TCState
stModuleNameHashes f s =
f (stPreModuleNameHashes (stPreScopeState s)) <&>
\ x -> s {stPreScopeState = (stPreScopeState s) {stPreModuleNameHashes = x}}
stFreshNameId :: Lens' NameId TCState
stFreshNameId f s =
f (stPostFreshNameId (stPostScopeState s)) <&>
\x -> s {stPostScopeState = (stPostScopeState s) {stPostFreshNameId = x}}
stSyntaxInfo :: Lens' HighlightingInfo TCState
stSyntaxInfo f s =
f (stPostSyntaxInfo (stPostScopeState s)) <&>
\x -> s {stPostScopeState = (stPostScopeState s) {stPostSyntaxInfo = x}}
stDisambiguatedNames :: Lens' DisambiguatedNames TCState
stDisambiguatedNames f s =
f (stPostDisambiguatedNames (stPostScopeState s)) <&>
\x -> s {stPostScopeState = (stPostScopeState s) {stPostDisambiguatedNames = x}}
stMetaStore :: Lens' MetaStore TCState
stMetaStore f s =
f (stPostMetaStore (stPostScopeState s)) <&>
\x -> s {stPostScopeState = (stPostScopeState s) {stPostMetaStore = x}}
stInteractionPoints :: Lens' InteractionPoints TCState
stInteractionPoints f s =
f (stPostInteractionPoints (stPostScopeState s)) <&>
\x -> s {stPostScopeState = (stPostScopeState s) {stPostInteractionPoints = x}}
stAwakeConstraints :: Lens' Constraints TCState
stAwakeConstraints f s =
f (stPostAwakeConstraints (stPostScopeState s)) <&>
\x -> s {stPostScopeState = (stPostScopeState s) {stPostAwakeConstraints = x}}
stSleepingConstraints :: Lens' Constraints TCState
stSleepingConstraints f s =
f (stPostSleepingConstraints (stPostScopeState s)) <&>
\x -> s {stPostScopeState = (stPostScopeState s) {stPostSleepingConstraints = x}}
stDirty :: Lens' Bool TCState
stDirty f s =
f (stPostDirty (stPostScopeState s)) <&>
\x -> s {stPostScopeState = (stPostScopeState s) {stPostDirty = x}}
stOccursCheckDefs :: Lens' (Set QName) TCState
stOccursCheckDefs f s =
f (stPostOccursCheckDefs (stPostScopeState s)) <&>
\x -> s {stPostScopeState = (stPostScopeState s) {stPostOccursCheckDefs = x}}
stSignature :: Lens' Signature TCState
stSignature f s =
f (stPostSignature (stPostScopeState s)) <&>
\x -> s {stPostScopeState = (stPostScopeState s) {stPostSignature = x}}
stModuleCheckpoints :: Lens' (Map ModuleName CheckpointId) TCState
stModuleCheckpoints f s =
f (stPostModuleCheckpoints (stPostScopeState s)) <&>
\x -> s {stPostScopeState = (stPostScopeState s) {stPostModuleCheckpoints = x}}
stImportsDisplayForms :: Lens' DisplayForms TCState
stImportsDisplayForms f s =
f (stPostImportsDisplayForms (stPostScopeState s)) <&>
\x -> s {stPostScopeState = (stPostScopeState s) {stPostImportsDisplayForms = x}}
stImportedDisplayForms :: Lens' DisplayForms TCState
stImportedDisplayForms f s =
f (stPreImportedDisplayForms (stPreScopeState s)) <&>
\x -> s {stPreScopeState = (stPreScopeState s) {stPreImportedDisplayForms = x}}
stCurrentModule :: Lens' (Maybe ModuleName) TCState
stCurrentModule f s =
f (Strict.toLazy $ stPostCurrentModule (stPostScopeState s)) <&>
\x -> s {stPostScopeState = (stPostScopeState s) {stPostCurrentModule = Strict.toStrict x}}
stImportedInstanceDefs :: Lens' InstanceTable TCState
stImportedInstanceDefs f s =
f (stPreImportedInstanceDefs (stPreScopeState s)) <&>
\x -> s {stPreScopeState = (stPreScopeState s) {stPreImportedInstanceDefs = x}}
stInstanceDefs :: Lens' TempInstanceTable TCState
stInstanceDefs f s =
f (stPostInstanceDefs (stPostScopeState s)) <&>
\x -> s {stPostScopeState = (stPostScopeState s) {stPostInstanceDefs = x}}
stConcreteNames :: Lens' ConcreteNames TCState
stConcreteNames f s =
f (stPostConcreteNames (stPostScopeState s)) <&>
\x -> s {stPostScopeState = (stPostScopeState s) {stPostConcreteNames = x}}
stUsedNames :: Lens' (Map RawName [RawName]) TCState
stUsedNames f s =
f (stPostUsedNames (stPostScopeState s)) <&>
\x -> s {stPostScopeState = (stPostScopeState s) {stPostUsedNames = x}}
stShadowingNames :: Lens' (Map Name [RawName]) TCState
stShadowingNames f s =
f (stPostShadowingNames (stPostScopeState s)) <&>
\x -> s {stPostScopeState = (stPostScopeState s) {stPostShadowingNames = x}}
stStatistics :: Lens' Statistics TCState
stStatistics f s =
f (stPostStatistics (stPostScopeState s)) <&>
\x -> s {stPostScopeState = (stPostScopeState s) {stPostStatistics = x}}
stTCWarnings :: Lens' [TCWarning] TCState
stTCWarnings f s =
f (stPostTCWarnings (stPostScopeState s)) <&>
\x -> s {stPostScopeState = (stPostScopeState s) {stPostTCWarnings = x}}
stMutualBlocks :: Lens' (Map MutualId MutualBlock) TCState
stMutualBlocks f s =
f (stPostMutualBlocks (stPostScopeState s)) <&>
\x -> s {stPostScopeState = (stPostScopeState s) {stPostMutualBlocks = x}}
stLocalBuiltins :: Lens' (BuiltinThings PrimFun) TCState
stLocalBuiltins f s =
f (stPostLocalBuiltins (stPostScopeState s)) <&>
\x -> s {stPostScopeState = (stPostScopeState s) {stPostLocalBuiltins = x}}
stFreshMetaId :: Lens' MetaId TCState
stFreshMetaId f s =
f (stPostFreshMetaId (stPostScopeState s)) <&>
\x -> s {stPostScopeState = (stPostScopeState s) {stPostFreshMetaId = x}}
stFreshMutualId :: Lens' MutualId TCState
stFreshMutualId f s =
f (stPostFreshMutualId (stPostScopeState s)) <&>
\x -> s {stPostScopeState = (stPostScopeState s) {stPostFreshMutualId = x}}
stFreshProblemId :: Lens' ProblemId TCState
stFreshProblemId f s =
f (stPostFreshProblemId (stPostScopeState s)) <&>
\x -> s {stPostScopeState = (stPostScopeState s) {stPostFreshProblemId = x}}
stFreshCheckpointId :: Lens' CheckpointId TCState
stFreshCheckpointId f s =
f (stPostFreshCheckpointId (stPostScopeState s)) <&>
\x -> s {stPostScopeState = (stPostScopeState s) {stPostFreshCheckpointId = x}}
stFreshInt :: Lens' Int TCState
stFreshInt f s =
f (stPostFreshInt (stPostScopeState s)) <&>
\x -> s {stPostScopeState = (stPostScopeState s) {stPostFreshInt = x}}
-- use @areWeCaching@ from the Caching module instead.
stAreWeCaching :: Lens' Bool TCState
stAreWeCaching f s =
f (stPostAreWeCaching (stPostScopeState s)) <&>
\x -> s {stPostScopeState = (stPostScopeState s) {stPostAreWeCaching = x}}
stPostponeInstanceSearch :: Lens' Bool TCState
stPostponeInstanceSearch f s =
f (stPostPostponeInstanceSearch (stPostScopeState s)) <&>
\x -> s {stPostScopeState = (stPostScopeState s) {stPostPostponeInstanceSearch = x}}
stConsideringInstance :: Lens' Bool TCState
stConsideringInstance f s =
f (stPostConsideringInstance (stPostScopeState s)) <&>
\x -> s {stPostScopeState = (stPostScopeState s) {stPostConsideringInstance = x}}
stInstantiateBlocking :: Lens' Bool TCState
stInstantiateBlocking f s =
f (stPostInstantiateBlocking (stPostScopeState s)) <&>
\x -> s {stPostScopeState = (stPostScopeState s) {stPostInstantiateBlocking = x}}
stBuiltinThings :: TCState -> BuiltinThings PrimFun
stBuiltinThings s = (s^.stLocalBuiltins) `Map.union` (s^.stImportedBuiltins)
-- * Fresh things
------------------------------------------------------------------------
class Enum i => HasFresh i where
freshLens :: Lens' i TCState
nextFresh' :: i -> i
nextFresh' = succ
nextFresh :: HasFresh i => TCState -> (i, TCState)
nextFresh s =
let !c = s^.freshLens
in (c, set freshLens (nextFresh' c) s)
class Monad m => MonadFresh i m where
fresh :: m i
default fresh :: (MonadTrans t, MonadFresh i n, t n ~ m) => m i
fresh = lift fresh
instance MonadFresh i m => MonadFresh i (ReaderT r m)
instance MonadFresh i m => MonadFresh i (StateT s m)
instance MonadFresh i m => MonadFresh i (ListT m)
instance MonadFresh i m => MonadFresh i (IdentityT m)
instance HasFresh i => MonadFresh i TCM where
fresh = do
!s <- getTC
let (!c , !s') = nextFresh s
putTC s'
return c
instance HasFresh MetaId where
freshLens = stFreshMetaId
instance HasFresh MutualId where
freshLens = stFreshMutualId
instance HasFresh InteractionId where
freshLens = stFreshInteractionId
instance HasFresh NameId where
freshLens = stFreshNameId
-- nextFresh increments the current fresh name by 2 so @NameId@s used
-- before caching starts do not overlap with the ones used after.
nextFresh' = succ . succ
instance HasFresh Int where
freshLens = stFreshInt
instance HasFresh ProblemId where
freshLens = stFreshProblemId
newtype CheckpointId = CheckpointId Int
deriving (Data, Eq, Ord, Enum, Real, Integral, Num, NFData)
instance Show CheckpointId where
show (CheckpointId n) = show n
instance Pretty CheckpointId where
pretty (CheckpointId n) = pretty n
instance HasFresh CheckpointId where
freshLens = stFreshCheckpointId
freshName :: MonadFresh NameId m => Range -> String -> m Name
freshName r s = do
i <- fresh
return $ mkName r i s
freshNoName :: MonadFresh NameId m => Range -> m Name
freshNoName r =
do i <- fresh
return $ makeName i (C.NoName noRange i) r noFixity' False
freshNoName_ :: MonadFresh NameId m => m Name
freshNoName_ = freshNoName noRange
freshRecordName :: MonadFresh NameId m => m Name
freshRecordName = do
i <- fresh
return $ makeName i (C.setNotInScope $ C.simpleName "r") noRange noFixity' True
-- | Create a fresh name from @a@.
class FreshName a where
freshName_ :: MonadFresh NameId m => a -> m Name
instance FreshName (Range, String) where
freshName_ = uncurry freshName
instance FreshName String where
freshName_ = freshName noRange
instance FreshName Range where
freshName_ = freshNoName
instance FreshName () where
freshName_ () = freshNoName_
---------------------------------------------------------------------------
-- ** Managing file names
---------------------------------------------------------------------------
-- | Maps top-level module names to the corresponding source file
-- names.
type ModuleToSource = Map TopLevelModuleName AbsolutePath
-- | Maps source file names to the corresponding top-level module
-- names.
type SourceToModule = Map AbsolutePath TopLevelModuleName
-- | Creates a 'SourceToModule' map based on 'stModuleToSource'.
--
-- O(n log n).
--
-- For a single reverse lookup in 'stModuleToSource',
-- rather use 'lookupModuleFromSourse'.
sourceToModule :: TCM SourceToModule
sourceToModule =
Map.fromListWith __IMPOSSIBLE__
. List.map (\(m, f) -> (f, m))
. Map.toList
<$> useTC stModuleToSource
-- | Lookup an 'AbsolutePath' in 'sourceToModule'.
--
-- O(n).
lookupModuleFromSource :: ReadTCState m => AbsolutePath -> m (Maybe TopLevelModuleName)
lookupModuleFromSource f =
fmap fst . List.find ((f ==) . snd) . Map.toList <$> useR stModuleToSource
---------------------------------------------------------------------------
-- ** Associating concrete names to an abstract name
---------------------------------------------------------------------------
-- | A monad that has read and write access to the stConcreteNames
-- part of the TCState. Basically, this is a synonym for `MonadState
-- ConcreteNames m` (which cannot be used directly because of the
-- limitations of Haskell's typeclass system).
class Monad m => MonadStConcreteNames m where
runStConcreteNames :: StateT ConcreteNames m a -> m a
useConcreteNames :: m ConcreteNames
useConcreteNames = runStConcreteNames get
modifyConcreteNames :: (ConcreteNames -> ConcreteNames) -> m ()
modifyConcreteNames = runStConcreteNames . modify
instance MonadStConcreteNames TCM where
runStConcreteNames m = stateTCLensM stConcreteNames $ runStateT m
instance MonadStConcreteNames m => MonadStConcreteNames (IdentityT m) where
runStConcreteNames m = IdentityT $ runStConcreteNames $ StateT $ runIdentityT . runStateT m
instance MonadStConcreteNames m => MonadStConcreteNames (ReaderT r m) where
runStConcreteNames m = ReaderT $ runStConcreteNames . StateT . flip (runReaderT . runStateT m)
instance MonadStConcreteNames m => MonadStConcreteNames (StateT s m) where
runStConcreteNames m = StateT $ \s -> runStConcreteNames $ StateT $ \ns -> do
((x,ns'),s') <- runStateT (runStateT m ns) s
return ((x,s'),ns')
---------------------------------------------------------------------------
-- ** Interface
---------------------------------------------------------------------------
-- | Distinguishes between type-checked and scope-checked interfaces
-- when stored in the map of `VisitedModules`.
data ModuleCheckMode
= ModuleScopeChecked
| ModuleTypeChecked
deriving (Eq, Ord, Bounded, Enum, Show, Generic)
data ModuleInfo = ModuleInfo
{ miInterface :: Interface
, miWarnings :: [TCWarning]
-- ^ Warnings were encountered when the module was type checked.
-- These might include warnings not stored in the interface itself,
-- specifically unsolved interaction metas.
-- See "Agda.Interaction.Imports"
, miPrimitive :: Bool
-- ^ 'True' if the module is a primitive module, which should always
-- be importable.
, miMode :: ModuleCheckMode
-- ^ The `ModuleCheckMode` used to create the `Interface`
}
deriving Generic
-- Note that the use of 'C.TopLevelModuleName' here is a potential
-- performance problem, because these names do not contain unique
-- identifiers.
type VisitedModules = Map C.TopLevelModuleName ModuleInfo
type DecodedModules = Map C.TopLevelModuleName ModuleInfo
data ForeignCode = ForeignCode Range String
deriving (Show, Generic)
data Interface = Interface
{ iSourceHash :: Hash
-- ^ Hash of the source code.
, iSource :: TL.Text
-- ^ The source code. The source code is stored so that the HTML
-- and LaTeX backends can generate their output without having to
-- re-read the (possibly out of date) source code.
, iFileType :: FileType
-- ^ Source file type, determined from the file extension
, iImportedModules :: [(ModuleName, Hash)]
-- ^ Imported modules and their hashes.
, iModuleName :: ModuleName
-- ^ Module name of this interface.
, iScope :: Map ModuleName Scope
-- ^ Scope defined by this module.
--
-- Andreas, AIM XX: Too avoid duplicate serialization, this field is
-- not serialized, so if you deserialize an interface, @iScope@
-- will be empty.
-- But 'constructIScope' constructs 'iScope' from 'iInsideScope'.
, iInsideScope :: ScopeInfo
-- ^ Scope after we loaded this interface.
-- Used in 'Agda.Interaction.BasicOps.AtTopLevel'
-- and 'Agda.Interaction.CommandLine.interactionLoop'.
, iSignature :: Signature
, iDisplayForms :: DisplayForms
-- ^ Display forms added for imported identifiers.
, iUserWarnings :: Map A.QName Text
-- ^ User warnings for imported identifiers
, iImportWarning :: Maybe Text
-- ^ Whether this module should raise a warning when imported
, iBuiltin :: BuiltinThings (String, QName)
, iForeignCode :: Map BackendName [ForeignCode]
, iHighlighting :: HighlightingInfo
, iDefaultPragmaOptions :: [OptionsPragma]
-- ^ Pragma options set in library files.
, iFilePragmaOptions :: [OptionsPragma]
-- ^ Pragma options set in the file.
, iOptionsUsed :: PragmaOptions
-- ^ Options/features used when checking the file (can be different
-- from options set directly in the file).
, iPatternSyns :: A.PatternSynDefns
, iWarnings :: [TCWarning]
, iPartialDefs :: Set QName
}
deriving (Show, Generic)
instance Pretty Interface where
pretty (Interface
sourceH source fileT importedM moduleN scope insideS signature
display userwarn importwarn builtin foreignCode highlighting
libPragmaO filePragmaO
oUsed patternS warnings partialdefs) =
hang "Interface" 2 $ vcat
[ "source hash:" <+> (pretty . show) sourceH
, "source:" $$ nest 2 (text $ TL.unpack source)
, "file type:" <+> (pretty . show) fileT
, "imported modules:" <+> (pretty . show) importedM
, "module name:" <+> pretty moduleN
, "scope:" <+> (pretty . show) scope
, "inside scope:" <+> (pretty . show) insideS
, "signature:" <+> (pretty . show) signature
, "display:" <+> (pretty . show) display
, "user warnings:" <+> (pretty . show) userwarn
, "import warning:" <+> (pretty . show) importwarn