mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 17:31:07 +01:00
Make C++ types impl Core.Default. (#6962)
C++ classes that are default-constructible now implement `Core.Default` by calling the default constructor.
This commit is contained in:
@@ -21,6 +21,10 @@ class C {
|
||||
C();
|
||||
};
|
||||
|
||||
struct NoDefault {
|
||||
NoDefault(int);
|
||||
};
|
||||
|
||||
// --- import_default.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
@@ -33,6 +37,59 @@ fn F() {
|
||||
//@dump-sem-ir-end
|
||||
}
|
||||
|
||||
// --- implicit_default.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
import Cpp library "default.h";
|
||||
|
||||
fn F() {
|
||||
//@dump-sem-ir-begin
|
||||
var unused c: Cpp.C;
|
||||
//@dump-sem-ir-end
|
||||
}
|
||||
|
||||
fn G(T:! Core.Default & Core.Destroy) {
|
||||
var unused x: T;
|
||||
}
|
||||
|
||||
fn CallG() {
|
||||
G(Cpp.C);
|
||||
}
|
||||
|
||||
// --- todo_fail_no_default_decl.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
import Cpp library "default.h";
|
||||
|
||||
fn F() {
|
||||
// TODO: This should fail, but currently does not because the min_prelude
|
||||
// version of UnformedInit is currently implemented by every type.
|
||||
var unused x: Cpp.NoDefault;
|
||||
}
|
||||
|
||||
// --- fail_no_default.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
import Cpp library "default.h";
|
||||
|
||||
fn G(T:! Core.Default & Core.Destroy) {
|
||||
var unused x: T;
|
||||
}
|
||||
|
||||
fn CallG() {
|
||||
// CHECK:STDERR: fail_no_default.carbon:[[@LINE+7]]:3: error: cannot convert type `NoDefault` into type implementing `Core.Default & Core.Destroy` [ConversionFailureTypeToFacet]
|
||||
// CHECK:STDERR: G(Cpp.NoDefault);
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~
|
||||
// CHECK:STDERR: fail_no_default.carbon:[[@LINE-8]]:6: note: initializing generic parameter `T` declared here [InitializingGenericParam]
|
||||
// CHECK:STDERR: fn G(T:! Core.Default & Core.Destroy) {
|
||||
// CHECK:STDERR: ^
|
||||
// CHECK:STDERR:
|
||||
G(Cpp.NoDefault);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Non default constructor
|
||||
// ============================================================================
|
||||
@@ -308,6 +365,62 @@ fn F() {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- implicit_default.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
|
||||
// CHECK:STDOUT: %C: type = class_type @C [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.217: type = pattern_type %C [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.binding.as_type.as.DefaultOrUnformed.impl.Op.type.8d1: type = fn_type @T.binding.as_type.as.DefaultOrUnformed.impl.Op, @T.binding.as_type.as.DefaultOrUnformed.impl(%T.50c) [symbolic]
|
||||
// CHECK:STDOUT: %T.binding.as_type.as.DefaultOrUnformed.impl.Op.185: %T.binding.as_type.as.DefaultOrUnformed.impl.Op.type.8d1 = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %C.Op.type: type = fn_type @C.Op [concrete]
|
||||
// CHECK:STDOUT: %C.Op: %C.Op.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %custom_witness.a0a: <witness> = custom_witness (%C.Op), @Default [concrete]
|
||||
// CHECK:STDOUT: %Default.facet.fdc: %Default.type = facet_value %C, (%custom_witness.a0a) [concrete]
|
||||
// CHECK:STDOUT: %DefaultOrUnformed.impl_witness.2aa: <witness> = impl_witness imports.%DefaultOrUnformed.impl_witness_table.608, @T.binding.as_type.as.DefaultOrUnformed.impl(%Default.facet.fdc) [concrete]
|
||||
// CHECK:STDOUT: %DefaultOrUnformed.facet.898: %DefaultOrUnformed.type = facet_value %C, (%DefaultOrUnformed.impl_witness.2aa) [concrete]
|
||||
// CHECK:STDOUT: %C.cpp_destructor.type: type = fn_type @C.cpp_destructor [concrete]
|
||||
// CHECK:STDOUT: %C.cpp_destructor: %C.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: .C = %C.decl
|
||||
// CHECK:STDOUT: import Cpp//...
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {}
|
||||
// CHECK:STDOUT: %Core.import_ref.9c6: @T.binding.as_type.as.DefaultOrUnformed.impl.%T.binding.as_type.as.DefaultOrUnformed.impl.Op.type (%T.binding.as_type.as.DefaultOrUnformed.impl.Op.type.8d1) = import_ref Core//prelude/parts/default, loc{{\d+_\d+}}, loaded [symbolic = @T.binding.as_type.as.DefaultOrUnformed.impl.%T.binding.as_type.as.DefaultOrUnformed.impl.Op (constants.%T.binding.as_type.as.DefaultOrUnformed.impl.Op.185)]
|
||||
// CHECK:STDOUT: %DefaultOrUnformed.impl_witness_table.608 = impl_witness_table (%Core.import_ref.9c6), @T.binding.as_type.as.DefaultOrUnformed.impl [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @F() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: name_binding_decl {
|
||||
// CHECK:STDOUT: %c.patt: %pattern_type.217 = ref_binding_pattern c [concrete]
|
||||
// CHECK:STDOUT: %c.var_patt: %pattern_type.217 = var_pattern %c.patt [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %c.var: ref %C = var %c.var_patt
|
||||
// CHECK:STDOUT: %DefaultOrUnformed.facet: %DefaultOrUnformed.type = facet_value constants.%C, (constants.%DefaultOrUnformed.impl_witness.2aa) [concrete = constants.%DefaultOrUnformed.facet.898]
|
||||
// CHECK:STDOUT: %.loc8_22.1: %DefaultOrUnformed.type = converted constants.%C, %DefaultOrUnformed.facet [concrete = constants.%DefaultOrUnformed.facet.898]
|
||||
// CHECK:STDOUT: %as_type: type = facet_access_type %.loc8_22.1 [concrete = constants.%C]
|
||||
// CHECK:STDOUT: %.loc8_22.2: type = converted %.loc8_22.1, %as_type [concrete = constants.%C]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %.loc8_3: ref %C = splice_block %c.var {}
|
||||
// CHECK:STDOUT: %T.binding.as_type.as.DefaultOrUnformed.impl.Op.call: init %C to %.loc8_3 = call %T.binding.as_type.as.DefaultOrUnformed.impl.Op.specific_fn()
|
||||
// CHECK:STDOUT: assign %c.var, %T.binding.as_type.as.DefaultOrUnformed.impl.Op.call
|
||||
// CHECK:STDOUT: %.loc8_20: type = splice_block %C.ref [concrete = constants.%C] {
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %C.ref: type = name_ref C, imports.%C.decl [concrete = constants.%C]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %c: ref %C = ref_binding c, %c.var
|
||||
// CHECK:STDOUT: %C.cpp_destructor.bound: <bound method> = bound_method %c.var, constants.%C.cpp_destructor
|
||||
// CHECK:STDOUT: %C.cpp_destructor.call: init %empty_tuple.type = call %C.cpp_destructor.bound(%c.var)
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- import_non_default.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
|
||||
Reference in New Issue
Block a user