Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 7 additions & 22 deletions src/v1/03_resolve.dag
Original file line number Diff line number Diff line change
Expand Up @@ -286,36 +286,21 @@ fn topo_sort_key(name: String) -> String {

fn topological_sort(modules: List<Node>, source_indices: Map<String, NewlineIndex>) -> TopoResult {
let module_names = modules |> map(m => authored_name_at(source_indices: source_indices, node: m))
let has_std_types = module_names |> any(name => name == "std.types")
let explicit_edges = modules |> flat_map(m =>
module_imports(n: m) |> map(imp => DepEdge { from_module: authored_name_at(source_indices: source_indices, node: imp), to_module: authored_name_at(source_indices: source_indices, node: m) })
)
// Bootstrap bridge: if std.types is present, temporarily inject it as a
// parent for modules that did not import it explicitly. This is not the
// end-state authority model; the bridge deletes when FF-9 is complete.
let implicit_std_types_edges = if has_std_types {
modules |> flat_map(m =>
let m_name = authored_name_at(source_indices: source_indices, node: m)
let imports_std_types = module_imports(n: m) |> any(imp => authored_name_at(source_indices: source_indices, node: imp) == "std.types")
if m_name != "std.types" && m_name != "std.algebra" && m_name != "std.error_primitives" && imports_std_types == false {
[DepEdge { from_module: "std.types", to_module: m_name }]
} else {
[]
}
)
} else {
[]
}

let adjacency = concat(explicit_edges, implicit_std_types_edges) |> fold(init: empty_map(), f: (acc, edge) =>
// §3 single-authority: ordering is import-driven only. The std.types
// implicit-parent bootstrap bridge was removed — it coupled every module
// (across the v1 and v2 trees) into one global sort, so unrelated import
// edges perturbed the order and let same-named v1/v2 types resolve to the
// wrong authority by merge order. Kahn now respects explicit edges alone.
let adjacency = explicit_edges |> fold(init: empty_map(), f: (acc, edge) =>
adjacency_add_edge(adjacency: acc, from_module: edge.from_module, to_module: edge.to_module)
)

let in_degree_map = modules |> fold(init: empty_map(), f: (acc, m) =>
let m_name = authored_name_at(source_indices: source_indices, node: m)
let imports_std_types = module_imports(n: m) |> any(imp => authored_name_at(source_indices: source_indices, node: imp) == "std.types")
let implicit_std_types_in_degree = if has_std_types && m_name != "std.types" && m_name != "std.algebra" && m_name != "std.error_primitives" && imports_std_types == false { 1 } else { 0 }
map_insert(acc, m_name, module_imports(n: m) |> count + implicit_std_types_in_degree)
map_insert(acc, m_name, module_imports(n: m) |> count)
)

let initial_queue = module_names
Expand Down
46 changes: 15 additions & 31 deletions src/v1/04_infer.dag
Original file line number Diff line number Diff line change
Expand Up @@ -5682,24 +5682,18 @@ fn build_type_env(module: ResolvedModule, parent_index: Map<String, TypedModule>
let kernel_recursive_type_set = fold(map_keys(compiler_recursive_types), init: empty_map(), f: (acc, name) => map_insert(acc, intern(table: intern_table, s: name).id, true))
let kernel = TypeEnv { bindings: kernel_bindings, recursive_types: kernel_recursive_types, recursive_type_set: kernel_recursive_type_set, inductive_fields: node_fields, source_indices: source_indices, intern_table: intern_table }

let imports_std_types = module.resolved_imports |> any(imp => imp.module_path == "std.types")
// Bootstrap bridge: seed std.types into modules that did not import it
// explicitly so declaration-driven lookup can run during the transition.
// §3 single-authority: a name resolves through each module's explicit
// import graph only. The std.types base-injection bootstrap bridge was
// removed — it was a second, implicit authority that let v1/v2 same-named
// types (FreeMonoid / Empty / Cons) collide by topological merge order.
// Modules that use kernel primitives keep resolving them from the kernel
// env; anything beyond the kernel must be imported explicitly.
let module_name_str = authored_name_at(source_indices: source_indices, node: module.module)
let std_types_parent_env = if module_name_str != "std.types" && imports_std_types == false {
match map_get(parent_index, "std.types") {
Present { value: typed_std } => [typed_std.type_env]
Absent => []
}
} else {
[]
}
let imported_parent_envs = flat_map(module.resolved_imports, imp => match map_get(parent_index, imp.module_path) { Present { value: typed_parent } => [typed_parent.type_env] Absent => [] })
let parent_envs = concat(std_types_parent_env, imported_parent_envs)
// Filter algebra type variable names from std.types imports so they
// do not leak as ambient user-facing type bindings.
let std_import_bindings = collect_parent_bindings_filtered(envs: std_types_parent_env)
let import_bindings = fold(module.resolved_imports, init: std_import_bindings, f: (acc, imp) =>
let parent_envs = flat_map(module.resolved_imports, imp => match map_get(parent_index, imp.module_path) { Present { value: typed_parent } => [typed_parent.type_env] Absent => [] })
// No implicit base bindings: the import fold below starts empty and is
// seeded only by the module's explicit imports (std.types type-variable
// filtering still applies when std.types is imported explicitly).
let import_bindings = fold(module.resolved_imports, init: collect_parent_bindings_filtered(envs: []), f: (acc, imp) =>
match map_get(parent_index, imp.module_path) {
Present { value: typed_parent } =>
if imp.module_path == "std.types" {
Expand Down Expand Up @@ -5834,21 +5828,11 @@ fn build_type_env_unresolved(module: ResolvedModule, parent_index: Map<String, T
let kernel_optional = Node { name: "Optional", span: kernel_span(name: "Optional"), ident_span: Present { value: kernel_span(name: "Optional") }, children: [present_variant, absent_variant], connective: Disj, params: [], inferred: none, return_cardinality: Required, uses: [], body: none, transport: none, properties: [], type_annotation: none, is_self_recursive: false, has_non_tail_self_call: false, match_pattern: none, expr_data: NoExprData }
let kernel_bindings = map_insert(kernel_bindings, intern(table: intern_table, s: "Optional").id, TypeBinding { name: "Optional", resolved: kernel_optional, provenance: SubValueUnknown })
let kernel = TypeEnv { bindings: kernel_bindings, recursive_types: [], recursive_type_set: empty_map(), inductive_fields: empty_map(), source_indices: source_indices, intern_table: intern_table }
let imports_std_types = module.resolved_imports |> any(imp => imp.module_path == "std.types")
// Mirror the same bootstrap bridge in the unresolved path.
// No implicit std.types base-injection (mirrors build_type_env): §3
// single-authority — resolution flows through explicit imports only.
let module_name_str = authored_name_at(source_indices: source_indices, node: module.module)
let std_types_parent_env = if module_name_str != "std.types" && imports_std_types == false {
match map_get(parent_index, "std.types") {
Present { value: typed_std } => [typed_std.type_env]
Absent => []
}
} else {
[]
}
let imported_parent_envs = flat_map(module.resolved_imports, imp => match map_get(parent_index, imp.module_path) { Present { value: typed_parent } => [typed_parent.type_env] Absent => [] })
let parent_envs = concat(std_types_parent_env, imported_parent_envs)
let std_import_bindings = collect_parent_bindings_filtered(envs: std_types_parent_env)
let import_bindings = fold(module.resolved_imports, init: std_import_bindings, f: (acc, imp) =>
let parent_envs = flat_map(module.resolved_imports, imp => match map_get(parent_index, imp.module_path) { Present { value: typed_parent } => [typed_parent.type_env] Absent => [] })
let import_bindings = fold(module.resolved_imports, init: collect_parent_bindings_filtered(envs: []), f: (acc, imp) =>
match map_get(parent_index, imp.module_path) {
Present { value: typed_parent } =>
if imp.module_path == "std.types" {
Expand Down
60 changes: 9 additions & 51 deletions src/v1/stage0/src/v1_compiler_infer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11823,29 +11823,11 @@ pub fn build_type_env(
source_indices: source_indices.clone(),
intern_table: intern_table.clone(),
});
let imports_std_types = {
let mut __found = false;
for imp in module.resolved_imports.clone().iter().cloned() {
if (imp.module_path.clone().as_str() == "std.types".to_string().as_str()) {
__found = true;
break;
}
}
__found
};
// §3 single-authority: no implicit std.types base-injection. Resolution
// flows through each module's explicit import graph only (mirrors
// v1.compiler.infer build_type_env in src/v1/04_infer.dag).
let module_name_str = authored_name_at(source_indices.clone(), module.module.clone());
let std_types_parent_env = if ((module_name_str.clone().as_str()
!= "std.types".to_string().as_str())
&& (imports_std_types == false))
{
match v1_rt::map_get(&parent_index, "std.types".to_string()) {
Some(typed_std) => Rc::new(vec![typed_std.type_env.clone()]),
None => Rc::new(vec![]),
}
} else {
Rc::new(vec![])
};
let imported_parent_envs = Rc::new({
let parent_envs = Rc::new({
let mut __result = Vec::new();
for imp in module.resolved_imports.clone().iter().cloned() {
__result.extend(
Expand All @@ -11859,10 +11841,8 @@ pub fn build_type_env(
}
__result
});
let parent_envs = v1_rt::concat(std_types_parent_env.clone(), imported_parent_envs);
let std_import_bindings = collect_parent_bindings_filtered(std_types_parent_env.clone());
let import_bindings = module.resolved_imports.clone().iter().cloned().fold(
std_import_bindings,
collect_parent_bindings_filtered(Rc::new(vec![])),
|acc: Rc<HashMap<i64, Rc<TypeBinding>>>, imp: Rc<ResolvedImport>| match v1_rt::map_get(
&parent_index,
imp.module_path.clone(),
Expand Down Expand Up @@ -12440,29 +12420,9 @@ pub fn build_type_env_unresolved(
source_indices: source_indices.clone(),
intern_table: intern_table.clone(),
});
let imports_std_types = {
let mut __found = false;
for imp in module.resolved_imports.clone().iter().cloned() {
if (imp.module_path.clone().as_str() == "std.types".to_string().as_str()) {
__found = true;
break;
}
}
__found
};
let module_name_str = authored_name_at(source_indices.clone(), module.module.clone());
let std_types_parent_env = if ((module_name_str.as_str()
!= "std.types".to_string().as_str())
&& (imports_std_types == false))
{
match v1_rt::map_get(&parent_index, "std.types".to_string()) {
Some(typed_std) => Rc::new(vec![typed_std.type_env.clone()]),
None => Rc::new(vec![]),
}
} else {
Rc::new(vec![])
};
let imported_parent_envs = Rc::new({
// §3 single-authority: no implicit std.types base-injection (mirrors
// build_type_env_unresolved in src/v1/04_infer.dag).
let parent_envs = Rc::new({
let mut __result = Vec::new();
for imp in module.resolved_imports.clone().iter().cloned() {
__result.extend(
Expand All @@ -12476,10 +12436,8 @@ pub fn build_type_env_unresolved(
}
__result
});
let parent_envs = v1_rt::concat(std_types_parent_env.clone(), imported_parent_envs);
let std_import_bindings = collect_parent_bindings_filtered(std_types_parent_env.clone());
let import_bindings = module.resolved_imports.clone().iter().cloned().fold(
std_import_bindings,
collect_parent_bindings_filtered(Rc::new(vec![])),
|acc: Rc<HashMap<i64, Rc<TypeBinding>>>, imp: Rc<ResolvedImport>| match v1_rt::map_get(
&parent_index,
imp.module_path.clone(),
Expand Down
101 changes: 10 additions & 91 deletions src/v1/stage0/src/v1_compiler_resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -509,16 +509,6 @@ pub fn topological_sort(
}
__result
});
let has_std_types = {
let mut __found = false;
for name in module_names.clone().iter().cloned() {
if (name.clone().as_str() == "std.types".to_string().as_str()) {
__found = true;
break;
}
}
__found
};
let explicit_edges = Rc::new({
let mut __result = Vec::new();
for m in modules.clone().iter().cloned() {
Expand All @@ -539,91 +529,20 @@ pub fn topological_sort(
}
__result
});
let implicit_std_types_edges = if has_std_types.clone() {
Rc::new({
let mut __result = Vec::new();
for m in modules.clone().iter().cloned() {
__result.extend(
(*{
let m_name = authored_name_at(source_indices.clone(), m.clone());
let imports_std_types = {
let mut __found = false;
for imp in module_imports(m.clone()).iter().cloned() {
if (authored_name_at(source_indices.clone(), imp.clone())
.as_str()
== "std.types".to_string().as_str())
{
__found = true;
break;
}
}
__found
};
if ((((m_name.clone().as_str() != "std.types".to_string().as_str())
&& (m_name.clone().as_str()
!= "std.algebra".to_string().as_str()))
&& (m_name.clone().as_str()
!= "std.error_primitives".to_string().as_str()))
&& (imports_std_types.clone() == false))
{
Rc::new(vec![Rc::new(DepEdge {
from_module: "std.types".to_string(),
to_module: m_name.clone(),
})])
} else {
Rc::new(vec![])
}
})
.iter()
.cloned(),
);
}
__result
})
} else {
Rc::new(vec![])
};
let adjacency = v1_rt::concat(explicit_edges, implicit_std_types_edges)
.iter()
.cloned()
.fold(
v1_rt::rc_empty_map::<String, Rc<Vec<String>>>(),
|acc: Rc<HashMap<String, Rc<Vec<String>>>>, edge: Rc<DepEdge>| {
adjacency_add_edge(acc, edge.from_module.clone(), edge.to_module.clone())
},
);
// §3 single-authority: ordering is import-driven only — the std.types
// implicit-parent bootstrap bridge was removed (mirrors
// v1.compiler.resolve topological_sort in src/v1/03_resolve.dag).
let adjacency = explicit_edges.iter().cloned().fold(
v1_rt::rc_empty_map::<String, Rc<Vec<String>>>(),
|acc: Rc<HashMap<String, Rc<Vec<String>>>>, edge: Rc<DepEdge>| {
adjacency_add_edge(acc, edge.from_module.clone(), edge.to_module.clone())
},
);
let in_degree_map = modules.clone().iter().cloned().fold(
v1_rt::rc_empty_map::<String, i64>(),
|acc: Rc<HashMap<String, i64>>, m: Rc<Node>| {
let m_name = authored_name_at(source_indices.clone(), m.clone());
let imports_std_types = {
let mut __found = false;
for imp in module_imports(m.clone()).iter().cloned() {
if (authored_name_at(source_indices.clone(), imp.clone()).as_str()
== "std.types".to_string().as_str())
{
__found = true;
break;
}
}
__found
};
let implicit_std_types_in_degree = if ((((has_std_types.clone()
&& (m_name.clone().as_str() != "std.types".to_string().as_str()))
&& (m_name.clone().as_str() != "std.algebra".to_string().as_str()))
&& (m_name.clone().as_str() != "std.error_primitives".to_string().as_str()))
&& (imports_std_types.clone() == false))
{
1
} else {
0
};
v1_rt::rc_map_insert(
acc,
m_name.clone(),
((module_imports(m.clone()).len() as i64)
+ implicit_std_types_in_degree.clone()),
)
v1_rt::rc_map_insert(acc, m_name.clone(), module_imports(m.clone()).len() as i64)
},
);
let initial_queue = Rc::new({
Expand Down
2 changes: 2 additions & 0 deletions src/v1/tests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ mod map_lookup_dual_dispatch_test;
#[cfg(test)]
mod measure_field_access_test;
#[cfg(test)]
mod module_authority_resolution_test;
#[cfg(test)]
mod money_carrier_cost_witness_test;
#[cfg(test)]
mod nodefold_generic_instantiation_test;
Expand Down
Loading
Loading