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
88 changes: 52 additions & 36 deletions src/v1/05_emit_rust.dag
Original file line number Diff line number Diff line change
Expand Up @@ -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<String, ItemInfo>, type_summaries: Map<String, TypeSummary>, typed_modules: List<TypedModule>, export_sets: Map<String, Map<String, Bool>>, source_indices: Map<String, NewlineIndex>, module_index: ModuleIndex, imported_enums: List<String>, import_module_enums: List<String>) -> 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<String>, emit_info: EmitGraphInfo, registry: Map<String, ItemInfo>, local_names: List<String>, export_sets: Map<String, Map<String, Bool>>, typed_modules: List<TypedModule>, source_indices: Map<String, NewlineIndex>, 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)))
Expand All @@ -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 }
)
Expand Down
150 changes: 94 additions & 56 deletions src/v1/stage0/src/v1_compiler_emit_rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<HashMap<String, Rc<ItemInfo>>>,
type_summaries: Rc<HashMap<String, Rc<TypeSummary>>>,
typed_modules: Rc<Vec<Rc<TypedModule>>>,
export_sets: Rc<HashMap<String, Rc<HashMap<String, bool>>>>,
source_indices: Rc<HashMap<String, Rc<NewlineIndex>>>,
module_index: Rc<ModuleIndex>,
imported_enums: Rc<Vec<String>>,
import_module_enums: Rc<Vec<String>>,
) -> 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,
Expand Down Expand Up @@ -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
})
Expand All @@ -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
Expand Down