mirror of
https://github.com/anoma/juvix.git
synced 2025-01-08 08:39:26 +03:00
Fix reachability analysis with imports in unreachable nested modules (#2062)
* Closes #2005 --------- Co-authored-by: Paul Cadman <git@paulcadman.dev> Co-authored-by: Jan Mas Rovira <janmasrovira@gmail.com>
This commit is contained in:
parent
11ebc4acde
commit
0462d623f2
@ -10,9 +10,13 @@ import Juvix.Prelude
|
|||||||
-- adjacency set representation
|
-- adjacency set representation
|
||||||
type DependencyGraph = HashMap Name (HashSet Name)
|
type DependencyGraph = HashMap Name (HashSet Name)
|
||||||
|
|
||||||
type StartNodes = HashSet Name
|
newtype VisitedModules = VisitedModules
|
||||||
|
{ _visitedModulesSet :: HashSet Name
|
||||||
|
}
|
||||||
|
|
||||||
type VisitedModules = HashSet Name
|
makeLenses ''VisitedModules
|
||||||
|
|
||||||
|
type StartNodes = HashSet Name
|
||||||
|
|
||||||
type ExportsTable = HashSet NameId
|
type ExportsTable = HashSet NameId
|
||||||
|
|
||||||
@ -40,7 +44,7 @@ buildDependencyInfoHelper tbl m = createDependencyInfo graph startNodes
|
|||||||
graph :: DependencyGraph
|
graph :: DependencyGraph
|
||||||
(startNodes, graph) =
|
(startNodes, graph) =
|
||||||
run $
|
run $
|
||||||
evalState (HashSet.empty :: VisitedModules) $
|
evalState (VisitedModules mempty) $
|
||||||
runState HashSet.empty $
|
runState HashSet.empty $
|
||||||
execState HashMap.empty $
|
execState HashMap.empty $
|
||||||
runReader tbl m
|
runReader tbl m
|
||||||
@ -86,8 +90,8 @@ checkBuiltinInductiveStartNode i = whenJust (i ^. inductiveBuiltin) go
|
|||||||
guardNotVisited :: (Member (State VisitedModules) r) => Name -> Sem r () -> Sem r ()
|
guardNotVisited :: (Member (State VisitedModules) r) => Name -> Sem r () -> Sem r ()
|
||||||
guardNotVisited n cont =
|
guardNotVisited n cont =
|
||||||
unlessM
|
unlessM
|
||||||
(HashSet.member n <$> get)
|
(HashSet.member n . (^. visitedModulesSet) <$> get)
|
||||||
(modify (HashSet.insert n) >> cont)
|
(modify (over visitedModulesSet (HashSet.insert n)) >> cont)
|
||||||
|
|
||||||
goModule :: (Members '[Reader ExportsTable, State DependencyGraph, State StartNodes, State VisitedModules] r) => Module -> Sem r ()
|
goModule :: (Members '[Reader ExportsTable, State DependencyGraph, State StartNodes, State VisitedModules] r) => Module -> Sem r ()
|
||||||
goModule m = do
|
goModule m = do
|
||||||
|
@ -3,16 +3,15 @@ module Juvix.Compiler.Internal.Translation.FromInternal.Analysis.Reachability wh
|
|||||||
import Juvix.Compiler.Abstract.Data.NameDependencyInfo
|
import Juvix.Compiler.Abstract.Data.NameDependencyInfo
|
||||||
import Juvix.Compiler.Internal.Language
|
import Juvix.Compiler.Internal.Language
|
||||||
import Juvix.Compiler.Internal.Translation.FromAbstract.Data.Context
|
import Juvix.Compiler.Internal.Translation.FromAbstract.Data.Context
|
||||||
-- import Juvix.Compiler.Internal.Translation.FromInternal.Analysis.TypeChecking.Data.Context qualified as MicroTyped
|
import Juvix.Compiler.Internal.Translation.FromInternal.Analysis.ArityChecking qualified as Arity
|
||||||
import Juvix.Compiler.Internal.Translation.FromInternal.Analysis.ArityChecking qualified as MicroArity
|
import Juvix.Compiler.Internal.Translation.FromInternal.Analysis.TypeChecking.Data.Context qualified as Typed
|
||||||
import Juvix.Compiler.Internal.Translation.FromInternal.Analysis.TypeChecking.Data.Context qualified as MicroTyped
|
|
||||||
import Juvix.Prelude
|
import Juvix.Prelude
|
||||||
|
|
||||||
filterUnreachable :: MicroTyped.InternalTypedResult -> MicroTyped.InternalTypedResult
|
filterUnreachable :: Typed.InternalTypedResult -> Typed.InternalTypedResult
|
||||||
filterUnreachable r = r {MicroTyped._resultModules = modules'}
|
filterUnreachable r = r {Typed._resultModules = modules'}
|
||||||
where
|
where
|
||||||
depInfo = r ^. (MicroTyped.resultInternalArityResult . MicroArity.resultInternalResult . resultDepInfo)
|
depInfo = r ^. (Typed.resultInternalArityResult . Arity.resultInternalResult . resultDepInfo)
|
||||||
modules = r ^. MicroTyped.resultModules
|
modules = r ^. Typed.resultModules
|
||||||
modules' = run $ runReader depInfo (mapM goModule modules)
|
modules' = run $ runReader depInfo (mapM goModule modules)
|
||||||
|
|
||||||
askIsReachable :: Member (Reader NameDependencyInfo) r => Name -> Sem r Bool
|
askIsReachable :: Member (Reader NameDependencyInfo) r => Name -> Sem r Bool
|
||||||
@ -43,6 +42,4 @@ goStatement s = case s of
|
|||||||
StatementInclude i -> do
|
StatementInclude i -> do
|
||||||
m <- goModule (i ^. includeModule)
|
m <- goModule (i ^. includeModule)
|
||||||
return (Just (StatementInclude i {_includeModule = m}))
|
return (Just (StatementInclude i {_includeModule = m}))
|
||||||
StatementModule m -> do
|
StatementModule m -> Just . StatementModule <$> goModule m
|
||||||
m' <- StatementModule <$> goModule m
|
|
||||||
returnIfReachable (m ^. moduleName) m'
|
|
||||||
|
@ -188,5 +188,10 @@ tests =
|
|||||||
"Case expression"
|
"Case expression"
|
||||||
$(mkRelDir ".")
|
$(mkRelDir ".")
|
||||||
$(mkRelFile "Case.juvix")
|
$(mkRelFile "Case.juvix")
|
||||||
$(mkRelFile "out/Case.out")
|
$(mkRelFile "out/Case.out"),
|
||||||
|
PosTest
|
||||||
|
"Import a module containing a nested module"
|
||||||
|
$(mkRelDir "NestedModuleScope")
|
||||||
|
$(mkRelFile "Import.juvix")
|
||||||
|
$(mkRelFile "out/NestedModuleScope.out")
|
||||||
]
|
]
|
||||||
|
5
tests/Internal/positive/NestedModuleScope/Base.juvix
Normal file
5
tests/Internal/positive/NestedModuleScope/Base.juvix
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
module Base;
|
||||||
|
|
||||||
|
module NestedBase;
|
||||||
|
open import Base2 public;
|
||||||
|
end;
|
3
tests/Internal/positive/NestedModuleScope/Base2.juvix
Normal file
3
tests/Internal/positive/NestedModuleScope/Base2.juvix
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
module Base2;
|
||||||
|
|
||||||
|
type Foo := foo : Foo;
|
7
tests/Internal/positive/NestedModuleScope/Import.juvix
Normal file
7
tests/Internal/positive/NestedModuleScope/Import.juvix
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
module Import;
|
||||||
|
|
||||||
|
open import Base;
|
||||||
|
open import Base2;
|
||||||
|
|
||||||
|
main : Foo;
|
||||||
|
main := foo;
|
@ -0,0 +1 @@
|
|||||||
|
foo
|
Loading…
Reference in New Issue
Block a user