Browse Source

Add a test where `impls` requires things of another generic type (#5713)

From open discussion on 2025-06-23:
https://docs.google.com/document/d/1Yt-i5AmF76LSvD4TrWRIAE_92kii6j5yFiW-S7ahzlg/edit?tab=t.0#heading=h.5mygrwse32v5

The test does not pass yet, as we have not completed implementation of
`impls` constraints.
Dana Jansens 10 months ago
parent
commit
67b67af7a6

+ 36 - 0
toolchain/check/testdata/facet/validate_impl_constraints.carbon

@@ -0,0 +1,36 @@
+// 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/facet_types.carbon
+//
+// AUTOUPDATE
+// TIP: To test this file alone, run:
+// TIP:   bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/facet/validate_impl_constraints.carbon
+// TIP: To dump output, run:
+// TIP:   bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/facet/validate_impl_constraints.carbon
+
+// --- fail_todo_where_impls_tests_associated_constant_of_generic_type.carbon
+
+class C(U:! type) {}
+
+// C(U) impls M if U impls L.
+interface L {}
+interface M {}
+impl forall [U:! L] C(U) as M {}
+
+// U requires that C(.Self) impls M.
+// - C(.Self) impls M can be rewritten as C(U) impls M.
+// - C(U) impls M if U impls L => Requires U impls L.
+fn F(U:! type where C(.Self) impls M) {}
+
+fn G(T:! L) {
+  // CHECK:STDERR: fail_todo_where_impls_tests_associated_constant_of_generic_type.carbon:[[@LINE+7]]:3: error: cannot convert type `T` that implements `L` into type implementing `type where...` [ConversionFailureFacetToFacet]
+  // CHECK:STDERR:   F(T);
+  // CHECK:STDERR:   ^~~~
+  // CHECK:STDERR: fail_todo_where_impls_tests_associated_constant_of_generic_type.carbon:[[@LINE-6]]:6: note: initializing generic parameter `U` declared here [InitializingGenericParam]
+  // CHECK:STDERR: fn F(U:! type where C(.Self) impls M) {}
+  // CHECK:STDERR:      ^
+  // CHECK:STDERR:
+  F(T);
+}

+ 42 - 0
toolchain/check/testdata/where_expr/designator.carbon

@@ -91,6 +91,48 @@ class D {
   fn G() -> .Self { return Self; }
 }
 
+// --- todo_fail_impls_constraint_does_not_constrain_self.carbon
+library "[[@TEST_NAME]]";
+
+interface I {}
+
+// TODO: Diagnose that the `where` on `T` does not refer to `.Self` at all.
+// See https://docs.carbon-lang.dev/docs/design/generics/details.html#constraints-must-use-a-designator
+fn F(U:! type, T:! type where U impls I) {}
+
+// --- todo_fail_equality_constraint_does_not_constrain_self.carbon
+library "[[@TEST_NAME]]";
+
+interface I {
+  let X:! type;
+}
+
+// TODO: Diagnose that the `where` on `T` does not refer to `.Self` at all.
+// See https://docs.carbon-lang.dev/docs/design/generics/details.html#constraints-must-use-a-designator
+fn F(U:! I, T:! type where U.X == ()) {}
+
+// --- todo_fail_combined_constraint_does_not_constrain_self.carbon
+library "[[@TEST_NAME]]";
+
+interface I {
+  let X:! type;
+}
+
+// TODO: Diagnose that the `where` on `T` does not refer to `.Self` at all.
+// See https://docs.carbon-lang.dev/docs/design/generics/details.html#constraints-must-use-a-designator
+fn F(U:! I, T:! type where U impls I and U.X == ()) {}
+
+// --- impls_constraint_does_constrain_self.carbon
+library "[[@TEST_NAME]]";
+
+interface I(T:! type) {}
+
+class C(T:! type);
+
+fn F(T:! type where C(.Self) impls I(())) {}
+
+fn G(T:! type where C(()) impls I(.Self)) {}
+
 // CHECK:STDOUT: --- success.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {