diff --git a/toolchain/check/convert.cpp b/toolchain/check/convert.cpp index 8f3eb5e40835..b07ebdc5423c 100644 --- a/toolchain/check/convert.cpp +++ b/toolchain/check/convert.cpp @@ -696,6 +696,8 @@ static auto IsValidExprCategoryForConversionTarget( category == SemIR::ExprCategory::DurableRef || category == SemIR::ExprCategory::EphemeralRef || category == SemIR::ExprCategory::Initializing; + case ConversionTarget::DurableRef: + return category == SemIR::ExprCategory::DurableRef; case ConversionTarget::ExplicitAs: return true; case ConversionTarget::Initializer: @@ -1340,12 +1342,19 @@ auto Convert(Context& context, SemIR::LocId loc_id, SemIR::InstId expr_id, // Commit to using a temporary for this initializing expression. // TODO: Don't create a temporary if the initializing representation // is already a value representation. + // TODO: If the target is DurableRef, materialize a VarStorage instead of + // a TemporaryStorage to lifetime-extend. expr_id = FinalizeTemporary(context, expr_id, target.kind == ConversionTarget::Discarded); // We now have an ephemeral reference. [[fallthrough]]; case SemIR::ExprCategory::DurableRef: + if (target.kind == ConversionTarget::DurableRef) { + break; + } + [[fallthrough]]; + case SemIR::ExprCategory::EphemeralRef: // If a reference expression is an acceptable result, we're done. if (target.kind == ConversionTarget::ValueOrRef || @@ -1362,6 +1371,18 @@ auto Convert(Context& context, SemIR::LocId loc_id, SemIR::InstId expr_id, [[fallthrough]]; case SemIR::ExprCategory::Value: + if (target.kind == ConversionTarget::DurableRef) { + if (target.diagnose) { + CARBON_DIAGNOSTIC(ConversionFailureNonRefToRef, Error, + "cannot bind durable reference to non-reference " + "value of type {0}", + SemIR::TypeId); + context.emitter().Emit(loc_id, ConversionFailureNonRefToRef, + target.type_id); + } + return SemIR::ErrorInst::InstId; + } + // When initializing from a value, perform a copy. if (target.is_initializer()) { expr_id = PerformCopy(context, expr_id, target.diagnose); diff --git a/toolchain/check/convert.h b/toolchain/check/convert.h index e1d6e37f30be..b0795c4acaa7 100644 --- a/toolchain/check/convert.h +++ b/toolchain/check/convert.h @@ -19,6 +19,8 @@ struct ConversionTarget { Value, // Convert to either a value or a reference of type `type_id`. ValueOrRef, + // Convert to a durable reference of type `type_id`. + DurableRef, // Convert for an explicit `as` cast. This allows any expression category // as the result, and uses the `As` interface instead of the `ImplicitAs` // interface. diff --git a/toolchain/check/pattern_match.cpp b/toolchain/check/pattern_match.cpp index 1810dda35c2c..136e98e8462a 100644 --- a/toolchain/check/pattern_match.cpp +++ b/toolchain/check/pattern_match.cpp @@ -48,10 +48,13 @@ class MatchContext { SemIR::InstId pattern_id; // `None` when processing the callee side. SemIR::InstId scrutinee_id; + // Whether we are in a context where plain bindings are reference bindings. + // This happens in var patterns. + bool ref_binding_context; auto Print(llvm::raw_ostream& out) const -> void { out << "{pattern_id: " << pattern_id << ", scrutinee_id: " << scrutinee_id - << "}"; + << ", ref_binding_context: " << ref_binding_context << "}"; } }; @@ -224,10 +227,18 @@ auto MatchContext::DoEmitPatternMatch(Context& context, InsertHere(context, type_expr_region_id); auto value_id = SemIR::InstId::None; if (kind_ == MatchKind::Local) { + auto conversion_kind = entry.ref_binding_context + ? ConversionTarget::DurableRef + : ConversionTarget::Value; + if (!bind_name_id.has_value()) { + // TODO: Is this appropriate, or should we perform a conversion based on + // whether the `_` binding is a value or ref binding first, and then + // separately discard the initializer for a `_` binding? + conversion_kind = ConversionTarget::Discarded; + } value_id = Convert(context, SemIR::LocId(entry.scrutinee_id), entry.scrutinee_id, - {.kind = bind_name_id.has_value() ? ConversionTarget::ValueOrRef - : ConversionTarget::Discarded, + {.kind = conversion_kind, .type_id = context.insts().Get(bind_name_id).type_id()}); } else { // In a function call, conversion is handled while matching the enclosing @@ -253,7 +264,8 @@ auto MatchContext::DoEmitPatternMatch(Context& context, // the caller side of the pattern, so we traverse without emitting any // insts. AddWork({.pattern_id = addr_pattern.inner_id, - .scrutinee_id = SemIR::InstId::None}); + .scrutinee_id = SemIR::InstId::None, + .ref_binding_context = false}); return; } CARBON_CHECK(entry.scrutinee_id.has_value()); @@ -279,13 +291,16 @@ auto MatchContext::DoEmitPatternMatch(Context& context, context, SemIR::LocId(scrutinee_ref_id), {.type_id = GetPointerType(context, scrutinee_ref_type_inst_id), .lvalue_id = scrutinee_ref_id}); - AddWork({.pattern_id = addr_pattern.inner_id, .scrutinee_id = new_scrutinee}); + AddWork({.pattern_id = addr_pattern.inner_id, + .scrutinee_id = new_scrutinee, + .ref_binding_context = false}); } auto MatchContext::DoEmitPatternMatch(Context& context, SemIR::ValueParamPattern param_pattern, SemIR::InstId pattern_inst_id, WorkItem entry) -> void { + CARBON_CHECK(!entry.ref_binding_context); switch (kind_) { case MatchKind::Caller: { CARBON_CHECK( @@ -320,7 +335,8 @@ auto MatchContext::DoEmitPatternMatch(Context& context, .pretty_name_id = SemIR::GetPrettyNameFromPatternId( context.sem_ir(), entry.pattern_id)}); AddWork({.pattern_id = param_pattern.subpattern_id, - .scrutinee_id = param_id}); + .scrutinee_id = param_id, + .ref_binding_context = entry.ref_binding_context}); results_.push_back(param_id); break; } @@ -334,6 +350,7 @@ auto MatchContext::DoEmitPatternMatch(Context& context, SemIR::RefParamPattern param_pattern, SemIR::InstId pattern_inst_id, WorkItem entry) -> void { + CARBON_CHECK(entry.ref_binding_context); switch (kind_) { case MatchKind::Caller: { CARBON_CHECK( @@ -362,7 +379,8 @@ auto MatchContext::DoEmitPatternMatch(Context& context, .pretty_name_id = SemIR::GetPrettyNameFromPatternId( context.sem_ir(), entry.pattern_id)}); AddWork({.pattern_id = param_pattern.subpattern_id, - .scrutinee_id = param_id}); + .scrutinee_id = param_id, + .ref_binding_context = entry.ref_binding_context}); results_.push_back(param_id); break; } @@ -376,6 +394,7 @@ auto MatchContext::DoEmitPatternMatch(Context& context, SemIR::OutParamPattern param_pattern, SemIR::InstId pattern_inst_id, WorkItem entry) -> void { + CARBON_CHECK(!entry.ref_binding_context); switch (kind_) { case MatchKind::Caller: { CARBON_CHECK( @@ -408,7 +427,8 @@ auto MatchContext::DoEmitPatternMatch(Context& context, .pretty_name_id = SemIR::GetPrettyNameFromPatternId( context.sem_ir(), entry.pattern_id)}); AddWork({.pattern_id = param_pattern.subpattern_id, - .scrutinee_id = param_id}); + .scrutinee_id = param_id, + .ref_binding_context = entry.ref_binding_context}); results_.push_back(param_id); break; } @@ -447,7 +467,8 @@ auto MatchContext::DoEmitPatternMatch(Context& context, // the caller side of the pattern, so we traverse without emitting any // insts. AddWork({.pattern_id = var_pattern.subpattern_id, - .scrutinee_id = SemIR::InstId::None}); + .scrutinee_id = SemIR::InstId::None, + .ref_binding_context = true}); return; } case MatchKind::Local: { @@ -481,8 +502,9 @@ auto MatchContext::DoEmitPatternMatch(Context& context, AddInst(context, SemIR::LocId(pattern_inst_id), {.lhs_id = storage_id, .rhs_id = init_id}); } - AddWork( - {.pattern_id = var_pattern.subpattern_id, .scrutinee_id = storage_id}); + AddWork({.pattern_id = var_pattern.subpattern_id, + .scrutinee_id = storage_id, + .ref_binding_context = true}); if (context.scope_stack().PeekIndex() == ScopeIndex::Package) { context.global_init().Suspend(); } @@ -500,8 +522,9 @@ auto MatchContext::DoEmitPatternMatch(Context& context, [&](llvm::ArrayRef subscrutinee_ids) { for (auto [subpattern_id, subscrutinee_id] : llvm::reverse(llvm::zip(subpattern_ids, subscrutinee_ids))) { - AddWork( - {.pattern_id = subpattern_id, .scrutinee_id = subscrutinee_id}); + AddWork({.pattern_id = subpattern_id, + .scrutinee_id = subscrutinee_id, + .ref_binding_context = entry.ref_binding_context}); } }; if (!entry.scrutinee_id.has_value()) { @@ -627,22 +650,25 @@ auto CalleePatternMatch(Context& context, // in the original order. if (return_slot_pattern_id.has_value()) { match.AddWork({.pattern_id = return_slot_pattern_id, - .scrutinee_id = SemIR::InstId::None}); + .scrutinee_id = SemIR::InstId::None, + .ref_binding_context = false}); } if (param_patterns_id.has_value()) { for (SemIR::InstId inst_id : llvm::reverse(context.inst_blocks().Get(param_patterns_id))) { - match.AddWork( - {.pattern_id = inst_id, .scrutinee_id = SemIR::InstId::None}); + match.AddWork({.pattern_id = inst_id, + .scrutinee_id = SemIR::InstId::None, + .ref_binding_context = false}); } } if (implicit_param_patterns_id.has_value()) { for (SemIR::InstId inst_id : llvm::reverse(context.inst_blocks().Get(implicit_param_patterns_id))) { - match.AddWork( - {.pattern_id = inst_id, .scrutinee_id = SemIR::InstId::None}); + match.AddWork({.pattern_id = inst_id, + .scrutinee_id = SemIR::InstId::None, + .ref_binding_context = false}); } } @@ -663,17 +689,22 @@ auto CallerPatternMatch(Context& context, SemIR::SpecificId specific_id, if (return_slot_arg_id.has_value()) { CARBON_CHECK(return_slot_pattern_id.has_value()); match.AddWork({.pattern_id = return_slot_pattern_id, - .scrutinee_id = return_slot_arg_id}); + .scrutinee_id = return_slot_arg_id, + .ref_binding_context = false}); } // Check type conversions per-element. for (auto [arg_id, param_pattern_id] : llvm::reverse(llvm::zip_equal( arg_refs, context.inst_blocks().GetOrEmpty(param_patterns_id)))) { - match.AddWork({.pattern_id = param_pattern_id, .scrutinee_id = arg_id}); + match.AddWork({.pattern_id = param_pattern_id, + .scrutinee_id = arg_id, + .ref_binding_context = false}); } if (self_pattern_id.has_value()) { - match.AddWork({.pattern_id = self_pattern_id, .scrutinee_id = self_arg_id}); + match.AddWork({.pattern_id = self_pattern_id, + .scrutinee_id = self_arg_id, + .ref_binding_context = false}); } return match.DoWork(context); @@ -682,7 +713,9 @@ auto CallerPatternMatch(Context& context, SemIR::SpecificId specific_id, auto LocalPatternMatch(Context& context, SemIR::InstId pattern_id, SemIR::InstId scrutinee_id) -> void { MatchContext match(MatchKind::Local); - match.AddWork({.pattern_id = pattern_id, .scrutinee_id = scrutinee_id}); + match.AddWork({.pattern_id = pattern_id, + .scrutinee_id = scrutinee_id, + .ref_binding_context = false}); match.DoWork(context); } diff --git a/toolchain/check/testdata/alias/basics.carbon b/toolchain/check/testdata/alias/basics.carbon index 8ebdfa4169bc..b2f86de316e6 100644 --- a/toolchain/check/testdata/alias/basics.carbon +++ b/toolchain/check/testdata/alias/basics.carbon @@ -187,7 +187,8 @@ extern alias C = Class; // CHECK:STDOUT: %.loc10_13.2: init %C = class_init (), %.loc10_13.1 [concrete = constants.%C.val] // CHECK:STDOUT: %.loc10_13.3: ref %C = temporary %.loc10_13.1, %.loc10_13.2 // CHECK:STDOUT: %.loc10_13.4: ref %C = converted @__global_init.%.loc10, %.loc10_13.3 -// CHECK:STDOUT: %d: ref %C = bind_name d, %.loc10_13.4 +// CHECK:STDOUT: %.loc10_13.5: %C = bind_value %.loc10_13.4 +// CHECK:STDOUT: %d: %C = bind_name d, %.loc10_13.5 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: fn @__global_init() { diff --git a/toolchain/check/testdata/as/adapter_conversion.carbon b/toolchain/check/testdata/as/adapter_conversion.carbon index 71afabf8110f..f17367fa1be1 100644 --- a/toolchain/check/testdata/as/adapter_conversion.carbon +++ b/toolchain/check/testdata/as/adapter_conversion.carbon @@ -182,9 +182,9 @@ var b: B = {.x = ()} as B; // CHECK:STDOUT: %Make: %Make.type = struct_value () [concrete] // CHECK:STDOUT: %B: type = class_type @B [concrete] // CHECK:STDOUT: %pattern_type.049: type = pattern_type %B [concrete] -// CHECK:STDOUT: %a_ref.var: ref %B = var file.%a_ref.var_patt [concrete] // CHECK:STDOUT: %ptr.e79: type = ptr_type %B [concrete] // CHECK:STDOUT: %pattern_type.960: type = pattern_type %ptr.e79 [concrete] +// CHECK:STDOUT: %a_ref.var: ref %B = var file.%a_ref.var_patt [concrete] // CHECK:STDOUT: %addr: %ptr.e79 = addr_of %a_ref.var [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -196,7 +196,7 @@ var b: B = {.x = ()} as B; // CHECK:STDOUT: %b_val.patt: %pattern_type.049 = binding_pattern b_val [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: %B.ref.loc22: type = name_ref B, %B.decl [concrete = constants.%B] -// CHECK:STDOUT: %b_val: ref %B = bind_name b_val, @__global_init.%.loc22_22.2 [concrete = constants.%a_ref.var] +// CHECK:STDOUT: %b_val: %B = bind_name b_val, @__global_init.%.loc22_22.2 // CHECK:STDOUT: name_binding_decl { // CHECK:STDOUT: %b_ptr.patt: %pattern_type.960 = binding_pattern b_ptr [concrete] // CHECK:STDOUT: } @@ -217,10 +217,10 @@ var b: B = {.x = ()} as B; // CHECK:STDOUT: fn @__global_init() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: -// CHECK:STDOUT: %a_val.ref: ref %A = name_ref a_val, file.%a_val [concrete = file.%a_ref.var] +// CHECK:STDOUT: %a_val.ref: %A = name_ref a_val, file.%a_val // CHECK:STDOUT: %B.ref.loc22: type = name_ref B, file.%B.decl [concrete = constants.%B] -// CHECK:STDOUT: %.loc22_22.1: ref %B = as_compatible %a_val.ref [concrete = constants.%a_ref.var] -// CHECK:STDOUT: %.loc22_22.2: ref %B = converted %a_val.ref, %.loc22_22.1 [concrete = constants.%a_ref.var] +// CHECK:STDOUT: %.loc22_22.1: %B = as_compatible %a_val.ref +// CHECK:STDOUT: %.loc22_22.2: %B = converted %a_val.ref, %.loc22_22.1 // CHECK:STDOUT: %a_ref.ref.loc23: ref %A = name_ref a_ref, file.%a_ref [concrete = file.%a_ref.var] // CHECK:STDOUT: %B.ref.loc23: type = name_ref B, file.%B.decl [concrete = constants.%B] // CHECK:STDOUT: %.loc23_25.1: ref %B = as_compatible %a_ref.ref.loc23 [concrete = constants.%a_ref.var] @@ -379,7 +379,8 @@ var b: B = {.x = ()} as B; // CHECK:STDOUT: %b_value.patt: %pattern_type.049 = binding_pattern b_value [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: %B.ref: type = name_ref B, %B.decl [concrete = constants.%B] -// CHECK:STDOUT: %b_value: ref %B = bind_name b_value, @__global_init.%.loc14_42.2 +// CHECK:STDOUT: %.loc14: %B = bind_value @__global_init.%.loc14_42.2 +// CHECK:STDOUT: %b_value: %B = bind_name b_value, %.loc14 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: fn @__global_init() { diff --git a/toolchain/check/testdata/as/basics.carbon b/toolchain/check/testdata/as/basics.carbon index d06261032f71..c2d7ba3fca30 100644 --- a/toolchain/check/testdata/as/basics.carbon +++ b/toolchain/check/testdata/as/basics.carbon @@ -362,8 +362,9 @@ let n: {.x: ()} = {.x = ()} as {.x = ()}; // CHECK:STDOUT: %n.patt: %pattern_type.c27 = binding_pattern n [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: %Y.ref: type = name_ref Y, %Y.decl [concrete = constants.%Y] -// CHECK:STDOUT: %.loc19: ref %Y = temporary @__global_init.%.loc19_29.1, @__global_init.%.loc19_29.2 -// CHECK:STDOUT: %n: ref %Y = bind_name n, %.loc19 +// CHECK:STDOUT: %.loc19_29.1: ref %Y = temporary @__global_init.%.loc19_29.1, @__global_init.%.loc19_29.2 +// CHECK:STDOUT: %.loc19_29.2: %Y = bind_value %.loc19_29.1 +// CHECK:STDOUT: %n: %Y = bind_name n, %.loc19_29.2 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: fn @__global_init() { diff --git a/toolchain/check/testdata/builtins/int/convert_checked.carbon b/toolchain/check/testdata/builtins/int/convert_checked.carbon index 57da663fcbdf..2896c9e0fea4 100644 --- a/toolchain/check/testdata/builtins/int/convert_checked.carbon +++ b/toolchain/check/testdata/builtins/int/convert_checked.carbon @@ -315,9 +315,9 @@ let convert_not_constant_widen: i64 = Int32ToInt64(not_constant); // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %u32: type = class_type @UInt, @UInt(constants.%int_32) [concrete = constants.%u32] // CHECK:STDOUT: } -// CHECK:STDOUT: %.loc6_42.1: ref %u32 = temporary_storage -// CHECK:STDOUT: %.loc6_42.2: ref %u32 = temporary %.loc6_42.1, @__global_init.%int.convert_checked.loc6_42 -// CHECK:STDOUT: %SizePreserving: ref %u32 = bind_name SizePreserving, %.loc6_42.2 +// CHECK:STDOUT: %.loc6_42.1: %u32 = value_of_initializer @__global_init.%int.convert_checked.loc6_42 [concrete = constants.%int_1.c1d] +// CHECK:STDOUT: %.loc6_42.2: %u32 = converted @__global_init.%int.convert_checked.loc6_42, %.loc6_42.1 [concrete = constants.%int_1.c1d] +// CHECK:STDOUT: %SizePreserving: %u32 = bind_name SizePreserving, %.loc6_42.2 // CHECK:STDOUT: name_binding_decl { // CHECK:STDOUT: %Narrowing.patt: %pattern_type.88f = binding_pattern Narrowing [concrete] // CHECK:STDOUT: } @@ -325,9 +325,9 @@ let convert_not_constant_widen: i64 = Int32ToInt64(not_constant); // CHECK:STDOUT: %int_16: Core.IntLiteral = int_value 16 [concrete = constants.%int_16] // CHECK:STDOUT: %i16: type = class_type @Int, @Int(constants.%int_16) [concrete = constants.%i16] // CHECK:STDOUT: } -// CHECK:STDOUT: %.loc7_36.1: ref %i16 = temporary_storage -// CHECK:STDOUT: %.loc7_36.2: ref %i16 = temporary %.loc7_36.1, @__global_init.%int.convert_checked.loc7_36 -// CHECK:STDOUT: %Narrowing: ref %i16 = bind_name Narrowing, %.loc7_36.2 +// CHECK:STDOUT: %.loc7_36.1: %i16 = value_of_initializer @__global_init.%int.convert_checked.loc7_36 [concrete = constants.%int_1.c22] +// CHECK:STDOUT: %.loc7_36.2: %i16 = converted @__global_init.%int.convert_checked.loc7_36, %.loc7_36.1 [concrete = constants.%int_1.c22] +// CHECK:STDOUT: %Narrowing: %i16 = bind_name Narrowing, %.loc7_36.2 // CHECK:STDOUT: name_binding_decl { // CHECK:STDOUT: %Widening.patt: %pattern_type.a10 = binding_pattern Widening [concrete] // CHECK:STDOUT: } @@ -335,9 +335,9 @@ let convert_not_constant_widen: i64 = Int32ToInt64(not_constant); // CHECK:STDOUT: %int_64: Core.IntLiteral = int_value 64 [concrete = constants.%int_64] // CHECK:STDOUT: %i64: type = class_type @Int, @Int(constants.%int_64) [concrete = constants.%i64] // CHECK:STDOUT: } -// CHECK:STDOUT: %.loc8_35.1: ref %i64 = temporary_storage -// CHECK:STDOUT: %.loc8_35.2: ref %i64 = temporary %.loc8_35.1, @__global_init.%int.convert_checked.loc8_35 -// CHECK:STDOUT: %Widening: ref %i64 = bind_name Widening, %.loc8_35.2 +// CHECK:STDOUT: %.loc8_35.1: %i64 = value_of_initializer @__global_init.%int.convert_checked.loc8_35 [concrete = constants.%int_1.a95] +// CHECK:STDOUT: %.loc8_35.2: %i64 = converted @__global_init.%int.convert_checked.loc8_35, %.loc8_35.1 [concrete = constants.%int_1.a95] +// CHECK:STDOUT: %Widening: %i64 = bind_name Widening, %.loc8_35.2 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: fn @__global_init() { diff --git a/toolchain/check/testdata/builtins/read/char.carbon b/toolchain/check/testdata/builtins/read/char.carbon index 7b691a0fe02b..c13ead7d4c93 100644 --- a/toolchain/check/testdata/builtins/read/char.carbon +++ b/toolchain/check/testdata/builtins/read/char.carbon @@ -58,9 +58,9 @@ fn Main() { // CHECK:STDOUT: %int_32.loc8: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc8: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: } -// CHECK:STDOUT: %.loc8_25.1: ref %i32 = temporary_storage -// CHECK:STDOUT: %.loc8_25.2: ref %i32 = temporary %.loc8_25.1, %read.char.loc8 -// CHECK:STDOUT: %n: ref %i32 = bind_name n, %.loc8_25.2 +// CHECK:STDOUT: %.loc8_25.1: %i32 = value_of_initializer %read.char.loc8 +// CHECK:STDOUT: %.loc8_25.2: %i32 = converted %read.char.loc8, %.loc8_25.1 +// CHECK:STDOUT: %n: %i32 = bind_name n, %.loc8_25.2 // CHECK:STDOUT: name_binding_decl { // CHECK:STDOUT: %m.patt: %pattern_type.7ce = binding_pattern m [concrete] // CHECK:STDOUT: } @@ -71,9 +71,9 @@ fn Main() { // CHECK:STDOUT: %int_32.loc9: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc9: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: } -// CHECK:STDOUT: %.loc9_30.1: ref %i32 = temporary_storage -// CHECK:STDOUT: %.loc9_30.2: ref %i32 = temporary %.loc9_30.1, %read.char.loc9 -// CHECK:STDOUT: %m: ref %i32 = bind_name m, %.loc9_30.2 +// CHECK:STDOUT: %.loc9_30.1: %i32 = value_of_initializer %read.char.loc9 +// CHECK:STDOUT: %.loc9_30.2: %i32 = converted %read.char.loc9, %.loc9_30.1 +// CHECK:STDOUT: %m: %i32 = bind_name m, %.loc9_30.2 // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/access_modifers.carbon b/toolchain/check/testdata/class/access_modifers.carbon index efe7e1dea60b..cde047b5e05f 100644 --- a/toolchain/check/testdata/class/access_modifers.carbon +++ b/toolchain/check/testdata/class/access_modifers.carbon @@ -307,24 +307,25 @@ class A { // CHECK:STDOUT: %Make.call: init %Circle = call %Make.ref() to %.loc18_36.1 // CHECK:STDOUT: %Circle.ref.loc18_15: type = name_ref Circle, file.%Circle.decl [concrete = constants.%Circle] // CHECK:STDOUT: %.loc18_36.2: ref %Circle = temporary %.loc18_36.1, %Make.call -// CHECK:STDOUT: %circle: ref %Circle = bind_name circle, %.loc18_36.2 +// CHECK:STDOUT: %.loc18_36.3: %Circle = bind_value %.loc18_36.2 +// CHECK:STDOUT: %circle: %Circle = bind_name circle, %.loc18_36.3 // CHECK:STDOUT: name_binding_decl { // CHECK:STDOUT: %radius.patt: %pattern_type.7ce = binding_pattern radius [concrete] // CHECK:STDOUT: } -// CHECK:STDOUT: %circle.ref.loc26: ref %Circle = name_ref circle, %circle +// CHECK:STDOUT: %circle.ref.loc26: %Circle = name_ref circle, %circle // CHECK:STDOUT: %radius.ref.loc26: = name_ref radius, [concrete = ] // CHECK:STDOUT: %.loc26: type = splice_block %i32 [concrete = constants.%i32] { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: } // CHECK:STDOUT: %radius: %i32 = bind_name radius, [concrete = ] -// CHECK:STDOUT: %circle.ref.loc34: ref %Circle = name_ref circle, %circle +// CHECK:STDOUT: %circle.ref.loc34: %Circle = name_ref circle, %circle // CHECK:STDOUT: %radius.ref.loc34: = name_ref radius, [concrete = ] // CHECK:STDOUT: %int_5: Core.IntLiteral = int_value 5 [concrete = constants.%int_5.64b] // CHECK:STDOUT: assign %radius.ref.loc34, -// CHECK:STDOUT: %circle.ref.loc42: ref %Circle = name_ref circle, %circle +// CHECK:STDOUT: %circle.ref.loc42: %Circle = name_ref circle, %circle // CHECK:STDOUT: %SOME_INTERNAL_CONSTANT.ref: = name_ref SOME_INTERNAL_CONSTANT, [concrete = ] -// CHECK:STDOUT: %circle.ref.loc51: ref %Circle = name_ref circle, %circle +// CHECK:STDOUT: %circle.ref.loc51: %Circle = name_ref circle, %circle // CHECK:STDOUT: %SomeInternalFunction.ref: = name_ref SomeInternalFunction, [concrete = ] // CHECK:STDOUT: return // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/class/adapter/init_adapt.carbon b/toolchain/check/testdata/class/adapter/init_adapt.carbon index c119145df540..23618d049f9d 100644 --- a/toolchain/check/testdata/class/adapter/init_adapt.carbon +++ b/toolchain/check/testdata/class/adapter/init_adapt.carbon @@ -191,17 +191,18 @@ var e: C = MakeAdaptC(); // CHECK:STDOUT: %.loc13_27.8: init %C = class_init (%.loc13_27.4, %.loc13_27.7), %.loc13_27.2 [concrete = constants.%C.val] // CHECK:STDOUT: %.loc13_27.9: ref %C = temporary %.loc13_27.2, %.loc13_27.8 // CHECK:STDOUT: %.loc13_27.10: ref %C = converted @__global_init.%.loc13, %.loc13_27.9 -// CHECK:STDOUT: %a: ref %C = bind_name a, %.loc13_27.10 +// CHECK:STDOUT: %.loc13_27.11: %C = bind_value %.loc13_27.10 +// CHECK:STDOUT: %a: %C = bind_name a, %.loc13_27.11 // CHECK:STDOUT: name_binding_decl { // CHECK:STDOUT: %b.patt: %pattern_type.a1a = binding_pattern b [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: %AdaptC.ref.loc15: type = name_ref AdaptC, %AdaptC.decl [concrete = constants.%AdaptC] -// CHECK:STDOUT: %b: ref %AdaptC = bind_name b, @__global_init.%.loc15_19.2 +// CHECK:STDOUT: %b: %AdaptC = bind_name b, @__global_init.%.loc15_19.2 // CHECK:STDOUT: name_binding_decl { // CHECK:STDOUT: %c.patt: %pattern_type.c48 = binding_pattern c [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: %C.ref.loc17: type = name_ref C, %C.decl [concrete = constants.%C] -// CHECK:STDOUT: %c: ref %C = bind_name c, @__global_init.%.loc17_14.2 +// CHECK:STDOUT: %c: %C = bind_name c, @__global_init.%.loc17_14.2 // CHECK:STDOUT: %MakeC.decl: %MakeC.type = fn_decl @MakeC [concrete = constants.%MakeC] { // CHECK:STDOUT: %return.patt: %pattern_type.c48 = return_slot_pattern [concrete] // CHECK:STDOUT: %return.param_patt: %pattern_type.c48 = out_param_pattern %return.patt, call_param0 [concrete] @@ -271,14 +272,14 @@ var e: C = MakeAdaptC(); // CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] // CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] // CHECK:STDOUT: %.loc13: %struct_type.a.b.cfd = struct_literal (%int_1, %int_2) -// CHECK:STDOUT: %a.ref: ref %C = name_ref a, file.%a +// CHECK:STDOUT: %a.ref: %C = name_ref a, file.%a // CHECK:STDOUT: %AdaptC.ref.loc15: type = name_ref AdaptC, file.%AdaptC.decl [concrete = constants.%AdaptC] -// CHECK:STDOUT: %.loc15_19.1: ref %AdaptC = as_compatible %a.ref -// CHECK:STDOUT: %.loc15_19.2: ref %AdaptC = converted %a.ref, %.loc15_19.1 -// CHECK:STDOUT: %b.ref: ref %AdaptC = name_ref b, file.%b +// CHECK:STDOUT: %.loc15_19.1: %AdaptC = as_compatible %a.ref +// CHECK:STDOUT: %.loc15_19.2: %AdaptC = converted %a.ref, %.loc15_19.1 +// CHECK:STDOUT: %b.ref: %AdaptC = name_ref b, file.%b // CHECK:STDOUT: %C.ref.loc17: type = name_ref C, file.%C.decl [concrete = constants.%C] -// CHECK:STDOUT: %.loc17_14.1: ref %C = as_compatible %b.ref -// CHECK:STDOUT: %.loc17_14.2: ref %C = converted %b.ref, %.loc17_14.1 +// CHECK:STDOUT: %.loc17_14.1: %C = as_compatible %b.ref +// CHECK:STDOUT: %.loc17_14.2: %C = converted %b.ref, %.loc17_14.1 // CHECK:STDOUT: %MakeC.ref: %MakeC.type = name_ref MakeC, file.%MakeC.decl [concrete = constants.%MakeC] // CHECK:STDOUT: %.loc23_1: ref %AdaptC = splice_block file.%d.var [concrete = file.%d.var] {} // CHECK:STDOUT: %MakeC.call: init %C = call %MakeC.ref() to %.loc23_1 @@ -392,7 +393,8 @@ var e: C = MakeAdaptC(); // CHECK:STDOUT: %.loc13_27.8: init %C = class_init (%.loc13_27.4, %.loc13_27.7), %.loc13_27.2 [concrete = constants.%C.val] // CHECK:STDOUT: %.loc13_27.9: ref %C = temporary %.loc13_27.2, %.loc13_27.8 // CHECK:STDOUT: %.loc13_27.10: ref %C = converted @__global_init.%.loc13, %.loc13_27.9 -// CHECK:STDOUT: %a: ref %C = bind_name a, %.loc13_27.10 +// CHECK:STDOUT: %.loc13_27.11: %C = bind_value %.loc13_27.10 +// CHECK:STDOUT: %a: %C = bind_name a, %.loc13_27.11 // CHECK:STDOUT: name_binding_decl { // CHECK:STDOUT: %b.patt: %pattern_type.a1a = binding_pattern b [concrete] // CHECK:STDOUT: } @@ -474,7 +476,7 @@ var e: C = MakeAdaptC(); // CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] // CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] // CHECK:STDOUT: %.loc13: %struct_type.a.b.cfd = struct_literal (%int_1, %int_2) -// CHECK:STDOUT: %a.ref: ref %C = name_ref a, file.%a +// CHECK:STDOUT: %a.ref: %C = name_ref a, file.%a // CHECK:STDOUT: %b.ref: %AdaptC = name_ref b, file.%b [concrete = ] // CHECK:STDOUT: %MakeC.ref: %MakeC.type = name_ref MakeC, file.%MakeC.decl [concrete = constants.%MakeC] // CHECK:STDOUT: %.loc46_23: ref %C = temporary_storage diff --git a/toolchain/check/testdata/class/derived_to_base.carbon b/toolchain/check/testdata/class/derived_to_base.carbon index 5d87d90b8d8a..3c99dee376f7 100644 --- a/toolchain/check/testdata/class/derived_to_base.carbon +++ b/toolchain/check/testdata/class/derived_to_base.carbon @@ -314,7 +314,8 @@ fn ConvertInit() { // CHECK:STDOUT: %.loc33_14.1: ref %B = class_element_access %c.ref, element0 // CHECK:STDOUT: %.loc33_14.2: ref %A = class_element_access %.loc33_14.1, element0 // CHECK:STDOUT: %.loc33_14.3: ref %A = converted %c.ref, %.loc33_14.2 -// CHECK:STDOUT: %a: ref %A = bind_name a, %.loc33_14.3 +// CHECK:STDOUT: %.loc33_14.4: %A = bind_value %.loc33_14.3 +// CHECK:STDOUT: %a: %A = bind_name a, %.loc33_14.4 // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -380,7 +381,8 @@ fn ConvertInit() { // CHECK:STDOUT: %.loc41_59.2: ref %B = class_element_access %.loc41_59.1, element0 // CHECK:STDOUT: %.loc41_59.3: ref %A = class_element_access %.loc41_59.2, element0 // CHECK:STDOUT: %.loc41_59.4: ref %A = converted %.loc41_59.1, %.loc41_59.3 -// CHECK:STDOUT: %a: ref %A = bind_name a, %.loc41_59.4 +// CHECK:STDOUT: %.loc41_59.5: %A = bind_value %.loc41_59.4 +// CHECK:STDOUT: %a: %A = bind_name a, %.loc41_59.5 // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/field_access_in_value.carbon b/toolchain/check/testdata/class/field_access_in_value.carbon index e09133afecbb..47597bff6519 100644 --- a/toolchain/check/testdata/class/field_access_in_value.carbon +++ b/toolchain/check/testdata/class/field_access_in_value.carbon @@ -140,13 +140,14 @@ fn Test() { // CHECK:STDOUT: } // CHECK:STDOUT: %cv.ref.loc23: ref %Class = name_ref cv, %cv // CHECK:STDOUT: %Class.ref.loc23: type = name_ref Class, file.%Class.decl [concrete = constants.%Class] -// CHECK:STDOUT: %c: ref %Class = bind_name c, %cv.ref.loc23 +// CHECK:STDOUT: %.loc23: %Class = bind_value %cv.ref.loc23 +// CHECK:STDOUT: %c: %Class = bind_name c, %.loc23 // CHECK:STDOUT: name_binding_decl { // CHECK:STDOUT: %cj.patt: %pattern_type.7ce = binding_pattern cj [concrete] // CHECK:STDOUT: %cj.var_patt: %pattern_type.7ce = var_pattern %cj.patt [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: %cj.var: ref %i32 = var %cj.var_patt -// CHECK:STDOUT: %c.ref.loc24: ref %Class = name_ref c, %c +// CHECK:STDOUT: %c.ref.loc24: %Class = name_ref c, %c // CHECK:STDOUT: %j.ref.loc24: %Class.elem = name_ref j, @Class.%.loc15 [concrete = @Class.%.loc15] // CHECK:STDOUT: %.loc24_18.1: ref %i32 = class_element_access %c.ref.loc24, element0 // CHECK:STDOUT: %.loc24_18.2: %i32 = bind_value %.loc24_18.1 @@ -161,7 +162,7 @@ fn Test() { // CHECK:STDOUT: %ck.var_patt: %pattern_type.7ce = var_pattern %ck.patt [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: %ck.var: ref %i32 = var %ck.var_patt -// CHECK:STDOUT: %c.ref.loc25: ref %Class = name_ref c, %c +// CHECK:STDOUT: %c.ref.loc25: %Class = name_ref c, %c // CHECK:STDOUT: %k.ref.loc25: %Class.elem = name_ref k, @Class.%.loc16 [concrete = @Class.%.loc16] // CHECK:STDOUT: %.loc25_18.1: ref %i32 = class_element_access %c.ref.loc25, element1 // CHECK:STDOUT: %.loc25_18.2: %i32 = bind_value %.loc25_18.1 diff --git a/toolchain/check/testdata/class/generic/base_is_generic.carbon b/toolchain/check/testdata/class/generic/base_is_generic.carbon index d6ce3fa20856..5cce919576cd 100644 --- a/toolchain/check/testdata/class/generic/base_is_generic.carbon +++ b/toolchain/check/testdata/class/generic/base_is_generic.carbon @@ -666,9 +666,9 @@ fn H() { // CHECK:STDOUT: %int_32.loc13_10: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc13_10: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: } -// CHECK:STDOUT: %.loc13_25.1: ref %i32 = temporary_storage -// CHECK:STDOUT: %.loc13_25.2: ref %i32 = temporary %.loc13_25.1, %G.call -// CHECK:STDOUT: %i: ref %i32 = bind_name i, %.loc13_25.2 +// CHECK:STDOUT: %.loc13_25.1: %i32 = value_of_initializer %G.call +// CHECK:STDOUT: %.loc13_25.2: %i32 = converted %G.call, %.loc13_25.1 +// CHECK:STDOUT: %i: %i32 = bind_name i, %.loc13_25.2 // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -865,9 +865,9 @@ fn H() { // CHECK:STDOUT: %int_32.loc7_10: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc7_10: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: } -// CHECK:STDOUT: %.loc7_25.1: ref %i32 = temporary_storage -// CHECK:STDOUT: %.loc7_25.2: ref %i32 = temporary %.loc7_25.1, %G.call -// CHECK:STDOUT: %j: ref %i32 = bind_name j, %.loc7_25.2 +// CHECK:STDOUT: %.loc7_25.1: %i32 = value_of_initializer %G.call +// CHECK:STDOUT: %.loc7_25.2: %i32 = converted %G.call, %.loc7_25.1 +// CHECK:STDOUT: %j: %i32 = bind_name j, %.loc7_25.2 // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/nested.carbon b/toolchain/check/testdata/class/nested.carbon index 4f0fac0603fd..647a801617e9 100644 --- a/toolchain/check/testdata/class/nested.carbon +++ b/toolchain/check/testdata/class/nested.carbon @@ -227,13 +227,14 @@ fn F(a: Outer*) { // CHECK:STDOUT: %a.ref.loc45: %ptr.5df = name_ref a, %a // CHECK:STDOUT: %.loc45_26: ref %Outer = deref %a.ref.loc45 // CHECK:STDOUT: %pi.ref.loc45: %Outer.elem.fe9 = name_ref pi, @Outer.%.loc41 [concrete = @Outer.%.loc41] -// CHECK:STDOUT: %.loc45_29: ref %ptr.36a = class_element_access %.loc45_26, element2 +// CHECK:STDOUT: %.loc45_29.1: ref %ptr.36a = class_element_access %.loc45_26, element2 // CHECK:STDOUT: %.loc45_21: type = splice_block %ptr.loc45 [concrete = constants.%ptr.36a] { // CHECK:STDOUT: %Outer.ref.loc45: type = name_ref Outer, file.%Outer.decl [concrete = constants.%Outer] // CHECK:STDOUT: %Inner.ref: type = name_ref Inner, @Outer.%Inner.decl [concrete = constants.%Inner] // CHECK:STDOUT: %ptr.loc45: type = ptr_type %Inner.ref [concrete = constants.%ptr.36a] // CHECK:STDOUT: } -// CHECK:STDOUT: %b: ref %ptr.36a = bind_name b, %.loc45_29 +// CHECK:STDOUT: %.loc45_29.2: %ptr.36a = bind_value %.loc45_29.1 +// CHECK:STDOUT: %b: %ptr.36a = bind_name b, %.loc45_29.2 // CHECK:STDOUT: %a.ref.loc47_3: %ptr.5df = name_ref a, %a // CHECK:STDOUT: %.loc47_4.1: ref %Outer = deref %a.ref.loc47_3 // CHECK:STDOUT: %po.ref.loc47: %Outer.elem.a16 = name_ref po, @Outer.%.loc39 [concrete = @Outer.%.loc39] @@ -256,16 +257,14 @@ fn F(a: Outer*) { // CHECK:STDOUT: %.loc49_12.2: ref %ptr.36a = class_element_access %.loc49_12.1, element2 // CHECK:STDOUT: %.loc49_12.3: %ptr.36a = bind_value %.loc49_12.2 // CHECK:STDOUT: assign %.loc49_4.2, %.loc49_12.3 -// CHECK:STDOUT: %b.ref.loc50: ref %ptr.36a = name_ref b, %b -// CHECK:STDOUT: %.loc50_3: %ptr.36a = bind_value %b.ref.loc50 -// CHECK:STDOUT: %.loc50_4.1: ref %Inner = deref %.loc50_3 +// CHECK:STDOUT: %b.ref.loc50: %ptr.36a = name_ref b, %b +// CHECK:STDOUT: %.loc50_4.1: ref %Inner = deref %b.ref.loc50 // CHECK:STDOUT: %po.ref.loc50: %Inner.elem.c30 = name_ref po, @Inner.%.loc23 [concrete = @Inner.%.loc23] // CHECK:STDOUT: %.loc50_4.2: ref %ptr.5df = class_element_access %.loc50_4.1, element1 // CHECK:STDOUT: %a.ref.loc50: %ptr.5df = name_ref a, %a // CHECK:STDOUT: assign %.loc50_4.2, %a.ref.loc50 -// CHECK:STDOUT: %b.ref.loc51: ref %ptr.36a = name_ref b, %b -// CHECK:STDOUT: %.loc51_3: %ptr.36a = bind_value %b.ref.loc51 -// CHECK:STDOUT: %.loc51_4.1: ref %Inner = deref %.loc51_3 +// CHECK:STDOUT: %b.ref.loc51: %ptr.36a = name_ref b, %b +// CHECK:STDOUT: %.loc51_4.1: ref %Inner = deref %b.ref.loc51 // CHECK:STDOUT: %pi.ref.loc51_4: %Inner.elem.640 = name_ref pi, @Inner.%.loc22 [concrete = @Inner.%.loc22] // CHECK:STDOUT: %.loc51_4.2: ref %ptr.36a = class_element_access %.loc51_4.1, element0 // CHECK:STDOUT: %a.ref.loc51: %ptr.5df = name_ref a, %a @@ -274,9 +273,8 @@ fn F(a: Outer*) { // CHECK:STDOUT: %.loc51_12.2: ref %ptr.36a = class_element_access %.loc51_12.1, element2 // CHECK:STDOUT: %.loc51_12.3: %ptr.36a = bind_value %.loc51_12.2 // CHECK:STDOUT: assign %.loc51_4.2, %.loc51_12.3 -// CHECK:STDOUT: %b.ref.loc52: ref %ptr.36a = name_ref b, %b -// CHECK:STDOUT: %.loc52_3: %ptr.36a = bind_value %b.ref.loc52 -// CHECK:STDOUT: %.loc52_4.1: ref %Inner = deref %.loc52_3 +// CHECK:STDOUT: %b.ref.loc52: %ptr.36a = name_ref b, %b +// CHECK:STDOUT: %.loc52_4.1: ref %Inner = deref %b.ref.loc52 // CHECK:STDOUT: %qi.ref: %Inner.elem.640 = name_ref qi, @Inner.%.loc24 [concrete = @Inner.%.loc24] // CHECK:STDOUT: %.loc52_4.2: ref %ptr.36a = class_element_access %.loc52_4.1, element2 // CHECK:STDOUT: %a.ref.loc52: %ptr.5df = name_ref a, %a diff --git a/toolchain/check/testdata/deduce/value_with_type_through_access.carbon b/toolchain/check/testdata/deduce/value_with_type_through_access.carbon index 1a1a6ef4c01a..f088d2f9d504 100644 --- a/toolchain/check/testdata/deduce/value_with_type_through_access.carbon +++ b/toolchain/check/testdata/deduce/value_with_type_through_access.carbon @@ -611,9 +611,10 @@ fn G() { // CHECK:STDOUT: %.loc26_26.4: init type = initialize_from %C.ref to %.loc26_26.3 [concrete = constants.%C] // CHECK:STDOUT: %.loc26_26.5: init %Class = class_init (%.loc26_26.4), %.loc26_26.2 [concrete = constants.%Class.val] // CHECK:STDOUT: %.loc26_26.6: ref %Class = temporary %.loc26_26.2, %.loc26_26.5 -// CHECK:STDOUT: %.loc26_28: ref %Class = converted %.loc26_26.1, %.loc26_26.6 +// CHECK:STDOUT: %.loc26_28.1: ref %Class = converted %.loc26_26.1, %.loc26_26.6 // CHECK:STDOUT: %Class.ref.loc26_11: type = name_ref Class, file.%Class.decl [concrete = constants.%Class] -// CHECK:STDOUT: %c: %Class = bind_symbolic_name c, 0, %.loc26_28 [symbolic = constants.%c] +// CHECK:STDOUT: %.loc26_28.2: %Class = bind_value %.loc26_28.1 +// CHECK:STDOUT: %c: %Class = bind_symbolic_name c, 0, %.loc26_28.2 [symbolic = constants.%c] // CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [concrete = constants.%F] // CHECK:STDOUT: %.loc27_6.1: %empty_struct_type = struct_literal () // CHECK:STDOUT: %HoldsType.ref: %HoldsType.type = name_ref HoldsType, file.%HoldsType.decl [concrete = constants.%HoldsType.generic] diff --git a/toolchain/check/testdata/facet/convert_facet_value_as_type_knows_original_type.carbon b/toolchain/check/testdata/facet/convert_facet_value_as_type_knows_original_type.carbon index b5fb4313af65..0bd7e5c2c939 100644 --- a/toolchain/check/testdata/facet/convert_facet_value_as_type_knows_original_type.carbon +++ b/toolchain/check/testdata/facet/convert_facet_value_as_type_knows_original_type.carbon @@ -331,7 +331,7 @@ fn F() { // CHECK:STDOUT: %.loc22_28.2: ref %Goat = temporary_storage // CHECK:STDOUT: %.loc22_28.3: init %Goat = class_init (), %.loc22_28.2 [concrete = constants.%Goat.val] // CHECK:STDOUT: %.loc22_28.4: ref %Goat = temporary %.loc22_28.2, %.loc22_28.3 -// CHECK:STDOUT: %.loc22_30: ref %Goat = converted %.loc22_28.1, %.loc22_28.4 +// CHECK:STDOUT: %.loc22_30.1: ref %Goat = converted %.loc22_28.1, %.loc22_28.4 // CHECK:STDOUT: %.loc22_15.1: type = splice_block %.loc22_15.3 [concrete = constants.%Goat] { // CHECK:STDOUT: %Goat.ref.loc22_10: type = name_ref Goat, file.%Goat.decl [concrete = constants.%Goat] // CHECK:STDOUT: %Animal.ref.loc22: type = name_ref Animal, file.%Animal.decl [concrete = constants.%Animal.type] @@ -340,11 +340,12 @@ fn F() { // CHECK:STDOUT: %as_type.loc22: type = facet_access_type %.loc22_15.2 [concrete = constants.%Goat] // CHECK:STDOUT: %.loc22_15.3: type = converted %.loc22_15.2, %as_type.loc22 [concrete = constants.%Goat] // CHECK:STDOUT: } -// CHECK:STDOUT: %x: ref %Goat = bind_name x, %.loc22_30 -// CHECK:STDOUT: %x.ref.loc23: ref %Goat = name_ref x, %x +// CHECK:STDOUT: %.loc22_30.2: %Goat = bind_value %.loc22_30.1 +// CHECK:STDOUT: %x: %Goat = bind_name x, %.loc22_30.2 +// CHECK:STDOUT: %x.ref.loc23: %Goat = name_ref x, %x // CHECK:STDOUT: %Bleet.ref.loc23: %Bleet.type = name_ref Bleet, @Goat.%Bleet.decl [concrete = constants.%Bleet] // CHECK:STDOUT: %Bleet.call.loc23: init %empty_tuple.type = call %Bleet.ref.loc23() -// CHECK:STDOUT: %x.ref.loc24: ref %Goat = name_ref x, %x +// CHECK:STDOUT: %x.ref.loc24: %Goat = name_ref x, %x // CHECK:STDOUT: %Eat.ref.loc24: %Eats.assoc_type = name_ref Eat, @Eats.%assoc0 [concrete = constants.%assoc0] // CHECK:STDOUT: %impl.elem0.loc24: %.f6e = impl_witness_access constants.%Eats.impl_witness, element0 [concrete = constants.%Eat.73e] // CHECK:STDOUT: %Eat.call.loc24: init %empty_tuple.type = call %impl.elem0.loc24() diff --git a/toolchain/check/testdata/facet/fail_deduction_uses_runtime_type_conversion.carbon b/toolchain/check/testdata/facet/fail_deduction_uses_runtime_type_conversion.carbon index 5490009fe47d..b67716187799 100644 --- a/toolchain/check/testdata/facet/fail_deduction_uses_runtime_type_conversion.carbon +++ b/toolchain/check/testdata/facet/fail_deduction_uses_runtime_type_conversion.carbon @@ -255,9 +255,10 @@ fn G(holds_to: HoldsType((RuntimeConvertTo, ))) { // CHECK:STDOUT: %.loc30_36.2: ref %RuntimeConvertFrom = temporary_storage // CHECK:STDOUT: %.loc30_36.3: init %RuntimeConvertFrom = class_init (), %.loc30_36.2 [concrete = constants.%RuntimeConvertFrom.val] // CHECK:STDOUT: %.loc30_36.4: ref %RuntimeConvertFrom = temporary %.loc30_36.2, %.loc30_36.3 -// CHECK:STDOUT: %.loc30_38: ref %RuntimeConvertFrom = converted %.loc30_36.1, %.loc30_36.4 +// CHECK:STDOUT: %.loc30_38.1: ref %RuntimeConvertFrom = converted %.loc30_36.1, %.loc30_36.4 // CHECK:STDOUT: %RuntimeConvertFrom.ref.loc30_14: type = name_ref RuntimeConvertFrom, file.%RuntimeConvertFrom.decl [concrete = constants.%RuntimeConvertFrom] -// CHECK:STDOUT: %from: %RuntimeConvertFrom = bind_symbolic_name from, 0, %.loc30_38 [symbolic = constants.%from] +// CHECK:STDOUT: %.loc30_38.2: %RuntimeConvertFrom = bind_value %.loc30_38.1 +// CHECK:STDOUT: %from: %RuntimeConvertFrom = bind_symbolic_name from, 0, %.loc30_38.2 [symbolic = constants.%from] // CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [concrete = constants.%F] // CHECK:STDOUT: %from.ref: %RuntimeConvertFrom = name_ref from, %from [symbolic = constants.%from] // CHECK:STDOUT: %holds_to.ref: %HoldsType.066 = name_ref holds_to, %holds_to diff --git a/toolchain/check/testdata/function/generic/type_param.carbon b/toolchain/check/testdata/function/generic/type_param.carbon index 162df96eeda5..6fd173835522 100644 --- a/toolchain/check/testdata/function/generic/type_param.carbon +++ b/toolchain/check/testdata/function/generic/type_param.carbon @@ -77,9 +77,10 @@ fn F(T:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: %p.ref: ref @F.%ptr.loc16_11.2 (%ptr) = name_ref p, %p // CHECK:STDOUT: %.loc17_15: @F.%ptr.loc16_11.2 (%ptr) = bind_value %p.ref -// CHECK:STDOUT: %.loc17_14: ref @F.%T.loc15_6.2 (%T) = deref %.loc17_15 +// CHECK:STDOUT: %.loc17_14.1: ref @F.%T.loc15_6.2 (%T) = deref %.loc17_15 // CHECK:STDOUT: %T.ref.loc17: type = name_ref T, %T.loc15_6.1 [symbolic = %T.loc15_6.2 (constants.%T)] -// CHECK:STDOUT: %n: ref @F.%T.loc15_6.2 (%T) = bind_name n, %.loc17_14 +// CHECK:STDOUT: %.loc17_14.2: @F.%T.loc15_6.2 (%T) = bind_value %.loc17_14.1 +// CHECK:STDOUT: %n: @F.%T.loc15_6.2 (%T) = bind_name n, %.loc17_14.2 // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/impl/extend_impl_generic.carbon b/toolchain/check/testdata/impl/extend_impl_generic.carbon index dc1c7b88b305..75abbd7b6c0b 100644 --- a/toolchain/check/testdata/impl/extend_impl_generic.carbon +++ b/toolchain/check/testdata/impl/extend_impl_generic.carbon @@ -270,12 +270,13 @@ class X(U:! type) { // CHECK:STDOUT: %F.call.loc21: init %Param = call %impl.elem0.loc21() to %.loc21_20.1 // CHECK:STDOUT: %.loc21_20.2: ref %Param = temporary %.loc21_20.1, %F.call.loc21 // CHECK:STDOUT: %x.ref.loc21: %Param.elem = name_ref x, @Param.%.loc9 [concrete = @Param.%.loc9] -// CHECK:STDOUT: %.loc21_21: ref %i32 = class_element_access %.loc21_20.2, element0 +// CHECK:STDOUT: %.loc21_21.1: ref %i32 = class_element_access %.loc21_20.2, element0 // CHECK:STDOUT: %.loc21_10: type = splice_block %i32.loc21 [concrete = constants.%i32] { // CHECK:STDOUT: %int_32.loc21: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc21: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: } -// CHECK:STDOUT: %a: ref %i32 = bind_name a, %.loc21_21 +// CHECK:STDOUT: %.loc21_21.2: %i32 = bind_value %.loc21_21.1 +// CHECK:STDOUT: %a: %i32 = bind_name a, %.loc21_21.2 // CHECK:STDOUT: name_binding_decl { // CHECK:STDOUT: %b.patt: %pattern_type.7ce = binding_pattern b [concrete] // CHECK:STDOUT: %b.var_patt: %pattern_type.7ce = var_pattern %b.patt [concrete] diff --git a/toolchain/check/testdata/impl/use_assoc_const.carbon b/toolchain/check/testdata/impl/use_assoc_const.carbon index b83b461513b5..0b1ec8c3e787 100644 --- a/toolchain/check/testdata/impl/use_assoc_const.carbon +++ b/toolchain/check/testdata/impl/use_assoc_const.carbon @@ -3871,7 +3871,7 @@ fn F() { // CHECK:STDOUT: %.loc12_21.2: ref %C.131 = temporary_storage // CHECK:STDOUT: %.loc12_21.3: init %C.131 = class_init (), %.loc12_21.2 [concrete = constants.%C.val] // CHECK:STDOUT: %.loc12_21.4: ref %C.131 = temporary %.loc12_21.2, %.loc12_21.3 -// CHECK:STDOUT: %.loc12_23: ref %C.131 = converted %.loc12_21.1, %.loc12_21.4 +// CHECK:STDOUT: %.loc12_23.1: ref %C.131 = converted %.loc12_21.1, %.loc12_21.4 // CHECK:STDOUT: %.loc12_11.1: type = splice_block %impl.elem0 [concrete = constants.%C.131] { // CHECK:STDOUT: %D.ref.loc12_10: type = name_ref D, file.%D.decl [concrete = constants.%D] // CHECK:STDOUT: %Z.ref: type = name_ref Z, file.%Z.decl [concrete = constants.%Z.type] @@ -3880,7 +3880,8 @@ fn F() { // CHECK:STDOUT: %.loc12_11.2: %Z.type = converted %D.ref.loc12_10, %Z.facet [concrete = constants.%Z.facet.f2a] // CHECK:STDOUT: %impl.elem0: type = impl_witness_access constants.%Z.impl_witness.19e, element0 [concrete = constants.%C.131] // CHECK:STDOUT: } -// CHECK:STDOUT: %a: ref %C.131 = bind_name a, %.loc12_23 +// CHECK:STDOUT: %.loc12_23.2: %C.131 = bind_value %.loc12_23.1 +// CHECK:STDOUT: %a: %C.131 = bind_name a, %.loc12_23.2 // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/interop/cpp/function_return.carbon b/toolchain/check/testdata/interop/cpp/function_return.carbon index 617638ea88fe..62d942133320 100644 --- a/toolchain/check/testdata/interop/cpp/function_return.carbon +++ b/toolchain/check/testdata/interop/cpp/function_return.carbon @@ -135,9 +135,9 @@ fn F() { // CHECK:STDOUT: %int_16: Core.IntLiteral = int_value 16 [concrete = constants.%int_16] // CHECK:STDOUT: %i16: type = class_type @Int, @Int(constants.%int_16) [concrete = constants.%i16] // CHECK:STDOUT: } -// CHECK:STDOUT: %.loc7_30.1: ref %i16 = temporary_storage -// CHECK:STDOUT: %.loc7_30.2: ref %i16 = temporary %.loc7_30.1, %foo_short.call -// CHECK:STDOUT: %x: ref %i16 = bind_name x, %.loc7_30.2 +// CHECK:STDOUT: %.loc7_30.1: %i16 = value_of_initializer %foo_short.call +// CHECK:STDOUT: %.loc7_30.2: %i16 = converted %foo_short.call, %.loc7_30.1 +// CHECK:STDOUT: %x: %i16 = bind_name x, %.loc7_30.2 // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/let/convert.carbon b/toolchain/check/testdata/let/convert.carbon index b1e77e9f77b4..c41b25df9da7 100644 --- a/toolchain/check/testdata/let/convert.carbon +++ b/toolchain/check/testdata/let/convert.carbon @@ -2,162 +2,78 @@ // Exceptions. See /LICENSE for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // -// TODO: Add ranges and switch to "--dump-sem-ir-ranges=only". -// EXTRA-ARGS: --dump-sem-ir-ranges=if-present -// // AUTOUPDATE // TIP: To test this file alone, run: // TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/let/convert.carbon // TIP: To dump output, run: // TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/let/convert.carbon +// --- convert.carbon + +library "[[@TEST_NAME]]"; + fn F() -> i32 { var v: (i32, i32, i32) = (1, 2, 3); // Convert from object representation to value representation. + //@dump-sem-ir-begin let w: (i32, i32, i32) = v; + //@dump-sem-ir-end return w.1; } +// --- fail_let_bound_to_ref_not_mutable.carbon + +library "[[@TEST_NAME]]"; + +fn G() { + var a: i32 = 0; + let n: i32 = a; + // CHECK:STDERR: fail_let_bound_to_ref_not_mutable.carbon:[[@LINE+4]]:3: error: expression is not assignable [AssignmentToNonAssignable] + // CHECK:STDERR: n = 1; + // CHECK:STDERR: ^ + // CHECK:STDERR: + n = 1; +} + // CHECK:STDOUT: --- convert.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete] -// CHECK:STDOUT: %Int.type: type = generic_class_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.7ce: type = pattern_type %i32 [concrete] -// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] -// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] // CHECK:STDOUT: %tuple.type.ff9: type = tuple_type (type, type, type) [concrete] // CHECK:STDOUT: %tuple.type.189: type = tuple_type (%i32, %i32, %i32) [concrete] // CHECK:STDOUT: %pattern_type.b5a: type = pattern_type %tuple.type.189 [concrete] -// CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] -// CHECK:STDOUT: %int_2.ecc: Core.IntLiteral = int_value 2 [concrete] -// CHECK:STDOUT: %int_3.1ba: Core.IntLiteral = int_value 3 [concrete] -// CHECK:STDOUT: %tuple.type.37f: type = tuple_type (Core.IntLiteral, Core.IntLiteral, Core.IntLiteral) [concrete] -// CHECK:STDOUT: %ImplicitAs.type.cc7: type = generic_interface_type @ImplicitAs [concrete] -// CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] -// CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] -// CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [concrete] -// CHECK:STDOUT: %To.c80: Core.IntLiteral = bind_symbolic_name To, 0 [symbolic] -// CHECK:STDOUT: %Convert.type.0f9: type = fn_type @Convert.3, @impl.4f9(%To.c80) [symbolic] -// CHECK:STDOUT: %Convert.f06: %Convert.type.0f9 = struct_value () [symbolic] -// CHECK:STDOUT: %ImplicitAs.impl_witness.c75: = impl_witness imports.%ImplicitAs.impl_witness_table.a2f, @impl.4f9(%int_32) [concrete] -// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.3, @impl.4f9(%int_32) [concrete] -// CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [concrete] -// CHECK:STDOUT: %ImplicitAs.facet.921: %ImplicitAs.type.205 = facet_value Core.IntLiteral, (%ImplicitAs.impl_witness.c75) [concrete] -// CHECK:STDOUT: %.9c3: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet.921 [concrete] -// CHECK:STDOUT: %Convert.bound.ab5: = bound_method %int_1.5b8, %Convert.956 [concrete] -// CHECK:STDOUT: %Convert.specific_fn: = specific_function %Convert.956, @Convert.3(%int_32) [concrete] -// CHECK:STDOUT: %bound_method.9a1: = bound_method %int_1.5b8, %Convert.specific_fn [concrete] -// CHECK:STDOUT: %int_1.5d2: %i32 = int_value 1 [concrete] -// CHECK:STDOUT: %Convert.bound.ef9: = bound_method %int_2.ecc, %Convert.956 [concrete] -// CHECK:STDOUT: %bound_method.b92: = bound_method %int_2.ecc, %Convert.specific_fn [concrete] -// CHECK:STDOUT: %int_2.ef8: %i32 = int_value 2 [concrete] -// CHECK:STDOUT: %Convert.bound.b30: = bound_method %int_3.1ba, %Convert.956 [concrete] -// CHECK:STDOUT: %bound_method.047: = bound_method %int_3.1ba, %Convert.specific_fn [concrete] -// CHECK:STDOUT: %int_3.822: %i32 = int_value 3 [concrete] -// CHECK:STDOUT: %tuple: %tuple.type.189 = tuple_value (%int_1.5d2, %int_2.ef8, %int_3.822) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { -// CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { -// CHECK:STDOUT: .Int = %Core.Int -// CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs -// CHECK:STDOUT: import Core//prelude -// CHECK:STDOUT: import Core//prelude/... -// CHECK:STDOUT: } -// CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/types/int, Int, loaded [concrete = constants.%Int.generic] -// CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/operators/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] -// CHECK:STDOUT: %Core.import_ref.a5b: @impl.4f9.%Convert.type (%Convert.type.0f9) = import_ref Core//prelude/types/int, loc19_39, loaded [symbolic = @impl.4f9.%Convert (constants.%Convert.f06)] -// CHECK:STDOUT: %ImplicitAs.impl_witness_table.a2f = impl_witness_table (%Core.import_ref.a5b), @impl.4f9 [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .Core = imports.%Core -// CHECK:STDOUT: .F = %F.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %Core.import = import Core -// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { -// CHECK:STDOUT: %return.patt: %pattern_type.7ce = return_slot_pattern [concrete] -// CHECK:STDOUT: %return.param_patt: %pattern_type.7ce = out_param_pattern %return.patt, call_param0 [concrete] -// CHECK:STDOUT: } { -// CHECK:STDOUT: %int_32.loc14: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] -// CHECK:STDOUT: %i32.loc14: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] -// CHECK:STDOUT: %return.param: ref %i32 = out_param call_param0 -// CHECK:STDOUT: %return: ref %i32 = return_slot %return.param -// CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: fn @F() -> %i32 { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %v.patt: %pattern_type.b5a = binding_pattern v [concrete] -// CHECK:STDOUT: %v.var_patt: %pattern_type.b5a = var_pattern %v.patt [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: %v.var: ref %tuple.type.189 = var %v.var_patt -// CHECK:STDOUT: %int_1.loc15: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] -// CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] -// CHECK:STDOUT: %int_3: Core.IntLiteral = int_value 3 [concrete = constants.%int_3.1ba] -// CHECK:STDOUT: %.loc15_36.1: %tuple.type.37f = tuple_literal (%int_1.loc15, %int_2, %int_3) -// CHECK:STDOUT: %impl.elem0.loc15_36.1: %.9c3 = impl_witness_access constants.%ImplicitAs.impl_witness.c75, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc15_36.1: = bound_method %int_1.loc15, %impl.elem0.loc15_36.1 [concrete = constants.%Convert.bound.ab5] -// CHECK:STDOUT: %specific_fn.loc15_36.1: = specific_function %impl.elem0.loc15_36.1, @Convert.3(constants.%int_32) [concrete = constants.%Convert.specific_fn] -// CHECK:STDOUT: %bound_method.loc15_36.2: = bound_method %int_1.loc15, %specific_fn.loc15_36.1 [concrete = constants.%bound_method.9a1] -// CHECK:STDOUT: %int.convert_checked.loc15_36.1: init %i32 = call %bound_method.loc15_36.2(%int_1.loc15) [concrete = constants.%int_1.5d2] -// CHECK:STDOUT: %.loc15_36.2: init %i32 = converted %int_1.loc15, %int.convert_checked.loc15_36.1 [concrete = constants.%int_1.5d2] -// CHECK:STDOUT: %tuple.elem0: ref %i32 = tuple_access %v.var, element0 -// CHECK:STDOUT: %.loc15_36.3: init %i32 = initialize_from %.loc15_36.2 to %tuple.elem0 [concrete = constants.%int_1.5d2] -// CHECK:STDOUT: %impl.elem0.loc15_36.2: %.9c3 = impl_witness_access constants.%ImplicitAs.impl_witness.c75, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc15_36.3: = bound_method %int_2, %impl.elem0.loc15_36.2 [concrete = constants.%Convert.bound.ef9] -// CHECK:STDOUT: %specific_fn.loc15_36.2: = specific_function %impl.elem0.loc15_36.2, @Convert.3(constants.%int_32) [concrete = constants.%Convert.specific_fn] -// CHECK:STDOUT: %bound_method.loc15_36.4: = bound_method %int_2, %specific_fn.loc15_36.2 [concrete = constants.%bound_method.b92] -// CHECK:STDOUT: %int.convert_checked.loc15_36.2: init %i32 = call %bound_method.loc15_36.4(%int_2) [concrete = constants.%int_2.ef8] -// CHECK:STDOUT: %.loc15_36.4: init %i32 = converted %int_2, %int.convert_checked.loc15_36.2 [concrete = constants.%int_2.ef8] -// CHECK:STDOUT: %tuple.elem1.loc15: ref %i32 = tuple_access %v.var, element1 -// CHECK:STDOUT: %.loc15_36.5: init %i32 = initialize_from %.loc15_36.4 to %tuple.elem1.loc15 [concrete = constants.%int_2.ef8] -// CHECK:STDOUT: %impl.elem0.loc15_36.3: %.9c3 = impl_witness_access constants.%ImplicitAs.impl_witness.c75, element0 [concrete = constants.%Convert.956] -// CHECK:STDOUT: %bound_method.loc15_36.5: = bound_method %int_3, %impl.elem0.loc15_36.3 [concrete = constants.%Convert.bound.b30] -// CHECK:STDOUT: %specific_fn.loc15_36.3: = specific_function %impl.elem0.loc15_36.3, @Convert.3(constants.%int_32) [concrete = constants.%Convert.specific_fn] -// CHECK:STDOUT: %bound_method.loc15_36.6: = bound_method %int_3, %specific_fn.loc15_36.3 [concrete = constants.%bound_method.047] -// CHECK:STDOUT: %int.convert_checked.loc15_36.3: init %i32 = call %bound_method.loc15_36.6(%int_3) [concrete = constants.%int_3.822] -// CHECK:STDOUT: %.loc15_36.6: init %i32 = converted %int_3, %int.convert_checked.loc15_36.3 [concrete = constants.%int_3.822] -// CHECK:STDOUT: %tuple.elem2: ref %i32 = tuple_access %v.var, element2 -// CHECK:STDOUT: %.loc15_36.7: init %i32 = initialize_from %.loc15_36.6 to %tuple.elem2 [concrete = constants.%int_3.822] -// CHECK:STDOUT: %.loc15_36.8: init %tuple.type.189 = tuple_init (%.loc15_36.3, %.loc15_36.5, %.loc15_36.7) to %v.var [concrete = constants.%tuple] -// CHECK:STDOUT: %.loc15_3: init %tuple.type.189 = converted %.loc15_36.1, %.loc15_36.8 [concrete = constants.%tuple] -// CHECK:STDOUT: assign %v.var, %.loc15_3 -// CHECK:STDOUT: %.loc15_24.1: type = splice_block %.loc15_24.3 [concrete = constants.%tuple.type.189] { -// CHECK:STDOUT: %int_32.loc15_11: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] -// CHECK:STDOUT: %i32.loc15_11: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] -// CHECK:STDOUT: %int_32.loc15_16: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] -// CHECK:STDOUT: %i32.loc15_16: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] -// CHECK:STDOUT: %int_32.loc15_21: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] -// CHECK:STDOUT: %i32.loc15_21: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] -// CHECK:STDOUT: %.loc15_24.2: %tuple.type.ff9 = tuple_literal (%i32.loc15_11, %i32.loc15_16, %i32.loc15_21) -// CHECK:STDOUT: %.loc15_24.3: type = converted %.loc15_24.2, constants.%tuple.type.189 [concrete = constants.%tuple.type.189] -// CHECK:STDOUT: } -// CHECK:STDOUT: %v: ref %tuple.type.189 = bind_name v, %v.var +// CHECK:STDOUT: // CHECK:STDOUT: name_binding_decl { // CHECK:STDOUT: %w.patt: %pattern_type.b5a = binding_pattern w [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: %v.ref: ref %tuple.type.189 = name_ref v, %v -// CHECK:STDOUT: %.loc17_24.1: type = splice_block %.loc17_24.3 [concrete = constants.%tuple.type.189] { -// CHECK:STDOUT: %int_32.loc17_11: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] -// CHECK:STDOUT: %i32.loc17_11: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] -// CHECK:STDOUT: %int_32.loc17_16: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] -// CHECK:STDOUT: %i32.loc17_16: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] -// CHECK:STDOUT: %int_32.loc17_21: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] -// CHECK:STDOUT: %i32.loc17_21: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] -// CHECK:STDOUT: %.loc17_24.2: %tuple.type.ff9 = tuple_literal (%i32.loc17_11, %i32.loc17_16, %i32.loc17_21) -// CHECK:STDOUT: %.loc17_24.3: type = converted %.loc17_24.2, constants.%tuple.type.189 [concrete = constants.%tuple.type.189] +// CHECK:STDOUT: %.loc8_24.1: type = splice_block %.loc8_24.3 [concrete = constants.%tuple.type.189] { +// CHECK:STDOUT: %int_32.loc8_11: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32.loc8_11: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: %int_32.loc8_16: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32.loc8_16: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: %int_32.loc8_21: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32.loc8_21: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: %.loc8_24.2: %tuple.type.ff9 = tuple_literal (%i32.loc8_11, %i32.loc8_16, %i32.loc8_21) +// CHECK:STDOUT: %.loc8_24.3: type = converted %.loc8_24.2, constants.%tuple.type.189 [concrete = constants.%tuple.type.189] // CHECK:STDOUT: } -// CHECK:STDOUT: %w: ref %tuple.type.189 = bind_name w, %v.ref -// CHECK:STDOUT: %w.ref: ref %tuple.type.189 = name_ref w, %w -// CHECK:STDOUT: %int_1.loc18: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] -// CHECK:STDOUT: %tuple.elem1.loc18: ref %i32 = tuple_access %w.ref, element1 -// CHECK:STDOUT: %.loc18: %i32 = bind_value %tuple.elem1.loc18 -// CHECK:STDOUT: return %.loc18 +// CHECK:STDOUT: %tuple.elem0.loc8: ref %i32 = tuple_access %v.ref, element0 +// CHECK:STDOUT: %.loc8_28.1: %i32 = bind_value %tuple.elem0.loc8 +// CHECK:STDOUT: %tuple.elem1.loc8: ref %i32 = tuple_access %v.ref, element1 +// CHECK:STDOUT: %.loc8_28.2: %i32 = bind_value %tuple.elem1.loc8 +// CHECK:STDOUT: %tuple.elem2.loc8: ref %i32 = tuple_access %v.ref, element2 +// CHECK:STDOUT: %.loc8_28.3: %i32 = bind_value %tuple.elem2.loc8 +// CHECK:STDOUT: %tuple: %tuple.type.189 = tuple_value (%.loc8_28.1, %.loc8_28.2, %.loc8_28.3) +// CHECK:STDOUT: %.loc8_28.4: %tuple.type.189 = converted %v.ref, %tuple +// CHECK:STDOUT: %w: %tuple.type.189 = bind_name w, %.loc8_28.4 +// CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/operators/overloaded/index_with_prelude.carbon b/toolchain/check/testdata/operators/overloaded/index_with_prelude.carbon index 4085f5712915..3afe6aaa01e6 100644 --- a/toolchain/check/testdata/operators/overloaded/index_with_prelude.carbon +++ b/toolchain/check/testdata/operators/overloaded/index_with_prelude.carbon @@ -146,7 +146,8 @@ let x: i32 = c[0]; // CHECK:STDOUT: %.loc14_25.2: init %SubscriptType.8ee = class_init (), %.loc14_25.1 [concrete = constants.%SubscriptType.val] // CHECK:STDOUT: %.loc14_25.3: ref %SubscriptType.8ee = temporary %.loc14_25.1, %.loc14_25.2 // CHECK:STDOUT: %.loc14_25.4: ref %SubscriptType.8ee = converted @__global_init.%.loc14, %.loc14_25.3 -// CHECK:STDOUT: %s: ref %SubscriptType.8ee = bind_name s, %.loc14_25.4 +// CHECK:STDOUT: %.loc14_25.5: %SubscriptType.8ee = bind_value %.loc14_25.4 +// CHECK:STDOUT: %s: %SubscriptType.8ee = bind_name s, %.loc14_25.5 // CHECK:STDOUT: name_binding_decl { // CHECK:STDOUT: %c.patt: %pattern_type.c48 = binding_pattern c [concrete] // CHECK:STDOUT: } @@ -155,13 +156,15 @@ let x: i32 = c[0]; // CHECK:STDOUT: %.loc15_13.2: init %C = class_init (), %.loc15_13.1 [concrete = constants.%C.val] // CHECK:STDOUT: %.loc15_13.3: ref %C = temporary %.loc15_13.1, %.loc15_13.2 // CHECK:STDOUT: %.loc15_13.4: ref %C = converted @__global_init.%.loc15, %.loc15_13.3 -// CHECK:STDOUT: %c: ref %C = bind_name c, %.loc15_13.4 +// CHECK:STDOUT: %.loc15_13.5: %C = bind_value %.loc15_13.4 +// CHECK:STDOUT: %c: %C = bind_name c, %.loc15_13.5 // CHECK:STDOUT: name_binding_decl { // CHECK:STDOUT: %x.patt: %pattern_type.c39 = binding_pattern x [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: %ElementType.ref: type = name_ref ElementType, %ElementType.decl [concrete = constants.%ElementType.e6b] -// CHECK:STDOUT: %.loc16: ref %ElementType.e6b = temporary @__global_init.%.loc16_25, @__global_init.%At.call -// CHECK:STDOUT: %x: ref %ElementType.e6b = bind_name x, %.loc16 +// CHECK:STDOUT: %.loc16_25.1: ref %ElementType.e6b = temporary @__global_init.%.loc16, @__global_init.%At.call +// CHECK:STDOUT: %.loc16_25.2: %ElementType.e6b = bind_value %.loc16_25.1 +// CHECK:STDOUT: %x: %ElementType.e6b = bind_name x, %.loc16_25.2 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: impl @impl: %C.ref as %IndexWith.type { @@ -230,14 +233,12 @@ let x: i32 = c[0]; // CHECK:STDOUT: !entry: // CHECK:STDOUT: %.loc14: %empty_struct_type = struct_literal () // CHECK:STDOUT: %.loc15: %empty_struct_type = struct_literal () -// CHECK:STDOUT: %c.ref: ref %C = name_ref c, file.%c -// CHECK:STDOUT: %s.ref: ref %SubscriptType.8ee = name_ref s, file.%s -// CHECK:STDOUT: %.loc16_24: %SubscriptType.8ee = bind_value %s.ref +// CHECK:STDOUT: %c.ref: %C = name_ref c, file.%c +// CHECK:STDOUT: %s.ref: %SubscriptType.8ee = name_ref s, file.%s // CHECK:STDOUT: %impl.elem0: %.d94 = impl_witness_access constants.%IndexWith.impl_witness, element0 [concrete = constants.%At.d43] // CHECK:STDOUT: %bound_method: = bound_method %c.ref, %impl.elem0 -// CHECK:STDOUT: %.loc16_25: ref %ElementType.e6b = temporary_storage -// CHECK:STDOUT: %.loc16_22: %C = bind_value %c.ref -// CHECK:STDOUT: %At.call: init %ElementType.e6b = call %bound_method(%.loc16_22, %.loc16_24) to %.loc16_25 +// CHECK:STDOUT: %.loc16: ref %ElementType.e6b = temporary_storage +// CHECK:STDOUT: %At.call: init %ElementType.e6b = call %bound_method(%c.ref, %s.ref) to %.loc16 // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -364,9 +365,9 @@ let x: i32 = c[0]; // CHECK:STDOUT: %int_32.loc11: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc11: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: } -// CHECK:STDOUT: %.loc11_17.1: ref %i32 = temporary_storage -// CHECK:STDOUT: %.loc11_17.2: ref %i32 = temporary %.loc11_17.1, @__global_init.%At.call -// CHECK:STDOUT: %e: ref %i32 = bind_name e, %.loc11_17.2 +// CHECK:STDOUT: %.loc11_17.1: %i32 = value_of_initializer @__global_init.%At.call +// CHECK:STDOUT: %.loc11_17.2: %i32 = converted @__global_init.%At.call, %.loc11_17.1 +// CHECK:STDOUT: %e: %i32 = bind_name e, %.loc11_17.2 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: impl @impl.18b: %.loc4_15.2 as %IndexWith.type { @@ -495,13 +496,15 @@ let x: i32 = c[0]; // CHECK:STDOUT: %.loc14_13.2: init %C = class_init (), %.loc14_13.1 [concrete = constants.%C.val] // CHECK:STDOUT: %.loc14_13.3: ref %C = temporary %.loc14_13.1, %.loc14_13.2 // CHECK:STDOUT: %.loc14_13.4: ref %C = converted @__global_init.%.loc14, %.loc14_13.3 -// CHECK:STDOUT: %c: ref %C = bind_name c, %.loc14_13.4 +// CHECK:STDOUT: %.loc14_13.5: %C = bind_value %.loc14_13.4 +// CHECK:STDOUT: %c: %C = bind_name c, %.loc14_13.5 // CHECK:STDOUT: name_binding_decl { // CHECK:STDOUT: %x.patt: %pattern_type.c39 = binding_pattern x [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: %ElementType.ref: type = name_ref ElementType, %ElementType.decl [concrete = constants.%ElementType.e6b] -// CHECK:STDOUT: %.loc22: ref %ElementType.e6b = temporary @__global_init.%.loc22_25.2, @__global_init.%At.call -// CHECK:STDOUT: %x: ref %ElementType.e6b = bind_name x, %.loc22 +// CHECK:STDOUT: %.loc22_25.1: ref %ElementType.e6b = temporary @__global_init.%.loc22_25.2, @__global_init.%At.call +// CHECK:STDOUT: %.loc22_25.2: %ElementType.e6b = bind_value %.loc22_25.1 +// CHECK:STDOUT: %x: %ElementType.e6b = bind_name x, %.loc22_25.2 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: impl @impl.066: %C.ref as %IndexWith.type { @@ -569,14 +572,13 @@ let x: i32 = c[0]; // CHECK:STDOUT: fn @__global_init() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %.loc14: %empty_struct_type = struct_literal () -// CHECK:STDOUT: %c.ref: ref %C = name_ref c, file.%c +// CHECK:STDOUT: %c.ref: %C = name_ref c, file.%c // CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0] // CHECK:STDOUT: %.loc22_25.1: %SubscriptType.8ee = converted %int_0, [concrete = ] // CHECK:STDOUT: %impl.elem0: %.d94 = impl_witness_access constants.%IndexWith.impl_witness, element0 [concrete = constants.%At.d43] // CHECK:STDOUT: %bound_method: = bound_method %c.ref, %impl.elem0 // CHECK:STDOUT: %.loc22_25.2: ref %ElementType.e6b = temporary_storage -// CHECK:STDOUT: %.loc22_22: %C = bind_value %c.ref -// CHECK:STDOUT: %At.call: init %ElementType.e6b = call %bound_method(%.loc22_22, ) to %.loc22_25.2 +// CHECK:STDOUT: %At.call: init %ElementType.e6b = call %bound_method(%c.ref, ) to %.loc22_25.2 // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -626,7 +628,8 @@ let x: i32 = c[0]; // CHECK:STDOUT: %.loc6_13.2: init %C = class_init (), %.loc6_13.1 [concrete = constants.%C.val] // CHECK:STDOUT: %.loc6_13.3: ref %C = temporary %.loc6_13.1, %.loc6_13.2 // CHECK:STDOUT: %.loc6_13.4: ref %C = converted @__global_init.%.loc6, %.loc6_13.3 -// CHECK:STDOUT: %c: ref %C = bind_name c, %.loc6_13.4 +// CHECK:STDOUT: %.loc6_13.5: %C = bind_value %.loc6_13.4 +// CHECK:STDOUT: %c: %C = bind_name c, %.loc6_13.5 // CHECK:STDOUT: name_binding_decl { // CHECK:STDOUT: %x.patt: %pattern_type.7ce = binding_pattern x [concrete] // CHECK:STDOUT: } @@ -649,7 +652,7 @@ let x: i32 = c[0]; // CHECK:STDOUT: fn @__global_init() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %.loc6: %empty_struct_type = struct_literal () -// CHECK:STDOUT: %c.ref: ref %C = name_ref c, file.%c +// CHECK:STDOUT: %c.ref: %C = name_ref c, file.%c // CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0] // CHECK:STDOUT: return // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/var/var_pattern.carbon b/toolchain/check/testdata/var/var_pattern.carbon index aa9848fa4076..427ffd9288b5 100644 --- a/toolchain/check/testdata/var/var_pattern.carbon +++ b/toolchain/check/testdata/var/var_pattern.carbon @@ -753,6 +753,7 @@ fn G() { // CHECK:STDOUT: %G: %G.type = struct_value () [concrete] // CHECK:STDOUT: %tuple.type: type = tuple_type (%empty_tuple.type, %empty_tuple.type, %empty_tuple.type) [concrete] // CHECK:STDOUT: %pattern_type.8c1: type = pattern_type %tuple.type [concrete] +// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -805,7 +806,9 @@ fn G() { // CHECK:STDOUT: } // CHECK:STDOUT: %.loc8_38.1: ref %empty_tuple.type = temporary_storage // CHECK:STDOUT: %.loc8_38.2: ref %empty_tuple.type = temporary %.loc8_38.1, %F.call.loc8_38 -// CHECK:STDOUT: %x: ref %empty_tuple.type = bind_name x, %.loc8_38.2 +// CHECK:STDOUT: %tuple.loc8_38: %empty_tuple.type = tuple_value () [concrete = constants.%empty_tuple] +// CHECK:STDOUT: %.loc8_38.3: %empty_tuple.type = converted %F.call.loc8_38, %tuple.loc8_38 [concrete = constants.%empty_tuple] +// CHECK:STDOUT: %x: %empty_tuple.type = bind_name x, %.loc8_38.3 // CHECK:STDOUT: assign %y.var, %F.call.loc8_43 // CHECK:STDOUT: %.loc8_23.1: type = splice_block %.loc8_23.3 [concrete = constants.%empty_tuple.type] { // CHECK:STDOUT: %.loc8_23.2: %empty_tuple.type = tuple_literal () @@ -818,7 +821,9 @@ fn G() { // CHECK:STDOUT: } // CHECK:STDOUT: %.loc8_48.1: ref %empty_tuple.type = temporary_storage // CHECK:STDOUT: %.loc8_48.2: ref %empty_tuple.type = temporary %.loc8_48.1, %F.call.loc8_48 -// CHECK:STDOUT: %z: ref %empty_tuple.type = bind_name z, %.loc8_48.2 +// CHECK:STDOUT: %tuple.loc8_48: %empty_tuple.type = tuple_value () [concrete = constants.%empty_tuple] +// CHECK:STDOUT: %.loc8_48.3: %empty_tuple.type = converted %F.call.loc8_48, %tuple.loc8_48 [concrete = constants.%empty_tuple] +// CHECK:STDOUT: %z: %empty_tuple.type = bind_name z, %.loc8_48.3 // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/diagnostics/coverage_test.cpp b/toolchain/diagnostics/coverage_test.cpp index 6d261274816c..d807c1eb4ea5 100644 --- a/toolchain/diagnostics/coverage_test.cpp +++ b/toolchain/diagnostics/coverage_test.cpp @@ -51,6 +51,13 @@ constexpr Kind UntestedKinds[] = { // - Require all diagnostics produced by compiling have their first location // be in the file being compiled, never an import. Kind::LanguageServerDiagnosticInWrongFile, + + // TODO: This can only fire if we attempt to convert a non-reference + // expression to a durable reference binding. At the moment, the only time + // we attempt reference binding is within a `var` pattern, where the + // conversion cannot fail. This should be covered once we support `ref` + // binding syntax. + Kind::ConversionFailureNonRefToRef, }; // Looks for diagnostic kinds that aren't covered by a file_test. diff --git a/toolchain/diagnostics/diagnostic_kind.def b/toolchain/diagnostics/diagnostic_kind.def index efa5fd74910f..22c6e3f6a5ab 100644 --- a/toolchain/diagnostics/diagnostic_kind.def +++ b/toolchain/diagnostics/diagnostic_kind.def @@ -440,6 +440,7 @@ CARBON_DIAGNOSTIC_KIND(ConversionFailure) CARBON_DIAGNOSTIC_KIND(ConversionFailureNonTypeToFacet) CARBON_DIAGNOSTIC_KIND(ConversionFailureFacetToFacet) CARBON_DIAGNOSTIC_KIND(ConversionFailureTypeToFacet) +CARBON_DIAGNOSTIC_KIND(ConversionFailureNonRefToRef) CARBON_DIAGNOSTIC_KIND(TypeExprEvaluationFailure) CARBON_DIAGNOSTIC_KIND(UnexpectedDeclNameParams) CARBON_DIAGNOSTIC_KIND(QualifiedNameInNonScope) diff --git a/toolchain/lower/testdata/class/method.carbon b/toolchain/lower/testdata/class/method.carbon index 3faaca82ab24..c70b6c06938b 100644 --- a/toolchain/lower/testdata/class/method.carbon +++ b/toolchain/lower/testdata/class/method.carbon @@ -30,11 +30,8 @@ fn F(p: C*) { // CHECK:STDOUT: define void @_CF.Main(ptr %p) !dbg !4 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %Get.call = call i32 @_CGet.C.Main(ptr %p), !dbg !7 -// CHECK:STDOUT: %.loc19_25.1.temp = alloca i32, align 4, !dbg !7 -// CHECK:STDOUT: store i32 %Get.call, ptr %.loc19_25.1.temp, align 4, !dbg !7 -// CHECK:STDOUT: %.loc20_12 = load i32, ptr %.loc19_25.1.temp, align 4, !dbg !8 -// CHECK:STDOUT: call void @_CSet.C.Main(ptr %p, i32 %.loc20_12), !dbg !9 -// CHECK:STDOUT: ret void, !dbg !10 +// CHECK:STDOUT: call void @_CSet.C.Main(ptr %p, i32 %Get.call), !dbg !8 +// CHECK:STDOUT: ret void, !dbg !9 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: !llvm.module.flags = !{!0, !1} @@ -48,6 +45,5 @@ fn F(p: C*) { // CHECK:STDOUT: !5 = !DISubroutineType(types: !6) // CHECK:STDOUT: !6 = !{} // CHECK:STDOUT: !7 = !DILocation(line: 19, column: 16, scope: !4) -// CHECK:STDOUT: !8 = !DILocation(line: 20, column: 12, scope: !4) -// CHECK:STDOUT: !9 = !DILocation(line: 20, column: 3, scope: !4) -// CHECK:STDOUT: !10 = !DILocation(line: 18, column: 1, scope: !4) +// CHECK:STDOUT: !8 = !DILocation(line: 20, column: 3, scope: !4) +// CHECK:STDOUT: !9 = !DILocation(line: 18, column: 1, scope: !4) diff --git a/toolchain/lower/testdata/function/generic/call_different_impls_with_const.carbon b/toolchain/lower/testdata/function/generic/call_different_impls_with_const.carbon index 11a9906890e7..f599c7d39163 100644 --- a/toolchain/lower/testdata/function/generic/call_different_impls_with_const.carbon +++ b/toolchain/lower/testdata/function/generic/call_different_impls_with_const.carbon @@ -69,16 +69,12 @@ fn Run() { // CHECK:STDOUT: define linkonce_odr void @_CG.Main.ae78220c5e9d4af5() !dbg !16 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %.loc35_20.1 = call i1 @"_CF.X.Main:I.Main"(), !dbg !17 -// CHECK:STDOUT: %.loc35_20.2.temp = alloca i1, align 1, !dbg !17 -// CHECK:STDOUT: store i1 %.loc35_20.1, ptr %.loc35_20.2.temp, align 1, !dbg !17 // CHECK:STDOUT: ret void, !dbg !18 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: define linkonce_odr void @_CG.Main.6b293b16be321a45() !dbg !19 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %.loc35_20.1 = call i32 @"_CF.Y.Main:I.Main"(), !dbg !20 -// CHECK:STDOUT: %.loc35_20.2.temp = alloca i32, align 4, !dbg !20 -// CHECK:STDOUT: store i32 %.loc35_20.1, ptr %.loc35_20.2.temp, align 4, !dbg !20 // CHECK:STDOUT: ret void, !dbg !21 // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/lower/testdata/let/copy_value_rep.carbon b/toolchain/lower/testdata/let/copy_value_rep.carbon new file mode 100644 index 000000000000..b42fd451671c --- /dev/null +++ b/toolchain/lower/testdata/let/copy_value_rep.carbon @@ -0,0 +1,64 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/lower/testdata/let/copy_value_rep.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/lower/testdata/let/copy_value_rep.carbon + +class X { + var a: i32; +} + +fn Run() -> i32 { + var x: X = {.a = 1}; + let n: i32 = x.a; + x.a = 2; + // Should return 1, not 2. + return n; +} + +// CHECK:STDOUT: ; ModuleID = 'copy_value_rep.carbon' +// CHECK:STDOUT: source_filename = "copy_value_rep.carbon" +// CHECK:STDOUT: +// CHECK:STDOUT: @X.val.loc16_3 = internal constant { i32 } { i32 1 } +// CHECK:STDOUT: +// CHECK:STDOUT: define i32 @main() !dbg !4 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %x.var = alloca { i32 }, align 8, !dbg !7 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %x.var), !dbg !7 +// CHECK:STDOUT: %.loc16_21.3.a = getelementptr inbounds nuw { i32 }, ptr %x.var, i32 0, i32 0, !dbg !8 +// CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %x.var, ptr align 4 @X.val.loc16_3, i64 4, i1 false), !dbg !7 +// CHECK:STDOUT: %.loc17_17.1.a = getelementptr inbounds nuw { i32 }, ptr %x.var, i32 0, i32 0, !dbg !9 +// CHECK:STDOUT: %.loc17_17.2 = load i32, ptr %.loc17_17.1.a, align 4, !dbg !9 +// CHECK:STDOUT: %.loc18_4.a = getelementptr inbounds nuw { i32 }, ptr %x.var, i32 0, i32 0, !dbg !10 +// CHECK:STDOUT: store i32 2, ptr %.loc18_4.a, align 4, !dbg !10 +// CHECK:STDOUT: ret i32 %.loc17_17.2, !dbg !11 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) +// CHECK:STDOUT: declare void @llvm.lifetime.start.p0(i64 immarg, ptr captures(none)) #0 +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: readwrite) +// CHECK:STDOUT: declare void @llvm.memcpy.p0.p0.i64(ptr noalias writeonly captures(none), ptr noalias readonly captures(none), i64, i1 immarg) #1 +// CHECK:STDOUT: +// CHECK:STDOUT: attributes #0 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } +// CHECK:STDOUT: attributes #1 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) } +// CHECK:STDOUT: +// CHECK:STDOUT: !llvm.module.flags = !{!0, !1} +// CHECK:STDOUT: !llvm.dbg.cu = !{!2} +// CHECK:STDOUT: +// CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5} +// CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3} +// CHECK:STDOUT: !2 = distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug) +// CHECK:STDOUT: !3 = !DIFile(filename: "copy_value_rep.carbon", directory: "") +// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "Run", linkageName: "main", scope: null, file: !3, line: 15, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !5 = !DISubroutineType(types: !6) +// CHECK:STDOUT: !6 = !{} +// CHECK:STDOUT: !7 = !DILocation(line: 16, column: 3, scope: !4) +// CHECK:STDOUT: !8 = !DILocation(line: 16, column: 14, scope: !4) +// CHECK:STDOUT: !9 = !DILocation(line: 17, column: 16, scope: !4) +// CHECK:STDOUT: !10 = !DILocation(line: 18, column: 3, scope: !4) +// CHECK:STDOUT: !11 = !DILocation(line: 20, column: 3, scope: !4)