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