Completing a type no longer ignores facet types (#5004)

Make facet types complete like other types. This means that in the body
of an interface, the type of `Self` is incomplete. This involved fixing
an issue where eval of a specific_id that was already canonical was not
resolving the specific declaration, which could occur as part of
substituting into a facet type.

---------

Co-authored-by: Josh L <josh11b@users.noreply.github.com>
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
Co-authored-by: Dana Jansens <danakj@orodu.net>
This commit is contained in:
josh11b
2025-02-22 21:40:43 +00:00
committed by GitHub
co-authored by Josh L Richard Smith Dana Jansens
parent 1d48270dc4
commit 3ebd098597
25 changed files with 184 additions and 145 deletions
+18
View File
@@ -452,6 +452,24 @@ static auto GetConstantValue(EvalContext& eval_context,
}
if (args_id == specific.args_id) {
const auto& specific = eval_context.specifics().Get(specific_id);
// A constant specific_id should always have a resolved declaration. The
// specific_id from the instruction may coincidentally be canonical, and so
// constant evaluation gives the same value. In that case, we still need to
// ensure its declaration is resolved.
//
// However, don't resolve the declaration if the generic's eval block hasn't
// been set yet. This happens when building the eval block during import.
//
// TODO: Change importing of generic eval blocks to be less fragile and
// remove this `if` so we unconditionally call `ResolveSpecificDeclaration`.
if (!specific.decl_block_id.has_value() && eval_context.context()
.generics()
.Get(specific.generic_id)
.decl_block_id.has_value()) {
ResolveSpecificDeclaration(eval_context.context(),
eval_context.fallback_loc(), specific_id);
}
return specific_id;
}
return MakeSpecific(eval_context.context(), eval_context.fallback_loc(),