Allow witnesses to come from a facet with partially identified type in the lookup target (#7260)

We allow impl lookup to use `Self` which is partially identified, but we
were only allowing this for the `Self` facet appearing in the impl
lookup query self. We should also allow it when `Self` appears in the
impl lookup query target facet type.

But demonstrate that `Self` appearing in the interface of an
ImplWitnessAccess (a compound member access) is not sufficient at this
time, as it does not put `Self` into the type structure.
This commit is contained in:
Dana Jansens
2026-05-25 23:02:06 +00:00
committed by GitHub
parent 58b135235c
commit bbca8668ae
2 changed files with 41 additions and 1 deletions
+1 -1
View File
@@ -432,7 +432,7 @@ static auto CollectFacetWitnessSources(
{
SemIR::TypeIterator iter(&context.sem_ir());
iter.Add(context.insts().GetAs<SemIR::FacetType>(query_facet_type_inst_id));
collect_facets(iter, /*allow_partially_identified=*/false);
collect_facets(iter, /*allow_partially_identified=*/true);
}
if (!context.where_stack().empty()) {
@@ -699,6 +699,46 @@ fn G(T:! Z) {
T as N;
}
// --- partially_identified_witness_from_self_in_lookup_facet_type.carbon
library "[[@TEST_NAME]]";
interface Z(T:! type) {
let Z1:! type;
}
interface Y(T:! type) {}
class C {}
constraint N {
require C impls Z(Self);
// Test that we can find the `C impls Z(Self)` witness above through the
// `Self` in the lookup target facet type in `C as Z(Self)`.
require C.(Z(Self).Z1) impls Y(Self);
}
// --- fail_self_in_compound_member_access_is_not_in_type_structure.carbon
library "[[@TEST_NAME]]";
interface Z(T:! type) {
let Z1:! type;
}
interface Y {}
class C {}
constraint N {
require C impls Z(Self);
// The type structure is `? impls Y`, where the `?` is dependent on `Self` but
// it is not `Self`. Since `Self` is not directly part of the type structure,
// we don't accept this require decl.
//
// CHECK:STDERR: fail_self_in_compound_member_access_is_not_in_type_structure.carbon:[[@LINE+4]]:3: error: no `Self` reference found in `require` declaration; `Self` must appear in the self-type or as a generic argument for each required interface, but found interface `Y` without a `Self` argument [RequireImplsMissingSelf]
// CHECK:STDERR: require C.(Z(Self).Z1) impls Y;
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
require C.(Z(Self).Z1) impls Y;
}
// CHECK:STDOUT: --- extend.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {