Skip to content

Commit

Permalink
Auto merge of #101562 - nnethercote:shrink-ast-Expr-harder, r=petroch…
Browse files Browse the repository at this point in the history
…enkov

Shrink `ast::Expr` harder

r? `@ghost`
  • Loading branch information
bors committed Nov 18, 2022
2 parents fd3bfb3 + 67d5cc0 commit 70fe5f0
Show file tree
Hide file tree
Showing 46 changed files with 486 additions and 383 deletions.
3 changes: 3 additions & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3476,6 +3476,7 @@ dependencies = [
"rustc_session",
"rustc_span",
"smallvec",
"thin-vec",
"tracing",
]

Expand Down Expand Up @@ -3916,6 +3917,7 @@ dependencies = [
"rustc_macros",
"rustc_session",
"rustc_span",
"thin-vec",
"tracing",
"unicode-normalization",
"unicode-width",
Expand Down Expand Up @@ -4051,6 +4053,7 @@ dependencies = [
"rustc_session",
"rustc_span",
"smallvec",
"thin-vec",
"tracing",
]

Expand Down
81 changes: 48 additions & 33 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ use rustc_span::{Span, DUMMY_SP};
use std::convert::TryFrom;
use std::fmt;
use std::mem;
use thin_vec::ThinVec;
use thin_vec::{thin_vec, ThinVec};

/// A "Label" is an identifier of some point in sources,
/// e.g. in the following code:
Expand Down Expand Up @@ -90,7 +90,7 @@ pub struct Path {
pub span: Span,
/// The segments in the path: the things separated by `::`.
/// Global paths begin with `kw::PathRoot`.
pub segments: Vec<PathSegment>,
pub segments: ThinVec<PathSegment>,
pub tokens: Option<LazyAttrTokenStream>,
}

Expand All @@ -114,7 +114,7 @@ impl Path {
// Convert a span and an identifier to the corresponding
// one-segment path.
pub fn from_ident(ident: Ident) -> Path {
Path { segments: vec![PathSegment::from_ident(ident)], span: ident.span, tokens: None }
Path { segments: thin_vec![PathSegment::from_ident(ident)], span: ident.span, tokens: None }
}

pub fn is_global(&self) -> bool {
Expand Down Expand Up @@ -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`.
Expand All @@ -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>>),
Expand Down Expand Up @@ -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 {
Expand All @@ -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`.
Expand All @@ -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,
Expand All @@ -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`).
Expand Down Expand Up @@ -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 { ... }`).
Expand Down Expand Up @@ -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>),
Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -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,
}

Expand Down Expand Up @@ -3031,28 +3046,28 @@ 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, 72);
static_assert_size!(ExprKind, 40);
static_assert_size!(Fn, 184);
static_assert_size!(ForeignItem, 96);
static_assert_size!(ForeignItemKind, 24);
static_assert_size!(GenericArg, 24);
static_assert_size!(GenericBound, 88);
static_assert_size!(GenericBound, 72);
static_assert_size!(Generics, 72);
static_assert_size!(Impl, 200);
static_assert_size!(Impl, 184);
static_assert_size!(Item, 184);
static_assert_size!(ItemKind, 112);
static_assert_size!(Lit, 48);
static_assert_size!(LitKind, 24);
static_assert_size!(Local, 72);
static_assert_size!(Param, 40);
static_assert_size!(Pat, 120);
static_assert_size!(Path, 40);
static_assert_size!(Pat, 88);
static_assert_size!(Path, 24);
static_assert_size!(PathSegment, 24);
static_assert_size!(PatKind, 96);
static_assert_size!(PatKind, 64);
static_assert_size!(Stmt, 32);
static_assert_size!(StmtKind, 16);
static_assert_size!(Ty, 96);
static_assert_size!(TyKind, 72);
static_assert_size!(Ty, 64);
static_assert_size!(TyKind, 40);
// tidy-alphabetical-end
}
7 changes: 3 additions & 4 deletions compiler/rustc_ast/src/attr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,18 @@ use crate::token::{self, CommentKind, Delimiter, Token};
use crate::tokenstream::{DelimSpan, Spacing, TokenTree};
use crate::tokenstream::{LazyAttrTokenStream, TokenStream};
use crate::util::comments;

use rustc_data_structures::sync::WorkerLocal;
use rustc_index::bit_set::GrowableBitSet;
use rustc_span::source_map::BytePos;
use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::Span;

use std::cell::Cell;
use std::iter;
#[cfg(debug_assertions)]
use std::ops::BitXor;
#[cfg(debug_assertions)]
use std::sync::atomic::{AtomicU32, Ordering};
use thin_vec::thin_vec;

pub struct MarkedAttrs(GrowableBitSet<AttrId>);

Expand Down Expand Up @@ -471,12 +470,12 @@ impl MetaItem {
tokens.peek()
{
tokens.next();
vec![PathSegment::from_ident(Ident::new(name, span))]
thin_vec![PathSegment::from_ident(Ident::new(name, span))]
} else {
break 'arm Path::from_ident(Ident::new(name, span));
}
} else {
vec![PathSegment::path_root(span)]
thin_vec![PathSegment::path_root(span)]
};
loop {
if let Some(TokenTree::Token(Token { kind: token::Ident(name, _), span }, _)) =
Expand Down
32 changes: 23 additions & 9 deletions compiler/rustc_ast/src/mut_visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down Expand Up @@ -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);
})
Expand Down Expand Up @@ -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) => {
Expand Down Expand Up @@ -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);
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_ast/src/util/classify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,16 @@ 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))
| Unary(_, e)
| Yield(Some(e)) => {
expr = e;
}
Closure(closure) => {
expr = &closure.body;
}
Async(..) | Block(..) | ForLoop(..) | If(..) | Loop(..) | Match(..) | Struct(..)
| TryBlock(..) | While(..) => break Some(expr),
_ => break None,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_ast/src/util/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
18 changes: 13 additions & 5 deletions compiler/rustc_ast/src/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
Loading

0 comments on commit 70fe5f0

Please sign in to comment.