mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 20:50:13 +01:00
Support StructValue in StringifyTypeExpr (#4696)
Co-authored-by: Josh L <josh11b@users.noreply.github.com> Co-authored-by: Richard Smith <richard@metafoo.co.uk>
This commit is contained in:
co-authored by
Josh L
Richard Smith
parent
557c9b022a
commit
6b3307c520
+194
-6
@@ -52,14 +52,41 @@ library "[[@TEST_NAME]]";
|
||||
|
||||
class C(N:! i32) {}
|
||||
|
||||
// CHECK:STDERR: fail_int_value.carbon:[[@LINE+6]]:1: error: cannot implicitly convert from `()` to `C(123)` [ImplicitAsConversionFailure]
|
||||
// CHECK:STDERR: fail_int_value.carbon:[[@LINE+7]]:1: error: cannot implicitly convert from `()` to `C(123)` [ImplicitAsConversionFailure]
|
||||
// CHECK:STDERR: var v: C(123) = ();
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~
|
||||
// CHECK:STDERR: fail_int_value.carbon:[[@LINE+3]]:1: note: type `()` does not implement interface `Core.ImplicitAs(C(123))` [MissingImplInMemberAccessNote]
|
||||
// CHECK:STDERR: fail_int_value.carbon:[[@LINE+4]]:1: note: type `()` does not implement interface `Core.ImplicitAs(C(123))` [MissingImplInMemberAccessNote]
|
||||
// CHECK:STDERR: var v: C(123) = ();
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~
|
||||
// CHECK:STDERR:
|
||||
var v: C(123) = ();
|
||||
|
||||
// --- fail_class_param.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
class D {
|
||||
var a: i32;
|
||||
var b: i32;
|
||||
}
|
||||
|
||||
class E(F:! D) {}
|
||||
|
||||
// CHECK:STDERR: fail_class_param.carbon:[[@LINE+13]]:8: error: argument for generic parameter is not a compile-time constant [CompTimeArgumentNotConstant]
|
||||
// CHECK:STDERR: var g: E({.a = 1, .b = 2}) = {} as E({.a = 3, .b = 4} as D);
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~
|
||||
// CHECK:STDERR: fail_class_param.carbon:[[@LINE-5]]:9: note: initializing generic parameter `F` declared here [InitializingGenericParam]
|
||||
// CHECK:STDERR: class E(F:! D) {}
|
||||
// CHECK:STDERR: ^
|
||||
// CHECK:STDERR:
|
||||
// CHECK:STDERR: fail_class_param.carbon:[[@LINE+6]]:36: error: argument for generic parameter is not a compile-time constant [CompTimeArgumentNotConstant]
|
||||
// CHECK:STDERR: var g: E({.a = 1, .b = 2}) = {} as E({.a = 3, .b = 4} as D);
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// CHECK:STDERR: fail_class_param.carbon:[[@LINE-12]]:9: note: initializing generic parameter `F` declared here [InitializingGenericParam]
|
||||
// CHECK:STDERR: class E(F:! D) {}
|
||||
// CHECK:STDERR: ^
|
||||
var g: E({.a = 1, .b = 2}) = {} as E({.a = 3, .b = 4} as D);
|
||||
|
||||
// CHECK:STDOUT: --- fail_empty_params.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
@@ -327,8 +354,8 @@ var v: C(123) = ();
|
||||
// CHECK:STDOUT: %Convert.bound: <bound method> = bound_method %int_123, %impl.elem0 [template = constants.%Convert.bound]
|
||||
// CHECK:STDOUT: %Convert.specific_fn: <specific function> = specific_function %Convert.bound, @Convert.2(constants.%int_32) [template = constants.%Convert.specific_fn]
|
||||
// CHECK:STDOUT: %int.convert_checked: init %i32 = call %Convert.specific_fn(%int_123) [template = constants.%int_123.2]
|
||||
// CHECK:STDOUT: %.loc12_13.1: %i32 = value_of_initializer %int.convert_checked [template = constants.%int_123.2]
|
||||
// CHECK:STDOUT: %.loc12_13.2: %i32 = converted %int_123, %.loc12_13.1 [template = constants.%int_123.2]
|
||||
// CHECK:STDOUT: %.loc13_13.1: %i32 = value_of_initializer %int.convert_checked [template = constants.%int_123.2]
|
||||
// CHECK:STDOUT: %.loc13_13.2: %i32 = converted %int_123, %.loc13_13.1 [template = constants.%int_123.2]
|
||||
// CHECK:STDOUT: %C: type = class_type @C, @C(constants.%int_123.2) [template = constants.%C.2]
|
||||
// CHECK:STDOUT: %v.var: ref %C.2 = var v
|
||||
// CHECK:STDOUT: %v: ref %C.2 = bind_name v, %v.var
|
||||
@@ -351,8 +378,8 @@ var v: C(123) = ();
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @__global_init() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %.loc12_18: %empty_tuple.type = tuple_literal ()
|
||||
// CHECK:STDOUT: %.loc12_19: %C.2 = converted %.loc12_18, <error> [template = <error>]
|
||||
// CHECK:STDOUT: %.loc13_18: %empty_tuple.type = tuple_literal ()
|
||||
// CHECK:STDOUT: %.loc13_19: %C.2 = converted %.loc13_18, <error> [template = <error>]
|
||||
// CHECK:STDOUT: assign file.%v.var, <error>
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
@@ -369,3 +396,164 @@ var v: C(123) = ();
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_class_param.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %D: type = class_type @D [template]
|
||||
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [template]
|
||||
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [template]
|
||||
// CHECK:STDOUT: %D.elem: type = unbound_element_type %D, %i32 [template]
|
||||
// CHECK:STDOUT: %struct_type.a.b.1: type = struct_type {.a: %i32, .b: %i32} [template]
|
||||
// CHECK:STDOUT: %complete_type.3: <witness> = complete_type_witness %struct_type.a.b.1 [template]
|
||||
// CHECK:STDOUT: %F: %D = bind_symbolic_name F, 0 [symbolic]
|
||||
// CHECK:STDOUT: %F.patt: %D = symbolic_binding_pattern F, 0 [symbolic]
|
||||
// CHECK:STDOUT: %E.type: type = generic_class_type @E [template]
|
||||
// CHECK:STDOUT: %E.generic: %E.type = struct_value () [template]
|
||||
// CHECK:STDOUT: %E: type = class_type @E, @E(%F) [symbolic]
|
||||
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [template]
|
||||
// CHECK:STDOUT: %complete_type.4: <witness> = complete_type_witness %empty_struct_type [template]
|
||||
// CHECK:STDOUT: %int_1.1: Core.IntLiteral = int_value 1 [template]
|
||||
// CHECK:STDOUT: %int_2.1: Core.IntLiteral = int_value 2 [template]
|
||||
// CHECK:STDOUT: %struct_type.a.b.2: type = struct_type {.a: Core.IntLiteral, .b: Core.IntLiteral} [template]
|
||||
// CHECK:STDOUT: %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(%i32) [template]
|
||||
// CHECK:STDOUT: %Convert.type.10: type = fn_type @Convert.2, @impl.1(%int_32) [template]
|
||||
// CHECK:STDOUT: %Convert.10: %Convert.type.10 = struct_value () [template]
|
||||
// CHECK:STDOUT: %interface.5: <witness> = interface_witness (%Convert.10) [template]
|
||||
// CHECK:STDOUT: %Convert.bound.1: <bound method> = bound_method %int_1.1, %Convert.10 [template]
|
||||
// CHECK:STDOUT: %Convert.specific_fn.1: <specific function> = specific_function %Convert.bound.1, @Convert.2(%int_32) [template]
|
||||
// CHECK:STDOUT: %int_1.2: %i32 = int_value 1 [template]
|
||||
// CHECK:STDOUT: %Convert.bound.2: <bound method> = bound_method %int_2.1, %Convert.10 [template]
|
||||
// CHECK:STDOUT: %Convert.specific_fn.2: <specific function> = specific_function %Convert.bound.2, @Convert.2(%int_32) [template]
|
||||
// CHECK:STDOUT: %int_2.2: %i32 = int_value 2 [template]
|
||||
// CHECK:STDOUT: %D.val.1: %D = struct_value (%int_1.2, %int_2.2) [template]
|
||||
// CHECK:STDOUT: %int_3.1: Core.IntLiteral = int_value 3 [template]
|
||||
// CHECK:STDOUT: %int_4.1: Core.IntLiteral = int_value 4 [template]
|
||||
// CHECK:STDOUT: %Convert.bound.3: <bound method> = bound_method %int_3.1, %Convert.10 [template]
|
||||
// CHECK:STDOUT: %Convert.specific_fn.3: <specific function> = specific_function %Convert.bound.3, @Convert.2(%int_32) [template]
|
||||
// CHECK:STDOUT: %int_3.2: %i32 = int_value 3 [template]
|
||||
// CHECK:STDOUT: %Convert.bound.4: <bound method> = bound_method %int_4.1, %Convert.10 [template]
|
||||
// CHECK:STDOUT: %Convert.specific_fn.4: <specific function> = specific_function %Convert.bound.4, @Convert.2(%int_32) [template]
|
||||
// CHECK:STDOUT: %int_4.2: %i32 = int_value 4 [template]
|
||||
// CHECK:STDOUT: %D.val.2: %D = struct_value (%int_3.2, %int_4.2) [template]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
// CHECK:STDOUT: %Core: <namespace> = namespace file.%Core.import, [template] {
|
||||
// CHECK:STDOUT: .Int = %import_ref.1
|
||||
// CHECK:STDOUT: .ImplicitAs = %import_ref.5
|
||||
// CHECK:STDOUT: import Core//prelude
|
||||
// CHECK:STDOUT: import Core//prelude/...
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: package: <namespace> = namespace [template] {
|
||||
// CHECK:STDOUT: .Core = imports.%Core
|
||||
// CHECK:STDOUT: .D = %D.decl
|
||||
// CHECK:STDOUT: .E = %E.decl
|
||||
// CHECK:STDOUT: .g = %g
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Core.import = import Core
|
||||
// CHECK:STDOUT: %D.decl: type = class_decl @D [template = constants.%D] {} {}
|
||||
// CHECK:STDOUT: %E.decl: %E.type = class_decl @E [template = constants.%E.generic] {
|
||||
// CHECK:STDOUT: %F.patt.loc9_9.1: %D = symbolic_binding_pattern F, 0 [symbolic = %F.patt.loc9_9.2 (constants.%F.patt)]
|
||||
// CHECK:STDOUT: %F.param_patt: %D = value_param_pattern %F.patt.loc9_9.1, runtime_param<invalid> [symbolic = %F.patt.loc9_9.2 (constants.%F.patt)]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %D.ref: type = name_ref D, file.%D.decl [template = constants.%D]
|
||||
// CHECK:STDOUT: %F.param: %D = value_param runtime_param<invalid>
|
||||
// CHECK:STDOUT: %F.loc9_9.1: %D = bind_symbolic_name F, 0, %F.param [symbolic = %F.loc9_9.2 (constants.%F)]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %E.ref: %E.type = name_ref E, %E.decl [template = constants.%E.generic]
|
||||
// CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [template = constants.%int_1.1]
|
||||
// CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [template = constants.%int_2.1]
|
||||
// CHECK:STDOUT: %.loc24_25.1: %struct_type.a.b.2 = struct_literal (%int_1, %int_2)
|
||||
// CHECK:STDOUT: %impl.elem0.loc24_25.1: %Convert.type.2 = interface_witness_access constants.%interface.5, element0 [template = constants.%Convert.10]
|
||||
// CHECK:STDOUT: %Convert.bound.loc24_25.1: <bound method> = bound_method %int_1, %impl.elem0.loc24_25.1 [template = constants.%Convert.bound.1]
|
||||
// CHECK:STDOUT: %Convert.specific_fn.loc24_25.1: <specific function> = specific_function %Convert.bound.loc24_25.1, @Convert.2(constants.%int_32) [template = constants.%Convert.specific_fn.1]
|
||||
// CHECK:STDOUT: %int.convert_checked.loc24_25.1: init %i32 = call %Convert.specific_fn.loc24_25.1(%int_1) [template = constants.%int_1.2]
|
||||
// CHECK:STDOUT: %.loc24_25.2: init %i32 = converted %int_1, %int.convert_checked.loc24_25.1 [template = constants.%int_1.2]
|
||||
// CHECK:STDOUT: %.loc24_25.3: ref %D = temporary_storage
|
||||
// CHECK:STDOUT: %.loc24_25.4: ref %i32 = class_element_access %.loc24_25.3, element0
|
||||
// CHECK:STDOUT: %.loc24_25.5: init %i32 = initialize_from %.loc24_25.2 to %.loc24_25.4 [template = constants.%int_1.2]
|
||||
// CHECK:STDOUT: %impl.elem0.loc24_25.2: %Convert.type.2 = interface_witness_access constants.%interface.5, element0 [template = constants.%Convert.10]
|
||||
// CHECK:STDOUT: %Convert.bound.loc24_25.2: <bound method> = bound_method %int_2, %impl.elem0.loc24_25.2 [template = constants.%Convert.bound.2]
|
||||
// CHECK:STDOUT: %Convert.specific_fn.loc24_25.2: <specific function> = specific_function %Convert.bound.loc24_25.2, @Convert.2(constants.%int_32) [template = constants.%Convert.specific_fn.2]
|
||||
// CHECK:STDOUT: %int.convert_checked.loc24_25.2: init %i32 = call %Convert.specific_fn.loc24_25.2(%int_2) [template = constants.%int_2.2]
|
||||
// CHECK:STDOUT: %.loc24_25.6: init %i32 = converted %int_2, %int.convert_checked.loc24_25.2 [template = constants.%int_2.2]
|
||||
// CHECK:STDOUT: %.loc24_25.7: ref %i32 = class_element_access %.loc24_25.3, element1
|
||||
// CHECK:STDOUT: %.loc24_25.8: init %i32 = initialize_from %.loc24_25.6 to %.loc24_25.7 [template = constants.%int_2.2]
|
||||
// CHECK:STDOUT: %.loc24_25.9: init %D = class_init (%.loc24_25.5, %.loc24_25.8), %.loc24_25.3 [template = constants.%D.val.1]
|
||||
// CHECK:STDOUT: %.loc24_25.10: ref %D = temporary %.loc24_25.3, %.loc24_25.9
|
||||
// CHECK:STDOUT: %.loc24_26.1: ref %D = converted %.loc24_25.1, %.loc24_25.10
|
||||
// CHECK:STDOUT: %.loc24_26.2: %D = bind_value %.loc24_26.1
|
||||
// CHECK:STDOUT: %g.var: ref <error> = var g
|
||||
// CHECK:STDOUT: %g: ref <error> = bind_name g, %g.var
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: class @D {
|
||||
// CHECK:STDOUT: %int_32.loc5: Core.IntLiteral = int_value 32 [template = constants.%int_32]
|
||||
// CHECK:STDOUT: %i32.loc5: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
|
||||
// CHECK:STDOUT: %.loc5: %D.elem = field_decl a, element0 [template]
|
||||
// CHECK:STDOUT: %int_32.loc6: Core.IntLiteral = int_value 32 [template = constants.%int_32]
|
||||
// CHECK:STDOUT: %i32.loc6: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
|
||||
// CHECK:STDOUT: %.loc6: %D.elem = field_decl b, element1 [template]
|
||||
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness %struct_type.a.b.1 [template = constants.%complete_type.3]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .Self = constants.%D
|
||||
// CHECK:STDOUT: .a = %.loc5
|
||||
// CHECK:STDOUT: .b = %.loc6
|
||||
// CHECK:STDOUT: complete_type_witness = %complete_type
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: generic class @E(%F.loc9_9.1: %D) {
|
||||
// CHECK:STDOUT: %F.loc9_9.2: %D = bind_symbolic_name F, 0 [symbolic = %F.loc9_9.2 (constants.%F)]
|
||||
// CHECK:STDOUT: %F.patt.loc9_9.2: %D = symbolic_binding_pattern F, 0 [symbolic = %F.patt.loc9_9.2 (constants.%F.patt)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: class {
|
||||
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness %empty_struct_type [template = constants.%complete_type.4]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .Self = constants.%E
|
||||
// CHECK:STDOUT: complete_type_witness = %complete_type
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @__global_init() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %.loc24_31: %empty_struct_type = struct_literal ()
|
||||
// CHECK:STDOUT: %E.ref: %E.type = name_ref E, file.%E.decl [template = constants.%E.generic]
|
||||
// CHECK:STDOUT: %int_3: Core.IntLiteral = int_value 3 [template = constants.%int_3.1]
|
||||
// CHECK:STDOUT: %int_4: Core.IntLiteral = int_value 4 [template = constants.%int_4.1]
|
||||
// CHECK:STDOUT: %.loc24_53.1: %struct_type.a.b.2 = struct_literal (%int_3, %int_4)
|
||||
// CHECK:STDOUT: %D.ref: type = name_ref D, file.%D.decl [template = constants.%D]
|
||||
// CHECK:STDOUT: %impl.elem0.loc24_53.1: %Convert.type.2 = interface_witness_access constants.%interface.5, element0 [template = constants.%Convert.10]
|
||||
// CHECK:STDOUT: %Convert.bound.loc24_53.1: <bound method> = bound_method %int_3, %impl.elem0.loc24_53.1 [template = constants.%Convert.bound.3]
|
||||
// CHECK:STDOUT: %Convert.specific_fn.loc24_53.1: <specific function> = specific_function %Convert.bound.loc24_53.1, @Convert.2(constants.%int_32) [template = constants.%Convert.specific_fn.3]
|
||||
// CHECK:STDOUT: %int.convert_checked.loc24_53.1: init %i32 = call %Convert.specific_fn.loc24_53.1(%int_3) [template = constants.%int_3.2]
|
||||
// CHECK:STDOUT: %.loc24_53.2: init %i32 = converted %int_3, %int.convert_checked.loc24_53.1 [template = constants.%int_3.2]
|
||||
// CHECK:STDOUT: %.loc24_53.3: ref %D = temporary_storage
|
||||
// CHECK:STDOUT: %.loc24_53.4: ref %i32 = class_element_access %.loc24_53.3, element0
|
||||
// CHECK:STDOUT: %.loc24_53.5: init %i32 = initialize_from %.loc24_53.2 to %.loc24_53.4 [template = constants.%int_3.2]
|
||||
// CHECK:STDOUT: %impl.elem0.loc24_53.2: %Convert.type.2 = interface_witness_access constants.%interface.5, element0 [template = constants.%Convert.10]
|
||||
// CHECK:STDOUT: %Convert.bound.loc24_53.2: <bound method> = bound_method %int_4, %impl.elem0.loc24_53.2 [template = constants.%Convert.bound.4]
|
||||
// CHECK:STDOUT: %Convert.specific_fn.loc24_53.2: <specific function> = specific_function %Convert.bound.loc24_53.2, @Convert.2(constants.%int_32) [template = constants.%Convert.specific_fn.4]
|
||||
// CHECK:STDOUT: %int.convert_checked.loc24_53.2: init %i32 = call %Convert.specific_fn.loc24_53.2(%int_4) [template = constants.%int_4.2]
|
||||
// CHECK:STDOUT: %.loc24_53.6: init %i32 = converted %int_4, %int.convert_checked.loc24_53.2 [template = constants.%int_4.2]
|
||||
// CHECK:STDOUT: %.loc24_53.7: ref %i32 = class_element_access %.loc24_53.3, element1
|
||||
// CHECK:STDOUT: %.loc24_53.8: init %i32 = initialize_from %.loc24_53.6 to %.loc24_53.7 [template = constants.%int_4.2]
|
||||
// CHECK:STDOUT: %.loc24_53.9: init %D = class_init (%.loc24_53.5, %.loc24_53.8), %.loc24_53.3 [template = constants.%D.val.2]
|
||||
// CHECK:STDOUT: %.loc24_53.10: ref %D = temporary %.loc24_53.3, %.loc24_53.9
|
||||
// CHECK:STDOUT: %.loc24_55.1: ref %D = converted %.loc24_53.1, %.loc24_53.10
|
||||
// CHECK:STDOUT: %.loc24_55.2: %D = bind_value %.loc24_55.1
|
||||
// CHECK:STDOUT: assign file.%g.var, <error>
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @E(constants.%F) {
|
||||
// CHECK:STDOUT: %F.loc9_9.2 => constants.%F
|
||||
// CHECK:STDOUT: %F.patt.loc9_9.2 => constants.%F
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
|
||||
+2
-2
@@ -43,10 +43,10 @@ var c_bad: C({.c = 1, .d = 2}) = F();
|
||||
// --- fail_bad_value.impl.carbon
|
||||
|
||||
impl package Implicit;
|
||||
// CHECK:STDERR: fail_bad_value.impl.carbon:[[@LINE+6]]:1: error: cannot implicitly convert from `C(<cannot stringify inst561 kind StructValue>)` to `C(<cannot stringify inst549 kind StructValue>)` [ImplicitAsConversionFailure]
|
||||
// CHECK:STDERR: fail_bad_value.impl.carbon:[[@LINE+6]]:1: error: cannot implicitly convert from `C({.a = 1, .b = 2})` to `C({.a = 3, .b = 4})` [ImplicitAsConversionFailure]
|
||||
// CHECK:STDERR: var c_bad: C({.a = 3, .b = 4}) = F();
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// CHECK:STDERR: fail_bad_value.impl.carbon:[[@LINE+3]]:1: note: type `C(<cannot stringify inst561 kind StructValue>)` does not implement interface `Core.ImplicitAs(C(<cannot stringify inst549 kind StructValue>))` [MissingImplInMemberAccessNote]
|
||||
// CHECK:STDERR: fail_bad_value.impl.carbon:[[@LINE+3]]:1: note: type `C({.a = 1, .b = 2})` does not implement interface `Core.ImplicitAs(C({.a = 3, .b = 4}))` [MissingImplInMemberAccessNote]
|
||||
// CHECK:STDERR: var c_bad: C({.a = 3, .b = 4}) = F();
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
var c_bad: C({.a = 3, .b = 4}) = F();
|
||||
|
||||
@@ -441,6 +441,33 @@ auto StringifyTypeExpr(const SemIR::File& sem_ir, InstId outer_inst_id)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CARBON_KIND(StructValue inst): {
|
||||
auto field_values = sem_ir.inst_blocks().Get(inst.elements_id);
|
||||
if (field_values.empty()) {
|
||||
out << "{}";
|
||||
break;
|
||||
}
|
||||
auto struct_type = sem_ir.types().GetAs<StructType>(
|
||||
sem_ir.types().GetObjectRepr(inst.type_id));
|
||||
auto fields = sem_ir.struct_type_fields().Get(struct_type.fields_id);
|
||||
if (fields.size() != field_values.size()) {
|
||||
out << "{<struct value type length mismatch>}";
|
||||
break;
|
||||
}
|
||||
out << "{";
|
||||
step_stack.PushString("}");
|
||||
for (auto index : llvm::reverse(llvm::seq(fields.size()))) {
|
||||
SemIR::InstId value_inst_id = field_values[index];
|
||||
step_stack.PushInstId(value_inst_id);
|
||||
step_stack.PushString(" = ");
|
||||
step_stack.PushNameId(fields[index].name_id);
|
||||
step_stack.PushString(".");
|
||||
if (index > 0) {
|
||||
step_stack.PushString(", ");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CARBON_KIND(TupleType inst): {
|
||||
auto refs = sem_ir.type_blocks().Get(inst.elements_id);
|
||||
if (refs.empty()) {
|
||||
@@ -544,7 +571,6 @@ auto StringifyTypeExpr(const SemIR::File& sem_ir, InstId outer_inst_id)
|
||||
case StructAccess::Kind:
|
||||
case StructInit::Kind:
|
||||
case StructLiteral::Kind:
|
||||
case StructValue::Kind:
|
||||
case SymbolicBindingPattern::Kind:
|
||||
case Temporary::Kind:
|
||||
case TemporaryStorage::Kind:
|
||||
|
||||
Reference in New Issue
Block a user