Add some more test coverage of designators (#7347)

- A test showing we need to search facets in the specific interface of
an access to find a witness
- A test using a `<type> impls ...` constraint from earlier in the same
facet type
- Some tests to show a rewrite constraint from earlier in the same facet
type is not incorrectly used when it's applied to a different facet
- A test of a facet type with a rewrite as the RHS of another rewrite,
and the rewrite there should not leak or access things from the outer
facet type
This commit is contained in:
Dana Jansens
2026-06-15 14:27:32 +00:00
committed by GitHub
parent fbf0157998
commit 3a7b49efaa
3 changed files with 124 additions and 2 deletions
+22
View File
@@ -416,6 +416,28 @@ fn F(U:! W, V:! Z(.Self) where .Z1 impls (Y where .Y1 impls (X where .X1 = U)))
V.(Z(V).Z1).(Y.Y1).(X.X1) as W;
}
// --- fail_todo_find_access_value_in_facet_from_specific_interface.carbon
library "[[@TEST_NAME]]";
interface Z {}
interface Y(T:! type) {
let Y1:! type;
}
class C;
// TODO: We need to look in `T` for the rewrite in the access of `(C as
// Y(T)).Y1` but we currently only look in `C`. See the TODO in
// `TryFindValueInRewriteConstraints()`.
fn F(T:! Z where C impls (Y(.Self) where .Y1 = {})) -> C.(Y(T).Y1) {
// CHECK:STDERR: fail_todo_find_access_value_in_facet_from_specific_interface.carbon:[[@LINE+7]]:3: error: cannot implicitly convert expression of type `{}` to `C.(Y(T).Y1)` [ConversionFailure]
// CHECK:STDERR: return {};
// CHECK:STDERR: ^~~~~~~~~~
// CHECK:STDERR: fail_todo_find_access_value_in_facet_from_specific_interface.carbon:[[@LINE+4]]:3: note: type `{}` does not implement interface `Core.ImplicitAs(C.(Y(T).Y1))` [MissingImplInMemberAccessInContext]
// CHECK:STDERR: return {};
// CHECK:STDERR: ^~~~~~~~~~
// CHECK:STDERR:
return {};
}
// CHECK:STDOUT: --- access_assoc_fn.carbon
// CHECK:STDOUT:
+22
View File
@@ -243,3 +243,25 @@ constraint N(V:! type) {
// CHECK:STDERR: ^~~~~~~~~~~~~~~
// CHECK:STDERR:
fn F(_:! Z(.Self) where C impls N(.Z1) and .Z2 = (.Z1 as Y(.Self))) {}
// --- early_type_impls_nested_self_impls.carbon
library "[[@TEST_NAME]]";
interface Z {
let Z1:! type;
}
interface Y {
let Y1:! type;
}
interface X {}
class C(T:! type);
class D(T:! X);
// TODO: Does the `.Y1 impls X` contain an ambiguous `.Self`? See
// https://github.com/carbon-language/carbon-lang/issues/7138.
// A lookup of `C(V).(Y.Y1) as X` requires us to see that the `.Y1 impls X`
// constraint is visible through the `C(.Self) impls (Y...)` constraint and that
// `C(.Self)` is used as the implied `.Self` in `.Y1 impls X`.
fn F(unused V:! Z where C(.Self) impls (Y where .Y1 impls X) and .Z1 = D(C(.Self).(Y.Y1))) {}
+80 -2
View File
@@ -395,6 +395,84 @@ interface Y {
let Y1:! type;
}
fn F(T:! Z where .Z1 impls (Y where .Y1 = ()) and .Z2 = .Z1.(Y.Y1)) -> T.Z2 {
return ();
interface Tuple {}
impl () as Tuple {}
class C(U:! Tuple);
fn F(unused T:! Z where .Z1 impls (Y where .Y1 = ()) and .Z2 = C(.Z1.(Y.Y1))) {}
// --- fail_early_rewrite_correct_interface_wrong_self_access_rewrite_in_period_self.carbon
library "[[@TEST_NAME]]";
interface Z {
let Z1:! type;
let Z2:! type;
}
interface Y {
let Y1:! type;
}
interface Tuple {}
impl () as Tuple {}
class C(U:! Tuple);
// This should fail: `T.(Y.Y1)` is rewritten to be `()` but `T.(Z.Z1).(Y.Y1)`
// is used in the argument to `C`.
//
// CHECK:STDERR: fail_early_rewrite_correct_interface_wrong_self_access_rewrite_in_period_self.carbon:[[@LINE+7]]:82: error: cannot convert type `.(Z.Z1).(Y.Y1)` into type implementing `Tuple` [ConversionFailureTypeToFacet]
// CHECK:STDERR: fn F(unused T:! Z where .Self impls (Y where .Y1 = ()) and .Z1 impls Y and .Z2 = C(.Z1.(Y.Y1))) {}
// CHECK:STDERR: ^~~~~~~~~~~~~
// CHECK:STDERR: fail_early_rewrite_correct_interface_wrong_self_access_rewrite_in_period_self.carbon:[[@LINE-8]]:9: note: initializing generic parameter `U` declared here [InitializingGenericParam]
// CHECK:STDERR: class C(U:! Tuple);
// CHECK:STDERR: ^~~~~~~~~
// CHECK:STDERR:
fn F(unused T:! Z where .Self impls (Y where .Y1 = ()) and .Z1 impls Y and .Z2 = C(.Z1.(Y.Y1))) {}
// --- fail_early_rewrite_correct_interface_wrong_self_access_rewrite_in_associated_constant.carbon
library "[[@TEST_NAME]]";
interface Z {
let Z1:! type;
let Z2:! type;
}
interface Y {
let Y1:! type;
}
interface Tuple {}
impl () as Tuple {}
class C(U:! Tuple);
// This should fail: `T.(Z.Z1).(Y.Y1)` is rewritten to be `()` but `T.(Y.Y1)` is used
// in the argument to `C`.
//
// CHECK:STDERR: fail_early_rewrite_correct_interface_wrong_self_access_rewrite_in_associated_constant.carbon:[[@LINE+4]]:84: error: name `Self` not found [NameNotFound]
// CHECK:STDERR: fn G(unused T:! Z where .Z1 impls (Y where .Y1 = ()) and .Self impls Y and .Z2 = C(Self.(Y.Y1))) {}
// CHECK:STDERR: ^~~~
// CHECK:STDERR:
fn G(unused T:! Z where .Z1 impls (Y where .Y1 = ()) and .Self impls Y and .Z2 = C(Self.(Y.Y1))) {}
// --- fail_nested_facet_type_in_rewrite_does_not_use_rewrite_from_outside.carbon
library "[[@TEST_NAME]]";
interface Z {
let X:! type;
let Y:! type;
}
// TODO: Does the `.X = .Y` contain an ambiguous `.Self` in `.Y`? See
// https://github.com/carbon-language/carbon-lang/issues/7138.
fn F(T:! Z where .Y = {} and .X = (Z where .X = .Y), U:! T.X) -> U.(Z.X) {
// This should fail: `U:! T.X` contains a rewrite `.X = .Y` in its type, but
// the value of `U.(Z.Y)` is not known. Only `T.(Z.Y)` is rewritten to `{}`.
//
// CHECK:STDERR: fail_nested_facet_type_in_rewrite_does_not_use_rewrite_from_outside.carbon:[[@LINE+7]]:3: error: cannot implicitly convert expression of type `{}` to `U.(Z.Y)` [ConversionFailure]
// CHECK:STDERR: return {};
// CHECK:STDERR: ^~~~~~~~~~
// CHECK:STDERR: fail_nested_facet_type_in_rewrite_does_not_use_rewrite_from_outside.carbon:[[@LINE+4]]:3: note: type `{}` does not implement interface `Core.ImplicitAs(U.(Z.Y))` [MissingImplInMemberAccessInContext]
// CHECK:STDERR: return {};
// CHECK:STDERR: ^~~~~~~~~~
// CHECK:STDERR:
return {};
}