Files
carbon-lang/toolchain/check/testdata/impl/lookup/fail_poison_custom_witness.carbon
T
Christopher Di Bella f7cd39428e Add Destroy.SubobjectDestroy as a temporary replacement for Destroy.Op (#7773)
This change partially implements [PR #7362], which revises how objects
are destroyed. It is a partial implementation for two reasons:

1. This change moves `Destroy.Op`'s current behaviour into
`Destroy.SubobjectDestroy`, but it doesn't add support for objects with
non-trivial destruction.
2. `Destroy.SubobjectDestroy` is a workaround for `require impls
SubobjectDestroy`. We aren't able to use the latter until the dependents
add their requirements' implementations to their own witness tables.

[PR #7362]: https://github.com/carbon-language/carbon-lang/pulls/7362
2026-09-24 00:06:28 +00:00

82 lines
2.6 KiB
Plaintext

// 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
//
// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/none.carbon
//
// AUTOUPDATE
// TIP: To test this file alone, run:
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/impl/lookup/fail_poison_custom_witness.carbon
// TIP: To dump output, run:
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/impl/lookup/fail_poison_custom_witness.carbon
// --- destroy.carbon
package Core library "destroy";
// TODO: uncomment when `require impls` adds a witness table entry.
// interface SubobjectDestroy {
// final fn Op(ref self) = "subobject.destroy";
// }
interface Destroy {
// TODO: uncomment when `require impls` adds a witness table entry.
// require impls SubobjectDestroy;
// TODO: change `Self` to `partial Self`.
fn Op(ref self);
// TODO: remove when `require impls` adds a witness table entry.
final fn SubobjectDestroy(unused ref self) {
// This function body is ignored by the toolchain. We can't use
// a built-in because the compiler treats it as an error. We
// should address this at some point, but it's not a high
// priority right now.
}
final fn SelfDestruct(ref self) {
self.Op();
self.SubobjectDestroy();
}
}
// TODO: uncomment when `require impls` adds a witness table entry.
// impl forall [T: SubobjectDestroy] partial T as Destroy {
// alias Op = T.Op;
// }
impl forall [T: type] T as Destroy {
fn Op(unused ref self) {}
}
// --- fail_poison_custom_witness.carbon
library "[[@TEST_NAME]]";
import Core library "destroy";
import Cpp;
inline Cpp '''
struct X {};
struct A {
virtual void f(const X& x) = 0;
};
''';
// CHECK:STDERR: fail_poison_custom_witness.carbon:[[@LINE+8]]:1: error: found `impl` for Cpp.A as Destroy, which has a custom witness [PoisonedImplLookupCustomResult]
// CHECK:STDERR: class B {
// CHECK:STDERR: ^~~~~~~~~
// CHECK:STDERR: fail_poison_custom_witness.carbon:[[@LINE-14]]:1: in import [InImport]
// CHECK:STDERR: destroy.carbon:35:1: note: the use tried to select the `impl` here, but a custom witness was already chosen [PoisonedImplLookupCustomResultNoteBadImpl]
// CHECK:STDERR: impl forall [T: type] T as Destroy {
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
class B {
extend base: Cpp.A;
override fn f(unused self, unused x: Cpp.X) {}
}
inline Cpp '''
Carbon::B b;
''';