mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 21:00:13 +01:00
Subst .Self in impl as rewrites (#7105)
This makes rewrites of a constraint that requires a generic `I(Self)` work. The `Self` there is replaced in the identified facet type by the impl-as self type. But the rewrite is for the interface `.I(.Self)`, so they don't match. Once `.Self` is replaced with the impl-as self type, then they match and the rewrite is applied.
This commit is contained in:
@@ -325,11 +325,24 @@ auto AddImpl(Context& context, const SemIR::Impl& impl,
|
||||
|
||||
// Returns whether the `LookupImplWitness` of `witness_id` matches `interface`.
|
||||
static auto WitnessQueryMatchesInterface(
|
||||
Context& context, SemIR::InstId witness_id,
|
||||
const SemIR::SpecificInterface& interface) -> bool {
|
||||
auto lookup = context.insts().GetAs<SemIR::LookupImplWitness>(witness_id);
|
||||
return interface ==
|
||||
context.specific_interfaces().Get(lookup.query_specific_interface_id);
|
||||
Context& context, SemIR::LocId loc_id, SemIR::InstId impl_self,
|
||||
SemIR::InstId access_witness_id,
|
||||
const SemIR::SpecificInterface& impl_interface) -> bool {
|
||||
auto lookup =
|
||||
context.insts().GetAs<SemIR::LookupImplWitness>(access_witness_id);
|
||||
auto access_interface =
|
||||
context.specific_interfaces().Get(lookup.query_specific_interface_id);
|
||||
|
||||
// The `impl_interface` comes from an IdentifiedFacetType so it has `.Self`
|
||||
// replaced. The access comes from a rewrite constraint, which do not have
|
||||
// `.Self` replaced, so we need to do that here.
|
||||
//
|
||||
// TODO: Do this more eagerly as soon as we know the full decl before we
|
||||
// construct the witness table from it?
|
||||
SubstPeriodSelfCallbacks callbacks(&context, loc_id,
|
||||
context.constant_values().Get(impl_self));
|
||||
access_interface = SubstPeriodSelf(context, callbacks, access_interface);
|
||||
return access_interface == impl_interface;
|
||||
}
|
||||
|
||||
auto AddImplWitnessForDeclaration(Context& context, SemIR::LocId loc_id,
|
||||
@@ -351,8 +364,8 @@ auto AddImplWitnessForDeclaration(Context& context, SemIR::LocId loc_id,
|
||||
[&](const SemIR::FacetTypeInfo::RewriteConstraint& rewrite) {
|
||||
auto access = context.insts().GetAs<SemIR::ImplWitnessAccess>(
|
||||
GetImplWitnessAccessWithoutSubstitution(context, rewrite.lhs_id));
|
||||
return WitnessQueryMatchesInterface(context, access.witness_id,
|
||||
impl.interface);
|
||||
return WitnessQueryMatchesInterface(context, loc_id, impl.self_id,
|
||||
access.witness_id, impl.interface);
|
||||
});
|
||||
|
||||
if (rewrites_into_interface_to_witness.empty()) {
|
||||
|
||||
@@ -210,7 +210,7 @@ fn G() {
|
||||
// F(C);
|
||||
}
|
||||
|
||||
// --- fail_todo_impl_as_symbolic_generic_constraint_where_rewrite.carbon
|
||||
// --- todo_impl_as_symbolic_generic_constraint_where_rewrite.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
interface I(T:! type) {
|
||||
@@ -222,13 +222,6 @@ constraint N {
|
||||
}
|
||||
|
||||
class C;
|
||||
// CHECK:STDERR: fail_todo_impl_as_symbolic_generic_constraint_where_rewrite.carbon:[[@LINE+7]]:1: error: associated constant I1 not given a value in impl of interface I [ImplAssociatedConstantNeedsValue]
|
||||
// CHECK:STDERR: impl C as N where .I1 = C {}
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// CHECK:STDERR: fail_todo_impl_as_symbolic_generic_constraint_where_rewrite.carbon:[[@LINE-11]]:7: note: associated constant declared here [AssociatedConstantHere]
|
||||
// CHECK:STDERR: let I1:! type;
|
||||
// CHECK:STDERR: ^~~~~~~~~
|
||||
// CHECK:STDERR:
|
||||
impl C as N where .I1 = C {}
|
||||
|
||||
fn F(_:! I(.Self) where .I1 = .Self) {}
|
||||
|
||||
Reference in New Issue
Block a user