Remove SelfParam, add an AddrPattern instead. (#3506)

This is intended to make the representation of a `self` pattern be more
similar to other patterns.
This commit is contained in:
Richard Smith
2023-12-14 20:53:51 +00:00
committed by GitHub
parent de0c02ddae
commit fbb4ecf319
22 changed files with 152 additions and 101 deletions
+18 -22
View File
@@ -11,15 +11,19 @@ namespace Carbon::Check {
auto HandleAddress(Context& context, Parse::NodeId parse_node) -> bool {
auto self_param_id =
context.node_stack().Peek<Parse::NodeKind::BindingPattern>();
if (auto self_param =
context.insts().Get(self_param_id).TryAs<SemIR::SelfParam>()) {
self_param->is_addr_self = SemIR::BoolValue::True;
context.insts().Set(self_param_id, *self_param);
context.node_stack().Pop<Parse::NodeKind::BindingPattern>();
auto self_param = context.insts().TryGetAs<SemIR::Param>(self_param_id);
if (self_param && self_param->name_id == SemIR::NameId::SelfValue) {
// TODO: The type of an `addr_pattern` should probably be the non-pointer
// type, because that's the type that the pattern matches.
context.AddInstAndPush(
parse_node,
SemIR::AddrPattern{parse_node, self_param->type_id, self_param_id});
} else {
CARBON_DIAGNOSTIC(AddrOnNonSelfParam, Error,
"`addr` can only be applied to a `self` parameter.");
context.emitter().Emit(TokenOnly(parse_node), AddrOnNonSelfParam);
context.node_stack().Push(parse_node, self_param_id);
}
return true;
}
@@ -35,28 +39,20 @@ auto HandleBindingPattern(Context& context, Parse::NodeId parse_node) -> bool {
auto type_node_copy = type_node;
auto cast_type_id = ExprAsType(context, type_node, parsed_type_id);
// A `self` binding doesn't have a name.
if (auto self_node =
context.node_stack()
.PopForSoloParseNodeIf<Parse::NodeKind::SelfValueName>()) {
if (context.parse_tree().node_kind(context.node_stack().PeekParseNode()) !=
Parse::NodeKind::ImplicitParamListStart) {
CARBON_DIAGNOSTIC(
SelfOutsideImplicitParamList, Error,
"`self` can only be declared in an implicit parameter list.");
context.emitter().Emit(parse_node, SelfOutsideImplicitParamList);
}
context.AddInstAndPush(
parse_node, SemIR::SelfParam{*self_node, cast_type_id,
/*is_addr_self=*/SemIR::BoolValue::False});
return true;
}
// TODO: Handle `_` bindings.
// Every other kind of pattern binding has a name.
auto [name_node, name_id] = context.node_stack().PopNameWithParseNode();
// A `self` binding can only appear in an implicit parameter list.
if (name_id == SemIR::NameId::SelfValue &&
!context.node_stack().PeekIs<Parse::NodeKind::ImplicitParamListStart>()) {
CARBON_DIAGNOSTIC(
SelfOutsideImplicitParamList, Error,
"`self` can only be declared in an implicit parameter list.");
context.emitter().Emit(parse_node, SelfOutsideImplicitParamList);
}
// Allocate an instruction of the appropriate kind, linked to the name for
// error locations.
// TODO: The node stack is a fragile way of getting context information.