diff --git a/src/v1/05_emit_rust.dag b/src/v1/05_emit_rust.dag index 00121dbbece..c7d10ad5769 100644 --- a/src/v1/05_emit_rust.dag +++ b/src/v1/05_emit_rust.dag @@ -2543,6 +2543,49 @@ fn is_emittable_parametric_type_alias_item(item: Node, item_text: String, source } } +// Single authority for "is this imported name an enum variant, and under which parent enum?". +// Used by BOTH the variant-parent set (which drives variant `use M::Parent::{..}` lines) AND +// the direct-import exclusion below, so a name can never be emitted as a direct `use M::{N}` +// AND a variant `use M::Parent::{N}` at once (E0252 reimport). Mirrors the 4-rung resolution +// order: same-module decl -> reexport surface -> imported-enum scope -> import-module-enum scope. +fn import_variant_parent_for_name(n: String, import_module: String, registry: Map, type_summaries: Map, typed_modules: List, export_sets: Map>, source_indices: Map, module_index: ModuleIndex, imported_enums: List, import_module_enums: List) -> String { + if is_import_graph_type_name(name: n, import_module: import_module, typed_modules: typed_modules, registry: registry, export_sets: export_sets, type_summaries: type_summaries, source_indices: source_indices, module_index: module_index) { + "" + } else if is_enum_in_summaries(type_summaries: type_summaries, type_name: n) { + "" + } else { + match find_variant_parent_in_module( + variant_name: n, + module_name: import_module, + typed_modules: typed_modules, + source_indices: source_indices, + module_index: module_index) { + Present { value: parent } => parent + Absent => + match reexport_variant_parent_in_import_module( + variant_name: n, + import_module: import_module, + registry: registry, + type_summaries: type_summaries, + typed_modules: typed_modules, + export_sets: export_sets, + source_indices: source_indices, + module_index: module_index) { + Present { value: parent } => parent + Absent => + match find_variant_parent(type_summaries: type_summaries, variant_name: n, scope_enums: imported_enums) { + Present { value: parent } => parent + Absent => + match find_variant_parent(type_summaries: type_summaries, variant_name: n, scope_enums: import_module_enums) { + Present { value: parent } => parent + Absent => "" + } + } + } + } + } +} + fn emit_specific_import_block(import_module: String, mod_name: String, filtered_names: List, emit_info: EmitGraphInfo, registry: Map, local_names: List, export_sets: Map>, typed_modules: List, source_indices: Map, module_index: ModuleIndex) -> String { let type_summaries = emit_info.type_summaries let deduped_names = unique_strings(items: filtered_names |> filter(n => local_names |> all(ln => ln != n))) @@ -2563,45 +2606,18 @@ fn emit_specific_import_block(import_module: String, mod_name: String, filtered_ let import_module_enums = import_module_enum_scope(import_module: import_module, registry: registry, type_summaries: type_summaries, export_sets: export_sets, typed_modules: typed_modules, source_indices: source_indices, module_index: module_index) let imported_enums = deduped_names |> filter(n => is_enum_in_summaries(type_summaries: type_summaries, type_name: n)) let all_parents = deduped_names |> map(n => - if is_import_graph_type_name(name: n, import_module: import_module, typed_modules: typed_modules, registry: registry, export_sets: export_sets, type_summaries: type_summaries, source_indices: source_indices, module_index: module_index) { - "" - } else if is_enum_in_summaries(type_summaries: type_summaries, type_name: n) { - "" - } else { - match find_variant_parent_in_module( - variant_name: n, - module_name: import_module, - typed_modules: typed_modules, - source_indices: source_indices, - module_index: module_index) { - Present { value: parent } => parent - Absent => - match reexport_variant_parent_in_import_module( - variant_name: n, - import_module: import_module, - registry: registry, - type_summaries: type_summaries, - typed_modules: typed_modules, - export_sets: export_sets, - source_indices: source_indices, - module_index: module_index) { - Present { value: parent } => parent - Absent => - match find_variant_parent(type_summaries: type_summaries, variant_name: n, scope_enums: imported_enums) { - Present { value: parent } => parent - Absent => - match find_variant_parent(type_summaries: type_summaries, variant_name: n, scope_enums: import_module_enums) { - Present { value: parent } => parent - Absent => "" - } - } - } - } - } + import_variant_parent_for_name(n: n, import_module: import_module, registry: registry, type_summaries: type_summaries, typed_modules: typed_modules, export_sets: export_sets, source_indices: source_indices, module_index: module_index, imported_enums: imported_enums, import_module_enums: import_module_enums) ) |> filter(p => p != "") let parent_list = unique_strings(items: all_parents) + // A name the variant authority claims (non-empty parent) is emitted as a variant + // `use M::Parent::{N}`, so it must NOT also appear in a direct `use M::{N}` — that is the + // E0252 reimport. The prior is_known_variant gate used a weaker authority (type_summaries + // only) that missed cross-module / reexported variants (File via UriScheme, Holds/Violates + // via Witness), leaving them in the direct set AND the variant set. let non_variant_top = top_level |> filter(n => - if is_known_variant(type_summaries: type_summaries, name: n) { + if import_variant_parent_for_name(n: n, import_module: import_module, registry: registry, type_summaries: type_summaries, typed_modules: typed_modules, export_sets: export_sets, source_indices: source_indices, module_index: module_index, imported_enums: imported_enums, import_module_enums: import_module_enums) != "" { + false + } else if is_known_variant(type_summaries: type_summaries, name: n) { is_enum_in_summaries(type_summaries: type_summaries, type_name: n) } else { true } ) diff --git a/src/v1/stage0/src/v1_compiler_emit_rust.rs b/src/v1/stage0/src/v1_compiler_emit_rust.rs index aca8525fb6b..6cb911c44f8 100644 --- a/src/v1/stage0/src/v1_compiler_emit_rust.rs +++ b/src/v1/stage0/src/v1_compiler_emit_rust.rs @@ -5416,6 +5416,73 @@ pub fn is_emittable_parametric_type_alias_item( } } +pub fn import_variant_parent_for_name( + n: String, + import_module: String, + registry: Rc>>, + type_summaries: Rc>>, + typed_modules: Rc>>, + export_sets: Rc>>>, + source_indices: Rc>>, + module_index: Rc, + imported_enums: Rc>, + import_module_enums: Rc>, +) -> String { + if is_import_graph_type_name( + n.clone(), + import_module.clone(), + typed_modules.clone(), + registry.clone(), + export_sets.clone(), + type_summaries.clone(), + source_indices.clone(), + module_index.clone(), + ) { + "".to_string() + } else { + if is_enum_in_summaries(type_summaries.clone(), n.clone()) { + "".to_string() + } else { + match find_variant_parent_in_module( + n.clone(), + import_module.clone(), + typed_modules.clone(), + source_indices.clone(), + module_index.clone(), + ) { + Some(parent) => parent.clone(), + None => match reexport_variant_parent_in_import_module( + n.clone(), + import_module.clone(), + registry.clone(), + type_summaries.clone(), + typed_modules.clone(), + export_sets.clone(), + source_indices.clone(), + module_index.clone(), + ) { + Some(parent) => parent.clone(), + None => match find_variant_parent( + type_summaries.clone(), + n.clone(), + imported_enums.clone(), + ) { + Some(parent) => parent.clone(), + None => match find_variant_parent( + type_summaries.clone(), + n.clone(), + import_module_enums.clone(), + ) { + Some(parent) => parent.clone(), + None => "".to_string(), + }, + }, + }, + } + } + } +} + pub fn emit_specific_import_block( import_module: String, mod_name: String, @@ -5517,61 +5584,18 @@ pub fn emit_specific_import_block( for p in Rc::new({ let mut __result = Vec::new(); for n in deduped_names.clone().iter().cloned() { - __result.push( - if is_import_graph_type_name( - n.clone(), - import_module.clone(), - typed_modules.clone(), - registry.clone(), - export_sets.clone(), - type_summaries.clone(), - source_indices.clone(), - module_index.clone(), - ) { - "".to_string() - } else { - if is_enum_in_summaries(type_summaries.clone(), n.clone()) { - "".to_string() - } else { - match find_variant_parent_in_module( - n.clone(), - import_module.clone(), - typed_modules.clone(), - source_indices.clone(), - module_index.clone(), - ) { - Some(parent) => parent.clone(), - None => match reexport_variant_parent_in_import_module( - n.clone(), - import_module.clone(), - registry.clone(), - type_summaries.clone(), - typed_modules.clone(), - export_sets.clone(), - source_indices.clone(), - module_index.clone(), - ) { - Some(parent) => parent.clone(), - None => match find_variant_parent( - type_summaries.clone(), - n.clone(), - imported_enums.clone(), - ) { - Some(parent) => parent.clone(), - None => match find_variant_parent( - type_summaries.clone(), - n.clone(), - import_module_enums.clone(), - ) { - Some(parent) => parent.clone(), - None => "".to_string(), - }, - }, - }, - } - } - }, - ); + __result.push(import_variant_parent_for_name( + n.clone(), + import_module.clone(), + registry.clone(), + type_summaries.clone(), + typed_modules.clone(), + export_sets.clone(), + source_indices.clone(), + module_index.clone(), + imported_enums.clone(), + import_module_enums.clone(), + )); } __result }) @@ -5588,7 +5612,21 @@ pub fn emit_specific_import_block( let non_variant_top = Rc::new({ let mut __result = Vec::new(); for n in top_level.clone().iter().cloned() { - if if is_known_variant(type_summaries.clone(), n.clone()) { + if if import_variant_parent_for_name( + n.clone(), + import_module.clone(), + registry.clone(), + type_summaries.clone(), + typed_modules.clone(), + export_sets.clone(), + source_indices.clone(), + module_index.clone(), + imported_enums.clone(), + import_module_enums.clone(), + ) != "".to_string() + { + false + } else if is_known_variant(type_summaries.clone(), n.clone()) { is_enum_in_summaries(type_summaries.clone(), n.clone()) } else { true