Skip to content

Commit bfc4d2b

Browse files
authored
C++ interop: Add return reference types support (#6178)
This is a follow up of #6082, which added support for reference types, but not for return types. C++ Interop Demo: ```carbon // main.carbon library "Main"; import Core library "io"; import Cpp inline ''' struct C { auto Inc() -> void { ++x; } int x = 0; }; auto GetC() -> C& { static C c; return c; } '''; fn Run() -> i32 { Core.Print(Cpp.GetC()->x); Cpp.GetC()->Inc(); Core.Print(Cpp.GetC()->x); Cpp.GetC()->Inc(); Core.Print(Cpp.GetC()->x); return 0; } ``` ```shell $ bazel build toolchain:carbon && bazel-bin/toolchain/carbon compile main.carbon && bazel-bin/toolchain/carbon link main.o --output=demo && ./demo 0 1 2 ``` **Without this change**: ```shell main.carbon:19:14: error: semantics TODO: `Unsupported: return type: C &` Core.Print(Cpp.GetC()->x); ^~~~~~~~~~ ``` Part of #6148.
1 parent ba8ed99 commit bfc4d2b

File tree

4 files changed

+268
-111
lines changed

4 files changed

+268
-111
lines changed

toolchain/check/cpp/import.cpp

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1446,16 +1446,26 @@ static auto MakeParamPatternsBlockId(Context& context, SemIR::LocId loc_id,
14461446
// TODO: Support more return types.
14471447
static auto GetReturnTypeExpr(Context& context, SemIR::LocId loc_id,
14481448
clang::FunctionDecl* clang_decl) -> TypeExpr {
1449-
clang::QualType ret_type = clang_decl->getReturnType();
1450-
if (!ret_type->isVoidType()) {
1451-
TypeExpr mapped_type = MapType(context, loc_id, ret_type);
1452-
if (!mapped_type.inst_id.has_value()) {
1449+
clang::QualType orig_ret_type = clang_decl->getReturnType();
1450+
if (!orig_ret_type->isVoidType()) {
1451+
// We map `T&` return type to `addr param: T*`, and `T&&` parameters to
1452+
// `param: T`.
1453+
// TODO: Revisit this and decide what we really want to do here.
1454+
clang::QualType ret_type = orig_ret_type.getNonReferenceType();
1455+
1456+
auto [orig_type_inst_id, type_id] = MapType(context, loc_id, ret_type);
1457+
if (!orig_type_inst_id.has_value()) {
14531458
context.TODO(loc_id, llvm::formatv("Unsupported: return type: {0}",
1454-
ret_type.getAsString()));
1459+
orig_ret_type.getAsString()));
14551460
return {.inst_id = SemIR::ErrorInst::TypeInstId,
14561461
.type_id = SemIR::ErrorInst::TypeId};
14571462
}
1458-
return mapped_type;
1463+
1464+
if (orig_ret_type->isLValueReferenceType()) {
1465+
type_id = GetPointerType(context, orig_type_inst_id);
1466+
}
1467+
1468+
return {orig_type_inst_id, type_id};
14591469
}
14601470

14611471
auto* ctor = dyn_cast<clang::CXXConstructorDecl>(clang_decl);

toolchain/check/cpp/thunk.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,14 @@ static auto GetNonnullType(clang::ASTContext& ast_context,
241241
pointer_type, pointer_type);
242242
}
243243

244+
// Given a type, returns the corresponding _Nonnull-qualified pointer type,
245+
// ignoring references.
246+
static auto GetNonNullablePointerType(clang::ASTContext& ast_context,
247+
clang::QualType type) {
248+
return GetNonnullType(ast_context,
249+
ast_context.getPointerType(type.getNonReferenceType()));
250+
}
251+
244252
// Given the type of a callee parameter, returns the type to use for the
245253
// corresponding thunk parameter.
246254
static auto GetThunkParameterType(clang::ASTContext& ast_context,
@@ -249,8 +257,7 @@ static auto GetThunkParameterType(clang::ASTContext& ast_context,
249257
if (IsSimpleAbiType(ast_context, callee_type)) {
250258
return callee_type;
251259
}
252-
return GetNonnullType(ast_context, ast_context.getPointerType(
253-
callee_type.getNonReferenceType()));
260+
return GetNonNullablePointerType(ast_context, callee_type);
254261
}
255262

256263
// Creates the thunk parameter types given the callee function.
@@ -272,9 +279,8 @@ static auto BuildThunkParameterTypes(clang::ASTContext& ast_context,
272279
}
273280

274281
if (!callee_info.has_simple_return_type) {
275-
thunk_param_types.push_back(GetNonnullType(
276-
ast_context,
277-
ast_context.getPointerType(callee_info.effective_return_type)));
282+
thunk_param_types.push_back(GetNonNullablePointerType(
283+
ast_context, callee_info.effective_return_type));
278284
}
279285

280286
CARBON_CHECK(thunk_param_types.size() == callee_info.num_thunk_params());
@@ -524,7 +530,7 @@ static auto BuildThunkBody(clang::Sema& sema,
524530

525531
auto* return_object_addr = BuildThunkParamRef(
526532
sema, thunk_function_decl, callee_info.GetThunkReturnParamIndex());
527-
auto return_type = callee_info.effective_return_type;
533+
auto return_type = callee_info.effective_return_type.getNonReferenceType();
528534
auto* return_type_info =
529535
sema.Context.getTrivialTypeSourceInfo(return_type, clang_loc);
530536
auto placement_new = sema.BuildCXXNew(

toolchain/check/testdata/interop/cpp/function/reference.carbon

Lines changed: 84 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -223,22 +223,20 @@ fn F() {
223223
// Lvalue reference as return type
224224
// ============================================================================
225225

226-
// --- fail_todo_call_return_lvalue_ref.carbon
226+
// --- return_lvalue_ref.h
227227

228-
library "[[@TEST_NAME]]";
229-
230-
import Cpp inline '''
231228
struct S {};
232229

233230
auto ReturnsLValue() -> S&;
234-
''';
231+
232+
// --- call_return_lvalue_ref.carbon
233+
234+
library "[[@TEST_NAME]]";
235+
236+
import Cpp library "return_lvalue_ref.h";
235237

236238
fn F() {
237239
//@dump-sem-ir-begin
238-
// CHECK:STDERR: fail_todo_call_return_lvalue_ref.carbon:[[@LINE+4]]:19: error: semantics TODO: `Unsupported: return type: S &` [SemanticsTodo]
239-
// CHECK:STDERR: let s: Cpp.S* = Cpp.ReturnsLValue();
240-
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~
241-
// CHECK:STDERR:
242240
let s: Cpp.S* = Cpp.ReturnsLValue();
243241
//@dump-sem-ir-end
244242
}
@@ -247,22 +245,20 @@ fn F() {
247245
// Rvalue reference as return type
248246
// ============================================================================
249247

250-
// --- fail_todo_call_return_rvalue_ref.carbon
248+
// --- return_rvalue_ref.h
251249

252-
library "[[@TEST_NAME]]";
253-
254-
import Cpp inline '''
255250
struct S {};
256251

257252
auto ReturnsRValue() -> S&&;
258-
''';
253+
254+
// --- call_return_rvalue_ref.carbon
255+
256+
library "[[@TEST_NAME]]";
257+
258+
import Cpp library "return_rvalue_ref.h";
259259

260260
fn F() {
261261
//@dump-sem-ir-begin
262-
// CHECK:STDERR: fail_todo_call_return_rvalue_ref.carbon:[[@LINE+4]]:18: error: semantics TODO: `Unsupported: return type: S &&` [SemanticsTodo]
263-
// CHECK:STDERR: var s: Cpp.S = Cpp.ReturnsRValue();
264-
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~
265-
// CHECK:STDERR:
266262
var s: Cpp.S = Cpp.ReturnsRValue();
267263
//@dump-sem-ir-end
268264
}
@@ -271,26 +267,41 @@ fn F() {
271267
// Const reference as return type
272268
// ============================================================================
273269

274-
// --- fail_todo_call_return_const_lvalue_ref.carbon
270+
// --- return_const_lvalue_ref.h
275271

276-
library "[[@TEST_NAME]]";
277-
278-
import Cpp inline '''
279272
struct S {};
280273

281274
auto ReturnConstLValue() -> const S&;
282-
''';
275+
276+
// --- call_return_const_lvalue_ref.carbon
277+
278+
library "[[@TEST_NAME]]";
279+
280+
import Cpp library "return_const_lvalue_ref.h";
283281

284282
fn F() {
285283
//@dump-sem-ir-begin
286-
// CHECK:STDERR: fail_todo_call_return_const_lvalue_ref.carbon:[[@LINE+4]]:24: error: semantics TODO: `Unsupported: return type: const S &` [SemanticsTodo]
287-
// CHECK:STDERR: var s: const Cpp.S = Cpp.ReturnConstLValue();
288-
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~
289-
// CHECK:STDERR:
290-
var s: const Cpp.S = Cpp.ReturnConstLValue();
284+
var s: const Cpp.S* = Cpp.ReturnConstLValue();
291285
//@dump-sem-ir-end
292286
}
293287

288+
// --- fail_call_return_const_lvalue_ref_const_correctness.carbon
289+
290+
library "[[@TEST_NAME]]";
291+
292+
import Cpp library "return_const_lvalue_ref.h";
293+
294+
fn F() {
295+
// CHECK:STDERR: fail_call_return_const_lvalue_ref_const_correctness.carbon:[[@LINE+7]]:3: error: cannot implicitly convert expression of type `const Cpp.S*` to `Cpp.S*` [ConversionFailure]
296+
// CHECK:STDERR: var s: Cpp.S* = Cpp.ReturnConstLValue();
297+
// CHECK:STDERR: ^~~~~~~~~~~~~
298+
// CHECK:STDERR: fail_call_return_const_lvalue_ref_const_correctness.carbon:[[@LINE+4]]:3: note: type `const Cpp.S*` does not implement interface `Core.ImplicitAs(Cpp.S*)` [MissingImplInMemberAccessNote]
299+
// CHECK:STDERR: var s: Cpp.S* = Cpp.ReturnConstLValue();
300+
// CHECK:STDERR: ^~~~~~~~~~~~~
301+
// CHECK:STDERR:
302+
var s: Cpp.S* = Cpp.ReturnConstLValue();
303+
}
304+
294305
// CHECK:STDOUT: --- call_param_lvalue_ref.carbon
295306
// CHECK:STDOUT:
296307
// CHECK:STDOUT: constants {
@@ -873,7 +884,7 @@ fn F() {
873884
// CHECK:STDOUT: <elided>
874885
// CHECK:STDOUT: }
875886
// CHECK:STDOUT:
876-
// CHECK:STDOUT: --- fail_todo_call_return_lvalue_ref.carbon
887+
// CHECK:STDOUT: --- call_return_lvalue_ref.carbon
877888
// CHECK:STDOUT:
878889
// CHECK:STDOUT: constants {
879890
// CHECK:STDOUT: %S: type = class_type @S [concrete]
@@ -905,33 +916,35 @@ fn F() {
905916
// CHECK:STDOUT: name_binding_decl {
906917
// CHECK:STDOUT: %s.patt: %pattern_type = binding_pattern s [concrete]
907918
// CHECK:STDOUT: }
908-
// CHECK:STDOUT: %Cpp.ref.loc16_19: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
919+
// CHECK:STDOUT: %Cpp.ref.loc8_19: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
909920
// CHECK:STDOUT: %ReturnsLValue.ref: %ReturnsLValue.cpp_overload_set.type = name_ref ReturnsLValue, imports.%ReturnsLValue.cpp_overload_set.value [concrete = constants.%ReturnsLValue.cpp_overload_set.value]
910-
// CHECK:STDOUT: %ReturnsLValue.call: init <error> = call imports.%ReturnsLValue.decl()
911-
// CHECK:STDOUT: %.loc16: type = splice_block %ptr [concrete = constants.%ptr] {
912-
// CHECK:STDOUT: %Cpp.ref.loc16_10: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
921+
// CHECK:STDOUT: %ReturnsLValue.call: init %ptr = call imports.%ReturnsLValue.decl()
922+
// CHECK:STDOUT: %.loc8_15: type = splice_block %ptr [concrete = constants.%ptr] {
923+
// CHECK:STDOUT: %Cpp.ref.loc8_10: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
913924
// CHECK:STDOUT: %S.ref: type = name_ref S, imports.%S.decl [concrete = constants.%S]
914925
// CHECK:STDOUT: %ptr: type = ptr_type %S.ref [concrete = constants.%ptr]
915926
// CHECK:STDOUT: }
916-
// CHECK:STDOUT: %s: %ptr = bind_name s, <error> [concrete = <error>]
927+
// CHECK:STDOUT: %.loc8_37.1: %ptr = value_of_initializer %ReturnsLValue.call
928+
// CHECK:STDOUT: %.loc8_37.2: %ptr = converted %ReturnsLValue.call, %.loc8_37.1
929+
// CHECK:STDOUT: %s: %ptr = bind_name s, %.loc8_37.2
917930
// CHECK:STDOUT: <elided>
918931
// CHECK:STDOUT: }
919932
// CHECK:STDOUT:
920-
// CHECK:STDOUT: --- fail_todo_call_return_rvalue_ref.carbon
933+
// CHECK:STDOUT: --- call_return_rvalue_ref.carbon
921934
// CHECK:STDOUT:
922935
// CHECK:STDOUT: constants {
923936
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
924937
// CHECK:STDOUT: %S: type = class_type @S [concrete]
925938
// CHECK:STDOUT: %pattern_type.7da: type = pattern_type %S [concrete]
926939
// CHECK:STDOUT: %ReturnsRValue.cpp_overload_set.type: type = cpp_overload_set_type @ReturnsRValue.cpp_overload_set [concrete]
927940
// CHECK:STDOUT: %ReturnsRValue.cpp_overload_set.value: %ReturnsRValue.cpp_overload_set.type = cpp_overload_set_value @ReturnsRValue.cpp_overload_set [concrete]
928-
// CHECK:STDOUT: %ReturnsRValue.type: type = fn_type @ReturnsRValue [concrete]
929-
// CHECK:STDOUT: %ReturnsRValue: %ReturnsRValue.type = struct_value () [concrete]
941+
// CHECK:STDOUT: %ptr.5c7: type = ptr_type %S [concrete]
942+
// CHECK:STDOUT: %ReturnsRValue__carbon_thunk.type: type = fn_type @ReturnsRValue__carbon_thunk [concrete]
943+
// CHECK:STDOUT: %ReturnsRValue__carbon_thunk: %ReturnsRValue__carbon_thunk.type = struct_value () [concrete]
930944
// CHECK:STDOUT: %type_where: type = facet_type <type where .Self impls <CanDestroy>> [concrete]
931945
// CHECK:STDOUT: %facet_value: %type_where = facet_value %S, () [concrete]
932946
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.34a: type = fn_type @DestroyT.binding.as_type.as.Destroy.impl.Op, @DestroyT.binding.as_type.as.Destroy.impl(%facet_value) [concrete]
933947
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.016: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.34a = struct_value () [concrete]
934-
// CHECK:STDOUT: %ptr.5c7: type = ptr_type %S [concrete]
935948
// CHECK:STDOUT: }
936949
// CHECK:STDOUT:
937950
// CHECK:STDOUT: imports {
@@ -942,7 +955,7 @@ fn F() {
942955
// CHECK:STDOUT: }
943956
// CHECK:STDOUT: %S.decl: type = class_decl @S [concrete = constants.%S] {} {}
944957
// CHECK:STDOUT: %ReturnsRValue.cpp_overload_set.value: %ReturnsRValue.cpp_overload_set.type = cpp_overload_set_value @ReturnsRValue.cpp_overload_set [concrete = constants.%ReturnsRValue.cpp_overload_set.value]
945-
// CHECK:STDOUT: %ReturnsRValue.decl: %ReturnsRValue.type = fn_decl @ReturnsRValue [concrete = constants.%ReturnsRValue] {
958+
// CHECK:STDOUT: %ReturnsRValue__carbon_thunk.decl: %ReturnsRValue__carbon_thunk.type = fn_decl @ReturnsRValue__carbon_thunk [concrete = constants.%ReturnsRValue__carbon_thunk] {
946959
// CHECK:STDOUT: <elided>
947960
// CHECK:STDOUT: } {
948961
// CHECK:STDOUT: <elided>
@@ -956,41 +969,45 @@ fn F() {
956969
// CHECK:STDOUT: %s.var_patt: %pattern_type.7da = var_pattern %s.patt [concrete]
957970
// CHECK:STDOUT: }
958971
// CHECK:STDOUT: %s.var: ref %S = var %s.var_patt
959-
// CHECK:STDOUT: %Cpp.ref.loc16_18: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
972+
// CHECK:STDOUT: %Cpp.ref.loc8_18: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
960973
// CHECK:STDOUT: %ReturnsRValue.ref: %ReturnsRValue.cpp_overload_set.type = name_ref ReturnsRValue, imports.%ReturnsRValue.cpp_overload_set.value [concrete = constants.%ReturnsRValue.cpp_overload_set.value]
961-
// CHECK:STDOUT: %ReturnsRValue.call: init <error> = call imports.%ReturnsRValue.decl()
962-
// CHECK:STDOUT: assign %s.var, <error>
963-
// CHECK:STDOUT: %.loc16_13: type = splice_block %S.ref [concrete = constants.%S] {
964-
// CHECK:STDOUT: %Cpp.ref.loc16_10: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
974+
// CHECK:STDOUT: %.loc8_3.1: ref %S = splice_block %s.var {}
975+
// CHECK:STDOUT: %addr.loc8_36: %ptr.5c7 = addr_of %.loc8_3.1
976+
// CHECK:STDOUT: %ReturnsRValue__carbon_thunk.call: init %empty_tuple.type = call imports.%ReturnsRValue__carbon_thunk.decl(%addr.loc8_36)
977+
// CHECK:STDOUT: %.loc8_36: init %S = in_place_init %ReturnsRValue__carbon_thunk.call, %.loc8_3.1
978+
// CHECK:STDOUT: assign %s.var, %.loc8_36
979+
// CHECK:STDOUT: %.loc8_13: type = splice_block %S.ref [concrete = constants.%S] {
980+
// CHECK:STDOUT: %Cpp.ref.loc8_10: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
965981
// CHECK:STDOUT: %S.ref: type = name_ref S, imports.%S.decl [concrete = constants.%S]
966982
// CHECK:STDOUT: }
967983
// CHECK:STDOUT: %s: ref %S = bind_name s, %s.var
968984
// CHECK:STDOUT: %facet_value: %type_where = facet_value constants.%S, () [concrete = constants.%facet_value]
969-
// CHECK:STDOUT: %.loc16_3: %type_where = converted constants.%S, %facet_value [concrete = constants.%facet_value]
985+
// CHECK:STDOUT: %.loc8_3.2: %type_where = converted constants.%S, %facet_value [concrete = constants.%facet_value]
970986
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound: <bound method> = bound_method %s.var, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.016
971987
// CHECK:STDOUT: <elided>
972988
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %s.var, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn
973-
// CHECK:STDOUT: %addr: %ptr.5c7 = addr_of %s.var
974-
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr)
989+
// CHECK:STDOUT: %addr.loc8_3: %ptr.5c7 = addr_of %s.var
990+
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr.loc8_3)
975991
// CHECK:STDOUT: <elided>
976992
// CHECK:STDOUT: }
977993
// CHECK:STDOUT:
978-
// CHECK:STDOUT: --- fail_todo_call_return_const_lvalue_ref.carbon
994+
// CHECK:STDOUT: --- call_return_const_lvalue_ref.carbon
979995
// CHECK:STDOUT:
980996
// CHECK:STDOUT: constants {
981997
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
982998
// CHECK:STDOUT: %S: type = class_type @S [concrete]
983999
// CHECK:STDOUT: %const: type = const_type %S [concrete]
984-
// CHECK:STDOUT: %pattern_type.9be: type = pattern_type %const [concrete]
1000+
// CHECK:STDOUT: %ptr.ff5: type = ptr_type %const [concrete]
1001+
// CHECK:STDOUT: %pattern_type.32f: type = pattern_type %ptr.ff5 [concrete]
9851002
// CHECK:STDOUT: %ReturnConstLValue.cpp_overload_set.type: type = cpp_overload_set_type @ReturnConstLValue.cpp_overload_set [concrete]
9861003
// CHECK:STDOUT: %ReturnConstLValue.cpp_overload_set.value: %ReturnConstLValue.cpp_overload_set.type = cpp_overload_set_value @ReturnConstLValue.cpp_overload_set [concrete]
9871004
// CHECK:STDOUT: %ReturnConstLValue.type: type = fn_type @ReturnConstLValue [concrete]
9881005
// CHECK:STDOUT: %ReturnConstLValue: %ReturnConstLValue.type = struct_value () [concrete]
9891006
// CHECK:STDOUT: %type_where: type = facet_type <type where .Self impls <CanDestroy>> [concrete]
990-
// CHECK:STDOUT: %facet_value: %type_where = facet_value %const, () [concrete]
991-
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.56e: type = fn_type @DestroyT.binding.as_type.as.Destroy.impl.Op, @DestroyT.binding.as_type.as.Destroy.impl(%facet_value) [concrete]
992-
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.089: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.56e = struct_value () [concrete]
993-
// CHECK:STDOUT: %ptr.ff5: type = ptr_type %const [concrete]
1007+
// CHECK:STDOUT: %facet_value: %type_where = facet_value %ptr.ff5, () [concrete]
1008+
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.40d: type = fn_type @DestroyT.binding.as_type.as.Destroy.impl.Op, @DestroyT.binding.as_type.as.Destroy.impl(%facet_value) [concrete]
1009+
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.c44: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.40d = struct_value () [concrete]
1010+
// CHECK:STDOUT: %ptr.dec: type = ptr_type %ptr.ff5 [concrete]
9941011
// CHECK:STDOUT: }
9951012
// CHECK:STDOUT:
9961013
// CHECK:STDOUT: imports {
@@ -1011,26 +1028,27 @@ fn F() {
10111028
// CHECK:STDOUT: fn @F() {
10121029
// CHECK:STDOUT: !entry:
10131030
// CHECK:STDOUT: name_binding_decl {
1014-
// CHECK:STDOUT: %s.patt: %pattern_type.9be = binding_pattern s [concrete]
1015-
// CHECK:STDOUT: %s.var_patt: %pattern_type.9be = var_pattern %s.patt [concrete]
1031+
// CHECK:STDOUT: %s.patt: %pattern_type.32f = binding_pattern s [concrete]
1032+
// CHECK:STDOUT: %s.var_patt: %pattern_type.32f = var_pattern %s.patt [concrete]
10161033
// CHECK:STDOUT: }
1017-
// CHECK:STDOUT: %s.var: ref %const = var %s.var_patt
1018-
// CHECK:STDOUT: %Cpp.ref.loc16_24: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
1034+
// CHECK:STDOUT: %s.var: ref %ptr.ff5 = var %s.var_patt
1035+
// CHECK:STDOUT: %Cpp.ref.loc8_25: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
10191036
// CHECK:STDOUT: %ReturnConstLValue.ref: %ReturnConstLValue.cpp_overload_set.type = name_ref ReturnConstLValue, imports.%ReturnConstLValue.cpp_overload_set.value [concrete = constants.%ReturnConstLValue.cpp_overload_set.value]
1020-
// CHECK:STDOUT: %ReturnConstLValue.call: init <error> = call imports.%ReturnConstLValue.decl()
1021-
// CHECK:STDOUT: assign %s.var, <error>
1022-
// CHECK:STDOUT: %.loc16_10: type = splice_block %const [concrete = constants.%const] {
1023-
// CHECK:STDOUT: %Cpp.ref.loc16_16: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
1037+
// CHECK:STDOUT: %ReturnConstLValue.call: init %ptr.ff5 = call imports.%ReturnConstLValue.decl()
1038+
// CHECK:STDOUT: assign %s.var, %ReturnConstLValue.call
1039+
// CHECK:STDOUT: %.loc8_21: type = splice_block %ptr [concrete = constants.%ptr.ff5] {
1040+
// CHECK:STDOUT: %Cpp.ref.loc8_16: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
10241041
// CHECK:STDOUT: %S.ref: type = name_ref S, imports.%S.decl [concrete = constants.%S]
10251042
// CHECK:STDOUT: %const: type = const_type %S.ref [concrete = constants.%const]
1043+
// CHECK:STDOUT: %ptr: type = ptr_type %const [concrete = constants.%ptr.ff5]
10261044
// CHECK:STDOUT: }
1027-
// CHECK:STDOUT: %s: ref %const = bind_name s, %s.var
1028-
// CHECK:STDOUT: %facet_value: %type_where = facet_value constants.%const, () [concrete = constants.%facet_value]
1029-
// CHECK:STDOUT: %.loc16_3: %type_where = converted constants.%const, %facet_value [concrete = constants.%facet_value]
1030-
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound: <bound method> = bound_method %s.var, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.089
1045+
// CHECK:STDOUT: %s: ref %ptr.ff5 = bind_name s, %s.var
1046+
// CHECK:STDOUT: %facet_value: %type_where = facet_value constants.%ptr.ff5, () [concrete = constants.%facet_value]
1047+
// CHECK:STDOUT: %.loc8_3: %type_where = converted constants.%ptr.ff5, %facet_value [concrete = constants.%facet_value]
1048+
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound: <bound method> = bound_method %s.var, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.c44
10311049
// CHECK:STDOUT: <elided>
10321050
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %s.var, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn
1033-
// CHECK:STDOUT: %addr: %ptr.ff5 = addr_of %s.var
1051+
// CHECK:STDOUT: %addr: %ptr.dec = addr_of %s.var
10341052
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr)
10351053
// CHECK:STDOUT: <elided>
10361054
// CHECK:STDOUT: }

0 commit comments

Comments
 (0)