Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Shrink ast::Expr harder #101562

Merged
merged 2 commits into from
Nov 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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