Implement macro-based deref!() syntax for deref patterns

Stop using `box PAT` syntax for deref patterns, as it's misleading and
also causes their semantics being tangled up.
This commit is contained in:
Michael Goulet 2024-03-20 16:53:50 -04:00
parent 2627e9f301
commit 2d633317f3
31 changed files with 123 additions and 35 deletions

View file

@ -498,11 +498,14 @@ impl<'a> Parser<'a> {
} else {
PatKind::Lit(const_expr)
}
} else if self.is_builtin() {
self.parse_pat_builtin()?
}
// Don't eagerly error on semantically invalid tokens when matching
// declarative macros, as the input to those doesn't have to be
// semantically valid. For attribute/derive proc macros this is not the
// case, so doing the recovery for them is fine.
} else if self.can_be_ident_pat()
else if self.can_be_ident_pat()
|| (self.is_lit_bad_ident().is_some() && self.may_recover())
{
// Parse `ident @ pat`
@ -1119,6 +1122,21 @@ impl<'a> Parser<'a> {
.contains(&self.token.kind)
}
fn parse_pat_builtin(&mut self) -> PResult<'a, PatKind> {
self.parse_builtin(|self_, _lo, ident| {
Ok(match ident.name {
// builtin#deref(PAT)
sym::deref => Some(ast::PatKind::Deref(self_.parse_pat_allow_top_alt(
None,
RecoverComma::Yes,
RecoverColon::Yes,
CommaRecoveryMode::LikelyTuple,
)?)),
_ => None,
})
})
}
/// Parses `box pat`
fn parse_pat_box(&mut self) -> PResult<'a, PatKind> {
let box_span = self.prev_token.span;