mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Handle merging of conflicting 'export name' cross-package imports. (#3973)
This commit is contained in:
@@ -72,6 +72,56 @@ auto AddImportRef(Context& context, SemIR::ImportIRInst import_ir_inst,
|
||||
return import_ref_id;
|
||||
}
|
||||
|
||||
auto GetCanonicalImportIRInst(Context& context, const SemIR::File* cursor_ir,
|
||||
SemIR::InstId cursor_inst_id)
|
||||
-> SemIR::ImportIRInst {
|
||||
while (true) {
|
||||
auto inst = cursor_ir->insts().Get(cursor_inst_id);
|
||||
CARBON_KIND_SWITCH(inst) {
|
||||
case CARBON_KIND(SemIR::ExportDecl bind_export): {
|
||||
cursor_inst_id = bind_export.value_id;
|
||||
continue;
|
||||
}
|
||||
case SemIR::ImportRefLoaded::Kind:
|
||||
case SemIR::ImportRefUnloaded::Kind: {
|
||||
auto import_ref = inst.As<SemIR::AnyImportRef>();
|
||||
auto import_ir_inst =
|
||||
cursor_ir->import_ir_insts().Get(import_ref.import_ir_inst_id);
|
||||
cursor_ir = cursor_ir->import_irs().Get(import_ir_inst.ir_id).sem_ir;
|
||||
cursor_inst_id = import_ir_inst.inst_id;
|
||||
continue;
|
||||
}
|
||||
default: {
|
||||
auto ir_id = SemIR::ImportIRId::Invalid;
|
||||
if (cursor_ir != &context.sem_ir()) {
|
||||
// This uses AddImportIR in case it was indirectly found, which can
|
||||
// happen with two or more steps of exports.
|
||||
ir_id = AddImportIR(context, {.node_id = Parse::NodeId::Invalid,
|
||||
.sem_ir = cursor_ir,
|
||||
.is_export = false});
|
||||
}
|
||||
return {.ir_id = ir_id, .inst_id = cursor_inst_id};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto VerifySameCanonicalImportIRInst(Context& context, SemIR::InstId prev_id,
|
||||
SemIR::ImportIRInst prev_import_ir_inst,
|
||||
SemIR::ImportIRId new_ir_id,
|
||||
const SemIR::File* new_import_ir,
|
||||
SemIR::InstId new_inst_id) -> void {
|
||||
auto new_import_ir_inst =
|
||||
GetCanonicalImportIRInst(context, new_import_ir, new_inst_id);
|
||||
if (new_import_ir_inst == prev_import_ir_inst) {
|
||||
return;
|
||||
}
|
||||
auto conflict_id =
|
||||
AddImportRef(context, {.ir_id = new_ir_id, .inst_id = new_inst_id},
|
||||
SemIR::BindNameId::Invalid);
|
||||
context.DiagnoseDuplicateName(conflict_id, prev_id);
|
||||
}
|
||||
|
||||
// Resolves an instruction from an imported IR into a constant referring to the
|
||||
// current IR.
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user