mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-04 14:11:05 +01:00
Fix calls to functions with const T&& parameters. (#7208)
This also fixes passing a value expression to a forwarding reference, since we currently deduce a `const T&&` parameter in that case. We were accidentally looking at the type of the thunk parameter (which is never an rvalue reference) rather than the type of the callee parameter.
This commit is contained in:
@@ -232,6 +232,77 @@ fn F() {
|
||||
Cpp.TakesConstLValue(t);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Const rvalue reference as a parameter type
|
||||
// ============================================================================
|
||||
|
||||
// --- param_const_rvalue_ref.h
|
||||
|
||||
struct S {};
|
||||
struct T {};
|
||||
|
||||
auto TakesConstRValue(const S&&) -> void;
|
||||
|
||||
// --- param_value_arg_for_const_rvalue_ref.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
import Cpp library "param_const_rvalue_ref.h";
|
||||
|
||||
fn F(v: Cpp.S, cv: const Cpp.S) {
|
||||
//@dump-sem-ir-begin
|
||||
Cpp.TakesConstRValue(v);
|
||||
Cpp.TakesConstRValue(cv);
|
||||
//@dump-sem-ir-end
|
||||
}
|
||||
|
||||
// --- param_init_arg_for_const_rvalue_ref.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
import Cpp library "param_const_rvalue_ref.h";
|
||||
|
||||
fn Make() -> Cpp.S;
|
||||
|
||||
fn F() {
|
||||
Cpp.TakesConstRValue({});
|
||||
Cpp.TakesConstRValue({} as Cpp.S);
|
||||
Cpp.TakesConstRValue(({} as Cpp.S) as const Cpp.S);
|
||||
Cpp.TakesConstRValue(Make());
|
||||
}
|
||||
|
||||
// --- fail_param_lvalue_ref_arg_const_rvalue_ref.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
import Cpp library "param_const_rvalue_ref.h";
|
||||
|
||||
fn F() {
|
||||
//@dump-sem-ir-begin
|
||||
var s: Cpp.S;
|
||||
// CHECK:STDERR: fail_param_lvalue_ref_arg_const_rvalue_ref.carbon:[[@LINE+8]]:25: error: no matching function for call to 'TakesConstRValue' [CppInteropParseError]
|
||||
// CHECK:STDERR: 17 | Cpp.TakesConstRValue(s);
|
||||
// CHECK:STDERR: | ^
|
||||
// CHECK:STDERR: fail_param_lvalue_ref_arg_const_rvalue_ref.carbon:[[@LINE-8]]:10: in file included here [InCppInclude]
|
||||
// CHECK:STDERR: ./param_const_rvalue_ref.h:5:6: note: candidate function not viable: expects an rvalue for 1st argument [CppInteropParseNote]
|
||||
// CHECK:STDERR: 5 | auto TakesConstRValue(const S&&) -> void;
|
||||
// CHECK:STDERR: | ^ ~~~~~~~~~
|
||||
// CHECK:STDERR:
|
||||
Cpp.TakesConstRValue(s);
|
||||
|
||||
var t: Cpp.T;
|
||||
// CHECK:STDERR: fail_param_lvalue_ref_arg_const_rvalue_ref.carbon:[[@LINE+8]]:25: error: no matching function for call to 'TakesConstRValue' [CppInteropParseError]
|
||||
// CHECK:STDERR: 28 | Cpp.TakesConstRValue(t);
|
||||
// CHECK:STDERR: | ^
|
||||
// CHECK:STDERR: fail_param_lvalue_ref_arg_const_rvalue_ref.carbon:[[@LINE-19]]:10: in file included here [InCppInclude]
|
||||
// CHECK:STDERR: ./param_const_rvalue_ref.h:5:6: note: candidate function not viable: no known conversion from 'T' to 'const S' for 1st argument [CppInteropParseNote]
|
||||
// CHECK:STDERR: 5 | auto TakesConstRValue(const S&&) -> void;
|
||||
// CHECK:STDERR: | ^ ~~~~~~~~~
|
||||
// CHECK:STDERR:
|
||||
Cpp.TakesConstRValue(t);
|
||||
//@dump-sem-ir-end
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Lvalue reference as return type
|
||||
// ============================================================================
|
||||
@@ -315,6 +386,61 @@ fn F() {
|
||||
let unused ref s: Cpp.S = Cpp.ReturnConstLValue();
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Forwarding references
|
||||
// ============================================================================
|
||||
|
||||
// --- forwarding_reference.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
import Cpp;
|
||||
|
||||
class X {}
|
||||
|
||||
inline Cpp '''c++
|
||||
template<typename T> void TakeAnything_ExpectLRef(T&&) {
|
||||
static_assert(__is_same(T, Carbon::X&));
|
||||
}
|
||||
template<typename T> void TakeAnything_ExpectConstLRef(T&&) {
|
||||
static_assert(__is_same(T, const Carbon::X&));
|
||||
}
|
||||
template<typename T> void TakeAnything_ExpectRRef(T&&) {
|
||||
static_assert(__is_same(T, Carbon::X));
|
||||
}
|
||||
template<typename T> void TakeAnything_ExpectConstRRef(T&&) {
|
||||
static_assert(__is_same(T, const Carbon::X));
|
||||
}
|
||||
''';
|
||||
|
||||
fn Make() -> X;
|
||||
|
||||
fn PassValue(x: X) {
|
||||
//@dump-sem-ir-begin
|
||||
// TODO: Is a `const X&&` the right choice here?
|
||||
Cpp.TakeAnything_ExpectConstRRef(x);
|
||||
//@dump-sem-ir-end
|
||||
}
|
||||
|
||||
fn PassRef(ref x: X) {
|
||||
//@dump-sem-ir-begin
|
||||
Cpp.TakeAnything_ExpectLRef(ref x);
|
||||
//@dump-sem-ir-end
|
||||
}
|
||||
|
||||
fn PassConstRef(ref x: const X) {
|
||||
//@dump-sem-ir-begin
|
||||
// TODO: This crashes!
|
||||
// Cpp.TakeAnything_ExpectConstLRef(ref x);
|
||||
Cpp.TakeAnything_ExpectConstLRef(x);
|
||||
//@dump-sem-ir-end
|
||||
}
|
||||
|
||||
fn PassInit() {
|
||||
//@dump-sem-ir-begin
|
||||
Cpp.TakeAnything_ExpectRRef(Make());
|
||||
//@dump-sem-ir-end
|
||||
}
|
||||
|
||||
// CHECK:STDOUT: --- call_param_lvalue_ref.carbon
|
||||
// CHECK:STDOUT:
|
||||
@@ -838,6 +964,156 @@ fn F() {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- param_value_arg_for_const_rvalue_ref.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %S: type = class_type @S [concrete]
|
||||
// CHECK:STDOUT: %const: type = const_type %S [concrete]
|
||||
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
|
||||
// CHECK:STDOUT: %TakesConstRValue.cpp_overload_set.type: type = cpp_overload_set_type @TakesConstRValue.cpp_overload_set [concrete]
|
||||
// CHECK:STDOUT: %TakesConstRValue.cpp_overload_set.value: %TakesConstRValue.cpp_overload_set.type = cpp_overload_set_value @TakesConstRValue.cpp_overload_set [concrete]
|
||||
// CHECK:STDOUT: %ptr.ff5: type = ptr_type %const [concrete]
|
||||
// CHECK:STDOUT: %TakesConstRValue__carbon_thunk.type: type = fn_type @TakesConstRValue__carbon_thunk [concrete]
|
||||
// CHECK:STDOUT: %TakesConstRValue__carbon_thunk: %TakesConstRValue__carbon_thunk.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %ptr.5c7: type = ptr_type %S [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
// CHECK:STDOUT: %Cpp: <namespace> = namespace file.%Cpp.import_cpp, [concrete] {
|
||||
// CHECK:STDOUT: .S = %S.decl
|
||||
// CHECK:STDOUT: .TakesConstRValue = %TakesConstRValue.cpp_overload_set.value
|
||||
// CHECK:STDOUT: import Cpp//...
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %S.decl: type = class_decl @S [concrete = constants.%S] {} {}
|
||||
// CHECK:STDOUT: %TakesConstRValue.cpp_overload_set.value: %TakesConstRValue.cpp_overload_set.type = cpp_overload_set_value @TakesConstRValue.cpp_overload_set [concrete = constants.%TakesConstRValue.cpp_overload_set.value]
|
||||
// CHECK:STDOUT: %TakesConstRValue__carbon_thunk.decl: %TakesConstRValue__carbon_thunk.type = fn_decl @TakesConstRValue__carbon_thunk [concrete = constants.%TakesConstRValue__carbon_thunk] {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @F(%v.param: %S, %cv.param: %const) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Cpp.ref.loc8: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %TakesConstRValue.ref.loc8: %TakesConstRValue.cpp_overload_set.type = name_ref TakesConstRValue, imports.%TakesConstRValue.cpp_overload_set.value [concrete = constants.%TakesConstRValue.cpp_overload_set.value]
|
||||
// CHECK:STDOUT: %v.ref: %S = name_ref v, %v
|
||||
// CHECK:STDOUT: %.loc8_24: ref %S = value_as_ref %v.ref
|
||||
// CHECK:STDOUT: %addr.loc8: %ptr.5c7 = addr_of %.loc8_24
|
||||
// CHECK:STDOUT: %.loc8_25.1: %ptr.ff5 = as_compatible %addr.loc8
|
||||
// CHECK:STDOUT: %.loc8_25.2: %ptr.ff5 = converted %addr.loc8, %.loc8_25.1
|
||||
// CHECK:STDOUT: %TakesConstRValue__carbon_thunk.call.loc8: init %empty_tuple.type = call imports.%TakesConstRValue__carbon_thunk.decl(%.loc8_25.2)
|
||||
// CHECK:STDOUT: %Cpp.ref.loc9: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %TakesConstRValue.ref.loc9: %TakesConstRValue.cpp_overload_set.type = name_ref TakesConstRValue, imports.%TakesConstRValue.cpp_overload_set.value [concrete = constants.%TakesConstRValue.cpp_overload_set.value]
|
||||
// CHECK:STDOUT: %cv.ref: %const = name_ref cv, %cv
|
||||
// CHECK:STDOUT: %.loc9_24.1: %S = as_compatible %cv.ref
|
||||
// CHECK:STDOUT: %.loc9_24.2: %S = converted %cv.ref, %.loc9_24.1
|
||||
// CHECK:STDOUT: %.loc9_24.3: ref %S = value_as_ref %.loc9_24.2
|
||||
// CHECK:STDOUT: %addr.loc9: %ptr.5c7 = addr_of %.loc9_24.3
|
||||
// CHECK:STDOUT: %.loc9_26.1: %ptr.ff5 = as_compatible %addr.loc9
|
||||
// CHECK:STDOUT: %.loc9_26.2: %ptr.ff5 = converted %addr.loc9, %.loc9_26.1
|
||||
// CHECK:STDOUT: %TakesConstRValue__carbon_thunk.call.loc9: init %empty_tuple.type = call imports.%TakesConstRValue__carbon_thunk.decl(%.loc9_26.2)
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_param_lvalue_ref_arg_const_rvalue_ref.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
|
||||
// CHECK:STDOUT: %S: type = class_type @S [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.7da: type = pattern_type %S [concrete]
|
||||
// CHECK:STDOUT: %DefaultOrUnformed.type: type = facet_type <@DefaultOrUnformed> [concrete]
|
||||
// CHECK:STDOUT: %Default.type: type = facet_type <@Default> [concrete]
|
||||
// CHECK:STDOUT: %T.50c: %Default.type = symbolic_binding T, 0 [symbolic]
|
||||
// CHECK:STDOUT: %T.as_type.as.DefaultOrUnformed.impl.Op.type.2c3: type = fn_type @T.as_type.as.DefaultOrUnformed.impl.Op, @T.as_type.as.DefaultOrUnformed.impl(%T.50c) [symbolic]
|
||||
// CHECK:STDOUT: %T.as_type.as.DefaultOrUnformed.impl.Op.85d: %T.as_type.as.DefaultOrUnformed.impl.Op.type.2c3 = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %S.Op.type: type = fn_type @S.Op [concrete]
|
||||
// CHECK:STDOUT: %S.Op: %S.Op.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %custom_witness.4cd: <witness> = custom_witness (%S.Op), @Default [concrete]
|
||||
// CHECK:STDOUT: %Default.facet.889: %Default.type = facet_value %S, (%custom_witness.4cd) [concrete]
|
||||
// CHECK:STDOUT: %DefaultOrUnformed.impl_witness.386: <witness> = impl_witness imports.%DefaultOrUnformed.impl_witness_table.fc3, @T.as_type.as.DefaultOrUnformed.impl(%Default.facet.889) [concrete]
|
||||
// CHECK:STDOUT: %DefaultOrUnformed.facet.536: %DefaultOrUnformed.type = facet_value %S, (%DefaultOrUnformed.impl_witness.386) [concrete]
|
||||
// CHECK:STDOUT: %TakesConstRValue.cpp_overload_set.type: type = cpp_overload_set_type @TakesConstRValue.cpp_overload_set [concrete]
|
||||
// CHECK:STDOUT: %TakesConstRValue.cpp_overload_set.value: %TakesConstRValue.cpp_overload_set.type = cpp_overload_set_value @TakesConstRValue.cpp_overload_set [concrete]
|
||||
// CHECK:STDOUT: %T.e15: type = class_type @T [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.e6b: type = pattern_type %T.e15 [concrete]
|
||||
// CHECK:STDOUT: %T.Op.type: type = fn_type @T.Op [concrete]
|
||||
// CHECK:STDOUT: %T.Op: %T.Op.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %custom_witness.3b9: <witness> = custom_witness (%T.Op), @Default [concrete]
|
||||
// CHECK:STDOUT: %Default.facet.2fe: %Default.type = facet_value %T.e15, (%custom_witness.3b9) [concrete]
|
||||
// CHECK:STDOUT: %DefaultOrUnformed.impl_witness.23e: <witness> = impl_witness imports.%DefaultOrUnformed.impl_witness_table.fc3, @T.as_type.as.DefaultOrUnformed.impl(%Default.facet.2fe) [concrete]
|
||||
// CHECK:STDOUT: %DefaultOrUnformed.facet.08c: %DefaultOrUnformed.type = facet_value %T.e15, (%DefaultOrUnformed.impl_witness.23e) [concrete]
|
||||
// CHECK:STDOUT: %T.cpp_destructor.type: type = fn_type @T.cpp_destructor [concrete]
|
||||
// CHECK:STDOUT: %T.cpp_destructor: %T.cpp_destructor.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %S.cpp_destructor.type: type = fn_type @S.cpp_destructor [concrete]
|
||||
// CHECK:STDOUT: %S.cpp_destructor: %S.cpp_destructor.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
// CHECK:STDOUT: %Cpp: <namespace> = namespace file.%Cpp.import_cpp, [concrete] {
|
||||
// CHECK:STDOUT: .S = %S.decl
|
||||
// CHECK:STDOUT: .TakesConstRValue = %TakesConstRValue.cpp_overload_set.value
|
||||
// CHECK:STDOUT: .T = %T.decl
|
||||
// CHECK:STDOUT: import Cpp//...
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %S.decl: type = class_decl @S [concrete = constants.%S] {} {}
|
||||
// CHECK:STDOUT: %Core.import_ref.653: @T.as_type.as.DefaultOrUnformed.impl.%T.as_type.as.DefaultOrUnformed.impl.Op.type (%T.as_type.as.DefaultOrUnformed.impl.Op.type.2c3) = import_ref Core//prelude/parts/default, loc{{\d+_\d+}}, loaded [symbolic = @T.as_type.as.DefaultOrUnformed.impl.%T.as_type.as.DefaultOrUnformed.impl.Op (constants.%T.as_type.as.DefaultOrUnformed.impl.Op.85d)]
|
||||
// CHECK:STDOUT: %DefaultOrUnformed.impl_witness_table.fc3 = impl_witness_table (%Core.import_ref.653), @T.as_type.as.DefaultOrUnformed.impl [concrete]
|
||||
// CHECK:STDOUT: %TakesConstRValue.cpp_overload_set.value: %TakesConstRValue.cpp_overload_set.type = cpp_overload_set_value @TakesConstRValue.cpp_overload_set [concrete = constants.%TakesConstRValue.cpp_overload_set.value]
|
||||
// CHECK:STDOUT: %T.decl: type = class_decl @T [concrete = constants.%T.e15] {} {}
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @F() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: name_binding_decl {
|
||||
// CHECK:STDOUT: %s.patt: %pattern_type.7da = ref_binding_pattern s [concrete]
|
||||
// CHECK:STDOUT: %s.var_patt: %pattern_type.7da = var_pattern %s.patt [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %s.var: ref %S = var %s.var_patt
|
||||
// CHECK:STDOUT: %DefaultOrUnformed.facet.loc8: %DefaultOrUnformed.type = facet_value constants.%S, (constants.%DefaultOrUnformed.impl_witness.386) [concrete = constants.%DefaultOrUnformed.facet.536]
|
||||
// CHECK:STDOUT: %.loc8_15.1: %DefaultOrUnformed.type = converted constants.%S, %DefaultOrUnformed.facet.loc8 [concrete = constants.%DefaultOrUnformed.facet.536]
|
||||
// CHECK:STDOUT: %as_type.loc8: type = facet_access_type %.loc8_15.1 [concrete = constants.%S]
|
||||
// CHECK:STDOUT: %.loc8_15.2: type = converted %.loc8_15.1, %as_type.loc8 [concrete = constants.%S]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %.loc8_3: ref %S = splice_block %s.var {}
|
||||
// CHECK:STDOUT: %T.as_type.as.DefaultOrUnformed.impl.Op.call.loc8: init %S to %.loc8_3 = call %T.as_type.as.DefaultOrUnformed.impl.Op.specific_fn.1()
|
||||
// CHECK:STDOUT: assign %s.var, %T.as_type.as.DefaultOrUnformed.impl.Op.call.loc8
|
||||
// CHECK:STDOUT: %.loc8_13: type = splice_block %S.ref [concrete = constants.%S] {
|
||||
// CHECK:STDOUT: %Cpp.ref.loc8: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %S.ref: type = name_ref S, imports.%S.decl [concrete = constants.%S]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %s: ref %S = ref_binding s, %s.var
|
||||
// CHECK:STDOUT: %Cpp.ref.loc17: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %TakesConstRValue.ref.loc17: %TakesConstRValue.cpp_overload_set.type = name_ref TakesConstRValue, imports.%TakesConstRValue.cpp_overload_set.value [concrete = constants.%TakesConstRValue.cpp_overload_set.value]
|
||||
// CHECK:STDOUT: %s.ref: ref %S = name_ref s, %s
|
||||
// CHECK:STDOUT: name_binding_decl {
|
||||
// CHECK:STDOUT: %t.patt: %pattern_type.e6b = ref_binding_pattern t [concrete]
|
||||
// CHECK:STDOUT: %t.var_patt: %pattern_type.e6b = var_pattern %t.patt [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %t.var: ref %T.e15 = var %t.var_patt
|
||||
// CHECK:STDOUT: %DefaultOrUnformed.facet.loc19: %DefaultOrUnformed.type = facet_value constants.%T.e15, (constants.%DefaultOrUnformed.impl_witness.23e) [concrete = constants.%DefaultOrUnformed.facet.08c]
|
||||
// CHECK:STDOUT: %.loc19_15.1: %DefaultOrUnformed.type = converted constants.%T.e15, %DefaultOrUnformed.facet.loc19 [concrete = constants.%DefaultOrUnformed.facet.08c]
|
||||
// CHECK:STDOUT: %as_type.loc19: type = facet_access_type %.loc19_15.1 [concrete = constants.%T.e15]
|
||||
// CHECK:STDOUT: %.loc19_15.2: type = converted %.loc19_15.1, %as_type.loc19 [concrete = constants.%T.e15]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %.loc19_3: ref %T.e15 = splice_block %t.var {}
|
||||
// CHECK:STDOUT: %T.as_type.as.DefaultOrUnformed.impl.Op.call.loc19: init %T.e15 to %.loc19_3 = call %T.as_type.as.DefaultOrUnformed.impl.Op.specific_fn.2()
|
||||
// CHECK:STDOUT: assign %t.var, %T.as_type.as.DefaultOrUnformed.impl.Op.call.loc19
|
||||
// CHECK:STDOUT: %.loc19_13: type = splice_block %T.ref [concrete = constants.%T.e15] {
|
||||
// CHECK:STDOUT: %Cpp.ref.loc19: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %T.ref: type = name_ref T, imports.%T.decl [concrete = constants.%T.e15]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %t: ref %T.e15 = ref_binding t, %t.var
|
||||
// CHECK:STDOUT: %Cpp.ref.loc28: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %TakesConstRValue.ref.loc28: %TakesConstRValue.cpp_overload_set.type = name_ref TakesConstRValue, imports.%TakesConstRValue.cpp_overload_set.value [concrete = constants.%TakesConstRValue.cpp_overload_set.value]
|
||||
// CHECK:STDOUT: %t.ref: ref %T.e15 = name_ref t, %t
|
||||
// CHECK:STDOUT: %T.cpp_destructor.bound: <bound method> = bound_method %t.var, constants.%T.cpp_destructor
|
||||
// CHECK:STDOUT: %T.cpp_destructor.call: init %empty_tuple.type = call %T.cpp_destructor.bound(%t.var)
|
||||
// CHECK:STDOUT: %S.cpp_destructor.bound: <bound method> = bound_method %s.var, constants.%S.cpp_destructor
|
||||
// CHECK:STDOUT: %S.cpp_destructor.call: init %empty_tuple.type = call %S.cpp_destructor.bound(%s.var)
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- call_return_lvalue_ref.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
@@ -954,3 +1230,117 @@ fn F() {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- forwarding_reference.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %X: type = class_type @X [concrete]
|
||||
// CHECK:STDOUT: %Make.type: type = fn_type @Make [concrete]
|
||||
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
|
||||
// CHECK:STDOUT: %Make: %Make.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %TakeAnything_ExpectConstRRef.cpp_overload_set.type: type = cpp_overload_set_type @TakeAnything_ExpectConstRRef.cpp_overload_set [concrete]
|
||||
// CHECK:STDOUT: %TakeAnything_ExpectConstRRef.cpp_overload_set.value: %TakeAnything_ExpectConstRRef.cpp_overload_set.type = cpp_overload_set_value @TakeAnything_ExpectConstRRef.cpp_overload_set [concrete]
|
||||
// CHECK:STDOUT: %const: type = const_type %X [concrete]
|
||||
// CHECK:STDOUT: %ptr.d4c: type = ptr_type %const [concrete]
|
||||
// CHECK:STDOUT: %TakeAnything_ExpectConstRRef__carbon_thunk.type: type = fn_type @TakeAnything_ExpectConstRRef__carbon_thunk [concrete]
|
||||
// CHECK:STDOUT: %TakeAnything_ExpectConstRRef__carbon_thunk: %TakeAnything_ExpectConstRRef__carbon_thunk.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %ptr.2a9: type = ptr_type %X [concrete]
|
||||
// CHECK:STDOUT: %TakeAnything_ExpectLRef.cpp_overload_set.type: type = cpp_overload_set_type @TakeAnything_ExpectLRef.cpp_overload_set [concrete]
|
||||
// CHECK:STDOUT: %TakeAnything_ExpectLRef.cpp_overload_set.value: %TakeAnything_ExpectLRef.cpp_overload_set.type = cpp_overload_set_value @TakeAnything_ExpectLRef.cpp_overload_set [concrete]
|
||||
// CHECK:STDOUT: %TakeAnything_ExpectLRef.type: type = fn_type @TakeAnything_ExpectLRef [concrete]
|
||||
// CHECK:STDOUT: %TakeAnything_ExpectLRef: %TakeAnything_ExpectLRef.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %TakeAnything_ExpectConstLRef.cpp_overload_set.type: type = cpp_overload_set_type @TakeAnything_ExpectConstLRef.cpp_overload_set [concrete]
|
||||
// CHECK:STDOUT: %TakeAnything_ExpectConstLRef.cpp_overload_set.value: %TakeAnything_ExpectConstLRef.cpp_overload_set.type = cpp_overload_set_value @TakeAnything_ExpectConstLRef.cpp_overload_set [concrete]
|
||||
// CHECK:STDOUT: %TakeAnything_ExpectConstLRef__carbon_thunk.type: type = fn_type @TakeAnything_ExpectConstLRef__carbon_thunk [concrete]
|
||||
// CHECK:STDOUT: %TakeAnything_ExpectConstLRef__carbon_thunk: %TakeAnything_ExpectConstLRef__carbon_thunk.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %TakeAnything_ExpectRRef.cpp_overload_set.type: type = cpp_overload_set_type @TakeAnything_ExpectRRef.cpp_overload_set [concrete]
|
||||
// CHECK:STDOUT: %TakeAnything_ExpectRRef.cpp_overload_set.value: %TakeAnything_ExpectRRef.cpp_overload_set.type = cpp_overload_set_value @TakeAnything_ExpectRRef.cpp_overload_set [concrete]
|
||||
// CHECK:STDOUT: %TakeAnything_ExpectRRef__carbon_thunk.type: type = fn_type @TakeAnything_ExpectRRef__carbon_thunk [concrete]
|
||||
// CHECK:STDOUT: %TakeAnything_ExpectRRef__carbon_thunk: %TakeAnything_ExpectRRef__carbon_thunk.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
// CHECK:STDOUT: %Cpp: <namespace> = namespace file.%Cpp.import_cpp, [concrete] {
|
||||
// CHECK:STDOUT: .TakeAnything_ExpectConstRRef = %TakeAnything_ExpectConstRRef.cpp_overload_set.value
|
||||
// CHECK:STDOUT: .TakeAnything_ExpectLRef = %TakeAnything_ExpectLRef.cpp_overload_set.value
|
||||
// CHECK:STDOUT: .TakeAnything_ExpectConstLRef = %TakeAnything_ExpectConstLRef.cpp_overload_set.value
|
||||
// CHECK:STDOUT: .TakeAnything_ExpectRRef = %TakeAnything_ExpectRRef.cpp_overload_set.value
|
||||
// CHECK:STDOUT: import Cpp//...
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %TakeAnything_ExpectConstRRef.cpp_overload_set.value: %TakeAnything_ExpectConstRRef.cpp_overload_set.type = cpp_overload_set_value @TakeAnything_ExpectConstRRef.cpp_overload_set [concrete = constants.%TakeAnything_ExpectConstRRef.cpp_overload_set.value]
|
||||
// CHECK:STDOUT: %TakeAnything_ExpectConstRRef__carbon_thunk.decl: %TakeAnything_ExpectConstRRef__carbon_thunk.type = fn_decl @TakeAnything_ExpectConstRRef__carbon_thunk [concrete = constants.%TakeAnything_ExpectConstRRef__carbon_thunk] {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %TakeAnything_ExpectLRef.cpp_overload_set.value: %TakeAnything_ExpectLRef.cpp_overload_set.type = cpp_overload_set_value @TakeAnything_ExpectLRef.cpp_overload_set [concrete = constants.%TakeAnything_ExpectLRef.cpp_overload_set.value]
|
||||
// CHECK:STDOUT: %TakeAnything_ExpectLRef.decl: %TakeAnything_ExpectLRef.type = fn_decl @TakeAnything_ExpectLRef [concrete = constants.%TakeAnything_ExpectLRef] {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %TakeAnything_ExpectConstLRef.cpp_overload_set.value: %TakeAnything_ExpectConstLRef.cpp_overload_set.type = cpp_overload_set_value @TakeAnything_ExpectConstLRef.cpp_overload_set [concrete = constants.%TakeAnything_ExpectConstLRef.cpp_overload_set.value]
|
||||
// CHECK:STDOUT: %TakeAnything_ExpectConstLRef__carbon_thunk.decl: %TakeAnything_ExpectConstLRef__carbon_thunk.type = fn_decl @TakeAnything_ExpectConstLRef__carbon_thunk [concrete = constants.%TakeAnything_ExpectConstLRef__carbon_thunk] {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %TakeAnything_ExpectRRef.cpp_overload_set.value: %TakeAnything_ExpectRRef.cpp_overload_set.type = cpp_overload_set_value @TakeAnything_ExpectRRef.cpp_overload_set [concrete = constants.%TakeAnything_ExpectRRef.cpp_overload_set.value]
|
||||
// CHECK:STDOUT: %TakeAnything_ExpectRRef__carbon_thunk.decl: %TakeAnything_ExpectRRef__carbon_thunk.type = fn_decl @TakeAnything_ExpectRRef__carbon_thunk [concrete = constants.%TakeAnything_ExpectRRef__carbon_thunk] {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @PassValue(%x.param: %X) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %TakeAnything_ExpectConstRRef.ref: %TakeAnything_ExpectConstRRef.cpp_overload_set.type = name_ref TakeAnything_ExpectConstRRef, imports.%TakeAnything_ExpectConstRRef.cpp_overload_set.value [concrete = constants.%TakeAnything_ExpectConstRRef.cpp_overload_set.value]
|
||||
// CHECK:STDOUT: %x.ref: %X = name_ref x, %x
|
||||
// CHECK:STDOUT: %.loc28_36: ref %X = value_as_ref %x.ref
|
||||
// CHECK:STDOUT: %addr: %ptr.2a9 = addr_of %.loc28_36
|
||||
// CHECK:STDOUT: %.loc28_37.1: %ptr.d4c = as_compatible %addr
|
||||
// CHECK:STDOUT: %.loc28_37.2: %ptr.d4c = converted %addr, %.loc28_37.1
|
||||
// CHECK:STDOUT: %TakeAnything_ExpectConstRRef__carbon_thunk.call: init %empty_tuple.type = call imports.%TakeAnything_ExpectConstRRef__carbon_thunk.decl(%.loc28_37.2)
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @PassRef(%x.param: ref %X) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %TakeAnything_ExpectLRef.ref: %TakeAnything_ExpectLRef.cpp_overload_set.type = name_ref TakeAnything_ExpectLRef, imports.%TakeAnything_ExpectLRef.cpp_overload_set.value [concrete = constants.%TakeAnything_ExpectLRef.cpp_overload_set.value]
|
||||
// CHECK:STDOUT: %x.ref: ref %X = name_ref x, %x
|
||||
// CHECK:STDOUT: %.loc34: %X = ref_tag %x.ref
|
||||
// CHECK:STDOUT: %TakeAnything_ExpectLRef.call: init %empty_tuple.type = call imports.%TakeAnything_ExpectLRef.decl(%.loc34)
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @PassConstRef(%x.param: ref %const) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %TakeAnything_ExpectConstLRef.ref: %TakeAnything_ExpectConstLRef.cpp_overload_set.type = name_ref TakeAnything_ExpectConstLRef, imports.%TakeAnything_ExpectConstLRef.cpp_overload_set.value [concrete = constants.%TakeAnything_ExpectConstLRef.cpp_overload_set.value]
|
||||
// CHECK:STDOUT: %x.ref: ref %const = name_ref x, %x
|
||||
// CHECK:STDOUT: %.loc42_36.1: ref %X = as_compatible %x.ref
|
||||
// CHECK:STDOUT: %.loc42_36.2: ref %X = converted %x.ref, %.loc42_36.1
|
||||
// CHECK:STDOUT: %.loc42_36.3: %X = acquire_value %.loc42_36.2
|
||||
// CHECK:STDOUT: %.loc42_36.4: ref %X = value_as_ref %.loc42_36.3
|
||||
// CHECK:STDOUT: %addr: %ptr.2a9 = addr_of %.loc42_36.4
|
||||
// CHECK:STDOUT: %.loc42_37.1: %ptr.d4c = as_compatible %addr
|
||||
// CHECK:STDOUT: %.loc42_37.2: %ptr.d4c = converted %addr, %.loc42_37.1
|
||||
// CHECK:STDOUT: %TakeAnything_ExpectConstLRef__carbon_thunk.call: init %empty_tuple.type = call imports.%TakeAnything_ExpectConstLRef__carbon_thunk.decl(%.loc42_37.2)
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @PassInit() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %TakeAnything_ExpectRRef.ref: %TakeAnything_ExpectRRef.cpp_overload_set.type = name_ref TakeAnything_ExpectRRef, imports.%TakeAnything_ExpectRRef.cpp_overload_set.value [concrete = constants.%TakeAnything_ExpectRRef.cpp_overload_set.value]
|
||||
// CHECK:STDOUT: %Make.ref: %Make.type = name_ref Make, file.%Make.decl [concrete = constants.%Make]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %Make.call: init %X to %_.var = call %Make.ref()
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %addr: %ptr.2a9 = addr_of %_.var
|
||||
// CHECK:STDOUT: %TakeAnything_ExpectRRef__carbon_thunk.call: init %empty_tuple.type = call imports.%TakeAnything_ExpectRRef__carbon_thunk.decl(%addr)
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
|
||||
Reference in New Issue
Block a user