|
|
@@ -158,6 +158,15 @@ static auto HandleAnyBindingPattern(Context& context, Parse::NodeId node_id,
|
|
|
return binding.pattern_id;
|
|
|
};
|
|
|
|
|
|
+ auto abstract_diagnoser = [&] {
|
|
|
+ CARBON_DIAGNOSTIC(AbstractTypeInVarPattern, Error,
|
|
|
+ "binding pattern has abstract type {0} in `var` "
|
|
|
+ "pattern",
|
|
|
+ SemIR::TypeId);
|
|
|
+ return context.emitter().Build(type_node, AbstractTypeInVarPattern,
|
|
|
+ cast_type_id);
|
|
|
+ };
|
|
|
+
|
|
|
// A `self` binding can only appear in an implicit parameter list.
|
|
|
if (name_id == SemIR::NameId::SelfValue &&
|
|
|
!context.node_stack().PeekIs(Parse::NodeKind::ImplicitParamListStart)) {
|
|
|
@@ -192,6 +201,29 @@ static auto HandleAnyBindingPattern(Context& context, Parse::NodeId node_id,
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
+ // Using `AsConcreteType` here causes `fn F[var self: Self]();`
|
|
|
+ // to fail since `Self` is an incomplete type.
|
|
|
+ if (node_kind == Parse::NodeKind::VarBindingPattern) {
|
|
|
+ auto [unqualified_type_id, qualifiers] =
|
|
|
+ context.types().GetUnqualifiedTypeAndQualifiers(cast_type_id);
|
|
|
+ if ((qualifiers & SemIR::TypeQualifiers::Partial) !=
|
|
|
+ SemIR::TypeQualifiers::Partial &&
|
|
|
+ context.types().Is<SemIR::ClassType>(unqualified_type_id)) {
|
|
|
+ auto class_type =
|
|
|
+ context.types().GetAs<SemIR::ClassType>(unqualified_type_id);
|
|
|
+ auto& class_info = context.classes().Get(class_type.class_id);
|
|
|
+ if (class_info.inheritance_kind ==
|
|
|
+ SemIR::Class::InheritanceKind::Abstract) {
|
|
|
+ auto builder = abstract_diagnoser();
|
|
|
+ auto direct_use = true;
|
|
|
+ NoteAbstractClass(context, class_type.class_id, direct_use,
|
|
|
+ builder);
|
|
|
+ builder.Emit();
|
|
|
+ cast_type_id = SemIR::ErrorInst::TypeId;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
auto result_inst_id = make_binding_pattern();
|
|
|
|
|
|
// A binding pattern in a function signature is a `Call` parameter
|
|
|
@@ -228,16 +260,8 @@ static auto HandleAnyBindingPattern(Context& context, Parse::NodeId node_id,
|
|
|
cast_type_inst_id);
|
|
|
};
|
|
|
if (node_kind == Parse::NodeKind::VarBindingPattern) {
|
|
|
- cast_type_id = AsConcreteType(
|
|
|
- context, cast_type_id, type_node, incomplete_diagnoser, [&] {
|
|
|
- CARBON_DIAGNOSTIC(
|
|
|
- AbstractTypeInVarPattern, Error,
|
|
|
- "binding pattern has abstract type {0} in `var` "
|
|
|
- "pattern",
|
|
|
- SemIR::TypeId);
|
|
|
- return context.emitter().Build(
|
|
|
- type_node, AbstractTypeInVarPattern, cast_type_id);
|
|
|
- });
|
|
|
+ cast_type_id = AsConcreteType(context, cast_type_id, type_node,
|
|
|
+ incomplete_diagnoser, abstract_diagnoser);
|
|
|
} else {
|
|
|
cast_type_id = AsCompleteType(context, cast_type_id, type_node,
|
|
|
incomplete_diagnoser);
|