mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-04 22:02:52 +01:00
Map Carbon value expressions to const-qualified C++ prvalues. (#6880)
In C++ overload resolution, when mapping a Carbon value expression into a C++ argument, produce a const-qualified argument where possible. This has two effects: * Overload resolution does not consider non-const-qualified member functions to be viable for a prvalue self any more. This is desirable since such functions are not actually callable with a prvalue self, and permits overload resolution to pick a const-qualified overload instead. * Overload resolution does not allow a Carbon value expression to be passed to a C++ `T&&` parameter any more. This is desirable since it's not correct to move from a value expression. Previously we allowed this and moved from the value!
This commit is contained in:
@@ -283,7 +283,7 @@ void operator+(C, short);
|
||||
''';
|
||||
|
||||
fn Test(c: Cpp.C) {
|
||||
// CHECK:STDERR: fail_ambiguous.carbon:[[@LINE+10]]:5: error: use of overloaded operator '+' is ambiguous (with operand types 'C' and 'int') [CppInteropParseError]
|
||||
// CHECK:STDERR: fail_ambiguous.carbon:[[@LINE+10]]:5: error: use of overloaded operator '+' is ambiguous (with operand types 'const C' and 'int') [CppInteropParseError]
|
||||
// CHECK:STDERR: 21 | c + 1;
|
||||
// CHECK:STDERR: | ^
|
||||
// CHECK:STDERR: fail_ambiguous.carbon:[[@LINE-8]]:6: note: candidate function [CppInteropParseNote]
|
||||
|
||||
+10
-68
@@ -48,7 +48,7 @@ fn F() {
|
||||
// CHECK:STDERR: 18 | Cpp.TakesLValue(s);
|
||||
// CHECK:STDERR: | ^
|
||||
// CHECK:STDERR: fail_param_lvalue_ref.carbon:[[@LINE-9]]:10: in file included here [InCppInclude]
|
||||
// CHECK:STDERR: ./param_lvalue_ref.h:5:6: note: candidate function not viable: expects an lvalue for 1st argument [CppInteropParseNote]
|
||||
// CHECK:STDERR: ./param_lvalue_ref.h:5:6: note: candidate function not viable: 1st argument ('const S') would lose const qualifier [CppInteropParseNote]
|
||||
// CHECK:STDERR: 5 | auto TakesLValue(S&) -> void;
|
||||
// CHECK:STDERR: | ^ ~~
|
||||
// CHECK:STDERR:
|
||||
@@ -111,21 +111,23 @@ fn F() {
|
||||
//@dump-sem-ir-end
|
||||
}
|
||||
|
||||
// --- todo_fail_param_value_arg_for_rvalue_ref.carbon
|
||||
// --- fail_param_value_arg_for_rvalue_ref.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
import Cpp library "param_rvalue_ref.h";
|
||||
|
||||
fn F() {
|
||||
//@dump-sem-ir-begin
|
||||
// TODO: We should probably reject binding an rvalue reference to a value
|
||||
// expression. If we don't reject, we should instead force a copy to be made,
|
||||
// at least if the type has a pointer value representation, so that moving
|
||||
// from the reference doesn't alter tne original value.
|
||||
let s: Cpp.S = {};
|
||||
// CHECK:STDERR: fail_param_value_arg_for_rvalue_ref.carbon:[[@LINE+8]]:20: error: no matching function for call to 'TakesRValue' [CppInteropParseError]
|
||||
// CHECK:STDERR: 16 | Cpp.TakesRValue(s);
|
||||
// CHECK:STDERR: | ^
|
||||
// CHECK:STDERR: fail_param_value_arg_for_rvalue_ref.carbon:[[@LINE-7]]:10: in file included here [InCppInclude]
|
||||
// CHECK:STDERR: ./param_rvalue_ref.h:5:6: note: candidate function not viable: 1st argument ('const S') would lose const qualifier [CppInteropParseNote]
|
||||
// CHECK:STDERR: 5 | auto TakesRValue(S&&) -> void;
|
||||
// CHECK:STDERR: | ^ ~~~
|
||||
// CHECK:STDERR:
|
||||
Cpp.TakesRValue(s);
|
||||
//@dump-sem-ir-end
|
||||
}
|
||||
|
||||
// --- fail_param_rvalue_ref.carbon
|
||||
@@ -526,66 +528,6 @@ fn F() {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- todo_fail_param_value_arg_for_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: %empty_struct_type: type = struct_type {} [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.7da: type = pattern_type %S [concrete]
|
||||
// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %S.val: %S = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %TakesRValue.cpp_overload_set.type: type = cpp_overload_set_type @TakesRValue.cpp_overload_set [concrete]
|
||||
// CHECK:STDOUT: %TakesRValue.cpp_overload_set.value: %TakesRValue.cpp_overload_set.type = cpp_overload_set_value @TakesRValue.cpp_overload_set [concrete]
|
||||
// CHECK:STDOUT: %ptr.5c7: type = ptr_type %S [concrete]
|
||||
// CHECK:STDOUT: %TakesRValue__carbon_thunk.type: type = fn_type @TakesRValue__carbon_thunk [concrete]
|
||||
// CHECK:STDOUT: %TakesRValue__carbon_thunk: %TakesRValue__carbon_thunk.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: .TakesRValue = %TakesRValue.cpp_overload_set.value
|
||||
// CHECK:STDOUT: import Cpp//...
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %S.decl: type = class_decl @S [concrete = constants.%S] {} {}
|
||||
// CHECK:STDOUT: %TakesRValue.cpp_overload_set.value: %TakesRValue.cpp_overload_set.type = cpp_overload_set_value @TakesRValue.cpp_overload_set [concrete = constants.%TakesRValue.cpp_overload_set.value]
|
||||
// CHECK:STDOUT: %TakesRValue__carbon_thunk.decl: %TakesRValue__carbon_thunk.type = fn_decl @TakesRValue__carbon_thunk [concrete = constants.%TakesRValue__carbon_thunk] {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @F() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: name_binding_decl {
|
||||
// CHECK:STDOUT: %s.patt: %pattern_type.7da = value_binding_pattern s [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %.loc12_19.1: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct]
|
||||
// CHECK:STDOUT: %.loc12_13: type = splice_block %S.ref [concrete = constants.%S] {
|
||||
// CHECK:STDOUT: %Cpp.ref.loc12: <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: %.loc12_19.2: ref %S = temporary_storage
|
||||
// CHECK:STDOUT: %.loc12_19.3: init %S to %.loc12_19.2 = class_init () [concrete = constants.%S.val]
|
||||
// CHECK:STDOUT: %.loc12_19.4: ref %S = temporary %.loc12_19.2, %.loc12_19.3
|
||||
// CHECK:STDOUT: %.loc12_19.5: ref %S = converted %.loc12_19.1, %.loc12_19.4
|
||||
// CHECK:STDOUT: %.loc12_19.6: %S = acquire_value %.loc12_19.5
|
||||
// CHECK:STDOUT: %s: %S = value_binding s, %.loc12_19.6
|
||||
// CHECK:STDOUT: %Cpp.ref.loc13: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %TakesRValue.ref: %TakesRValue.cpp_overload_set.type = name_ref TakesRValue, imports.%TakesRValue.cpp_overload_set.value [concrete = constants.%TakesRValue.cpp_overload_set.value]
|
||||
// CHECK:STDOUT: %s.ref: %S = name_ref s, %s
|
||||
// CHECK:STDOUT: %.loc13: ref %S = value_as_ref %s.ref
|
||||
// CHECK:STDOUT: %addr: %ptr.5c7 = addr_of %.loc13
|
||||
// CHECK:STDOUT: %TakesRValue__carbon_thunk.call: init %empty_tuple.type = call imports.%TakesRValue__carbon_thunk.decl(%addr)
|
||||
// CHECK:STDOUT: %S.cpp_destructor.bound: <bound method> = bound_method %.loc12_19.4, constants.%S.cpp_destructor
|
||||
// CHECK:STDOUT: %S.cpp_destructor.call: init %empty_tuple.type = call %S.cpp_destructor.bound(%.loc12_19.4)
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_param_rvalue_ref.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
|
||||
Reference in New Issue
Block a user