From 4ae4e4e4d92c795fcc8b706aa4d5833af6c2f9ad Mon Sep 17 00:00:00 2001 From: Jan Mas Rovira Date: Fri, 6 Sep 2024 14:32:03 +0200 Subject: [PATCH] Fix a bug that prevented use of name signature defined after the point (#3001) - Fixes #2999 --- .../Compiler/Concrete/Data/Scope/Base.hs | 4 ++-- .../FromParsed/Analysis/Scoping.hs | 21 +++++++++++-------- test/Scope/Positive.hs | 4 ++++ tests/positive/issue2999.juvix | 10 +++++++++ 4 files changed, 28 insertions(+), 11 deletions(-) create mode 100644 tests/positive/issue2999.juvix diff --git a/src/Juvix/Compiler/Concrete/Data/Scope/Base.hs b/src/Juvix/Compiler/Concrete/Data/Scope/Base.hs index 3287d78725..4483949bc5 100644 --- a/src/Juvix/Compiler/Concrete/Data/Scope/Base.hs +++ b/src/Juvix/Compiler/Concrete/Data/Scope/Base.hs @@ -59,8 +59,8 @@ data ScoperState = ScoperState { -- | Local and top modules currently in scope - used to look up qualified symbols _scoperModules :: HashMap S.NameId ScopedModule, _scoperAlias :: HashMap S.NameId PreSymbolEntry, - _scoperSignatures :: HashMap S.NameId (NameSignature 'Parsed), - _scoperScopedSignatures :: HashMap S.NameId (NameSignature 'Scoped), + _scoperScopedNameSignatures :: HashMap S.NameId (NameSignature 'Scoped), + _scoperNameSignatures :: HashMap S.NameId (NameSignature 'Parsed), -- | Indexed by the inductive type. This is used for record updates _scoperRecordFields :: HashMap S.NameId RecordInfo, -- | Indexed by constructor. This is used for record patterns diff --git a/src/Juvix/Compiler/Concrete/Translation/FromParsed/Analysis/Scoping.hs b/src/Juvix/Compiler/Concrete/Translation/FromParsed/Analysis/Scoping.hs index d9f8572d54..a51525e63a 100644 --- a/src/Juvix/Compiler/Concrete/Translation/FromParsed/Analysis/Scoping.hs +++ b/src/Juvix/Compiler/Concrete/Translation/FromParsed/Analysis/Scoping.hs @@ -48,8 +48,8 @@ iniScoperState :: InfoTable -> ScoperState iniScoperState tab = ScoperState { _scoperModules = mempty, - _scoperSignatures = tab ^. infoParsedNameSigs, - _scoperScopedSignatures = tab ^. infoNameSigs, + _scoperScopedNameSignatures = tab ^. infoNameSigs, + _scoperNameSignatures = tab ^. infoParsedNameSigs, _scoperRecordFields = tab ^. infoRecords, _scoperAlias = tab ^. infoScoperAlias, _scoperConstructorFields = tab ^. infoParsedConstructorSigs, @@ -252,7 +252,7 @@ registerNameSignature :: Sem r () registerNameSignature uid d = do sig <- mkNameSignature d - modify (set (scoperScopedSignatures . at uid) (Just sig)) + modify (set (scoperScopedNameSignatures . at uid) (Just sig)) registerNameSig uid sig registerConstructorSignature :: @@ -292,7 +292,7 @@ reserveSymbolOfNameSpace ns kind kindPretty nameSig builtin s = do strat <- ask s' <- freshSymbol kind kindPretty s whenJust builtin (`registerBuiltin` s') - whenJust nameSig (modify' . set (scoperSignatures . at (s' ^. S.nameId)) . Just) + whenJust nameSig (modify' . set (scoperNameSignatures . at (s' ^. S.nameId)) . Just) whenJust nameSig (registerParsedNameSig (s' ^. S.nameId)) modify (set (scopeNameSpaceLocal sns . at s) (Just s')) registerName s' @@ -2710,7 +2710,10 @@ checkNamedApplicationNew :: checkNamedApplicationNew napp = do let nargs = napp ^. namedApplicationNewArguments aname <- checkScopedIden (napp ^. namedApplicationNewName) - sig <- if null nargs then return $ NameSignature [] else getNameSignature aname + sig :: NameSignature 'Parsed <- + if + | null nargs -> return (NameSignature []) + | otherwise -> getNameSignatureParsed aname let namesInSignature = hashSet (concatMap (HashMap.keys . (^. nameBlock)) (sig ^. nameSignatureArgs)) forM_ nargs (checkNameInSignature namesInSignature . (^. namedArgumentNewSymbol)) puns <- scopePuns @@ -2873,16 +2876,16 @@ getRecordInfo' loc name nameId = err :: Sem r a err = throw (ErrNotARecord (NotARecord name loc)) -getNameSignature :: (Members '[State ScoperState, Error ScoperError] r) => ScopedIden -> Sem r (NameSignature 'Scoped) -getNameSignature s = do +getNameSignatureParsed :: (Members '[State ScoperState, Error ScoperError] r) => ScopedIden -> Sem r (NameSignature 'Parsed) +getNameSignatureParsed s = do sig <- maybeM (throw err) return (lookupNameSignature (s ^. scopedIdenFinal . S.nameId)) when (null (sig ^. nameSignatureArgs)) (throw err) return sig where err = ErrNoNameSignature (NoNameSignature s) - lookupNameSignature :: (Members '[State ScoperState] r) => S.NameId -> Sem r (Maybe (NameSignature 'Scoped)) - lookupNameSignature s' = gets (^. scoperScopedSignatures . at s') + lookupNameSignature :: (Members '[State ScoperState] r) => S.NameId -> Sem r (Maybe (NameSignature 'Parsed)) + lookupNameSignature s' = gets (^. scoperNameSignatures . at s') checkIterator :: (Members '[HighlightBuilder, Reader ScopeParameters, Error ScoperError, State Scope, State ScoperState, InfoTableBuilder, Reader InfoTable, NameIdGen, Reader Package] r) => diff --git a/test/Scope/Positive.hs b/test/Scope/Positive.hs index a0eebda0d4..2c27ecdafa 100644 --- a/test/Scope/Positive.hs +++ b/test/Scope/Positive.hs @@ -258,6 +258,10 @@ tests = "Record field iterator" $(mkRelDir ".") $(mkRelFile "RecordIterator.juvix"), + posTest + "Forward reference name signature" + $(mkRelDir ".") + $(mkRelFile "issue2999.juvix"), posTest "Scan name with 'import' prefix" $(mkRelDir "issue2929") diff --git a/tests/positive/issue2999.juvix b/tests/positive/issue2999.juvix new file mode 100644 index 0000000000..0150c02591 --- /dev/null +++ b/tests/positive/issue2999.juvix @@ -0,0 +1,10 @@ +module issue2999; + +type T := t; + +fun : T := + namedFun@{ + x := t + }; + +namedFun (x : T) : T := t;