1
Fork 0

Box ExprKind::{Closure,MethodCall}, and QSelf in expressions, types, and patterns.

This commit is contained in:
Nicholas Nethercote 2022-09-08 10:52:51 +10:00
parent bebd57a960
commit 6b7ca2fcf2
37 changed files with 409 additions and 318 deletions

View file

@ -718,10 +718,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(Option<QSelf>, Path, Vec<PatField>, /* recovered */ bool),
Struct(Option<P<QSelf>>, Path, Vec<PatField>, /* recovered */ bool),
/// A tuple struct/variant pattern (`Variant(x, y, .., z)`).
TupleStruct(Option<QSelf>, Path, Vec<P<Pat>>),
TupleStruct(Option<P<QSelf>>, Path, Vec<P<Pat>>),
/// An or-pattern `A | B | C`.
/// Invariant: `pats.len() >= 2`.
@ -731,7 +731,7 @@ pub enum PatKind {
/// Unqualified path patterns `A::B::C` can legally refer to variants, structs, constants
/// or associated constants. Qualified path patterns `<A>::B::C`/`<A as Trait>::B::C` can
/// only legally refer to associated constants.
Path(Option<QSelf>, Path),
Path(Option<P<QSelf>>, Path),
/// A tuple pattern (`(a, b)`).
Tuple(Vec<P<Pat>>),
@ -1272,6 +1272,18 @@ impl Expr {
}
}
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct Closure {
pub binder: ClosureBinder,
pub capture_clause: CaptureBy,
pub asyncness: Async,
pub movability: Movability,
pub fn_decl: P<FnDecl>,
pub body: P<Expr>,
/// The span of the argument block `|...|`.
pub fn_decl_span: Span,
}
/// Limit types of a range (inclusive or exclusive)
#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug)]
pub enum RangeLimits {
@ -1281,6 +1293,20 @@ pub enum RangeLimits {
Closed,
}
/// A method call (e.g. `x.foo::<Bar, Baz>(a, b, c)`).
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct MethodCall {
/// The method name and its generic arguments, e.g. `foo::<Bar, Baz>`.
pub seg: PathSegment,
/// The receiver, e.g. `x`.
pub receiver: P<Expr>,
/// The arguments, e.g. `a, b, c`.
pub args: Vec<P<Expr>>,
/// The span of the function, without the dot and receiver e.g. `foo::<Bar,
/// Baz>(a, b, c)`.
pub span: Span,
}
#[derive(Clone, Encodable, Decodable, Debug)]
pub enum StructRest {
/// `..x`.
@ -1293,7 +1319,7 @@ pub enum StructRest {
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct StructExpr {
pub qself: Option<QSelf>,
pub qself: Option<P<QSelf>>,
pub path: Path,
pub fields: Vec<ExprField>,
pub rest: StructRest,
@ -1314,17 +1340,8 @@ pub enum ExprKind {
/// This also represents calling the constructor of
/// tuple-like ADTs such as tuple structs and enum variants.
Call(P<Expr>, Vec<P<Expr>>),
/// A method call (`x.foo::<'static, Bar, Baz>(a, b, c, d)`)
///
/// The `PathSegment` represents the method name and its generic arguments
/// (within the angle brackets).
/// The standalone `Expr` is the receiver expression.
/// The vector of `Expr` is the arguments.
/// `x.foo::<Bar, Baz>(a, b, c, d)` is represented as
/// `ExprKind::MethodCall(PathSegment { foo, [Bar, Baz] }, x, [a, b, c, d])`.
/// This `Span` is the span of the function, without the dot and receiver
/// (e.g. `foo(a, b)` in `x.foo(a, b)`
MethodCall(PathSegment, P<Expr>, Vec<P<Expr>>, Span),
/// A method call (e.g. `x.foo::<Bar, Baz>(a, b, c)`).
MethodCall(Box<MethodCall>),
/// A tuple (e.g., `(a, b, c, d)`).
Tup(Vec<P<Expr>>),
/// A binary operation (e.g., `a + b`, `a * b`).
@ -1363,9 +1380,7 @@ pub enum ExprKind {
/// A `match` block.
Match(P<Expr>, Vec<Arm>),
/// A closure (e.g., `move |a, b, c| a + b + c`).
///
/// The final span is the span of the argument block `|...|`.
Closure(ClosureBinder, CaptureBy, Async, Movability, P<FnDecl>, P<Expr>, Span),
Closure(Box<Closure>),
/// A block (`'label: { ... }`).
Block(P<Block>, Option<Label>),
/// An async block (`async move { ... }`).
@ -1403,7 +1418,7 @@ pub enum ExprKind {
/// parameters (e.g., `foo::bar::<baz>`).
///
/// Optionally "qualified" (e.g., `<Vec<T> as SomeTrait>::SomeType`).
Path(Option<QSelf>, Path),
Path(Option<P<QSelf>>, Path),
/// A referencing operation (`&a`, `&mut a`, `&raw const a` or `&raw mut a`).
AddrOf(BorrowKind, Mutability, P<Expr>),
@ -2006,7 +2021,7 @@ pub enum TyKind {
/// "qualified", e.g., `<Vec<T> as SomeTrait>::SomeType`.
///
/// Type parameters are stored in the `Path` itself.
Path(Option<QSelf>, Path),
Path(Option<P<QSelf>>, Path),
/// A trait object type `Bound1 + Bound2 + Bound3`
/// where `Bound` is a trait or a lifetime.
TraitObject(GenericBounds, TraitObjectSyntax),
@ -2138,7 +2153,7 @@ impl InlineAsmTemplatePiece {
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct InlineAsmSym {
pub id: NodeId,
pub qself: Option<QSelf>,
pub qself: Option<P<QSelf>>,
pub path: Path,
}
@ -3031,8 +3046,8 @@ mod size_asserts {
static_assert_size!(AssocItemKind, 32);
static_assert_size!(Attribute, 32);
static_assert_size!(Block, 48);
static_assert_size!(Expr, 104);
static_assert_size!(ExprKind, 72);
static_assert_size!(Expr, 88);
static_assert_size!(ExprKind, 56);
static_assert_size!(Fn, 184);
static_assert_size!(ForeignItem, 96);
static_assert_size!(ForeignItemKind, 24);
@ -3046,13 +3061,13 @@ mod size_asserts {
static_assert_size!(LitKind, 24);
static_assert_size!(Local, 72);
static_assert_size!(Param, 40);
static_assert_size!(Pat, 120);
static_assert_size!(Pat, 104);
static_assert_size!(Path, 40);
static_assert_size!(PathSegment, 24);
static_assert_size!(PatKind, 96);
static_assert_size!(PatKind, 80);
static_assert_size!(Stmt, 32);
static_assert_size!(StmtKind, 16);
static_assert_size!(Ty, 96);
static_assert_size!(TyKind, 72);
static_assert_size!(Ty, 80);
static_assert_size!(TyKind, 56);
// tidy-alphabetical-end
}

View file

@ -194,7 +194,7 @@ pub trait MutVisitor: Sized {
noop_visit_path(p, self);
}
fn visit_qself(&mut self, qs: &mut Option<QSelf>) {
fn visit_qself(&mut self, qs: &mut Option<P<QSelf>>) {
noop_visit_qself(qs, self);
}
@ -529,8 +529,9 @@ pub fn noop_visit_path<T: MutVisitor>(Path { segments, span, tokens }: &mut Path
visit_lazy_tts(tokens, vis);
}
pub fn noop_visit_qself<T: MutVisitor>(qself: &mut Option<QSelf>, vis: &mut T) {
visit_opt(qself, |QSelf { ty, path_span, position: _ }| {
pub fn noop_visit_qself<T: MutVisitor>(qself: &mut Option<P<QSelf>>, vis: &mut T) {
visit_opt(qself, |qself| {
let QSelf { ty, path_span, position: _ } = &mut **qself;
vis.visit_ty(ty);
vis.visit_span(path_span);
})
@ -1303,12 +1304,17 @@ pub fn noop_visit_expr<T: MutVisitor>(
vis.visit_expr(f);
visit_exprs(args, vis);
}
ExprKind::MethodCall(PathSegment { ident, id, args }, receiver, exprs, span) => {
ExprKind::MethodCall(box MethodCall {
seg: PathSegment { ident, id, args: seg_args },
receiver,
args: call_args,
span,
}) => {
vis.visit_ident(ident);
vis.visit_id(id);
visit_opt(args, |args| vis.visit_generic_args(args));
visit_opt(seg_args, |args| vis.visit_generic_args(args));
vis.visit_method_receiver_expr(receiver);
visit_exprs(exprs, vis);
visit_exprs(call_args, vis);
vis.visit_span(span);
}
ExprKind::Binary(_binop, lhs, rhs) => {
@ -1353,12 +1359,20 @@ pub fn noop_visit_expr<T: MutVisitor>(
vis.visit_expr(expr);
arms.flat_map_in_place(|arm| vis.flat_map_arm(arm));
}
ExprKind::Closure(binder, _capture_by, asyncness, _movability, decl, body, span) => {
ExprKind::Closure(box Closure {
binder,
capture_clause: _,
asyncness,
movability: _,
fn_decl,
body,
fn_decl_span,
}) => {
vis.visit_closure_binder(binder);
vis.visit_asyncness(asyncness);
vis.visit_fn_decl(decl);
vis.visit_fn_decl(fn_decl);
vis.visit_expr(body);
vis.visit_span(span);
vis.visit_span(fn_decl_span);
}
ExprKind::Block(blk, label) => {
vis.visit_block(blk);

View file

@ -36,7 +36,6 @@ pub fn expr_trailing_brace(mut expr: &ast::Expr) -> Option<&ast::Expr> {
| Binary(_, _, e)
| Box(e)
| Break(_, Some(e))
| Closure(.., e, _)
| Let(_, e, _)
| Range(_, Some(e), _)
| Ret(Some(e))
@ -44,6 +43,9 @@ pub fn expr_trailing_brace(mut expr: &ast::Expr) -> Option<&ast::Expr> {
| Yield(Some(e)) => {
expr = e;
}
Closure(closure) => {
expr = &closure.body;
}
Async(..) | Block(..) | ForLoop(..) | If(..) | Loop(..) | Match(..) | Struct(..)
| TryBlock(..) | While(..) => break Some(expr),
_ => break None,

View file

@ -396,7 +396,7 @@ pub fn contains_exterior_struct_lit(value: &ast::Expr) -> bool {
contains_exterior_struct_lit(&x)
}
ast::ExprKind::MethodCall(_, ref receiver, _, _) => {
ast::ExprKind::MethodCall(box ast::MethodCall { ref receiver, .. }) => {
// X { y: 1 }.bar(...)
contains_exterior_struct_lit(&receiver)
}

View file

@ -798,10 +798,10 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
visitor.visit_expr(callee_expression);
walk_list!(visitor, visit_expr, arguments);
}
ExprKind::MethodCall(ref segment, ref receiver, ref arguments, _span) => {
visitor.visit_path_segment(segment);
ExprKind::MethodCall(box MethodCall { ref seg, ref receiver, ref args, span: _ }) => {
visitor.visit_path_segment(seg);
visitor.visit_expr(receiver);
walk_list!(visitor, visit_expr, arguments);
walk_list!(visitor, visit_expr, args);
}
ExprKind::Binary(_, ref left_expression, ref right_expression) => {
visitor.visit_expr(left_expression);
@ -842,8 +842,16 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
visitor.visit_expr(subexpression);
walk_list!(visitor, visit_arm, arms);
}
ExprKind::Closure(ref binder, _, _, _, ref decl, ref body, _decl_span) => {
visitor.visit_fn(FnKind::Closure(binder, decl, body), expression.span, expression.id)
ExprKind::Closure(box Closure {
ref binder,
capture_clause: _,
asyncness: _,
movability: _,
ref fn_decl,
ref body,
fn_decl_span: _,
}) => {
visitor.visit_fn(FnKind::Closure(binder, fn_decl, body), expression.span, expression.id)
}
ExprKind::Block(ref block, ref opt_label) => {
walk_list!(visitor, visit_label, opt_label);