mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
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:
@@ -432,7 +432,7 @@ static auto CollectFacetWitnessSources(
|
|||||||
{
|
{
|
||||||
SemIR::TypeIterator iter(&context.sem_ir());
|
SemIR::TypeIterator iter(&context.sem_ir());
|
||||||
iter.Add(context.insts().GetAs<SemIR::FacetType>(query_facet_type_inst_id));
|
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()) {
|
if (!context.where_stack().empty()) {
|
||||||
|
|||||||
@@ -699,6 +699,46 @@ fn G(T:! Z) {
|
|||||||
T as N;
|
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: --- extend.carbon
|
||||||
// CHECK:STDOUT:
|
// CHECK:STDOUT:
|
||||||
// CHECK:STDOUT: constants {
|
// CHECK:STDOUT: constants {
|
||||||
|
|||||||
Reference in New Issue
Block a user