mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-11-10 12:28:25 +00:00
Fix import of val and ref return forms. (#7989)
Importing a function with a `-> val` return form, such as `fn F() -> val i32`, crashed because `TryResolveInstCanonical` had no case for `ValueForm`. Also, an imported `RefForm` was given type `type` rather than `Core.Form`. Import all three primitive forms with a single function template. Assisted-by: Claude via Antigravity
This commit is contained in:
1 parent
fea77fe598
commit
14a3de9ff1
3 files changed
+156
-25
No files matched your search
@@ -4194,24 +4194,6 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
{.elements_id = elements_id, .impl_id = impl_id});
|
||||
}
|
||||
|
||||
static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
SemIR::InitForm inst) -> ResolveResult {
|
||||
auto type_const_id = GetLocalConstantId(resolver, inst.type_id);
|
||||
auto type_component_const_id =
|
||||
GetLocalConstantId(resolver, inst.type_component_inst_id);
|
||||
if (resolver.HasNewWork()) {
|
||||
return ResolveResult::Retry();
|
||||
}
|
||||
return ResolveResult::Deduplicated<SemIR::InitForm>(
|
||||
resolver,
|
||||
SemIR::InitForm{
|
||||
.type_id =
|
||||
resolver.local_types().GetTypeIdForTypeConstantId(type_const_id),
|
||||
.type_component_inst_id = resolver.local_types().GetTypeInstId(
|
||||
resolver.local_types().GetTypeIdForTypeConstantId(
|
||||
type_component_const_id))});
|
||||
}
|
||||
|
||||
static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
SemIR::IntValue inst) -> ResolveResult {
|
||||
auto type_id = GetLocalConstantId(resolver, inst.type_id);
|
||||
@@ -4337,19 +4319,21 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
resolver, {.type_id = SemIR::TypeType::TypeId, .pointee_id = pointee_id});
|
||||
}
|
||||
|
||||
template <typename PrimitiveFormT>
|
||||
requires SemIR::Internal::HasInstCategory<SemIR::AnyPrimitiveForm,
|
||||
PrimitiveFormT>
|
||||
static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
SemIR::RefForm inst) -> ResolveResult {
|
||||
PrimitiveFormT inst) -> ResolveResult {
|
||||
CARBON_CHECK(inst.type_id == SemIR::FormType::TypeId);
|
||||
auto type_component_inst_id =
|
||||
GetLocalConstantId(resolver, inst.type_component_inst_id);
|
||||
GetLocalTypeInstId(resolver, inst.type_component_inst_id);
|
||||
if (resolver.HasNewWork()) {
|
||||
return ResolveResult::Retry();
|
||||
}
|
||||
|
||||
return ResolveResult::Deduplicated<SemIR::RefForm>(
|
||||
resolver, {.type_id = SemIR::TypeType::TypeId,
|
||||
.type_component_inst_id = resolver.local_types().GetTypeInstId(
|
||||
resolver.local_types().GetTypeIdForTypeConstantId(
|
||||
type_component_inst_id))});
|
||||
return ResolveResult::Deduplicated<PrimitiveFormT>(
|
||||
resolver, {.type_id = SemIR::FormType::TypeId,
|
||||
.type_component_inst_id = type_component_inst_id});
|
||||
}
|
||||
|
||||
static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
@@ -4925,6 +4909,9 @@ static auto TryResolveInstCanonical(ImportRefResolver& resolver,
|
||||
case CARBON_KIND(SemIR::ValueBindingPattern inst): {
|
||||
return TryResolveTypedInst(resolver, inst);
|
||||
}
|
||||
case CARBON_KIND(SemIR::ValueForm inst): {
|
||||
return TryResolveTypedInst(resolver, inst);
|
||||
}
|
||||
case CARBON_KIND(SemIR::ValueParamPattern inst): {
|
||||
return TryResolveTypedInst(resolver, inst);
|
||||
}
|
||||
|
||||
@@ -37,6 +37,26 @@ library "[[@TEST_NAME]]";
|
||||
// CHECK:STDERR:
|
||||
fn F() -> (ref i32);
|
||||
|
||||
// --- ref_return_lib.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
var g: i32 = 0;
|
||||
|
||||
fn F() -> ref i32 { return g; }
|
||||
|
||||
// --- import_ref_return.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
import library "ref_return_lib";
|
||||
|
||||
//@include-in-dumps
|
||||
|
||||
fn G() {
|
||||
let unused ref x: i32 = F();
|
||||
}
|
||||
|
||||
// CHECK:STDOUT: --- ref_return.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
@@ -99,3 +119,56 @@ fn F() -> (ref i32);
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- import_ref_return.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
|
||||
// CHECK:STDOUT: %G.type: type = fn_type @G [concrete]
|
||||
// CHECK:STDOUT: %G: %G.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
|
||||
// CHECK:STDOUT: %Int.type: type = parameterized_class_name_type @Int [concrete]
|
||||
// CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.d94: type = pattern_type %i32 [concrete]
|
||||
// CHECK:STDOUT: %x.patt: %pattern_type.d94 = ref_binding_pattern x [concrete]
|
||||
// CHECK:STDOUT: %F.type: type = fn_type @F [concrete]
|
||||
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
// CHECK:STDOUT: %Main.g = import_ref Main//ref_return_lib, g, unloaded
|
||||
// CHECK:STDOUT: %Main.F: %F.type = import_ref Main//ref_return_lib, F, loaded [concrete = constants.%F]
|
||||
// CHECK:STDOUT: %Core: <namespace> = namespace file.%Core.import, [concrete] {
|
||||
// CHECK:STDOUT: .Int = %Core.Int
|
||||
// CHECK:STDOUT: import Core//prelude
|
||||
// CHECK:STDOUT: import Core//prelude/...
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: package: <namespace> = namespace [concrete] {
|
||||
// CHECK:STDOUT: .g = imports.%Main.g
|
||||
// CHECK:STDOUT: .F = imports.%Main.F
|
||||
// CHECK:STDOUT: .Core = imports.%Core
|
||||
// CHECK:STDOUT: .G = %G.decl
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Core.import = import Core
|
||||
// CHECK:STDOUT: %default.import = import <none>
|
||||
// CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [concrete = constants.%G] {} {}
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @G() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %F.ref: %F.type = name_ref F, imports.%Main.F [concrete = constants.%F]
|
||||
// CHECK:STDOUT: %F.call: ref %i32 = call %F.ref()
|
||||
// CHECK:STDOUT: %i32: type = type_literal constants.%i32 [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %x: ref %i32 = wrapper_binding x, %F.call
|
||||
// CHECK:STDOUT: name_binding_decl {
|
||||
// CHECK:STDOUT: %x.patt: %pattern_type.d94 = ref_binding_pattern x [concrete = constants.%x.patt]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @F [from "ref_return_lib.carbon"];
|
||||
// CHECK:STDOUT:
|
||||
@@ -95,6 +95,26 @@ fn F() -> var i32 {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// --- val_return_lib.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
fn F() -> val i32 {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// --- import_val_return.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
import library "val_return_lib";
|
||||
|
||||
//@include-in-dumps
|
||||
|
||||
fn G() {
|
||||
let unused x: i32 = F();
|
||||
}
|
||||
|
||||
// CHECK:STDOUT: --- val_return.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
@@ -298,3 +318,54 @@ fn F() -> var i32 {
|
||||
// CHECK:STDOUT: return %.loc7_11.2
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- import_val_return.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
|
||||
// CHECK:STDOUT: %G.type: type = fn_type @G [concrete]
|
||||
// CHECK:STDOUT: %G: %G.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
|
||||
// CHECK:STDOUT: %Int.type: type = parameterized_class_name_type @Int [concrete]
|
||||
// CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.d94: type = pattern_type %i32 [concrete]
|
||||
// CHECK:STDOUT: %x.patt: %pattern_type.d94 = value_binding_pattern x [concrete]
|
||||
// CHECK:STDOUT: %F.type: type = fn_type @F [concrete]
|
||||
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
// CHECK:STDOUT: %Main.F: %F.type = import_ref Main//val_return_lib, F, loaded [concrete = constants.%F]
|
||||
// CHECK:STDOUT: %Core: <namespace> = namespace file.%Core.import, [concrete] {
|
||||
// CHECK:STDOUT: .Int = %Core.Int
|
||||
// CHECK:STDOUT: import Core//prelude
|
||||
// CHECK:STDOUT: import Core//prelude/...
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: package: <namespace> = namespace [concrete] {
|
||||
// CHECK:STDOUT: .F = imports.%Main.F
|
||||
// CHECK:STDOUT: .Core = imports.%Core
|
||||
// CHECK:STDOUT: .G = %G.decl
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Core.import = import Core
|
||||
// CHECK:STDOUT: %default.import = import <none>
|
||||
// CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [concrete = constants.%G] {} {}
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @G() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %F.ref: %F.type = name_ref F, imports.%Main.F [concrete = constants.%F]
|
||||
// CHECK:STDOUT: %F.call: %i32 = call %F.ref()
|
||||
// CHECK:STDOUT: %i32: type = type_literal constants.%i32 [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %x: %i32 = wrapper_binding x, %F.call
|
||||
// CHECK:STDOUT: name_binding_decl {
|
||||
// CHECK:STDOUT: %x.patt: %pattern_type.d94 = value_binding_pattern x [concrete = constants.%x.patt]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @F [from "val_return_lib.carbon"];
|
||||
// CHECK:STDOUT:
|
||||
Reference in new issue
Block a user