remove suffixed from Pattern

This commit is contained in:
Luke Boswell 2024-04-27 13:20:51 +10:00
parent 2fe03e6c91
commit db4607125b
No known key found for this signature in database
GPG key ID: F6DB3C9DB47377B0
14 changed files with 69 additions and 231 deletions

View file

@ -25,10 +25,7 @@ fn to_encoder<'a>(env: &mut Env<'a>, at_opaque: &'a str) -> ast::Expr<'a> {
opaque_ref, opaque_ref,
&*env.arena.alloc([Loc::at( &*env.arena.alloc([Loc::at(
DERIVED_REGION, DERIVED_REGION,
ast::Pattern::Identifier { ast::Pattern::Identifier { ident: payload },
ident: payload,
suffixed: 0,
},
)]), )]),
); );
@ -100,20 +97,8 @@ fn decoder<'a>(env: &mut Env<'a>, at_opaque: &'a str) -> ast::Expr<'a> {
// Decode.mapResult (Decode.decodeWith bytes Decode.decoder fmt) @Opaq // Decode.mapResult (Decode.decodeWith bytes Decode.decoder fmt) @Opaq
let custom_closure = ast::Expr::Closure( let custom_closure = ast::Expr::Closure(
env.arena.alloc([ env.arena.alloc([
Loc::at( Loc::at(DERIVED_REGION, ast::Pattern::Identifier { ident: bytes }),
DERIVED_REGION, Loc::at(DERIVED_REGION, ast::Pattern::Identifier { ident: fmt }),
ast::Pattern::Identifier {
ident: bytes,
suffixed: 0,
},
),
Loc::at(
DERIVED_REGION,
ast::Pattern::Identifier {
ident: fmt,
suffixed: 0,
},
),
]), ]),
alloc_expr(call_map_result), alloc_expr(call_map_result),
); );
@ -145,10 +130,7 @@ fn hash<'a>(env: &mut Env<'a>, at_opaque: &'a str) -> ast::Expr<'a> {
opaque_ref, opaque_ref,
&*env.arena.alloc([Loc::at( &*env.arena.alloc([Loc::at(
DERIVED_REGION, DERIVED_REGION,
ast::Pattern::Identifier { ast::Pattern::Identifier { ident: payload },
ident: payload,
suffixed: 0,
},
)]), )]),
); );
@ -174,13 +156,7 @@ fn hash<'a>(env: &mut Env<'a>, at_opaque: &'a str) -> ast::Expr<'a> {
// \hasher, @Opaq payload -> Hash.hash hasher payload // \hasher, @Opaq payload -> Hash.hash hasher payload
ast::Expr::Closure( ast::Expr::Closure(
env.arena.alloc([ env.arena.alloc([
Loc::at( Loc::at(DERIVED_REGION, ast::Pattern::Identifier { ident: hasher }),
DERIVED_REGION,
ast::Pattern::Identifier {
ident: hasher,
suffixed: 0,
},
),
Loc::at(DERIVED_REGION, opaque_apply_pattern), Loc::at(DERIVED_REGION, opaque_apply_pattern),
]), ]),
call_member, call_member,
@ -200,10 +176,7 @@ fn is_eq<'a>(env: &mut Env<'a>, at_opaque: &'a str) -> ast::Expr<'a> {
opaque_ref, opaque_ref,
&*env.arena.alloc([Loc::at( &*env.arena.alloc([Loc::at(
DERIVED_REGION, DERIVED_REGION,
ast::Pattern::Identifier { ast::Pattern::Identifier { ident: payload1 },
ident: payload1,
suffixed: 0,
},
)]), )]),
); );
// \@Opaq payload2 // \@Opaq payload2
@ -211,10 +184,7 @@ fn is_eq<'a>(env: &mut Env<'a>, at_opaque: &'a str) -> ast::Expr<'a> {
opaque_ref, opaque_ref,
&*env.arena.alloc([Loc::at( &*env.arena.alloc([Loc::at(
DERIVED_REGION, DERIVED_REGION,
ast::Pattern::Identifier { ast::Pattern::Identifier { ident: payload2 },
ident: payload2,
suffixed: 0,
},
)]), )]),
); );
@ -260,10 +230,7 @@ fn to_inspector<'a>(env: &mut Env<'a>, at_opaque: &'a str) -> ast::Expr<'a> {
opaque_ref, opaque_ref,
&*env.arena.alloc([Loc::at( &*env.arena.alloc([Loc::at(
DERIVED_REGION, DERIVED_REGION,
ast::Pattern::Identifier { ast::Pattern::Identifier { ident: payload },
ident: payload,
suffixed: 0,
},
)]), )]),
); );
@ -316,10 +283,7 @@ fn to_inspector<'a>(env: &mut Env<'a>, at_opaque: &'a str) -> ast::Expr<'a> {
let custom_closure = alloc_expr(ast::Expr::Closure( let custom_closure = alloc_expr(ast::Expr::Closure(
env.arena.alloc([Loc::at( env.arena.alloc([Loc::at(
DERIVED_REGION, DERIVED_REGION,
ast::Pattern::Identifier { ast::Pattern::Identifier { ident: fmt },
ident: fmt,
suffixed: 0,
},
)]), )]),
apply_opaque_inspector, apply_opaque_inspector,
)); ));

View file

@ -1069,10 +1069,7 @@ fn record_builder_arg<'a>(
for label in apply_field_names.iter().rev() { for label in apply_field_names.iter().rev() {
let name = arena.alloc("#".to_owned() + label.value); let name = arena.alloc("#".to_owned() + label.value);
let ident = roc_parse::ast::Pattern::Identifier { let ident = roc_parse::ast::Pattern::Identifier { ident: name };
ident: name,
suffixed: 0,
};
let arg_pattern = arena.alloc(Loc { let arg_pattern = arena.alloc(Loc {
value: ident, value: ident,

View file

@ -265,10 +265,7 @@ pub fn canonicalize_def_header_pattern<'a>(
match pattern { match pattern {
// Identifiers that shadow ability members may appear (and may only appear) at the header of a def. // Identifiers that shadow ability members may appear (and may only appear) at the header of a def.
Identifier { Identifier { ident: name } => {
ident: name,
suffixed: _,
} => {
match scope.introduce_or_shadow_ability_member( match scope.introduce_or_shadow_ability_member(
pending_abilities_in_scope, pending_abilities_in_scope,
(*name).into(), (*name).into(),
@ -376,13 +373,12 @@ pub fn canonicalize_pattern<'a>(
use PatternType::*; use PatternType::*;
let can_pattern = match pattern { let can_pattern = match pattern {
Identifier { Identifier { ident: name } => {
ident: name, match canonicalize_pattern_symbol(env, scope, output, region, permit_shadows, name) {
suffixed: _, Ok(symbol) => Pattern::Identifier(symbol),
} => match canonicalize_pattern_symbol(env, scope, output, region, permit_shadows, name) { Err(pattern) => pattern,
Ok(symbol) => Pattern::Identifier(symbol), }
Err(pattern) => pattern, }
},
Underscore(name) => { Underscore(name) => {
// An underscored identifier can't be used, but we'll still add it to the scope // An underscored identifier can't be used, but we'll still add it to the scope
// for better error messages if someone tries to use it. // for better error messages if someone tries to use it.
@ -632,10 +628,7 @@ pub fn canonicalize_pattern<'a>(
for loc_pattern in patterns.iter() { for loc_pattern in patterns.iter() {
match loc_pattern.value { match loc_pattern.value {
Identifier { Identifier { ident: label } => {
ident: label,
suffixed: _,
} => {
match scope.introduce(label.into(), region) { match scope.introduce(label.into(), region) {
Ok(symbol) => { Ok(symbol) => {
output.references.insert_bound(symbol); output.references.insert_bound(symbol);

View file

@ -34,7 +34,6 @@ fn next_suffixed_answer_pattern(arena: &Bump) -> (Expr, Pattern) {
}, },
Pattern::Identifier { Pattern::Identifier {
ident: answer_ident.as_str(), ident: answer_ident.as_str(),
suffixed: 0,
}, },
) )
}) })
@ -194,18 +193,6 @@ pub fn unwrap_suffixed_expression_closure_help<'a>(
) -> Result<&'a Loc<Expr<'a>>, EUnwrapped<'a>> { ) -> Result<&'a Loc<Expr<'a>>, EUnwrapped<'a>> {
match loc_expr.value { match loc_expr.value {
Expr::Closure(closure_args, closure_loc_ret) => { Expr::Closure(closure_args, closure_loc_ret) => {
// Check to make sure that arguments are not suffixed
let suffixed_arg_count = closure_args
.iter()
.filter(|loc_pat| loc_pat.value.is_suffixed())
.count();
if suffixed_arg_count > 0 {
debug_assert!(false,"closure arguments should not be suffixed");
return Err(EUnwrapped::Malformed);
}
// note we use `None` here as we don't want to pass a DefExpr up and // note we use `None` here as we don't want to pass a DefExpr up and
// unwrap the definition pattern for the closure // unwrap the definition pattern for the closure
match unwrap_suffixed_expression(arena, closure_loc_ret, None) { match unwrap_suffixed_expression(arena, closure_loc_ret, None) {

File diff suppressed because one or more lines are too long

View file

@ -88,16 +88,9 @@ impl<'a> Formattable for Pattern<'a> {
use self::Pattern::*; use self::Pattern::*;
match self { match self {
Identifier { Identifier { ident: string } => {
ident: string,
suffixed,
} => {
buf.indent(indent); buf.indent(indent);
buf.push_str(string); buf.push_str(string);
for _ in 0..*suffixed {
buf.push('!');
}
} }
Tag(name) | OpaqueRef(name) => { Tag(name) | OpaqueRef(name) => {
buf.indent(indent); buf.indent(indent);
@ -277,21 +270,13 @@ impl<'a> Formattable for Pattern<'a> {
buf.indent(indent); buf.indent(indent);
buf.push_str(string); buf.push_str(string);
} }
QualifiedIdentifier { QualifiedIdentifier { module_name, ident } => {
module_name,
ident,
suffixed,
} => {
buf.indent(indent); buf.indent(indent);
if !module_name.is_empty() { if !module_name.is_empty() {
buf.push_str(module_name); buf.push_str(module_name);
buf.push('.'); buf.push('.');
} }
for _ in 0..*suffixed {
buf.push('!');
}
buf.push_str(ident); buf.push_str(ident);
} }
} }

View file

@ -795,7 +795,7 @@ fn remove_spaces_bad_ident(ident: BadIdent) -> BadIdent {
impl<'a> RemoveSpaces<'a> for Pattern<'a> { impl<'a> RemoveSpaces<'a> for Pattern<'a> {
fn remove_spaces(&self, arena: &'a Bump) -> Self { fn remove_spaces(&self, arena: &'a Bump) -> Self {
match *self { match *self {
Pattern::Identifier { ident, suffixed } => Pattern::Identifier { ident, suffixed }, Pattern::Identifier { ident } => Pattern::Identifier { ident },
Pattern::Tag(a) => Pattern::Tag(a), Pattern::Tag(a) => Pattern::Tag(a),
Pattern::OpaqueRef(a) => Pattern::OpaqueRef(a), Pattern::OpaqueRef(a) => Pattern::OpaqueRef(a),
Pattern::Apply(a, b) => Pattern::Apply( Pattern::Apply(a, b) => Pattern::Apply(
@ -828,15 +828,9 @@ impl<'a> RemoveSpaces<'a> for Pattern<'a> {
Pattern::Underscore(a) => Pattern::Underscore(a), Pattern::Underscore(a) => Pattern::Underscore(a),
Pattern::Malformed(a) => Pattern::Malformed(a), Pattern::Malformed(a) => Pattern::Malformed(a),
Pattern::MalformedIdent(a, b) => Pattern::MalformedIdent(a, remove_spaces_bad_ident(b)), Pattern::MalformedIdent(a, b) => Pattern::MalformedIdent(a, remove_spaces_bad_ident(b)),
Pattern::QualifiedIdentifier { Pattern::QualifiedIdentifier { module_name, ident } => {
module_name, Pattern::QualifiedIdentifier { module_name, ident }
ident, }
suffixed,
} => Pattern::QualifiedIdentifier {
module_name,
ident,
suffixed,
},
Pattern::SpaceBefore(a, _) => a.remove_spaces(arena), Pattern::SpaceBefore(a, _) => a.remove_spaces(arena),
Pattern::SpaceAfter(a, _) => a.remove_spaces(arena), Pattern::SpaceAfter(a, _) => a.remove_spaces(arena),
Pattern::SingleQuote(a) => Pattern::SingleQuote(a), Pattern::SingleQuote(a) => Pattern::SingleQuote(a),

View file

@ -212,11 +212,7 @@ fn generate_entry_docs(
match either_index.split() { match either_index.split() {
Err(value_index) => match &defs.value_defs[value_index.index()] { Err(value_index) => match &defs.value_defs[value_index.index()] {
ValueDef::Annotation(loc_pattern, loc_ann) => { ValueDef::Annotation(loc_pattern, loc_ann) => {
if let Pattern::Identifier { if let Pattern::Identifier { ident: identifier } = loc_pattern.value {
ident: identifier,
suffixed: _,
} = loc_pattern.value
{
// Check if this module exposes the def // Check if this module exposes the def
if let Some(ident_id) = ident_ids.get_id(identifier) { if let Some(ident_id) = ident_ids.get_id(identifier) {
let name = identifier.to_string(); let name = identifier.to_string();
@ -237,11 +233,7 @@ fn generate_entry_docs(
ann_type, ann_type,
.. ..
} => { } => {
if let Pattern::Identifier { if let Pattern::Identifier { ident: identifier } = ann_pattern.value {
ident: identifier,
suffixed: _,
} = ann_pattern.value
{
// Check if this module exposes the def // Check if this module exposes the def
if let Some(ident_id) = ident_ids.get_id(identifier) { if let Some(ident_id) = ident_ids.get_id(identifier) {
let doc_def = DocDef { let doc_def = DocDef {
@ -257,11 +249,7 @@ fn generate_entry_docs(
} }
ValueDef::Body(pattern, _) => { ValueDef::Body(pattern, _) => {
if let Pattern::Identifier { if let Pattern::Identifier { ident: identifier } = pattern.value {
ident: identifier,
suffixed: _,
} = pattern.value
{
// Check if this module exposes the def // Check if this module exposes the def
if let Some(ident_id) = ident_ids.get_id(identifier) { if let Some(ident_id) = ident_ids.get_id(identifier) {
let doc_def = DocDef { let doc_def = DocDef {
@ -316,11 +304,7 @@ fn generate_entry_docs(
let mut type_vars = Vec::new(); let mut type_vars = Vec::new();
for var in vars.iter() { for var in vars.iter() {
if let Pattern::Identifier { if let Pattern::Identifier { ident: ident_name } = var.value {
ident: ident_name,
suffixed: _,
} = var.value
{
type_vars.push(ident_name.to_string()); type_vars.push(ident_name.to_string());
} }
} }
@ -354,11 +338,7 @@ fn generate_entry_docs(
let mut type_vars = Vec::new(); let mut type_vars = Vec::new();
for var in vars.iter() { for var in vars.iter() {
if let Pattern::Identifier { if let Pattern::Identifier { ident: ident_name } = var.value {
ident: ident_name,
suffixed: _,
} = var.value
{
type_vars.push(ident_name.to_string()); type_vars.push(ident_name.to_string());
} }
} }
@ -382,11 +362,7 @@ fn generate_entry_docs(
let mut type_vars = Vec::new(); let mut type_vars = Vec::new();
for var in vars.iter() { for var in vars.iter() {
if let Pattern::Identifier { if let Pattern::Identifier { ident: ident_name } = var.value {
ident: ident_name,
suffixed: _,
} = var.value
{
type_vars.push(ident_name.to_string()); type_vars.push(ident_name.to_string());
} }
} }
@ -648,7 +624,7 @@ fn type_to_docs(in_func_type_ann: bool, type_annotation: ast::TypeAnnotation) ->
.vars .vars
.iter() .iter()
.filter_map(|loc_pattern| match loc_pattern.value { .filter_map(|loc_pattern| match loc_pattern.value {
ast::Pattern::Identifier { ident, suffixed: _ } => Some(ident.to_string()), ast::Pattern::Identifier { ident } => Some(ident.to_string()),
_ => None, _ => None,
}) })
.collect(), .collect(),

View file

@ -5663,13 +5663,7 @@ fn value_def_from_imports<'a>(
}; };
let typed_ident = typed_ident.extract_spaces().item; let typed_ident = typed_ident.extract_spaces().item;
let Loc { region, value } = typed_ident.ident; let Loc { region, value } = typed_ident.ident;
let ident = arena.alloc(Loc::at( let ident = arena.alloc(Loc::at(region, Pattern::Identifier { ident: value }));
region,
Pattern::Identifier {
ident: value,
suffixed: 0,
},
));
let ann_type = arena.alloc(typed_ident.ann); let ann_type = arena.alloc(typed_ident.ann);
Some(ValueDef::AnnotatedBody { Some(ValueDef::AnnotatedBody {

View file

@ -1130,12 +1130,10 @@ pub enum Pattern<'a> {
// Identifier // Identifier
Identifier { Identifier {
ident: &'a str, ident: &'a str,
suffixed: u8,
}, },
QualifiedIdentifier { QualifiedIdentifier {
module_name: &'a str, module_name: &'a str,
ident: &'a str, ident: &'a str,
suffixed: u8,
}, },
Tag(&'a str), Tag(&'a str),
@ -1253,21 +1251,11 @@ impl<'a> Pattern<'a> {
// { x, y } : { x : Int, y ? Bool } // { x, y } : { x : Int, y ? Bool }
// { x, y ? False } = rec // { x, y ? False } = rec
OptionalField(x, _) => match other { OptionalField(x, _) => match other {
Identifier { Identifier { ident: y } | OptionalField(y, _) => x == y,
ident: y,
suffixed: 0,
}
| OptionalField(y, _) => x == y,
_ => false, _ => false,
}, },
Identifier { Identifier { ident: x } => match other {
ident: x, Identifier { ident: y } => x == y,
suffixed: a,
} => match other {
Identifier {
ident: y,
suffixed: b,
} => x == y && a == b,
OptionalField(y, _) => x == y, OptionalField(y, _) => x == y,
_ => false, _ => false,
}, },
@ -1329,15 +1317,13 @@ impl<'a> Pattern<'a> {
QualifiedIdentifier { QualifiedIdentifier {
module_name: a, module_name: a,
ident: x, ident: x,
suffixed: i,
} => { } => {
if let QualifiedIdentifier { if let QualifiedIdentifier {
module_name: b, module_name: b,
ident: y, ident: y,
suffixed: j,
} = other } = other
{ {
a == b && x == y && i == j a == b && x == y
} else { } else {
false false
} }
@ -1402,15 +1388,6 @@ impl<'a> Pattern<'a> {
} }
} }
} }
// used to check if a pattern is suffixed to report as an error
pub fn is_suffixed(&self) -> bool {
match self {
Pattern::Identifier { suffixed, .. } => *suffixed > 0,
Pattern::QualifiedIdentifier { suffixed, .. } => *suffixed > 0,
_ => false,
}
}
} }
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub struct Collection<'a, T> { pub struct Collection<'a, T> {

View file

@ -2186,13 +2186,9 @@ fn expr_to_pattern_help<'a>(arena: &'a Bump, expr: &Expr<'a>) -> Result<Pattern<
let mut pat = match expr.item { let mut pat = match expr.item {
Expr::Var { module_name, ident } => { Expr::Var { module_name, ident } => {
if module_name.is_empty() { if module_name.is_empty() {
Pattern::Identifier { ident, suffixed: 0 } Pattern::Identifier { ident }
} else { } else {
Pattern::QualifiedIdentifier { Pattern::QualifiedIdentifier { module_name, ident }
module_name,
ident,
suffixed: 0,
}
} }
} }
Expr::Underscore(opt_name) => Pattern::Underscore(opt_name), Expr::Underscore(opt_name) => Pattern::Underscore(opt_name),
@ -2328,10 +2324,7 @@ fn assigned_expr_field_to_pattern_help<'a>(
) )
} }
} }
AssignedField::LabelOnly(name) => Pattern::Identifier { AssignedField::LabelOnly(name) => Pattern::Identifier { ident: name.value },
ident: name.value,
suffixed: 0,
},
AssignedField::SpaceBefore(nested, spaces) => Pattern::SpaceBefore( AssignedField::SpaceBefore(nested, spaces) => Pattern::SpaceBefore(
arena.alloc(assigned_expr_field_to_pattern_help(arena, nested)?), arena.alloc(assigned_expr_field_to_pattern_help(arena, nested)?),
spaces, spaces,

View file

@ -406,10 +406,7 @@ fn loc_ident_pattern_help<'a>(
MadeProgress, MadeProgress,
Loc { Loc {
region: loc_ident.region, region: loc_ident.region,
value: Pattern::Identifier { value: Pattern::Identifier { ident: var },
ident: var,
suffixed: 0,
},
}, },
state, state,
)) ))
@ -424,7 +421,6 @@ fn loc_ident_pattern_help<'a>(
value: Pattern::QualifiedIdentifier { value: Pattern::QualifiedIdentifier {
module_name, module_name,
ident: var, ident: var,
suffixed: 0,
}, },
}, },
state, state,
@ -451,10 +447,7 @@ fn loc_ident_pattern_help<'a>(
MadeProgress, MadeProgress,
Loc { Loc {
region: loc_ident.region, region: loc_ident.region,
value: Pattern::Identifier { value: Pattern::Identifier { ident: var },
ident: var,
suffixed: 0,
},
}, },
state, state,
)); ));
@ -615,18 +608,9 @@ fn record_pattern_field<'a>() -> impl Parser<'a, Loc<Pattern<'a>>, PRecord<'a>>
None => { None => {
let Loc { value, region } = loc_label; let Loc { value, region } = loc_label;
let value = if !spaces.is_empty() { let value = if !spaces.is_empty() {
Pattern::SpaceAfter( Pattern::SpaceAfter(arena.alloc(Pattern::Identifier { ident: value }), spaces)
arena.alloc(Pattern::Identifier {
ident: value,
suffixed: 0,
}),
spaces,
)
} else { } else {
Pattern::Identifier { Pattern::Identifier { ident: value }
ident: value,
suffixed: 0,
}
}; };
Ok((MadeProgress, Loc::at(region, value), state)) Ok((MadeProgress, Loc::at(region, value), state))

View file

@ -70,13 +70,7 @@ fn check_type_alias<'a>(
var_names.reserve(vars.len()); var_names.reserve(vars.len());
for var in vars { for var in vars {
if let TypeAnnotation::BoundVariable(v) = var.value { if let TypeAnnotation::BoundVariable(v) = var.value {
var_names.push(Loc::at( var_names.push(Loc::at(var.region, Pattern::Identifier { ident: v }));
var.region,
Pattern::Identifier {
ident: v,
suffixed: 0,
},
));
} else { } else {
return Err(ETypeInlineAlias::ArgumentNotLowercase(var.region.start())); return Err(ETypeInlineAlias::ArgumentNotLowercase(var.region.start()));
} }

View file

@ -74,7 +74,7 @@ impl ReplState {
ValueDef::Annotation( ValueDef::Annotation(
Loc { Loc {
// TODO is this right for suffixed // TODO is this right for suffixed
value: Pattern::Identifier { ident, suffixed: _ }, value: Pattern::Identifier { ident },
.. ..
}, },
_, _,
@ -89,7 +89,7 @@ impl ReplState {
ValueDef::Body( ValueDef::Body(
Loc { Loc {
// TODO is this right for suffixed // TODO is this right for suffixed
value: Pattern::Identifier { ident, suffixed: _ }, value: Pattern::Identifier { ident },
.. ..
}, },
_, _,
@ -98,7 +98,7 @@ impl ReplState {
body_pattern: body_pattern:
Loc { Loc {
// TODO is this right for suffixed // TODO is this right for suffixed
value: Pattern::Identifier { ident, suffixed: _ }, value: Pattern::Identifier { ident },
.. ..
}, },
.. ..