1{-# LANGUAGE NondecreasingIndentation #-}
2
3{-| The scope monad with operations.
4-}
5
6module Agda.Syntax.Scope.Monad where
7
8import Prelude hiding (null)
9
10import Control.Arrow ((***))
11import Control.Monad
12import Control.Monad.Except
13import Control.Monad.Writer hiding ((<>))
14import Control.Monad.State
15
16import Data.Either ( partitionEithers )
17import Data.Foldable (all, traverse_)
18import qualified Data.List as List
19import Data.Map (Map)
20import qualified Data.Map as Map
21import Data.Maybe
22import Data.Set (Set)
23import qualified Data.Set as Set
24import Data.Traversable hiding (for)
25
26import Agda.Interaction.Options
27import Agda.Interaction.Options.Warnings
28
29import Agda.Syntax.Common
30import Agda.Syntax.Position
31import Agda.Syntax.Fixity
32import Agda.Syntax.Notation
33import Agda.Syntax.Abstract.Name as A
34import qualified Agda.Syntax.Abstract as A
35import Agda.Syntax.Abstract (ScopeCopyInfo(..))
36import Agda.Syntax.Concrete as C
37import Agda.Syntax.Concrete.Fixity
38import Agda.Syntax.Concrete.Definitions ( DeclarationWarning(..) ,DeclarationWarning'(..) )
39  -- TODO: move the relevant warnings out of there
40import Agda.Syntax.Scope.Base as A
41
42import Agda.TypeChecking.Monad.Base
43import Agda.TypeChecking.Monad.Builtin ( HasBuiltins , getBuiltinName' , builtinSet , builtinProp , builtinSetOmega, builtinSSetOmega )
44import Agda.TypeChecking.Monad.Debug
45import Agda.TypeChecking.Monad.State
46import Agda.TypeChecking.Monad.Trace
47import Agda.TypeChecking.Positivity.Occurrence (Occurrence)
48import Agda.TypeChecking.Warnings ( warning, warning' )
49
50import qualified Agda.Utils.AssocList as AssocList
51import Agda.Utils.CallStack ( CallStack, HasCallStack, withCallerCallStack )
52import Agda.Utils.Functor
53import Agda.Utils.Lens
54import Agda.Utils.List
55import Agda.Utils.List1 (List1, pattern (:|), nonEmpty)
56import Agda.Utils.List2 (List2(List2))
57import qualified Agda.Utils.List1 as List1
58import qualified Agda.Utils.List2 as List2
59import Agda.Utils.Maybe
60import Agda.Utils.Monad
61import Agda.Utils.Null
62import Agda.Utils.Pretty
63import Agda.Utils.Singleton
64import Agda.Utils.Suffix as C
65
66import Agda.Utils.Impossible
67
68---------------------------------------------------------------------------
69-- * The scope checking monad
70---------------------------------------------------------------------------
71
72-- | To simplify interaction between scope checking and type checking (in
73--   particular when chasing imports), we use the same monad.
74type ScopeM = TCM
75
76-- Debugging
77
78printLocals :: Int -> String -> ScopeM ()
79printLocals v s = verboseS "scope.top" v $ do
80  locals <- getLocalVars
81  reportSLn "scope.top" v $ s ++ " " ++ prettyShow locals
82
83scopeWarning' :: CallStack -> DeclarationWarning' -> ScopeM ()
84scopeWarning' loc = warning' loc . NicifierIssue . DeclarationWarning loc
85
86scopeWarning :: HasCallStack => DeclarationWarning' -> ScopeM ()
87scopeWarning = withCallerCallStack scopeWarning'
88
89---------------------------------------------------------------------------
90-- * General operations
91---------------------------------------------------------------------------
92
93isDatatypeModule :: ReadTCState m => A.ModuleName -> m (Maybe DataOrRecordModule)
94isDatatypeModule m = do
95   scopeDatatypeModule . Map.findWithDefault __IMPOSSIBLE__ m <$> useScope scopeModules
96
97getCurrentModule :: ReadTCState m => m A.ModuleName
98getCurrentModule = setRange noRange <$> useScope scopeCurrent
99
100setCurrentModule :: MonadTCState m => A.ModuleName -> m ()
101setCurrentModule m = modifyScope $ set scopeCurrent m
102
103withCurrentModule :: (ReadTCState m, MonadTCState m) => A.ModuleName -> m a -> m a
104withCurrentModule new action = do
105  old <- getCurrentModule
106  setCurrentModule new
107  x   <- action
108  setCurrentModule old
109  return x
110
111withCurrentModule' :: (MonadTrans t, Monad (t ScopeM)) => A.ModuleName -> t ScopeM a -> t ScopeM a
112withCurrentModule' new action = do
113  old <- lift getCurrentModule
114  lift $ setCurrentModule new
115  x   <- action
116  lift $ setCurrentModule old
117  return x
118
119getNamedScope :: A.ModuleName -> ScopeM Scope
120getNamedScope m = do
121  scope <- getScope
122  case Map.lookup m (scope ^. scopeModules) of
123    Just s  -> return s
124    Nothing -> do
125      reportSLn "" 0 $ "ERROR: In scope\n" ++ prettyShow scope ++ "\nNO SUCH SCOPE " ++ prettyShow m
126      __IMPOSSIBLE__
127
128getCurrentScope :: ScopeM Scope
129getCurrentScope = getNamedScope =<< getCurrentModule
130
131-- | Create a new module with an empty scope.
132--   If the module is not new (e.g. duplicate @import@),
133--   don't erase its contents.
134--   (@Just@ if it is a datatype or record module.)
135createModule :: Maybe DataOrRecordModule -> A.ModuleName -> ScopeM ()
136createModule b m = do
137  reportSLn "scope.createModule" 10 $ "createModule " ++ prettyShow m
138  s <- getCurrentScope
139  let parents = scopeName s : scopeParents s
140      sm = emptyScope { scopeName           = m
141                      , scopeParents        = parents
142                      , scopeDatatypeModule = b }
143  -- Andreas, 2015-07-02: internal error if module is not new.
144  -- Ulf, 2016-02-15: It's not new if multiple imports (#1770).
145  -- Andreas, 2020-05-18, issue #3933:
146  -- If it is not new (but apparently did not clash),
147  -- we do not erase its contents for reasons of monotonicity.
148  modifyScopes $ Map.insertWith mergeScope m sm
149
150-- | Apply a function to the scope map.
151modifyScopes :: (Map A.ModuleName Scope -> Map A.ModuleName Scope) -> ScopeM ()
152modifyScopes = modifyScope . over scopeModules
153
154-- | Apply a function to the given scope.
155modifyNamedScope :: A.ModuleName -> (Scope -> Scope) -> ScopeM ()
156modifyNamedScope m f = modifyScopes $ Map.adjust f m
157
158setNamedScope :: A.ModuleName -> Scope -> ScopeM ()
159setNamedScope m s = modifyNamedScope m $ const s
160
161-- | Apply a monadic function to the top scope.
162modifyNamedScopeM :: A.ModuleName -> (Scope -> ScopeM (a, Scope)) -> ScopeM a
163modifyNamedScopeM m f = do
164  (a, s) <- f =<< getNamedScope m
165  setNamedScope m s
166  return a
167
168-- | Apply a function to the current scope.
169modifyCurrentScope :: (Scope -> Scope) -> ScopeM ()
170modifyCurrentScope f = getCurrentModule >>= (`modifyNamedScope` f)
171
172modifyCurrentScopeM :: (Scope -> ScopeM (a, Scope)) -> ScopeM a
173modifyCurrentScopeM f = getCurrentModule >>= (`modifyNamedScopeM` f)
174
175-- | Apply a function to the public or private name space.
176modifyCurrentNameSpace :: NameSpaceId -> (NameSpace -> NameSpace) -> ScopeM ()
177modifyCurrentNameSpace acc f = modifyCurrentScope $ updateScopeNameSpaces $
178  AssocList.updateAt acc f
179
180setContextPrecedence :: PrecedenceStack -> ScopeM ()
181setContextPrecedence = modifyScope_ . set scopePrecedence
182
183withContextPrecedence :: ReadTCState m => Precedence -> m a -> m a
184withContextPrecedence p =
185  locallyTCState (stScope . scopePrecedence) $ pushPrecedence p
186
187getLocalVars :: ReadTCState m => m LocalVars
188getLocalVars = useScope scopeLocals
189
190modifyLocalVars :: (LocalVars -> LocalVars) -> ScopeM ()
191modifyLocalVars = modifyScope_ . updateScopeLocals
192
193setLocalVars :: LocalVars -> ScopeM ()
194setLocalVars vars = modifyLocalVars $ const vars
195
196-- | Run a computation without changing the local variables.
197withLocalVars :: ScopeM a -> ScopeM a
198withLocalVars = bracket_ getLocalVars setLocalVars
199
200-- | Run a computation outside some number of local variables and add them back afterwards. This
201--   lets you bind variables in the middle of the context and is used when binding generalizable
202--   variables (#3735).
203outsideLocalVars :: Int -> ScopeM a -> ScopeM a
204outsideLocalVars n m = do
205  inner <- take n <$> getLocalVars
206  modifyLocalVars (drop n)
207  x <- m
208  modifyLocalVars (inner ++)
209  return x
210
211-- | Check that the newly added variable have unique names.
212
213withCheckNoShadowing :: ScopeM a -> ScopeM a
214withCheckNoShadowing = bracket_ getLocalVars $ \ lvarsOld ->
215  checkNoShadowing lvarsOld =<< getLocalVars
216
217checkNoShadowing :: LocalVars  -- ^ Old local scope
218                 -> LocalVars  -- ^ New local scope
219                 -> ScopeM ()
220checkNoShadowing old new = do
221  opts <- pragmaOptions
222  when (ShadowingInTelescope_ `Set.member`
223          (optWarningMode opts ^. warningSet)) $ do
224    -- LocalVars is currnently an AssocList so the difference between
225    -- two local scope is the left part of the new one.
226    let diff = dropEnd (length old) new
227    -- Filter out the underscores.
228    let newNames = filter (not . isNoName) $ AssocList.keys diff
229    -- Associate each name to its occurrences.
230    let nameOccs1 :: [(C.Name, List1 Range)]
231        nameOccs1 = Map.toList $ Map.fromListWith (<>) $ map pairWithRange newNames
232    -- Warn if we have two or more occurrences of the same name.
233    let nameOccs2 :: [(C.Name, List2 Range)]
234        nameOccs2 = mapMaybe (traverseF List2.fromList1Maybe) nameOccs1
235    caseList nameOccs2 (return ()) $ \ c conflicts -> do
236      scopeWarning $ ShadowingInTelescope $ c :| conflicts
237  where
238    pairWithRange :: C.Name -> (C.Name, List1 Range)
239    pairWithRange n = (n, singleton $ getRange n)
240
241getVarsToBind :: ScopeM LocalVars
242getVarsToBind = useScope scopeVarsToBind
243
244addVarToBind :: C.Name -> LocalVar -> ScopeM ()
245addVarToBind x y = modifyScope_ $ updateVarsToBind $ AssocList.insert x y
246
247-- | After collecting some variable names in the scopeVarsToBind,
248--   bind them all simultaneously.
249bindVarsToBind :: ScopeM ()
250bindVarsToBind = do
251  vars <- getVarsToBind
252  modifyLocalVars (vars++)
253  printLocals 10 "bound variables:"
254  modifyScope_ $ setVarsToBind []
255
256---------------------------------------------------------------------------
257-- * Names
258---------------------------------------------------------------------------
259
260-- | Create a fresh abstract name from a concrete name.
261--
262--   This function is used when we translate a concrete name
263--   in a binder.  The 'Range' of the concrete name is
264--   saved as the 'nameBindingSite' of the abstract name.
265freshAbstractName :: Fixity' -> C.Name -> ScopeM A.Name
266freshAbstractName fx x = do
267  i <- fresh
268  return $ A.Name
269    { nameId          = i
270    , nameConcrete    = x
271    , nameCanonical   = x
272    , nameBindingSite = getRange x
273    , nameFixity      = fx
274    , nameIsRecordName = False
275    }
276
277-- | @freshAbstractName_ = freshAbstractName noFixity'@
278freshAbstractName_ :: C.Name -> ScopeM A.Name
279freshAbstractName_ = freshAbstractName noFixity'
280
281-- | Create a fresh abstract qualified name.
282freshAbstractQName :: Fixity' -> C.Name -> ScopeM A.QName
283freshAbstractQName fx x = do
284  y <- freshAbstractName fx x
285  m <- getCurrentModule
286  return $ A.qualify m y
287
288freshAbstractQName' :: C.Name -> ScopeM A.QName
289freshAbstractQName' x = do
290  fx <- getConcreteFixity x
291  freshAbstractQName fx x
292
293-- | Create a concrete name that is not yet in scope.
294-- | NOTE: See @chooseName@ in @Agda.Syntax.Translation.AbstractToConcrete@ for similar logic.
295-- | NOTE: See @withName@ in @Agda.Syntax.Translation.ReflectedToAbstract@ for similar logic.
296freshConcreteName :: Range -> Int -> String -> ScopeM C.Name
297freshConcreteName r i s = do
298  let cname = C.Name r C.NotInScope $ singleton $ Id $ stringToRawName $ s ++ show i
299  resolveName (C.QName cname) >>= \case
300    UnknownName -> return cname
301    _           -> freshConcreteName r (i+1) s
302
303---------------------------------------------------------------------------
304-- * Resolving names
305---------------------------------------------------------------------------
306
307-- | Look up the abstract name referred to by a given concrete name.
308resolveName :: C.QName -> ScopeM ResolvedName
309resolveName = resolveName' allKindsOfNames Nothing
310
311-- | Look up the abstract name corresponding to a concrete name of
312--   a certain kind and/or from a given set of names.
313--   Sometimes we know already that we are dealing with a constructor
314--   or pattern synonym (e.g. when we have parsed a pattern).
315--   Then, we can ignore conflicting definitions of that name
316--   of a different kind. (See issue 822.)
317resolveName' ::
318  KindsOfNames -> Maybe (Set A.Name) -> C.QName -> ScopeM ResolvedName
319resolveName' kinds names x = runExceptT (tryResolveName kinds names x) >>= \case
320  Left ys  -> traceCall (SetRange $ getRange x) $ typeError $ AmbiguousName x ys
321  Right x' -> return x'
322
323tryResolveName
324  :: (ReadTCState m, HasBuiltins m, MonadError (List1 A.QName) m)
325  => KindsOfNames       -- ^ Restrict search to these kinds of names.
326  -> Maybe (Set A.Name) -- ^ Unless 'Nothing', restrict search to match any of these names.
327  -> C.QName            -- ^ Name to be resolved
328  -> m ResolvedName     -- ^ If illegally ambiguous, throw error with the ambiguous name.
329tryResolveName kinds names x = do
330  scope <- getScope
331  let vars     = AssocList.mapKeysMonotonic C.QName $ scope ^. scopeLocals
332  case lookup x vars of
333    -- Case: we have a local variable x, but is (perhaps) shadowed by some imports ys.
334    Just (LocalVar y b ys) ->
335      -- We may ignore the imports filtered out by the @names@ filter.
336      ifNull (filterNames id ys)
337        {-then-} (return $ VarName y{ nameConcrete = unqualify x } b)
338        {-else-} $ \ ys' ->
339          throwError $ A.qualify_ y :| map anameName ys'
340    -- Case: we do not have a local variable x.
341    Nothing -> do
342      -- Consider only names that are in the given set of names and
343      -- are of one of the given kinds
344      let filtKind = filter $ (`elemKindsOfNames` kinds) . anameKind . fst
345          possibleNames z = filtKind $ filterNames fst $ scopeLookup' z scope
346      -- If the name has a suffix, also consider the possibility that
347      -- the base name is in scope (e.g. the builtin sorts `Set` and `Prop`).
348      canHaveSuffix <- canHaveSuffixTest
349      let (xsuffix, xbase) = (C.lensQNameName . nameSuffix) (,Nothing) x
350          possibleBaseNames = filter (canHaveSuffix . anameName . fst) $ possibleNames xbase
351          suffixedNames = (,) <$> fromConcreteSuffix xsuffix <*> nonEmpty possibleBaseNames
352      case (nonEmpty $ possibleNames x) of
353        Just ds  | let ks = fmap (isConName . anameKind . fst) ds
354                 , all isJust ks
355                 , isNothing suffixedNames ->
356          return $ ConstructorName (Set.fromList $ List1.catMaybes ks) $ fmap (upd . fst) ds
357
358        Just ds  | all ((FldName ==) . anameKind . fst) ds , isNothing suffixedNames ->
359          return $ FieldName $ fmap (upd . fst) ds
360
361        Just ds  | all ((PatternSynName ==) . anameKind . fst) ds , isNothing suffixedNames ->
362          return $ PatternSynResName $ fmap (upd . fst) ds
363
364        Just ((d, a) :| []) | isNothing suffixedNames ->
365          return $ DefinedName a (upd d) A.NoSuffix
366
367        Just ds -> throwError $ fmap (anameName . fst) $ caseMaybe suffixedNames id ((<>) . snd) ds
368
369        Nothing -> case suffixedNames of
370          Nothing -> return UnknownName
371          Just (suffix , (d, a) :| []) -> return $ DefinedName a (upd d) suffix
372          Just (suffix , sds) -> throwError $ fmap (anameName . fst) sds
373
374  where
375  -- @names@ intended semantics: a filter on names.
376  -- @Nothing@: don't filter out anything.
377  -- @Just ns@: filter by membership in @ns@.
378  filterNames :: forall a. (a -> AbstractName) -> [a] -> [a]
379  filterNames = case names of
380    Nothing -> \ f -> id
381    Just ns -> \ f -> filter $ (`Set.member` ns) . A.qnameName . anameName . f
382    -- lambda-dropped style by intention
383  upd d = updateConcreteName d $ unqualify x
384  updateConcreteName :: AbstractName -> C.Name -> AbstractName
385  updateConcreteName d@(AbsName { anameName = A.QName qm qn }) x =
386    d { anameName = A.QName (setRange (getRange x) qm) (qn { nameConcrete = x }) }
387  fromConcreteSuffix = \case
388    Nothing              -> Nothing
389    Just C.Prime{}       -> Nothing
390    Just (C.Index i)     -> Just $ A.Suffix $ toInteger i
391    Just (C.Subscript i) -> Just $ A.Suffix $ toInteger i
392
393-- | Test if a given abstract name can appear with a suffix. Currently
394--   only true for the names of builtin sorts @Set@ and @Prop@.
395canHaveSuffixTest :: HasBuiltins m => m (A.QName -> Bool)
396canHaveSuffixTest = do
397  builtinSet  <- getBuiltinName' builtinSet
398  builtinProp <- getBuiltinName' builtinProp
399  builtinSetOmega <- getBuiltinName' builtinSetOmega
400  builtinSSetOmega <- getBuiltinName' builtinSSetOmega
401  return $ \x -> Just x `elem` [builtinSet, builtinProp, builtinSetOmega, builtinSSetOmega]
402
403-- | Look up a module in the scope.
404resolveModule :: C.QName -> ScopeM AbstractModule
405resolveModule x = do
406  ms <- scopeLookup x <$> getScope
407  caseMaybe (nonEmpty ms) (typeError $ NoSuchModule x) $ \ case
408    AbsModule m why :| [] -> return $ AbsModule (m `withRangeOf` x) why
409    ms                    -> typeError $ AmbiguousModule x (fmap amodName ms)
410
411-- | Get the fixity of a not yet bound name.
412getConcreteFixity :: C.Name -> ScopeM Fixity'
413getConcreteFixity x = Map.findWithDefault noFixity' x <$> useScope scopeFixities
414
415-- | Get the polarities of a not yet bound name.
416getConcretePolarity :: C.Name -> ScopeM (Maybe [Occurrence])
417getConcretePolarity x = Map.lookup x <$> useScope scopePolarities
418
419instance MonadFixityError ScopeM where
420  throwMultipleFixityDecls xs         = case xs of
421    (x, _) : _ -> setCurrentRange (getRange x) $ typeError $ MultipleFixityDecls xs
422    []         -> __IMPOSSIBLE__
423  throwMultiplePolarityPragmas xs     = case xs of
424    x : _ -> setCurrentRange (getRange x) $ typeError $ MultiplePolarityPragmas xs
425    []    -> __IMPOSSIBLE__
426  warnUnknownNamesInFixityDecl        = scopeWarning . UnknownNamesInFixityDecl
427  warnUnknownNamesInPolarityPragmas   = scopeWarning . UnknownNamesInPolarityPragmas
428  warnUnknownFixityInMixfixDecl       = scopeWarning . UnknownFixityInMixfixDecl
429  warnPolarityPragmasButNotPostulates = scopeWarning . PolarityPragmasButNotPostulates
430
431-- | Collect the fixity/syntax declarations and polarity pragmas from the list
432--   of declarations and store them in the scope.
433computeFixitiesAndPolarities :: DoWarn -> [C.Declaration] -> ScopeM a -> ScopeM a
434computeFixitiesAndPolarities warn ds cont = do
435  fp <- fixitiesAndPolarities warn ds
436  -- Andreas, 2019-08-16:
437  -- Since changing fixities and polarities does not affect the name sets,
438  -- we do not need to invoke @modifyScope@ here
439  -- (which does @recomputeInverseScopeMaps@).
440  -- A simple @locallyScope@ is sufficient.
441  locallyScope scopeFixitiesAndPolarities (const fp) cont
442
443-- | Get the notation of a name. The name is assumed to be in scope.
444getNotation
445  :: C.QName
446  -> Set A.Name
447     -- ^ The name must correspond to one of the names in this set.
448  -> ScopeM NewNotation
449getNotation x ns = do
450  r <- resolveName' allKindsOfNames (Just ns) x
451  case r of
452    VarName y _         -> return $ namesToNotation x y
453    DefinedName _ d _   -> return $ notation d
454    FieldName ds        -> return $ oneNotation ds
455    ConstructorName _ ds-> return $ oneNotation ds
456    PatternSynResName n -> return $ oneNotation n
457    UnknownName         -> __IMPOSSIBLE__
458  where
459    notation = namesToNotation x . qnameName . anameName
460    oneNotation ds =
461      case mergeNotations $ map notation $ List1.toList ds of
462        [n] -> n
463        _   -> __IMPOSSIBLE__
464
465---------------------------------------------------------------------------
466-- * Binding names
467---------------------------------------------------------------------------
468
469-- | Bind a variable.
470bindVariable
471  :: A.BindingSource -- ^ @λ@, @Π@, @let@, ...?
472  -> C.Name          -- ^ Concrete name.
473  -> A.Name          -- ^ Abstract name.
474  -> ScopeM ()
475bindVariable b x y = modifyLocalVars $ AssocList.insert x $ LocalVar y b []
476
477-- | Temporarily unbind a variable. Used for non-recursive lets.
478unbindVariable :: C.Name -> ScopeM a -> ScopeM a
479unbindVariable x = bracket_ (getLocalVars <* modifyLocalVars (AssocList.delete x)) (modifyLocalVars . const)
480
481-- | Bind a defined name. Must not shadow anything.
482bindName :: Access -> KindOfName -> C.Name -> A.QName -> ScopeM ()
483bindName acc kind x y = bindName' acc kind NoMetadata x y
484
485bindName' :: Access -> KindOfName -> NameMetadata -> C.Name -> A.QName -> ScopeM ()
486bindName' acc kind meta x y = whenJustM (bindName'' acc kind meta x y) typeError
487
488-- | Bind a name. Returns the 'TypeError' if exists, but does not throw it.
489bindName'' :: Access -> KindOfName -> NameMetadata -> C.Name -> A.QName -> ScopeM (Maybe TypeError)
490bindName'' acc kind meta x y = do
491  when (isNoName x) $ modifyScopes $ Map.map $ removeNameFromScope PrivateNS x
492  r  <- resolveName (C.QName x)
493  let y' :: Either TypeError AbstractName
494      y' = case r of
495        -- Binding an anonymous declaration always succeeds.
496        -- In case it's not the first one, we simply remove the one that came before
497        _ | isNoName x      -> success
498        DefinedName _ d _   -> clash $ anameName d
499        VarName z _         -> clash $ A.qualify_ z
500        FieldName       ds  -> ambiguous (== FldName) ds
501        ConstructorName i ds-> ambiguous (isJust . isConName) ds
502        PatternSynResName n -> ambiguous (== PatternSynName) n
503        UnknownName         -> success
504  let ns = if isNoName x then PrivateNS else localNameSpace acc
505  traverse_ (modifyCurrentScope . addNameToScope ns x) y'
506  pure $ either Just (const Nothing) y'
507  where
508    success = Right $ AbsName y kind Defined meta
509    clash n = Left $ ClashingDefinition (C.QName x) n Nothing
510
511    ambiguous f ds =
512      if f kind && all (f . anameKind) ds
513      then success else clash $ anameName (List1.head ds)
514
515-- | Rebind a name. Use with care!
516--   Ulf, 2014-06-29: Currently used to rebind the name defined by an
517--   unquoteDecl, which is a 'QuotableName' in the body, but a 'DefinedName'
518--   later on.
519rebindName :: Access -> KindOfName -> C.Name -> A.QName -> ScopeM ()
520rebindName acc kind x y = do
521  modifyCurrentScope $ removeNameFromScope (localNameSpace acc) x
522  bindName acc kind x y
523
524-- | Bind a module name.
525bindModule :: Access -> C.Name -> A.ModuleName -> ScopeM ()
526bindModule acc x m = modifyCurrentScope $
527  addModuleToScope (localNameSpace acc) x (AbsModule m Defined)
528
529-- | Bind a qualified module name. Adds it to the imports field of the scope.
530bindQModule :: Access -> C.QName -> A.ModuleName -> ScopeM ()
531bindQModule acc q m = modifyCurrentScope $ \s ->
532  s { scopeImports = Map.insert q m (scopeImports s) }
533
534---------------------------------------------------------------------------
535-- * Module manipulation operations
536---------------------------------------------------------------------------
537
538-- | Clear the scope of any no names.
539stripNoNames :: ScopeM ()
540stripNoNames = modifyScopes $ Map.map $ mapScope_ stripN stripN id
541  where
542    stripN = Map.filterWithKey $ const . not . isNoName
543
544type WSM = StateT ScopeMemo ScopeM
545
546data ScopeMemo = ScopeMemo
547  { memoNames   :: A.Ren A.QName
548  , memoModules :: Map ModuleName (ModuleName, Bool)
549    -- ^ Bool: did we copy recursively? We need to track this because we don't
550    --   copy recursively when creating new modules for reexported functions
551    --   (issue1985), but we might need to copy recursively later.
552  }
553
554memoToScopeInfo :: ScopeMemo -> ScopeCopyInfo
555memoToScopeInfo (ScopeMemo names mods) =
556  ScopeCopyInfo { renNames   = names
557                , renModules = Map.map (pure . fst) mods }
558
559-- | Create a new scope with the given name from an old scope. Renames
560--   public names in the old scope to match the new name and returns the
561--   renamings.
562copyScope :: C.QName -> A.ModuleName -> Scope -> ScopeM (Scope, ScopeCopyInfo)
563copyScope oldc new0 s = (inScopeBecause (Applied oldc) *** memoToScopeInfo) <$> runStateT (copy new0 s) (ScopeMemo mempty mempty)
564  where
565    copy :: A.ModuleName -> Scope -> WSM Scope
566    copy new s = do
567      lift $ reportSLn "scope.copy" 20 $ "Copying scope " ++ prettyShow old ++ " to " ++ prettyShow new
568      lift $ reportSLn "scope.copy" 50 $ prettyShow s
569      s0 <- lift $ getNamedScope new
570      -- Delete private names, then copy names and modules. Recompute inScope
571      -- set rather than trying to copy it.
572      s' <- recomputeInScopeSets <$> mapScopeM_ copyD copyM return (setNameSpace PrivateNS emptyNameSpace s)
573      -- Fix name and parent.
574      return $ s' { scopeName    = scopeName s0
575                  , scopeParents = scopeParents s0
576                  }
577      where
578        rnew = getRange new
579        new' = killRange new
580        newL = A.mnameToList new'
581        old  = scopeName s
582
583        copyD :: NamesInScope -> WSM NamesInScope
584        copyD = traverse $ mapM $ onName renName
585
586        copyM :: ModulesInScope -> WSM ModulesInScope
587        copyM = traverse $ mapM $ lensAmodName renMod
588
589        onName :: (A.QName -> WSM A.QName) -> AbstractName -> WSM AbstractName
590        onName f d =
591          case anameKind d of
592            PatternSynName -> return d  -- Pattern synonyms are simply aliased, not renamed
593            _ -> lensAnameName f d
594
595        -- Adding to memo structure.
596        addName x y     = modify $ \ i -> i { memoNames   = Map.insertWith (<>) x (pure y) (memoNames i) }
597        addMod  x y rec = modify $ \ i -> i { memoModules = Map.insert x (y, rec) (memoModules i) }
598
599        -- Querying the memo structure.
600        findName x = gets (Map.lookup x . memoNames) -- NB:: Defined but not used
601        findMod  x = gets (Map.lookup x . memoModules)
602
603        refresh :: A.Name -> WSM A.Name
604        refresh x = do
605          i <- lift fresh
606          return $ x { A.nameId = i }
607
608        -- Change a binding M.x -> old.M'.y to M.x -> new.M'.y
609        renName :: A.QName -> WSM A.QName
610        renName x = do
611          -- Issue 1985: For re-exported names we can't use new' as the
612          -- module, since it has the wrong telescope. Example:
613          --
614          --    module M1 (A : Set) where
615          --      module M2 (B : Set) where
616          --        postulate X : Set
617          --      module M3 (C : Set) where
618          --        module M4 (D E : Set) where
619          --          open M2 public
620          --
621          --    module M = M1.M3 A C
622          --
623          -- Here we can't copy M1.M2.X to M.M4.X since we need
624          -- X : (B : Set) → Set, but M.M4 has telescope (D E : Set). Thus, we
625          -- would break the invariant that all functions in a module share the
626          -- module telescope. Instead we copy M1.M2.X to M.M2.X for a fresh
627          -- module M2 that gets the right telescope.
628          m <- if x `isInModule` old
629                 then return new'
630                 else renMod' False (qnameModule x)
631                          -- Don't copy recursively here, we only know that the
632                          -- current name x should be copied.
633          -- Generate a fresh name for the target.
634          -- Andreas, 2015-08-11 Issue 1619:
635          -- Names copied by a module macro should get the module macro's
636          -- range as declaration range
637          -- (maybe rather the one of the open statement).
638          -- For now, we just set their range
639          -- to the new module name's one, which fixes issue 1619.
640          y <- setRange rnew . A.qualify m <$> refresh (qnameName x)
641          lift $ reportSLn "scope.copy" 50 $ "  Copying " ++ prettyShow x ++ " to " ++ prettyShow y
642          addName x y
643          return y
644
645        -- Change a binding M.x -> old.M'.y to M.x -> new.M'.y
646        renMod :: A.ModuleName -> WSM A.ModuleName
647        renMod = renMod' True
648
649        renMod' rec x = do
650          -- Andreas, issue 1607:
651          -- If we have already copied this module, return the copy.
652          z <- findMod x
653          case z of
654            Just (y, False) | rec -> y <$ copyRec x y
655            Just (y, _)           -> return y
656            Nothing -> do
657            -- Ulf (issue 1985): If copying a reexported module we put it at the
658            -- top-level, to make sure we don't mess up the invariant that all
659            -- (abstract) names M.f share the argument telescope of M.
660            let newM = if x `isLtChildModuleOf` old then newL else mnameToList new0
661
662            y <- do
663               -- Andreas, Jesper, 2015-07-02: Issue 1597
664               -- Don't blindly drop a prefix of length of the old qualifier.
665               -- If things are imported by open public they do not have the old qualifier
666               -- as prefix.  Those need just to be linked, not copied.
667               -- return $ A.mnameFromList $ (newL ++) $ drop (size old) $ A.mnameToList x
668               -- caseMaybe (stripPrefix (A.mnameToList old) (A.mnameToList x)) (return x) $ \ suffix -> do
669               --   return $ A.mnameFromList $ newL ++ suffix
670               -- Ulf, 2016-02-22: #1726
671               -- We still need to copy modules from 'open public'. Same as in renName.
672               y <- refresh $ lastWithDefault __IMPOSSIBLE__ $ A.mnameToList x
673               return $ A.mnameFromList $ newM ++ [y]
674            -- Andreas, Jesper, 2015-07-02: Issue 1597
675            -- Don't copy a module over itself, it will just be emptied of its contents.
676            if (x == y) then return x else do
677            lift $ reportSLn "scope.copy" 50 $ "  Copying module " ++ prettyShow x ++ " to " ++ prettyShow y
678            addMod x y rec
679            lift $ createModule Nothing y
680            -- We need to copy the contents of included modules recursively (only when 'rec')
681            when rec $ copyRec x y
682            return y
683          where
684            copyRec x y = do
685              s0 <- lift $ getNamedScope x
686              s  <- withCurrentModule' y $ copy y s0
687              lift $ modifyNamedScope y (const s)
688
689---------------------------------------------------------------------------
690-- * Import directives
691---------------------------------------------------------------------------
692
693-- | Warn about useless fixity declarations in @renaming@ directives.
694--   Monadic for the sake of error reporting.
695checkNoFixityInRenamingModule :: [C.Renaming] -> ScopeM ()
696checkNoFixityInRenamingModule ren = do
697  whenJust (nonEmpty $ mapMaybe rangeOfUselessInfix ren) $ \ rs -> do
698    setCurrentRange rs $ do
699      warning $ FixityInRenamingModule rs
700  where
701  rangeOfUselessInfix :: C.Renaming -> Maybe Range
702  rangeOfUselessInfix = \case
703    Renaming ImportedModule{} _ mfx _ -> getRange <$> mfx
704    _ -> Nothing
705
706-- Moved here carefully from Parser.y to preserve the archaeological artefact
707-- dating from Oct 2005 (5ba14b647b9bd175733f9563e744176425c39126).
708-- | Check that an import directive doesn't contain repeated names.
709verifyImportDirective :: [C.ImportedName] -> C.HidingDirective -> C.RenamingDirective -> ScopeM ()
710verifyImportDirective usn hdn ren =
711    case filter ((>1) . length)
712         $ List.group
713         $ List.sort xs
714    of
715        []  -> return ()
716        yss -> setCurrentRange yss $ genericError $
717                "Repeated name" ++ s ++ " in import directive: " ++
718                concat (List.intersperse ", " $ map (prettyShow . head) yss)
719            where
720                s = case yss of
721                        [_] -> ""
722                        _   -> "s"
723    where
724        xs = usn ++ hdn ++ map renFrom ren
725
726-- | Apply an import directive and check that all the names mentioned actually
727--   exist.
728--
729--   Monadic for the sake of error reporting.
730applyImportDirectiveM
731  :: C.QName                           -- ^ Name of the scope, only for error reporting.
732  -> C.ImportDirective                 -- ^ Description of how scope is to be modified.
733  -> Scope                             -- ^ Input scope.
734  -> ScopeM (A.ImportDirective, Scope) -- ^ Scope-checked description, output scope.
735applyImportDirectiveM m (ImportDirective rng usn' hdn' ren' public) scope0 = do
736
737    -- Module names do not come with fixities, thus, we should complain if the
738    -- user has supplied fixity annotations to @renaming module@ clauses.
739    checkNoFixityInRenamingModule ren'
740
741    -- Andreas, 2020-06-06, issue #4707
742    -- Duplicates in @using@ directive are dropped with a warning.
743    usingList <- discardDuplicatesInUsing usn'
744
745    -- The following check was originally performed by the parser.
746    -- The Great Ulf Himself added the check back in the dawn of time
747    -- (5ba14b647b9bd175733f9563e744176425c39126)
748    -- when Agda 2 wasn't even believed to exist yet.
749    verifyImportDirective usingList hdn' ren'
750
751    -- We start by checking that all of the names talked about in the import
752    -- directive do exist.  If some do not then we remove them and raise a warning.
753    let (missingExports, namesA) = checkExist $ usingList ++ hdn' ++ map renFrom ren'
754    unless (null missingExports) $ setCurrentRange rng $ do
755      reportSLn "scope.import.apply" 20 $ "non existing names: " ++ prettyShow missingExports
756      warning $ ModuleDoesntExport m (Map.keys namesInScope) (Map.keys modulesInScope) missingExports
757
758    -- We can now define a cleaned-up version of the import directive.
759    let notMissing = not . (missingExports `hasElem`)  -- #3997, efficient lookup in missingExports
760    let usn = filter notMissing usingList        -- remove missingExports from usn'
761    let hdn = filter notMissing hdn'             -- remove missingExports from hdn'
762    let ren = filter (notMissing . renFrom) ren'                   -- and from ren'
763    let dir = ImportDirective rng (mapUsing (const usn) usn') hdn ren public
764
765    -- Convenient shorthands for defined names and names brought into scope:
766    let names        = map renFrom ren ++ hdn ++ usn
767    let definedNames = map renTo ren
768    let targetNames  = usn ++ definedNames
769
770    -- Efficient test of (`elem` names):
771    let inNames      = (names `hasElem`)
772
773    -- Efficient test of whether a module import should be added to the import
774    -- of a definition (like a data or record definition).
775    let extra x = inNames (ImportedName   x)
776               && notMissing (ImportedModule x)
777               && (not . inNames $ ImportedModule x)
778                  -- The last test implies that @hiding (module M)@ prevents @module M@
779                  -- from entering the @using@ list in @addExtraModule@.
780
781    dir' <- sanityCheck (not . inNames) $ addExtraModules extra dir
782
783    -- Check for duplicate imports in a single import directive.
784    -- @dup@ : To be imported names that are mentioned more than once.
785    unlessNull (allDuplicates targetNames) $ \ dup ->
786      typeError $ DuplicateImports m dup
787
788    -- Apply the import directive.
789    let (scope', (nameClashes, moduleClashes)) = applyImportDirective_ dir' scope
790
791    -- Andreas, 2019-11-08, issue #4154, report clashes
792    -- introduced by the @renaming@.
793    unless (null nameClashes) $
794      warning $ ClashesViaRenaming NameNotModule $ Set.toList nameClashes
795    unless (null moduleClashes) $
796      warning $ ClashesViaRenaming ModuleNotName $ Set.toList moduleClashes
797
798    -- Look up the defined names in the new scope.
799    let namesInScope'   = (allNamesInScope scope' :: ThingsInScope AbstractName)
800    let modulesInScope' = (allNamesInScope scope' :: ThingsInScope AbstractModule)
801    let look x = headWithDefault __IMPOSSIBLE__ . Map.findWithDefault __IMPOSSIBLE__ x
802    -- We set the ranges to the ranges of the concrete names in order to get
803    -- highlighting for the names in the import directive.
804    let definedA = for definedNames $ \case
805          ImportedName   x -> ImportedName   . (x,) . setRange (getRange x) . anameName $ look x namesInScope'
806          ImportedModule x -> ImportedModule . (x,) . setRange (getRange x) . amodName  $ look x modulesInScope'
807
808    let adir = mapImportDir namesA definedA dir
809    return (adir, scope') -- TODO Issue 1714: adir
810
811  where
812    -- Andreas, 2020-06-23, issue #4773, fixing regression in 2.5.1.
813    -- Import directive may not mention private things.
814    -- ```agda
815    --   module M where private X = Set
816    --   module N = M using (X)
817    -- ```
818    -- Further, modules (N) need not copy private things (X) from other
819    -- modules (M) ever, since they cannot legally referred to
820    -- (neither through qualification (N.X) nor open N).
821    -- Thus, we can unconditionally remove private definitions
822    -- before we apply the import directive.
823    scope = restrictPrivate scope0
824
825    -- Return names in the @using@ directive, discarding duplicates.
826    -- Monadic for the sake of throwing warnings.
827    discardDuplicatesInUsing :: C.Using -> ScopeM [C.ImportedName]
828    discardDuplicatesInUsing = \case
829      UseEverything -> return []
830      Using  xs     -> do
831        let (ys, dups) = nubAndDuplicatesOn id xs
832        List1.unlessNull dups $ warning . DuplicateUsing
833        return ys
834
835    -- If both @using@ and @hiding@ directive are present,
836    -- the hiding directive may only contain modules whose twins are mentioned.
837    -- Monadic for the sake of error reporting.
838    sanityCheck notMentioned = \case
839      dir@(ImportDirective{ using = Using{}, hiding = ys }) -> do
840          let useless = \case
841                ImportedName{}   -> True
842                ImportedModule y -> notMentioned (ImportedName y)
843          unlessNull (filter useless ys) $ warning . UselessHiding
844          -- We can empty @hiding@ now, since there is an explicit @using@ directive
845          -- and @hiding@ served its purpose to prevent modules to enter the @Using@ list.
846          return dir{ hiding = [] }
847      dir -> return dir
848
849    addExtraModules :: (C.Name -> Bool) -> C.ImportDirective -> C.ImportDirective
850    addExtraModules extra dir =
851      dir{ using       = mapUsing (concatMap addExtra) $ using dir
852         , hiding      = concatMap addExtra            $ hiding dir
853         , impRenaming = concatMap extraRenaming       $ impRenaming dir
854         }
855      where
856        addExtra f@(ImportedName y) | extra y = [f, ImportedModule y]
857        addExtra m = [m]
858
859        extraRenaming = \case
860          r@(Renaming (ImportedName y) (ImportedName z) _fixity rng) | extra y ->
861             [ r , Renaming (ImportedModule y) (ImportedModule z) Nothing rng ]
862          r -> [r]
863
864    -- Names and modules (abstract) in scope before the import.
865    namesInScope   = (allNamesInScope scope :: ThingsInScope AbstractName)
866    modulesInScope = (allNamesInScope scope :: ThingsInScope AbstractModule)
867    concreteNamesInScope = (Map.keys namesInScope ++ Map.keys modulesInScope :: [C.Name])
868
869    -- AST versions of the concrete names passed as an argument.
870    -- We get back a pair consisting of a list of missing exports first,
871    -- and a list of successful imports second.
872    checkExist :: [ImportedName] -> ([ImportedName], [ImportedName' (C.Name, A.QName) (C.Name, A.ModuleName)])
873    checkExist xs = partitionEithers $ for xs $ \ name -> case name of
874      ImportedName x   -> ImportedName   . (x,) . setRange (getRange x) . anameName <$> resolve name x namesInScope
875      ImportedModule x -> ImportedModule . (x,) . setRange (getRange x) . amodName  <$> resolve name x modulesInScope
876
877      where resolve :: Ord a => err -> a -> Map a [b] -> Either err b
878            resolve err x m = maybe (Left err) (Right . head) $ Map.lookup x m
879
880-- | Translation of @ImportDirective@.
881mapImportDir
882  :: (Ord n1, Ord m1)
883  => [ImportedName' (n1,n2) (m1,m2)]  -- ^ Translation of imported names.
884  -> [ImportedName' (n1,n2) (m1,m2)]  -- ^ Translation of names defined by this import.
885  -> ImportDirective' n1 m1
886  -> ImportDirective' n2 m2
887mapImportDir src0 tgt0 (ImportDirective r u h ren open) =
888  ImportDirective r
889    (mapUsing (map (lookupImportedName src)) u)
890    (map (lookupImportedName src) h)
891    (map (mapRenaming src tgt) ren)
892    open
893  where
894  src = importedNameMapFromList src0
895  tgt = importedNameMapFromList tgt0
896
897-- | A finite map for @ImportedName@s.
898
899data ImportedNameMap n1 n2 m1 m2 = ImportedNameMap
900  { inameMap   :: Map n1 n2
901  , imoduleMap :: Map m1 m2
902  }
903
904-- | Create a 'ImportedNameMap'.
905importedNameMapFromList
906  :: (Ord n1, Ord m1)
907  => [ImportedName' (n1,n2) (m1,m2)]
908  -> ImportedNameMap n1 n2 m1 m2
909importedNameMapFromList = foldr (flip add) $ ImportedNameMap Map.empty Map.empty
910  where
911  add (ImportedNameMap nm mm) = \case
912    ImportedName   (x,y) -> ImportedNameMap (Map.insert x y nm) mm
913    ImportedModule (x,y) -> ImportedNameMap nm (Map.insert x y mm)
914
915-- | Apply a 'ImportedNameMap'.
916lookupImportedName
917  :: (Ord n1, Ord m1)
918  => ImportedNameMap n1 n2 m1 m2
919  -> ImportedName' n1 m1
920  -> ImportedName' n2 m2
921lookupImportedName (ImportedNameMap nm mm) = \case
922    ImportedName   x -> ImportedName   $ Map.findWithDefault __IMPOSSIBLE__ x nm
923    ImportedModule x -> ImportedModule $ Map.findWithDefault __IMPOSSIBLE__ x mm
924
925-- | Translation of @Renaming@.
926mapRenaming
927  ::  (Ord n1, Ord m1)
928  => ImportedNameMap n1 n2 m1 m2  -- ^ Translation of 'renFrom' names and module names.
929  -> ImportedNameMap n1 n2 m1 m2  -- ^ Translation of 'rento'   names and module names.
930  -> Renaming' n1 m1  -- ^ Renaming before translation (1).
931  -> Renaming' n2 m2  -- ^ Renaming after  translation (2).
932mapRenaming src tgt (Renaming from to fixity r) =
933  Renaming (lookupImportedName src from) (lookupImportedName tgt to) fixity r
934
935---------------------------------------------------------------------------
936-- * Opening a module
937---------------------------------------------------------------------------
938
939data OpenKind = LetOpenModule | TopOpenModule
940
941noGeneralizedVarsIfLetOpen :: OpenKind -> Scope -> Scope
942noGeneralizedVarsIfLetOpen TopOpenModule = id
943noGeneralizedVarsIfLetOpen LetOpenModule = disallowGeneralizedVars
944
945-- | Open a module.
946openModule_ :: OpenKind -> C.QName -> C.ImportDirective -> ScopeM A.ImportDirective
947openModule_ kind cm dir = openModule kind Nothing cm dir
948
949-- | Open a module, possibly given an already resolved module name.
950openModule :: OpenKind -> Maybe A.ModuleName  -> C.QName -> C.ImportDirective -> ScopeM A.ImportDirective
951openModule kind mam cm dir = do
952  current <- getCurrentModule
953  m <- caseMaybe mam (amodName <$> resolveModule cm) return
954  let acc | Nothing <- publicOpen dir     = PrivateNS
955          | m `isLtChildModuleOf` current = PublicNS
956          | otherwise                     = ImportedNS
957
958  -- Get the scope exported by module to be opened.
959  (adir, s') <- applyImportDirectiveM cm dir . inScopeBecause (Opened cm) .
960                noGeneralizedVarsIfLetOpen kind =<< getNamedScope m
961  let s  = setScopeAccess acc s'
962  let ns = scopeNameSpace acc s
963  modifyCurrentScope (`mergeScope` s)
964  -- Andreas, 2018-06-03, issue #3057:
965  -- If we simply check for ambiguous exported identifiers _after_
966  -- importing the new identifiers into the current scope, we also
967  -- catch the case of importing an ambiguous identifier.
968  checkForClashes
969
970  -- Importing names might shadow existing locals.
971  verboseS "scope.locals" 10 $ do
972    locals <- mapMaybe (\ (c,x) -> c <$ notShadowedLocal x) <$> getLocalVars
973    let newdefs = Map.keys $ nsNames ns
974        shadowed = locals `List.intersect` newdefs
975    reportSLn "scope.locals" 10 $ "opening module shadows the following locals vars: " ++ prettyShow shadowed
976  -- Andreas, 2014-09-03, issue 1266: shadow local variables by imported defs.
977  modifyLocalVars $ AssocList.mapWithKey $ \ c x ->
978    case Map.lookup c $ nsNames ns of
979      Nothing -> x
980      Just ys -> shadowLocal ys x
981
982  return adir
983
984  where
985    -- Only checks for clashes that would lead to the same
986    -- name being exported twice from the module.
987    checkForClashes = when (isJust $ publicOpen dir) $ do
988
989        exported <- allThingsInScope . restrictPrivate <$> (getNamedScope =<< getCurrentModule)
990
991        -- Get all exported concrete names that are mapped to at least 2 abstract names
992        let defClashes = filter (\ (_c, as) -> length as >= 2) $ Map.toList $ nsNames exported
993            modClashes = filter (\ (_c, as) -> length as >= 2) $ Map.toList $ nsModules exported
994
995            -- No ambiguity if concrete identifier is only mapped to
996            -- constructor names or only to projection names.
997            defClash (_, qs) = not $ all (isJust . isConName) ks || all (==FldName) ks
998              where ks = map anameKind qs
999        -- We report the first clashing exported identifier.
1000        unlessNull (filter (\ x -> defClash x) defClashes) $
1001          \ ((x, q:_) : _) -> typeError $ ClashingDefinition (C.QName x) (anameName q) Nothing
1002
1003        unlessNull modClashes $ \ ((_, ms) : _) -> do
1004          caseMaybe (last2 ms) __IMPOSSIBLE__ $ \ (m0, m1) -> do
1005            typeError $ ClashingModule (amodName m0) (amodName m1)
1006