mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
Add 'ast::PatKind::Rest'.
This commit is contained in:
parent
c798dffac9
commit
f7c75cc11a
@ -4264,6 +4264,10 @@ impl<'a> LoweringContext<'a> {
|
||||
slice.as_ref().map(|x| self.lower_pat(x)),
|
||||
after.iter().map(|x| self.lower_pat(x)).collect(),
|
||||
),
|
||||
PatKind::Rest => {
|
||||
// If we reach here the `..` pattern is not semantically allowed.
|
||||
self.ban_illegal_rest_pat(p.span)
|
||||
}
|
||||
PatKind::Paren(ref inner) => return self.lower_pat(inner),
|
||||
PatKind::Mac(_) => panic!("Shouldn't exist here"),
|
||||
};
|
||||
@ -4275,6 +4279,19 @@ impl<'a> LoweringContext<'a> {
|
||||
})
|
||||
}
|
||||
|
||||
/// Used to ban the `..` pattern in places it shouldn't be semantically.
|
||||
fn ban_illegal_rest_pat(&self, sp: Span) -> hir::PatKind {
|
||||
self.diagnostic()
|
||||
.struct_span_err(sp, "`..` patterns are not allowed here")
|
||||
.note("only allowed in tuple, tuple struct, and slice patterns")
|
||||
.emit();
|
||||
|
||||
// We're not in a list context so `..` can be reasonably treated
|
||||
// as `_` because it should always be valid and roughly matches the
|
||||
// intent of `..` (notice that the rest of a single slot is that slot).
|
||||
hir::PatKind::Wild
|
||||
}
|
||||
|
||||
fn lower_range_end(&mut self, e: &RangeEnd) -> hir::RangeEnd {
|
||||
match *e {
|
||||
RangeEnd::Included(_) => hir::RangeEnd::Included,
|
||||
|
@ -572,6 +572,7 @@ impl Pat {
|
||||
&& after.iter().all(|p| p.walk(it))
|
||||
}
|
||||
PatKind::Wild
|
||||
| PatKind::Rest
|
||||
| PatKind::Lit(_)
|
||||
| PatKind::Range(..)
|
||||
| PatKind::Ident(..)
|
||||
@ -661,6 +662,20 @@ pub enum PatKind {
|
||||
/// `PatKind::Slice(box [a, b], Some(i), box [y, z])`
|
||||
Slice(Vec<P<Pat>>, Option<P<Pat>>, Vec<P<Pat>>),
|
||||
|
||||
/// A rest pattern `..`.
|
||||
///
|
||||
/// Syntactically it is valid anywhere.
|
||||
///
|
||||
/// Semantically however, it only has meaning immediately inside:
|
||||
/// - a slice pattern: `[a, .., b]`,
|
||||
/// - a binding pattern immediately inside a slice pattern: `[a, r @ ..]`,
|
||||
/// - a tuple pattern: `(a, .., b)`,
|
||||
/// - a tuple struct/variant pattern: `$path(a, .., b)`.
|
||||
///
|
||||
/// In all of these cases, an additional restriction applies,
|
||||
/// only one rest pattern may occur in the pattern sequences.
|
||||
Rest,
|
||||
|
||||
/// Parentheses in patterns used for grouping (i.e., `(PAT)`).
|
||||
Paren(P<Pat>),
|
||||
|
||||
|
@ -1020,7 +1020,7 @@ pub fn noop_visit_pat<T: MutVisitor>(pat: &mut P<Pat>, vis: &mut T) {
|
||||
let Pat { id, node, span } = pat.deref_mut();
|
||||
vis.visit_id(id);
|
||||
match node {
|
||||
PatKind::Wild => {}
|
||||
PatKind::Wild | PatKind::Rest => {}
|
||||
PatKind::Ident(_binding_mode, ident, sub) => {
|
||||
vis.visit_ident(ident);
|
||||
visit_opt(sub, |sub| vis.visit_pat(sub));
|
||||
|
@ -2478,6 +2478,7 @@ impl<'a> State<'a> {
|
||||
|s, p| s.print_pat(p));
|
||||
self.s.word("]");
|
||||
}
|
||||
PatKind::Rest => self.s.word(".."),
|
||||
PatKind::Paren(ref inner) => {
|
||||
self.popen();
|
||||
self.print_pat(inner);
|
||||
|
@ -463,7 +463,7 @@ pub fn walk_pat<'a, V: Visitor<'a>>(visitor: &mut V, pattern: &'a Pat) {
|
||||
visitor.visit_expr(lower_bound);
|
||||
visitor.visit_expr(upper_bound);
|
||||
}
|
||||
PatKind::Wild => (),
|
||||
PatKind::Wild | PatKind::Rest => {},
|
||||
PatKind::Slice(ref prepatterns, ref slice_pattern, ref postpatterns) => {
|
||||
walk_list!(visitor, visit_pat, prepatterns);
|
||||
walk_list!(visitor, visit_pat, slice_pattern);
|
||||
|
Loading…
Reference in New Issue
Block a user