Skip to content

Commit 71fd29f

Browse files
author
Kristian Larsson
committed
Fix transitive witness propagation
importWits now imports witnesses from transitive dependencies by reading the .ty interface files. This ensures that witnesses defined in module A are visible to module C when C imports B which imports A, without C needing to explicitly import A.
1 parent 0b2482b commit 71fd29f

1 file changed

Lines changed: 34 additions & 7 deletions

File tree

compiler/lib/src/Acton/Env.hs

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -451,7 +451,7 @@ initEnv path False = do (_,nmod,_) <- InterfaceFiles.readFile (joinPath
451451
witnesses = primWits,
452452
thismod = Nothing,
453453
envX = () }
454-
env = importAll mBuiltin envBuiltin $ importWits mBuiltin envBuiltin $ env0
454+
env <- importAll mBuiltin envBuiltin <$> importWits [] mBuiltin envBuiltin env0
455455
return env
456456

457457
withModulesFrom :: EnvF x -> EnvF x -> EnvF x
@@ -1183,13 +1183,16 @@ impModule spath env (Import _ ms)
11831183
imp env (ModuleItem m as : is)
11841184
= do (env1,te) <- doImp spath env m
11851185
let env2 = maybe (addImport m) (\n->define [(n, NMAlias m)]) as env1
1186-
imp (importWits m te env2) is
1186+
env3 <- importWits spath m te env2
1187+
imp env3 is
11871188
impModule spath env (FromImport _ (ModRef (0,Just m)) items)
11881189
= do (env1,te) <- doImp spath env m
1189-
return $ importSome items m te $ importWits m te $ env1
1190+
env2 <- importWits spath m te env1
1191+
return $ importSome items m te env2
11901192
impModule spath env (FromImportAll _ (ModRef (0,Just m)))
11911193
= do (env1,te) <- doImp spath env m
1192-
return $ importAll m te $ importWits m te $ env1
1194+
env2 <- importWits spath m te env1
1195+
return $ importAll m te env2
11931196
impModule _ _ i = illegalImport (loc i)
11941197

11951198

@@ -1247,9 +1250,33 @@ impNames m te = mapMaybe imp te
12471250
imp (n, NDef t d _) = Just (n, NAlias (GName m n))
12481251
imp _ = Nothing -- cannot happen
12491252

1250-
importWits :: ModName -> TEnv -> EnvF x -> EnvF x
1251-
importWits m te env = foldl addWit env ws
1252-
where ws = [ WClass q (tCon c) p (GName m n) ws | (n, NExt q c ps te' _) <- te, (ws,p) <- ps ]
1253+
-- Import witnesses from a module and all its transitive dependencies
1254+
importWits :: [FilePath] -> ModName -> TEnv -> EnvF x -> IO (EnvF x)
1255+
importWits spath m te env = do
1256+
-- First import witnesses from the module itself
1257+
let env' = importWitsFromModule m te env
1258+
1259+
-- Then import witnesses from its dependencies
1260+
tyFile <- findTyFile spath m
1261+
case tyFile of
1262+
Nothing -> return env' -- No .ty file (e.g., builtin module) or not found
1263+
Just tyF -> do
1264+
(deps, _, _) <- InterfaceFiles.readFile tyF
1265+
-- Recursively import witnesses from each dependency
1266+
foldM importDepWits env' deps
1267+
where
1268+
importDepWits envAcc dep = case lookupMod dep envAcc of
1269+
Just depTe -> return $ importWitsFromModule dep depTe envAcc
1270+
Nothing -> return envAcc -- Dependency not loaded yet, skip it
1271+
1272+
-- Extract and import witnesses from a single module's TEnv
1273+
importWitsFromModule mod modTe modEnv = foldl addWit modEnv ws
1274+
where
1275+
ws = [ WClass q (tCon $ qualifyTCon mod c) p (GName mod n) ws | (n, NExt q c ps te' _) <- modTe, (ws,p) <- ps ]
1276+
-- Ensure the type constructor is properly qualified with the module name
1277+
qualifyTCon md (TC n ts) = TC (qualifyName md n) ts
1278+
qualifyName md (NoQ n) = GName md n
1279+
qualifyName md qn = qn
12531280

12541281

12551282

0 commit comments

Comments
 (0)