1
Fork 0

Add support for using qualified paths with structs in expression and pattern

position.
This commit is contained in:
Ryan Levick 2020-12-10 13:20:07 +01:00 committed by Ryan Levick
parent c5fbcd35a8
commit 6936349233
38 changed files with 374 additions and 187 deletions

View file

@ -623,12 +623,13 @@ impl Pat {
PatKind::Ident(_, _, Some(p)) => p.walk(it),
// Walk into each field of struct.
PatKind::Struct(_, fields, _) => fields.iter().for_each(|field| field.pat.walk(it)),
PatKind::Struct(_, _, fields, _) => fields.iter().for_each(|field| field.pat.walk(it)),
// Sequence of patterns.
PatKind::TupleStruct(_, s) | PatKind::Tuple(s) | PatKind::Slice(s) | PatKind::Or(s) => {
s.iter().for_each(|p| p.walk(it))
}
PatKind::TupleStruct(_, _, s)
| PatKind::Tuple(s)
| PatKind::Slice(s)
| PatKind::Or(s) => s.iter().for_each(|p| p.walk(it)),
// Trivial wrappers over inner patterns.
PatKind::Box(s) | PatKind::Ref(s, _) | PatKind::Paren(s) => s.walk(it),
@ -701,10 +702,10 @@ pub enum PatKind {
/// A struct or struct variant pattern (e.g., `Variant {x, y, ..}`).
/// The `bool` is `true` in the presence of a `..`.
Struct(Path, Vec<PatField>, /* recovered */ bool),
Struct(Option<QSelf>, Path, Vec<PatField>, /* recovered */ bool),
/// A tuple struct/variant pattern (`Variant(x, y, .., z)`).
TupleStruct(Path, Vec<P<Pat>>),
TupleStruct(Option<QSelf>, Path, Vec<P<Pat>>),
/// An or-pattern `A | B | C`.
/// Invariant: `pats.len() >= 2`.
@ -1247,6 +1248,7 @@ pub enum StructRest {
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct StructExpr {
pub qself: Option<QSelf>,
pub path: Path,
pub fields: Vec<ExprField>,
pub rest: StructRest,

View file

@ -1139,7 +1139,8 @@ pub fn noop_visit_pat<T: MutVisitor>(pat: &mut P<Pat>, vis: &mut T) {
visit_opt(sub, |sub| vis.visit_pat(sub));
}
PatKind::Lit(e) => vis.visit_expr(e),
PatKind::TupleStruct(path, elems) => {
PatKind::TupleStruct(qself, path, elems) => {
vis.visit_qself(qself);
vis.visit_path(path);
visit_vec(elems, |elem| vis.visit_pat(elem));
}
@ -1147,7 +1148,8 @@ pub fn noop_visit_pat<T: MutVisitor>(pat: &mut P<Pat>, vis: &mut T) {
vis.visit_qself(qself);
vis.visit_path(path);
}
PatKind::Struct(path, fields, _etc) => {
PatKind::Struct(qself, path, fields, _etc) => {
vis.visit_qself(qself);
vis.visit_path(path);
fields.flat_map_in_place(|field| vis.flat_map_pat_field(field));
}
@ -1333,7 +1335,8 @@ pub fn noop_visit_expr<T: MutVisitor>(
}
ExprKind::MacCall(mac) => vis.visit_mac_call(mac),
ExprKind::Struct(se) => {
let StructExpr { path, fields, rest } = se.deref_mut();
let StructExpr { qself, path, fields, rest } = se.deref_mut();
vis.visit_qself(qself);
vis.visit_path(path);
fields.flat_map_in_place(|field| vis.flat_map_expr_field(field));
match rest {

View file

@ -497,7 +497,10 @@ pub fn walk_assoc_ty_constraint<'a, V: Visitor<'a>>(
pub fn walk_pat<'a, V: Visitor<'a>>(visitor: &mut V, pattern: &'a Pat) {
match pattern.kind {
PatKind::TupleStruct(ref path, ref elems) => {
PatKind::TupleStruct(ref opt_qself, ref path, ref elems) => {
if let Some(ref qself) = *opt_qself {
visitor.visit_ty(&qself.ty);
}
visitor.visit_path(path, pattern.id);
walk_list!(visitor, visit_pat, elems);
}
@ -507,7 +510,10 @@ pub fn walk_pat<'a, V: Visitor<'a>>(visitor: &mut V, pattern: &'a Pat) {
}
visitor.visit_path(path, pattern.id)
}
PatKind::Struct(ref path, ref fields, _) => {
PatKind::Struct(ref opt_qself, ref path, ref fields, _) => {
if let Some(ref qself) = *opt_qself {
visitor.visit_ty(&qself.ty);
}
visitor.visit_path(path, pattern.id);
walk_list!(visitor, visit_pat_field, fields);
}
@ -740,6 +746,9 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
visitor.visit_anon_const(count)
}
ExprKind::Struct(ref se) => {
if let Some(ref qself) = se.qself {
visitor.visit_ty(&qself.ty);
}
visitor.visit_path(&se.path, expression.id);
walk_list!(visitor, visit_expr_field, &se.fields);
match &se.rest {