mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 20:00:12 +01:00
Handle merging of conflicting 'export name' cross-package imports. (#3973)
This commit is contained in:
+19
-11
@@ -23,6 +23,7 @@
|
||||
#include "toolchain/sem_ir/builtin_kind.h"
|
||||
#include "toolchain/sem_ir/file.h"
|
||||
#include "toolchain/sem_ir/ids.h"
|
||||
#include "toolchain/sem_ir/import_ir.h"
|
||||
#include "toolchain/sem_ir/inst.h"
|
||||
#include "toolchain/sem_ir/inst_kind.h"
|
||||
#include "toolchain/sem_ir/typed_insts.h"
|
||||
@@ -300,7 +301,8 @@ static auto LookupInImportIRScopes(Context& context, SemIRLoc loc,
|
||||
});
|
||||
|
||||
auto result_id = SemIR::InstId::Invalid;
|
||||
auto bind_name_id = SemIR::BindNameId::Invalid;
|
||||
std::optional<SemIR::ImportIRInst> canonical_result_inst;
|
||||
|
||||
for (auto [import_ir_id, import_scope_id] : scope.import_ir_scopes) {
|
||||
auto& import_ir = context.import_irs().Get(import_ir_id);
|
||||
|
||||
@@ -330,19 +332,25 @@ static auto LookupInImportIRScopes(Context& context, SemIRLoc loc,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!bind_name_id.is_valid()) {
|
||||
bind_name_id = context.bind_names().Add(
|
||||
if (result_id.is_valid()) {
|
||||
// On a conflict, we verify the canonical instruction is the same.
|
||||
if (!canonical_result_inst) {
|
||||
canonical_result_inst =
|
||||
GetCanonicalImportIRInst(context, &context.sem_ir(), result_id);
|
||||
}
|
||||
VerifySameCanonicalImportIRInst(context, result_id,
|
||||
*canonical_result_inst, import_ir_id,
|
||||
import_ir.sem_ir, it->second);
|
||||
} else {
|
||||
// Add the first result found.
|
||||
auto bind_name_id = context.bind_names().Add(
|
||||
{.name_id = name_id,
|
||||
.enclosing_scope_id = scope_id,
|
||||
.bind_index = SemIR::CompileTimeBindIndex::Invalid});
|
||||
}
|
||||
auto import_inst_id = AddImportRef(
|
||||
context, {.ir_id = import_ir_id, .inst_id = it->second}, bind_name_id);
|
||||
if (result_id.is_valid()) {
|
||||
context.DiagnoseDuplicateName(import_inst_id, result_id);
|
||||
} else {
|
||||
LoadImportRef(context, import_inst_id);
|
||||
result_id = import_inst_id;
|
||||
result_id =
|
||||
AddImportRef(context, {.ir_id = import_ir_id, .inst_id = it->second},
|
||||
bind_name_id);
|
||||
LoadImportRef(context, result_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -217,43 +217,6 @@ static auto CopyEnclosingNameScopesFromImportIR(
|
||||
return scope_cursor;
|
||||
}
|
||||
|
||||
// Returns the canonical IR inst for an entity. Returns an invalid ir_id for the
|
||||
// current IR.
|
||||
static 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};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Adds an ImportRef for an entity, handling merging if needed.
|
||||
static auto AddImportRefOrMerge(Context& context, SemIR::ImportIRId ir_id,
|
||||
const SemIR::File& import_sem_ir,
|
||||
@@ -275,17 +238,8 @@ static auto AddImportRefOrMerge(Context& context, SemIR::ImportIRId ir_id,
|
||||
|
||||
auto prev_ir_inst =
|
||||
GetCanonicalImportIRInst(context, &context.sem_ir(), it->second);
|
||||
auto new_ir_inst =
|
||||
GetCanonicalImportIRInst(context, &import_sem_ir, import_inst_id);
|
||||
|
||||
// Diagnose if the imported instructions aren't equal. However, then we need
|
||||
// to form an instruction for the duplicate diagnostic.
|
||||
if (prev_ir_inst != new_ir_inst) {
|
||||
auto conflict_id =
|
||||
AddImportRef(context, {.ir_id = ir_id, .inst_id = import_inst_id},
|
||||
SemIR::BindNameId::Invalid);
|
||||
context.DiagnoseDuplicateName(conflict_id, it->second);
|
||||
}
|
||||
VerifySameCanonicalImportIRInst(context, it->second, prev_ir_inst, ir_id,
|
||||
&import_sem_ir, import_inst_id);
|
||||
}
|
||||
|
||||
auto ImportLibrariesFromCurrentPackage(
|
||||
|
||||
@@ -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.
|
||||
//
|
||||
|
||||
@@ -24,6 +24,20 @@ auto AddImportIR(Context& context, SemIR::ImportIR import_ir)
|
||||
auto AddImportRef(Context& context, SemIR::ImportIRInst import_ir_inst,
|
||||
SemIR::BindNameId bind_name_id) -> SemIR::InstId;
|
||||
|
||||
// Returns the canonical IR inst for an entity. Returns an invalid ir_id for the
|
||||
// current IR.
|
||||
auto GetCanonicalImportIRInst(Context& context, const SemIR::File* cursor_ir,
|
||||
SemIR::InstId cursor_inst_id)
|
||||
-> SemIR::ImportIRInst;
|
||||
|
||||
// Verifies a new instruction is the same as a previous instruction.
|
||||
// prev_import_ir_inst should come from GetCanonicalImportIRInst.
|
||||
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;
|
||||
|
||||
// If the passed in instruction ID is an ImportRefUnloaded, turns it into an
|
||||
// ImportRefLoaded for use.
|
||||
auto LoadImportRef(Context& context, SemIR::InstId inst_id) -> void;
|
||||
|
||||
+182
-111
@@ -16,6 +16,12 @@ class C {
|
||||
var x: ();
|
||||
};
|
||||
|
||||
// --- conflict.carbon
|
||||
|
||||
package Other library "conflict";
|
||||
|
||||
fn C() {}
|
||||
|
||||
// --- export_import.carbon
|
||||
|
||||
package Other library "export_import";
|
||||
@@ -95,35 +101,13 @@ import Other library "export_name";
|
||||
|
||||
var c: Other.C = {.x = ()};
|
||||
|
||||
// --- fail_todo_use_export_name_with_copy.carbon
|
||||
// --- use_export_name_with_copy.carbon
|
||||
|
||||
library "use_export_name_with_copy";
|
||||
|
||||
import Other library "export_name";
|
||||
// CHECK:STDERR: fail_todo_use_export_name_with_copy.carbon:[[@LINE+18]]:1: In import.
|
||||
// CHECK:STDERR: import Other library "export_name_copy";
|
||||
// CHECK:STDERR: ^~~~~~
|
||||
// CHECK:STDERR: export_name_copy.carbon:4:1: In import.
|
||||
// CHECK:STDERR: import library "base";
|
||||
// CHECK:STDERR: ^~~~~~
|
||||
// CHECK:STDERR: base.carbon:4:1: ERROR: Duplicate name being declared in the same scope.
|
||||
// CHECK:STDERR: class C {
|
||||
// CHECK:STDERR: ^~~~~~~~~
|
||||
// CHECK:STDERR: fail_todo_use_export_name_with_copy.carbon:[[@LINE-10]]:1: In import.
|
||||
// CHECK:STDERR: import Other library "export_name";
|
||||
// CHECK:STDERR: ^~~~~~
|
||||
// CHECK:STDERR: export_name.carbon:4:1: In import.
|
||||
// CHECK:STDERR: import library "base";
|
||||
// CHECK:STDERR: ^~~~~~
|
||||
// CHECK:STDERR: base.carbon:4:1: Name is previously declared here.
|
||||
// CHECK:STDERR: class C {
|
||||
// CHECK:STDERR: ^~~~~~~~~
|
||||
import Other library "export_name_copy";
|
||||
|
||||
// CHECK:STDERR: fail_todo_use_export_name_with_copy.carbon:[[@LINE+4]]:8: In name lookup for `C`.
|
||||
// CHECK:STDERR: var c: Other.C = {.x = ()};
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR:
|
||||
var c: Other.C = {.x = ()};
|
||||
|
||||
// --- use_export_name_indirect.carbon
|
||||
@@ -134,84 +118,85 @@ import Other library "export_name_indirect";
|
||||
|
||||
var c: Other.C = {.x = ()};
|
||||
|
||||
// --- fail_todo_use_export_all.carbon
|
||||
// --- use_export_all.carbon
|
||||
|
||||
library "use_export_all";
|
||||
|
||||
// CHECK:STDERR: fail_todo_use_export_all.carbon:[[@LINE+6]]:1: In import.
|
||||
// CHECK:STDERR: import Other library "export_import";
|
||||
// CHECK:STDERR: ^~~~~~
|
||||
// CHECK:STDERR: base.carbon:4:1: ERROR: Duplicate name being declared in the same scope.
|
||||
// CHECK:STDERR: class C {
|
||||
// CHECK:STDERR: ^~~~~~~~~
|
||||
import Other library "export_import";
|
||||
// CHECK:STDERR: fail_todo_use_export_all.carbon:[[@LINE+9]]:1: In import.
|
||||
// CHECK:STDERR: import Other library "export_name";
|
||||
// CHECK:STDERR: ^~~~~~
|
||||
// CHECK:STDERR: export_name.carbon:4:1: In import.
|
||||
// CHECK:STDERR: import library "base";
|
||||
// CHECK:STDERR: ^~~~~~
|
||||
// CHECK:STDERR: base.carbon:4:1: Name is previously declared here.
|
||||
// CHECK:STDERR: class C {
|
||||
// CHECK:STDERR: ^~~~~~~~~
|
||||
import Other library "export_name";
|
||||
import Other library "export_import_copy";
|
||||
import Other library "export_name_copy";
|
||||
import Other library "export_import_indirect";
|
||||
import Other library "export_name_indirect";
|
||||
|
||||
// CHECK:STDERR: fail_todo_use_export_all.carbon:[[@LINE+50]]:8: In name lookup for `C`.
|
||||
// CHECK:STDERR: var c: Other.C = {.x = ()};
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR:
|
||||
// CHECK:STDERR: fail_todo_use_export_all.carbon:[[@LINE-8]]:1: In import.
|
||||
// CHECK:STDERR: import Other library "export_name_copy";
|
||||
// CHECK:STDERR: ^~~~~~
|
||||
// CHECK:STDERR: export_name_copy.carbon:4:1: In import.
|
||||
// CHECK:STDERR: import library "base";
|
||||
// CHECK:STDERR: ^~~~~~
|
||||
// CHECK:STDERR: base.carbon:4:1: ERROR: Duplicate name being declared in the same scope.
|
||||
// CHECK:STDERR: class C {
|
||||
// CHECK:STDERR: ^~~~~~~~~
|
||||
// CHECK:STDERR: fail_todo_use_export_all.carbon:[[@LINE-19]]:1: In import.
|
||||
// CHECK:STDERR: import Other library "export_name";
|
||||
// CHECK:STDERR: ^~~~~~
|
||||
// CHECK:STDERR: export_name.carbon:4:1: In import.
|
||||
// CHECK:STDERR: import library "base";
|
||||
// CHECK:STDERR: ^~~~~~
|
||||
// CHECK:STDERR: base.carbon:4:1: Name is previously declared here.
|
||||
// CHECK:STDERR: class C {
|
||||
// CHECK:STDERR: ^~~~~~~~~
|
||||
// CHECK:STDERR: fail_todo_use_export_all.carbon:[[@LINE+28]]:8: In name lookup for `C`.
|
||||
// CHECK:STDERR: var c: Other.C = {.x = ()};
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR:
|
||||
// CHECK:STDERR: fail_todo_use_export_all.carbon:[[@LINE-28]]:1: In import.
|
||||
// CHECK:STDERR: import Other library "export_name_indirect";
|
||||
// CHECK:STDERR: ^~~~~~
|
||||
// CHECK:STDERR: export_name_indirect.carbon:4:1: In import.
|
||||
// CHECK:STDERR: import library "export_name";
|
||||
// CHECK:STDERR: ^~~~~~
|
||||
// CHECK:STDERR: export_name.carbon:4:1: In import.
|
||||
// CHECK:STDERR: import library "base";
|
||||
// CHECK:STDERR: ^~~~~~
|
||||
// CHECK:STDERR: base.carbon:4:1: ERROR: Duplicate name being declared in the same scope.
|
||||
// CHECK:STDERR: class C {
|
||||
// CHECK:STDERR: ^~~~~~~~~
|
||||
// CHECK:STDERR: fail_todo_use_export_all.carbon:[[@LINE-44]]:1: In import.
|
||||
// CHECK:STDERR: import Other library "export_name";
|
||||
// CHECK:STDERR: ^~~~~~
|
||||
// CHECK:STDERR: export_name.carbon:4:1: In import.
|
||||
// CHECK:STDERR: import library "base";
|
||||
// CHECK:STDERR: ^~~~~~
|
||||
// CHECK:STDERR: base.carbon:4:1: Name is previously declared here.
|
||||
// CHECK:STDERR: class C {
|
||||
// CHECK:STDERR: ^~~~~~~~~
|
||||
// CHECK:STDERR: fail_todo_use_export_all.carbon:[[@LINE+3]]:8: In name lookup for `C`.
|
||||
// CHECK:STDERR: var c: Other.C = {.x = ()};
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
var c: Other.C = {.x = ()};
|
||||
|
||||
// --- unused_conflict_on_export_import.carbon
|
||||
|
||||
library "unused_conflict_on_export_import";
|
||||
|
||||
import Other library "export_import";
|
||||
import Other library "conflict";
|
||||
|
||||
// --- unused_conflict_on_export_name.carbon
|
||||
|
||||
library "unused_conflict_on_export_name";
|
||||
|
||||
import Other library "export_name";
|
||||
import Other library "conflict";
|
||||
|
||||
// --- fail_conflict_on_export_import.carbon
|
||||
|
||||
library "fail_conflict_on_export_import";
|
||||
|
||||
// CHECK:STDERR: fail_conflict_on_export_import.carbon:[[@LINE+6]]:1: In import.
|
||||
// CHECK:STDERR: import Other library "export_import";
|
||||
// CHECK:STDERR: ^~~~~~
|
||||
// CHECK:STDERR: base.carbon:4:1: ERROR: Duplicate name being declared in the same scope.
|
||||
// CHECK:STDERR: class C {
|
||||
// CHECK:STDERR: ^~~~~~~~~
|
||||
import Other library "export_import";
|
||||
// CHECK:STDERR: fail_conflict_on_export_import.carbon:[[@LINE+6]]:1: In import.
|
||||
// CHECK:STDERR: import Other library "conflict";
|
||||
// CHECK:STDERR: ^~~~~~
|
||||
// CHECK:STDERR: conflict.carbon:4:1: Name is previously declared here.
|
||||
// CHECK:STDERR: fn C() {}
|
||||
// CHECK:STDERR: ^~~~~~~~
|
||||
import Other library "conflict";
|
||||
|
||||
// CHECK:STDERR: fail_conflict_on_export_import.carbon:[[@LINE+4]]:11: In name lookup for `C`.
|
||||
// CHECK:STDERR: alias C = Other.C;
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR:
|
||||
alias C = Other.C;
|
||||
|
||||
// --- fail_conflict_on_export_name.carbon
|
||||
|
||||
library "fail_conflict_on_export_name";
|
||||
|
||||
import Other library "export_name";
|
||||
// CHECK:STDERR: fail_conflict_on_export_name.carbon:[[@LINE+15]]:1: In import.
|
||||
// CHECK:STDERR: import Other library "conflict";
|
||||
// CHECK:STDERR: ^~~~~~
|
||||
// CHECK:STDERR: conflict.carbon:4:1: ERROR: Duplicate name being declared in the same scope.
|
||||
// CHECK:STDERR: fn C() {}
|
||||
// CHECK:STDERR: ^~~~~~~~
|
||||
// CHECK:STDERR: fail_conflict_on_export_name.carbon:[[@LINE-7]]:1: In import.
|
||||
// CHECK:STDERR: import Other library "export_name";
|
||||
// CHECK:STDERR: ^~~~~~
|
||||
// CHECK:STDERR: export_name.carbon:4:1: In import.
|
||||
// CHECK:STDERR: import library "base";
|
||||
// CHECK:STDERR: ^~~~~~
|
||||
// CHECK:STDERR: base.carbon:4:1: Name is previously declared here.
|
||||
// CHECK:STDERR: class C {
|
||||
// CHECK:STDERR: ^~~~~~~~~
|
||||
import Other library "conflict";
|
||||
|
||||
// CHECK:STDERR: fail_conflict_on_export_name.carbon:[[@LINE+3]]:11: In name lookup for `C`.
|
||||
// CHECK:STDERR: alias C = Other.C;
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
alias C = Other.C;
|
||||
|
||||
// CHECK:STDOUT: --- base.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
@@ -238,6 +223,26 @@ var c: Other.C = {.x = ()};
|
||||
// CHECK:STDOUT: .x = %.loc5_8
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- conflict.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %C: type = fn_type @C [template]
|
||||
// CHECK:STDOUT: %.1: type = tuple_type () [template]
|
||||
// CHECK:STDOUT: %struct: C = struct_value () [template]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: package: <namespace> = namespace [template] {
|
||||
// CHECK:STDOUT: .C = %C.decl
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %C.decl: C = fn_decl @C [template = constants.%struct] {}
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @C() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- export_import.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
@@ -517,7 +522,7 @@ var c: Other.C = {.x = ()};
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_todo_use_export_name_with_copy.carbon
|
||||
// CHECK:STDOUT: --- use_export_name_with_copy.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %C: type = class_type @C [template]
|
||||
@@ -538,7 +543,6 @@ var c: Other.C = {.x = ()};
|
||||
// CHECK:STDOUT: %import_ref.1: type = import_ref ir1, inst+10, loaded [template = constants.%C]
|
||||
// CHECK:STDOUT: %import_ref.2 = import_ref ir1, inst+8, unloaded
|
||||
// CHECK:STDOUT: %import_ref.3 = import_ref ir1, inst+9, unloaded
|
||||
// CHECK:STDOUT: %import_ref.4 = import_ref ir2, inst+10, unloaded
|
||||
// CHECK:STDOUT: %C.ref: type = name_ref C, %import_ref.1 [template = constants.%C]
|
||||
// CHECK:STDOUT: %c.var: ref C = var c
|
||||
// CHECK:STDOUT: %c: ref C = bind_name c, %c.var
|
||||
@@ -552,14 +556,14 @@ var c: Other.C = {.x = ()};
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @__global_init() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %.loc29_25.1: () = tuple_literal ()
|
||||
// CHECK:STDOUT: %.loc29_26.1: {.x: ()} = struct_literal (%.loc29_25.1)
|
||||
// CHECK:STDOUT: %.loc29_26.2: ref () = class_element_access file.%c.var, element0
|
||||
// CHECK:STDOUT: %.loc29_25.2: init () = tuple_init () to %.loc29_26.2 [template = constants.%tuple]
|
||||
// CHECK:STDOUT: %.loc29_26.3: init () = converted %.loc29_25.1, %.loc29_25.2 [template = constants.%tuple]
|
||||
// CHECK:STDOUT: %.loc29_26.4: init C = class_init (%.loc29_26.3), file.%c.var [template = constants.%struct]
|
||||
// CHECK:STDOUT: %.loc29_27: init C = converted %.loc29_26.1, %.loc29_26.4 [template = constants.%struct]
|
||||
// CHECK:STDOUT: assign file.%c.var, %.loc29_27
|
||||
// CHECK:STDOUT: %.loc7_25.1: () = tuple_literal ()
|
||||
// CHECK:STDOUT: %.loc7_26.1: {.x: ()} = struct_literal (%.loc7_25.1)
|
||||
// CHECK:STDOUT: %.loc7_26.2: ref () = class_element_access file.%c.var, element0
|
||||
// CHECK:STDOUT: %.loc7_25.2: init () = tuple_init () to %.loc7_26.2 [template = constants.%tuple]
|
||||
// CHECK:STDOUT: %.loc7_26.3: init () = converted %.loc7_25.1, %.loc7_25.2 [template = constants.%tuple]
|
||||
// CHECK:STDOUT: %.loc7_26.4: init C = class_init (%.loc7_26.3), file.%c.var [template = constants.%struct]
|
||||
// CHECK:STDOUT: %.loc7_27: init C = converted %.loc7_26.1, %.loc7_26.4 [template = constants.%struct]
|
||||
// CHECK:STDOUT: assign file.%c.var, %.loc7_27
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -608,7 +612,7 @@ var c: Other.C = {.x = ()};
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_todo_use_export_all.carbon
|
||||
// CHECK:STDOUT: --- use_export_all.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %C: type = class_type @C [template]
|
||||
@@ -629,9 +633,6 @@ var c: Other.C = {.x = ()};
|
||||
// CHECK:STDOUT: %import_ref.1: type = import_ref ir2, inst+10, loaded [template = constants.%C]
|
||||
// CHECK:STDOUT: %import_ref.2 = import_ref ir2, inst+8, unloaded
|
||||
// CHECK:STDOUT: %import_ref.3 = import_ref ir2, inst+9, unloaded
|
||||
// CHECK:STDOUT: %import_ref.4 = import_ref ir4, inst+10, unloaded
|
||||
// CHECK:STDOUT: %import_ref.5 = import_ref ir6, inst+10, unloaded
|
||||
// CHECK:STDOUT: %import_ref.6 = import_ref ir7, inst+1, unloaded
|
||||
// CHECK:STDOUT: %C.ref: type = name_ref C, %import_ref.1 [template = constants.%C]
|
||||
// CHECK:STDOUT: %c.var: ref C = var c
|
||||
// CHECK:STDOUT: %c: ref C = bind_name c, %c.var
|
||||
@@ -645,14 +646,84 @@ var c: Other.C = {.x = ()};
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @__global_init() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %.loc76_25.1: () = tuple_literal ()
|
||||
// CHECK:STDOUT: %.loc76_26.1: {.x: ()} = struct_literal (%.loc76_25.1)
|
||||
// CHECK:STDOUT: %.loc76_26.2: ref () = class_element_access file.%c.var, element0
|
||||
// CHECK:STDOUT: %.loc76_25.2: init () = tuple_init () to %.loc76_26.2 [template = constants.%tuple]
|
||||
// CHECK:STDOUT: %.loc76_26.3: init () = converted %.loc76_25.1, %.loc76_25.2 [template = constants.%tuple]
|
||||
// CHECK:STDOUT: %.loc76_26.4: init C = class_init (%.loc76_26.3), file.%c.var [template = constants.%struct]
|
||||
// CHECK:STDOUT: %.loc76_27: init C = converted %.loc76_26.1, %.loc76_26.4 [template = constants.%struct]
|
||||
// CHECK:STDOUT: assign file.%c.var, %.loc76_27
|
||||
// CHECK:STDOUT: %.loc11_25.1: () = tuple_literal ()
|
||||
// CHECK:STDOUT: %.loc11_26.1: {.x: ()} = struct_literal (%.loc11_25.1)
|
||||
// CHECK:STDOUT: %.loc11_26.2: ref () = class_element_access file.%c.var, element0
|
||||
// CHECK:STDOUT: %.loc11_25.2: init () = tuple_init () to %.loc11_26.2 [template = constants.%tuple]
|
||||
// CHECK:STDOUT: %.loc11_26.3: init () = converted %.loc11_25.1, %.loc11_25.2 [template = constants.%tuple]
|
||||
// CHECK:STDOUT: %.loc11_26.4: init C = class_init (%.loc11_26.3), file.%c.var [template = constants.%struct]
|
||||
// CHECK:STDOUT: %.loc11_27: init C = converted %.loc11_26.1, %.loc11_26.4 [template = constants.%struct]
|
||||
// CHECK:STDOUT: assign file.%c.var, %.loc11_27
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- unused_conflict_on_export_import.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: package: <namespace> = namespace [template] {
|
||||
// CHECK:STDOUT: .Other = %Other
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Other: <namespace> = namespace [template] {}
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- unused_conflict_on_export_name.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: package: <namespace> = namespace [template] {
|
||||
// CHECK:STDOUT: .Other = %Other
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Other: <namespace> = namespace [template] {}
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_conflict_on_export_import.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %C: type = fn_type @C [template]
|
||||
// CHECK:STDOUT: %.1: type = tuple_type () [template]
|
||||
// CHECK:STDOUT: %struct: C = struct_value () [template]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: package: <namespace> = namespace [template] {
|
||||
// CHECK:STDOUT: .Other = %Other
|
||||
// CHECK:STDOUT: .C = %C
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Other: <namespace> = namespace [template] {}
|
||||
// CHECK:STDOUT: %Other.ref: <namespace> = name_ref Other, %Other [template = %Other]
|
||||
// CHECK:STDOUT: %import_ref.1: C = import_ref ir2, inst+1, loaded [template = constants.%struct]
|
||||
// CHECK:STDOUT: %import_ref.2 = import_ref ir3, inst+1, unloaded
|
||||
// CHECK:STDOUT: %C.ref: C = name_ref C, %import_ref.1 [template = constants.%struct]
|
||||
// CHECK:STDOUT: %C: C = bind_alias C, %import_ref.1 [template = constants.%struct]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @C();
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_conflict_on_export_name.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %C: type = class_type @C [template]
|
||||
// CHECK:STDOUT: %.1: type = tuple_type () [template]
|
||||
// CHECK:STDOUT: %.2: type = struct_type {.x: ()} [template]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: package: <namespace> = namespace [template] {
|
||||
// CHECK:STDOUT: .Other = %Other
|
||||
// CHECK:STDOUT: .C = %C
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Other: <namespace> = namespace [template] {}
|
||||
// CHECK:STDOUT: %Other.ref: <namespace> = name_ref Other, %Other [template = %Other]
|
||||
// CHECK:STDOUT: %import_ref.1: type = import_ref ir1, inst+10, loaded [template = constants.%C]
|
||||
// CHECK:STDOUT: %import_ref.2 = import_ref ir1, inst+8, unloaded
|
||||
// CHECK:STDOUT: %import_ref.3 = import_ref ir1, inst+9, unloaded
|
||||
// CHECK:STDOUT: %import_ref.4 = import_ref ir2, inst+1, unloaded
|
||||
// CHECK:STDOUT: %C.ref: type = name_ref C, %import_ref.1 [template = constants.%C]
|
||||
// CHECK:STDOUT: %C: type = bind_alias C, %import_ref.1 [template = constants.%C]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: class @C {
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .Self = file.%import_ref.2
|
||||
// CHECK:STDOUT: .x = file.%import_ref.3
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
|
||||
Reference in New Issue
Block a user