Allow checking to continue after 'impl as' outside class (#4937)

Currently it returns false which just ends typechecking. Instead handle
the error state later and avoid firing overlapping diagnostics in
'extend impl as'.

---------

Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com>
This commit is contained in:
Dana Jansens
2025-02-14 20:02:10 +00:00
committed by GitHub
co-authored by josh11b
parent 311b4ff03d
commit d5f3d3365a
9 changed files with 776 additions and 107 deletions
+4 -4
View File
@@ -99,7 +99,6 @@ auto HandleParseNode(Context& context, Parse::DefaultSelfImplAsId node_id)
"`impl as` can only be used in a class");
context.emitter().Emit(node_id, ImplAsOutsideClass);
self_type_id = SemIR::ErrorInst::SingletonTypeId;
return false;
}
// Build the implicit access to the enclosing `Self`.
@@ -141,14 +140,14 @@ static auto ExtendImpl(Context& context, Parse::NodeId extend_node,
DiagnoseExtendImplOutsideClass(context, node_id);
return false;
}
auto& parent_scope = context.name_scopes().Get(parent_scope_id);
// TODO: This is also valid in a mixin.
if (!TryAsClassScope(context, parent_scope_id)) {
DiagnoseExtendImplOutsideClass(context, node_id);
return false;
}
auto& parent_scope = context.name_scopes().Get(parent_scope_id);
if (params_node.has_value()) {
CARBON_DIAGNOSTIC(ExtendImplForall, Error,
"cannot `extend` a parameterized `impl`");
@@ -387,7 +386,8 @@ static auto BuildImplDecl(Context& context, Parse::AnyImplDeclId node_id,
ReplaceInstBeforeConstantUse(context, impl_decl_id, impl_decl);
// For an `extend impl` declaration, mark the impl as extending this `impl`.
if (introducer.modifier_set.HasAnyOf(KeywordModifierSet::Extend)) {
if (self_type_id != SemIR::ErrorInst::SingletonTypeId &&
introducer.modifier_set.HasAnyOf(KeywordModifierSet::Extend)) {
auto extend_node = introducer.modifier_node_id(ModifierOrder::Decl);
if (impl_info.generic_id.has_value()) {
SemIR::TypeId type_id = context.insts().Get(constraint_inst_id).type_id();