diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:18:25 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:18:25 +0000 |
commit | 5363f350887b1e5b5dd21a86f88c8af9d7fea6da (patch) | |
tree | 35ca005eb6e0e9a1ba3bb5dbc033209ad445dc17 /compiler/rustc_ast | |
parent | Adding debian version 1.66.0+dfsg1-1. (diff) | |
download | rustc-5363f350887b1e5b5dd21a86f88c8af9d7fea6da.tar.xz rustc-5363f350887b1e5b5dd21a86f88c8af9d7fea6da.zip |
Merging upstream version 1.67.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
30 files changed, 1671 insertions, 1725 deletions
diff --git a/compiler/rustc_ast/Cargo.toml b/compiler/rustc_ast/Cargo.toml index fcbf96818..9253b7e68 100644 --- a/compiler/rustc_ast/Cargo.toml +++ b/compiler/rustc_ast/Cargo.toml @@ -14,5 +14,5 @@ rustc_macros = { path = "../rustc_macros" } rustc_serialize = { path = "../rustc_serialize" } rustc_span = { path = "../rustc_span" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } -thin-vec = "0.2.8" +thin-vec = "0.2.9" tracing = "0.1" diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 4ef43735a..4d80f904a 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -13,7 +13,7 @@ //! - [`FnDecl`], [`FnHeader`] and [`Param`]: Metadata associated with a function declaration. //! - [`Generics`], [`GenericParam`], [`WhereClause`]: Metadata associated with generic parameters. //! - [`EnumDef`] and [`Variant`]: Enum declaration. -//! - [`Lit`] and [`LitKind`]: Literal expressions. +//! - [`MetaItemLit`] and [`LitKind`]: Literal expressions. //! - [`MacroDef`], [`MacStmtStyle`], [`MacCall`], [`MacDelimiter`]: Macro definition and invocation. //! - [`Attribute`]: Metadata associated with item. //! - [`UnOp`], [`BinOp`], and [`BinOpKind`]: Unary and binary operators. @@ -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: @@ -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>, } @@ -111,10 +111,10 @@ impl<CTX: rustc_span::HashStableContext> HashStable<CTX> for Path { } impl Path { - // Convert a span and an identifier to the corresponding - // one-segment 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 { @@ -175,9 +175,9 @@ impl GenericArgs { } pub fn span(&self) -> Span { - match *self { - AngleBracketed(ref data) => data.span, - Parenthesized(ref data) => data.span, + match self { + AngleBracketed(data) => data.span, + Parenthesized(data) => data.span, } } } @@ -312,8 +312,8 @@ pub enum GenericBound { impl GenericBound { pub fn span(&self) -> Span { match self { - GenericBound::Trait(ref t, ..) => t.span, - GenericBound::Outlives(ref l) => l.ident.span, + GenericBound::Trait(t, ..) => t.span, + GenericBound::Outlives(l) => l.ident.span, } } } @@ -392,15 +392,7 @@ pub struct Generics { impl Default for Generics { /// Creates an instance of `Generics`. fn default() -> Generics { - Generics { - params: Vec::new(), - where_clause: WhereClause { - has_where_token: false, - predicates: Vec::new(), - span: DUMMY_SP, - }, - span: DUMMY_SP, - } + Generics { params: Vec::new(), where_clause: Default::default(), span: DUMMY_SP } } } @@ -415,6 +407,12 @@ pub struct WhereClause { pub span: Span, } +impl Default for WhereClause { + fn default() -> WhereClause { + WhereClause { has_where_token: false, predicates: Vec::new(), span: DUMMY_SP } + } +} + /// A single predicate in a where-clause. #[derive(Clone, Encodable, Decodable, Debug)] pub enum WherePredicate { @@ -481,20 +479,10 @@ pub struct Crate { pub is_placeholder: bool, } -/// Possible values inside of compile-time attribute lists. -/// -/// E.g., the '..' in `#[name(..)]`. -#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)] -pub enum NestedMetaItem { - /// A full MetaItem, for recursive meta items. - MetaItem(MetaItem), - /// A literal. - /// - /// E.g., `"foo"`, `64`, `true`. - Literal(Lit), -} - -/// A spanned compile-time attribute item. +/// A semantic representation of a meta item. A meta item is a slightly +/// restricted form of an attribute -- it can only contain expressions in +/// certain leaf positions, rather than arbitrary token streams -- that is used +/// for most built-in attributes. /// /// E.g., `#[test]`, `#[derive(..)]`, `#[rustfmt::skip]` or `#[feature = "foo"]`. #[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)] @@ -504,23 +492,37 @@ pub struct MetaItem { pub span: Span, } -/// A compile-time attribute item. -/// -/// E.g., `#[test]`, `#[derive(..)]` or `#[feature = "foo"]`. +/// The meta item kind, containing the data after the initial path. #[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)] pub enum MetaItemKind { /// Word meta item. /// - /// E.g., `test` as in `#[test]`. + /// E.g., `#[test]`, which lacks any arguments after `test`. Word, + /// List meta item. /// - /// E.g., `derive(..)` as in `#[derive(..)]`. + /// E.g., `#[derive(..)]`, where the field represents the `..`. List(Vec<NestedMetaItem>), + /// Name value meta item. /// - /// E.g., `feature = "foo"` as in `#[feature = "foo"]`. - NameValue(Lit), + /// E.g., `#[feature = "foo"]`, where the field represents the `"foo"`. + NameValue(MetaItemLit), +} + +/// Values inside meta item lists. +/// +/// E.g., each of `Clone`, `Copy` in `#[derive(Clone, Copy)]`. +#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)] +pub enum NestedMetaItem { + /// A full MetaItem, for recursive meta items. + MetaItem(MetaItem), + + /// A literal. + /// + /// E.g., `"foo"`, `64`, `true`. + Lit(MetaItemLit), } /// A block (`{ .. }`). @@ -720,10 +722,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`. @@ -733,7 +735,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>>), @@ -777,8 +779,9 @@ pub enum PatKind { #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Copy)] #[derive(HashStable_Generic, Encodable, Decodable)] pub enum Mutability { - Mut, + // N.B. Order is deliberate, so that Not < Mut Not, + Mut, } impl Mutability { @@ -789,12 +792,39 @@ impl Mutability { } } - pub fn prefix_str(&self) -> &'static str { + /// Returns `""` (empty string) or `"mut "` depending on the mutability. + pub fn prefix_str(self) -> &'static str { match self { Mutability::Mut => "mut ", Mutability::Not => "", } } + + /// Returns `"&"` or `"&mut "` depending on the mutability. + pub fn ref_prefix_str(self) -> &'static str { + match self { + Mutability::Not => "&", + Mutability::Mut => "&mut ", + } + } + + /// Returns `""` (empty string) or `"mutably "` depending on the mutability. + pub fn mutably_str(self) -> &'static str { + match self { + Mutability::Not => "", + Mutability::Mut => "mutably ", + } + } + + /// Return `true` if self is mutable + pub fn is_mut(self) -> bool { + matches!(self, Self::Mut) + } + + /// Return `true` if self is **not** mutable + pub fn is_not(self) -> bool { + matches!(self, Self::Not) + } } /// The kind of borrow in an `AddrOf` expression, @@ -1117,23 +1147,23 @@ impl Expr { /// If this is not the case, name resolution does not resolve `N` when using /// `min_const_generics` as more complex expressions are not supported. pub fn is_potential_trivial_const_param(&self) -> bool { - let this = if let ExprKind::Block(ref block, None) = self.kind { - if block.stmts.len() == 1 { - if let StmtKind::Expr(ref expr) = block.stmts[0].kind { expr } else { self } - } else { - self - } + let this = if let ExprKind::Block(block, None) = &self.kind + && block.stmts.len() == 1 + && let StmtKind::Expr(expr) = &block.stmts[0].kind + { + expr } else { self }; - if let ExprKind::Path(None, ref path) = this.kind { - if path.segments.len() == 1 && path.segments[0].args.is_none() { - return true; - } + if let ExprKind::Path(None, path) = &this.kind + && path.segments.len() == 1 + && path.segments[0].args.is_none() + { + true + } else { + false } - - false } pub fn to_bound(&self) -> Option<GenericBound> { @@ -1149,7 +1179,7 @@ impl Expr { pub fn peel_parens(&self) -> &Expr { let mut expr = self; while let ExprKind::Paren(inner) = &expr.kind { - expr = &inner; + expr = inner; } expr } @@ -1208,7 +1238,7 @@ impl Expr { ExprKind::Tup(_) => ExprPrecedence::Tup, ExprKind::Binary(op, ..) => ExprPrecedence::Binary(op.node), ExprKind::Unary(..) => ExprPrecedence::Unary, - ExprKind::Lit(_) => ExprPrecedence::Lit, + ExprKind::Lit(_) | ExprKind::IncludedBytes(..) => ExprPrecedence::Lit, ExprKind::Type(..) | ExprKind::Cast(..) => ExprPrecedence::Cast, ExprKind::Let(..) => ExprPrecedence::Let, ExprKind::If(..) => ExprPrecedence::If, @@ -1257,7 +1287,7 @@ impl Expr { ) } - // To a first-order approximation, is this a pattern + /// To a first-order approximation, is this a pattern? pub fn is_approximately_pattern(&self) -> bool { match &self.peel_parens().kind { ExprKind::Box(_) @@ -1274,6 +1304,20 @@ 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 declaration block: 'move |...| -> ...' + pub fn_decl_span: Span, + /// The span of the argument block `|...|` + pub fn_arg_span: Span, +} + /// Limit types of a range (inclusive or exclusive) #[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug)] pub enum RangeLimits { @@ -1283,6 +1327,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`. @@ -1295,7 +1353,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, @@ -1316,17 +1374,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`). @@ -1334,7 +1383,7 @@ pub enum ExprKind { /// A unary operation (e.g., `!x`, `*x`). Unary(UnOp, P<Expr>), /// A literal (e.g., `1`, `"foo"`). - Lit(Lit), + Lit(token::Lit), /// A cast (e.g., `foo as f64`). Cast(P<Expr>, P<Ty>), /// A type ascription (e.g., `42: usize`). @@ -1361,13 +1410,11 @@ pub enum ExprKind { /// Conditionless loop (can be exited with `break`, `continue`, or `return`). /// /// `'label: loop { block }` - Loop(P<Block>, Option<Label>), + Loop(P<Block>, Option<Label>, Span), /// 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 { ... }`). @@ -1405,7 +1452,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>), @@ -1446,6 +1493,12 @@ pub enum ExprKind { /// with an optional value to be returned. Yeet(Option<P<Expr>>), + /// Bytes included via `include_bytes!` + /// Added for optimization purposes to avoid the need to escape + /// large binary blobs - should always behave like [`ExprKind::Lit`] + /// with a `ByteStr` literal. + IncludedBytes(Lrc<[u8]>), + /// Placeholder for an expression that wasn't syntactically well formed in some way. Err, } @@ -1525,55 +1578,48 @@ pub enum ClosureBinder { #[derive(Clone, Encodable, Decodable, Debug)] pub struct MacCall { pub path: Path, - pub args: P<MacArgs>, + pub args: P<DelimArgs>, pub prior_type_ascription: Option<(Span, bool)>, } impl MacCall { pub fn span(&self) -> Span { - self.path.span.to(self.args.span().unwrap_or(self.path.span)) + self.path.span.to(self.args.dspan.entire()) } } -/// Arguments passed to an attribute or a function-like macro. +/// Arguments passed to an attribute macro. #[derive(Clone, Encodable, Decodable, Debug)] -pub enum MacArgs { - /// No arguments - `#[attr]`. +pub enum AttrArgs { + /// No arguments: `#[attr]`. Empty, - /// Delimited arguments - `#[attr()/[]/{}]` or `mac!()/[]/{}`. - Delimited(DelimSpan, MacDelimiter, TokenStream), - /// Arguments of a key-value attribute - `#[attr = "value"]`. + /// Delimited arguments: `#[attr()/[]/{}]`. + Delimited(DelimArgs), + /// Arguments of a key-value attribute: `#[attr = "value"]`. Eq( /// Span of the `=` token. Span, /// The "value". - MacArgsEq, + AttrArgsEq, ), } -// The RHS of a `MacArgs::Eq` starts out as an expression. Once macro expansion -// is completed, all cases end up either as a literal, which is the form used -// after lowering to HIR, or as an error. +// The RHS of an `AttrArgs::Eq` starts out as an expression. Once macro +// expansion is completed, all cases end up either as a meta item literal, +// which is the form used after lowering to HIR, or as an error. #[derive(Clone, Encodable, Decodable, Debug)] -pub enum MacArgsEq { +pub enum AttrArgsEq { Ast(P<Expr>), - Hir(Lit), + Hir(MetaItemLit), } -impl MacArgs { - pub fn delim(&self) -> Option<Delimiter> { - match self { - MacArgs::Delimited(_, delim, _) => Some(delim.to_token()), - MacArgs::Empty | MacArgs::Eq(..) => None, - } - } - +impl AttrArgs { pub fn span(&self) -> Option<Span> { match self { - MacArgs::Empty => None, - MacArgs::Delimited(dspan, ..) => Some(dspan.entire()), - MacArgs::Eq(eq_span, MacArgsEq::Ast(expr)) => Some(eq_span.to(expr.span)), - MacArgs::Eq(_, MacArgsEq::Hir(lit)) => { + AttrArgs::Empty => None, + AttrArgs::Delimited(args) => Some(args.dspan.entire()), + AttrArgs::Eq(eq_span, AttrArgsEq::Ast(expr)) => Some(eq_span.to(expr.span)), + AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => { unreachable!("in literal form when getting span: {:?}", lit); } } @@ -1583,39 +1629,29 @@ impl MacArgs { /// Proc macros see these tokens, for example. pub fn inner_tokens(&self) -> TokenStream { match self { - MacArgs::Empty => TokenStream::default(), - MacArgs::Delimited(.., tokens) => tokens.clone(), - MacArgs::Eq(_, MacArgsEq::Ast(expr)) => TokenStream::from_ast(expr), - MacArgs::Eq(_, MacArgsEq::Hir(lit)) => { + AttrArgs::Empty => TokenStream::default(), + AttrArgs::Delimited(args) => args.tokens.clone(), + AttrArgs::Eq(_, AttrArgsEq::Ast(expr)) => TokenStream::from_ast(expr), + AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => { unreachable!("in literal form when getting inner tokens: {:?}", lit) } } } - - /// Whether a macro with these arguments needs a semicolon - /// when used as a standalone item or statement. - pub fn need_semicolon(&self) -> bool { - !matches!(self, MacArgs::Delimited(_, MacDelimiter::Brace, _)) - } } -impl<CTX> HashStable<CTX> for MacArgs +impl<CTX> HashStable<CTX> for AttrArgs where CTX: crate::HashStableContext, { fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { mem::discriminant(self).hash_stable(ctx, hasher); match self { - MacArgs::Empty => {} - MacArgs::Delimited(dspan, delim, tokens) => { - dspan.hash_stable(ctx, hasher); - delim.hash_stable(ctx, hasher); - tokens.hash_stable(ctx, hasher); - } - MacArgs::Eq(_eq_span, MacArgsEq::Ast(expr)) => { + AttrArgs::Empty => {} + AttrArgs::Delimited(args) => args.hash_stable(ctx, hasher), + AttrArgs::Eq(_eq_span, AttrArgsEq::Ast(expr)) => { unreachable!("hash_stable {:?}", expr); } - MacArgs::Eq(eq_span, MacArgsEq::Hir(lit)) => { + AttrArgs::Eq(eq_span, AttrArgsEq::Hir(lit)) => { eq_span.hash_stable(ctx, hasher); lit.hash_stable(ctx, hasher); } @@ -1623,6 +1659,34 @@ where } } +/// Delimited arguments, as used in `#[attr()/[]/{}]` or `mac!()/[]/{}`. +#[derive(Clone, Encodable, Decodable, Debug)] +pub struct DelimArgs { + pub dspan: DelimSpan, + pub delim: MacDelimiter, + pub tokens: TokenStream, +} + +impl DelimArgs { + /// Whether a macro with these arguments needs a semicolon + /// when used as a standalone item or statement. + pub fn need_semicolon(&self) -> bool { + !matches!(self, DelimArgs { delim: MacDelimiter::Brace, .. }) + } +} + +impl<CTX> HashStable<CTX> for DelimArgs +where + CTX: crate::HashStableContext, +{ + fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { + let DelimArgs { dspan, delim, tokens } = self; + dspan.hash_stable(ctx, hasher); + delim.hash_stable(ctx, hasher); + tokens.hash_stable(ctx, hasher); + } +} + #[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)] pub enum MacDelimiter { Parenthesis, @@ -1652,7 +1716,7 @@ impl MacDelimiter { /// Represents a macro definition. #[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)] pub struct MacroDef { - pub body: P<MacArgs>, + pub body: P<DelimArgs>, /// `true` if macro was defined with `macro_rules`. pub macro_rules: bool, } @@ -1668,19 +1732,18 @@ pub enum StrStyle { Raw(u8), } -/// An AST literal. +/// A literal in a meta item. #[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)] -pub struct Lit { +pub struct MetaItemLit { /// The original literal token as written in source code. pub token_lit: token::Lit, /// The "semantic" representation of the literal lowered from the original tokens. /// Strings are unescaped, hexadecimal forms are eliminated, etc. - /// FIXME: Remove this and only create the semantic representation during lowering to HIR. pub kind: LitKind, pub span: Span, } -/// Same as `Lit`, but restricted to string literals. +/// Similar to `MetaItemLit`, but restricted to string literals. #[derive(Clone, Copy, Encodable, Decodable, Debug)] pub struct StrLit { /// The original literal token as written in source code. @@ -1689,21 +1752,16 @@ pub struct StrLit { pub suffix: Option<Symbol>, pub span: Span, /// The unescaped "semantic" representation of the literal lowered from the original token. - /// FIXME: Remove this and only create the semantic representation during lowering to HIR. pub symbol_unescaped: Symbol, } impl StrLit { - pub fn as_lit(&self) -> Lit { + pub fn as_token_lit(&self) -> token::Lit { let token_kind = match self.style { StrStyle::Cooked => token::Str, StrStyle::Raw(n) => token::StrRaw(n), }; - Lit { - token_lit: token::Lit::new(token_kind, self.symbol, self.suffix), - span: self.span, - kind: LitKind::Str(self.symbol_unescaped, self.style), - } + token::Lit::new(token_kind, self.symbol, self.suffix) } } @@ -1729,9 +1787,12 @@ pub enum LitFloatType { Unsuffixed, } -/// Literal kind. +/// This type is used within both `ast::MetaItemLit` and `hir::Lit`. /// -/// E.g., `"foo"`, `42`, `12.34`, or `bool`. +/// Note that the entire literal (including the suffix) is considered when +/// deciding the `LitKind`. This means that float literals like `1f32` are +/// classified by this type as `Float`. This is different to `token::LitKind` +/// which does *not* consider the suffix. #[derive(Clone, Encodable, Decodable, Debug, Hash, Eq, PartialEq, HashStable_Generic)] pub enum LitKind { /// A string literal (`"foo"`). The symbol is unescaped, and so may differ @@ -1745,10 +1806,11 @@ pub enum LitKind { Char(char), /// An integer literal (`1`). Int(u128, LitIntType), - /// A float literal (`1f64` or `1E10f64`). Stored as a symbol rather than - /// `f64` so that `LitKind` can impl `Eq` and `Hash`. + /// A float literal (`1.0`, `1f64` or `1E10f64`). The pre-suffix part is + /// stored as a symbol rather than `f64` so that `LitKind` can impl `Eq` + /// and `Hash`. Float(Symbol, LitFloatType), - /// A boolean literal. + /// A boolean literal (`true`, `false`). Bool(bool), /// Placeholder for a literal that wasn't well-formed in some way. Err, @@ -1967,7 +2029,7 @@ impl Ty { pub fn peel_refs(&self) -> &Self { let mut final_ty = self; while let TyKind::Rptr(_, MutTy { ty, .. }) = &final_ty.kind { - final_ty = &ty; + final_ty = ty; } final_ty } @@ -2004,7 +2066,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), @@ -2136,7 +2198,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, } @@ -2376,9 +2438,9 @@ pub enum FnRetTy { impl FnRetTy { pub fn span(&self) -> Span { - match *self { - FnRetTy::Default(span) => span, - FnRetTy::Ty(ref ty) => ty.span, + match self { + &FnRetTy::Default(span) => span, + FnRetTy::Ty(ty) => ty.span, } } } @@ -2457,10 +2519,7 @@ pub struct Variant { #[derive(Clone, Encodable, Decodable, Debug)] pub enum UseTreeKind { /// `use prefix` or `use prefix as rename` - /// - /// The extra `NodeId`s are for HIR lowering, when additional statements are created for each - /// namespace. - Simple(Option<Ident>, NodeId, NodeId), + Simple(Option<Ident>), /// `use prefix::{...}` Nested(Vec<(UseTree, NodeId)>), /// `use prefix::*` @@ -2479,8 +2538,8 @@ pub struct UseTree { impl UseTree { pub fn ident(&self) -> Ident { match self.kind { - UseTreeKind::Simple(Some(rename), ..) => rename, - UseTreeKind::Simple(None, ..) => { + UseTreeKind::Simple(Some(rename)) => rename, + UseTreeKind::Simple(None) => { self.prefix.segments.last().expect("empty prefix in a simple import").ident } _ => panic!("`UseTree::ident` can only be used on a simple import"), @@ -2514,17 +2573,10 @@ impl<D: Decoder> Decodable<D> for AttrId { } } -#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)] -pub struct AttrItem { - pub path: Path, - pub args: MacArgs, - pub tokens: Option<LazyAttrTokenStream>, -} - /// A list of attributes. pub type AttrVec = ThinVec<Attribute>; -/// Metadata associated with an item. +/// A syntax-level representation of an attribute. #[derive(Clone, Encodable, Decodable, Debug)] pub struct Attribute { pub kind: AttrKind, @@ -2536,12 +2588,6 @@ pub struct Attribute { } #[derive(Clone, Encodable, Decodable, Debug)] -pub struct NormalAttr { - pub item: AttrItem, - pub tokens: Option<LazyAttrTokenStream>, -} - -#[derive(Clone, Encodable, Decodable, Debug)] pub enum AttrKind { /// A normal attribute. Normal(P<NormalAttr>), @@ -2552,6 +2598,19 @@ pub enum AttrKind { DocComment(CommentKind, Symbol), } +#[derive(Clone, Encodable, Decodable, Debug)] +pub struct NormalAttr { + pub item: AttrItem, + pub tokens: Option<LazyAttrTokenStream>, +} + +#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)] +pub struct AttrItem { + pub path: Path, + pub args: AttrArgs, + pub tokens: Option<LazyAttrTokenStream>, +} + /// `TraitRef`s appear in impls. /// /// Resolution maps each `TraitRef`'s `ref_id` to its defining trait; that's all @@ -2640,14 +2699,14 @@ pub enum VariantData { impl VariantData { /// Return the fields of this variant. pub fn fields(&self) -> &[FieldDef] { - match *self { - VariantData::Struct(ref fields, ..) | VariantData::Tuple(ref fields, _) => fields, + match self { + VariantData::Struct(fields, ..) | VariantData::Tuple(fields, _) => fields, _ => &[], } } /// Return the `NodeId` of this variant's constructor, if it has one. - pub fn ctor_id(&self) -> Option<NodeId> { + pub fn ctor_node_id(&self) -> Option<NodeId> { match *self { VariantData::Struct(..) => None, VariantData::Tuple(_, id) | VariantData::Unit(id) => Some(id), @@ -3029,28 +3088,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!(MetaItemLit, 48); 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 } diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 990f4f8f1..057cc26b5 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -1,35 +1,33 @@ //! Functions dealing with attributes and meta items. use crate::ast; -use crate::ast::{AttrId, AttrItem, AttrKind, AttrStyle, Attribute}; -use crate::ast::{Lit, LitKind}; -use crate::ast::{MacArgs, MacArgsEq, MacDelimiter, MetaItem, MetaItemKind, NestedMetaItem}; -use crate::ast::{Path, PathSegment}; +use crate::ast::{AttrArgs, AttrArgsEq, AttrId, AttrItem, AttrKind, AttrStyle, AttrVec, Attribute}; +use crate::ast::{DelimArgs, Expr, ExprKind, LitKind, MetaItemLit}; +use crate::ast::{MacDelimiter, MetaItem, MetaItemKind, NestedMetaItem, NormalAttr}; +use crate::ast::{Path, PathSegment, StrStyle, DUMMY_NODE_ID}; use crate::ptr::P; 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>); impl MarkedAttrs { - // We have no idea how many attributes there will be, so just - // initiate the vectors with 0 bits. We'll grow them as necessary. pub fn new() -> Self { + // We have no idea how many attributes there will be, so just + // initiate the vectors with 0 bits. We'll grow them as necessary. MarkedAttrs(GrowableBitSet::new_empty()) } @@ -45,16 +43,16 @@ impl MarkedAttrs { impl NestedMetaItem { /// Returns the `MetaItem` if `self` is a `NestedMetaItem::MetaItem`. pub fn meta_item(&self) -> Option<&MetaItem> { - match *self { - NestedMetaItem::MetaItem(ref item) => Some(item), + match self { + NestedMetaItem::MetaItem(item) => Some(item), _ => None, } } - /// Returns the `Lit` if `self` is a `NestedMetaItem::Literal`s. - pub fn literal(&self) -> Option<&Lit> { - match *self { - NestedMetaItem::Literal(ref lit) => Some(lit), + /// Returns the `MetaItemLit` if `self` is a `NestedMetaItem::Literal`s. + pub fn lit(&self) -> Option<&MetaItemLit> { + match self { + NestedMetaItem::Lit(lit) => Some(lit), _ => None, } } @@ -79,12 +77,12 @@ impl NestedMetaItem { } /// Returns a name and single literal value tuple of the `MetaItem`. - pub fn name_value_literal(&self) -> Option<(Symbol, &Lit)> { + pub fn name_value_literal(&self) -> Option<(Symbol, &MetaItemLit)> { self.meta_item().and_then(|meta_item| { meta_item.meta_item_list().and_then(|meta_item_list| { if meta_item_list.len() == 1 && let Some(ident) = meta_item.ident() - && let Some(lit) = meta_item_list[0].literal() + && let Some(lit) = meta_item_list[0].lit() { return Some((ident.name, lit)); } @@ -117,18 +115,18 @@ impl NestedMetaItem { impl Attribute { #[inline] pub fn has_name(&self, name: Symbol) -> bool { - match self.kind { - AttrKind::Normal(ref normal) => normal.item.path == name, + match &self.kind { + AttrKind::Normal(normal) => normal.item.path == name, AttrKind::DocComment(..) => false, } } /// For a single-segment attribute, returns its name; otherwise, returns `None`. pub fn ident(&self) -> Option<Ident> { - match self.kind { - AttrKind::Normal(ref normal) => { - if normal.item.path.segments.len() == 1 { - Some(normal.item.path.segments[0].ident) + match &self.kind { + AttrKind::Normal(normal) => { + if let [ident] = &*normal.item.path.segments { + Some(ident.ident) } else { None } @@ -141,17 +139,15 @@ impl Attribute { } pub fn value_str(&self) -> Option<Symbol> { - match self.kind { - AttrKind::Normal(ref normal) => { - normal.item.meta_kind().and_then(|kind| kind.value_str()) - } + match &self.kind { + AttrKind::Normal(normal) => normal.item.meta_kind().and_then(|kind| kind.value_str()), AttrKind::DocComment(..) => None, } } pub fn meta_item_list(&self) -> Option<Vec<NestedMetaItem>> { - match self.kind { - AttrKind::Normal(ref normal) => match normal.item.meta_kind() { + match &self.kind { + AttrKind::Normal(normal) => match normal.item.meta_kind() { Some(MetaItemKind::List(list)) => Some(list), _ => None, }, @@ -161,7 +157,7 @@ impl Attribute { pub fn is_word(&self) -> bool { if let AttrKind::Normal(normal) = &self.kind { - matches!(normal.item.args, MacArgs::Empty) + matches!(normal.item.args, AttrArgs::Empty) } else { false } @@ -177,10 +173,12 @@ impl MetaItem { self.ident().unwrap_or_else(Ident::empty).name } - // Example: - // #[attribute(name = "value")] - // ^^^^^^^^^^^^^^ - pub fn name_value_literal(&self) -> Option<&Lit> { + /// ```text + /// Example: + /// #[attribute(name = "value")] + /// ^^^^^^^^^^^^^^ + /// ``` + pub fn name_value_literal(&self) -> Option<&MetaItemLit> { match &self.kind { MetaItemKind::NameValue(v) => Some(v), _ => None, @@ -192,8 +190,8 @@ impl MetaItem { } pub fn meta_item_list(&self) -> Option<&[NestedMetaItem]> { - match self.kind { - MetaItemKind::List(ref l) => Some(&l[..]), + match &self.kind { + MetaItemKind::List(l) => Some(&**l), _ => None, } } @@ -224,15 +222,11 @@ impl AttrItem { } pub fn meta(&self, span: Span) -> Option<MetaItem> { - Some(MetaItem { - path: self.path.clone(), - kind: MetaItemKind::from_mac_args(&self.args)?, - span, - }) + Some(MetaItem { path: self.path.clone(), kind: self.meta_kind()?, span }) } pub fn meta_kind(&self) -> Option<MetaItemKind> { - MetaItemKind::from_mac_args(&self.args) + MetaItemKind::from_attr_args(&self.args) } } @@ -269,9 +263,9 @@ impl Attribute { /// * `#[doc = "doc"]` returns `Some("doc")`. /// * `#[doc(...)]` returns `None`. pub fn doc_str(&self) -> Option<Symbol> { - match self.kind { - AttrKind::DocComment(.., data) => Some(data), - AttrKind::Normal(ref normal) if normal.item.path == sym::doc => { + match &self.kind { + AttrKind::DocComment(.., data) => Some(*data), + AttrKind::Normal(normal) if normal.item.path == sym::doc => { normal.item.meta_kind().and_then(|kind| kind.value_str()) } _ => None, @@ -283,8 +277,8 @@ impl Attribute { } pub fn get_normal_item(&self) -> &AttrItem { - match self.kind { - AttrKind::Normal(ref normal) => &normal.item, + match &self.kind { + AttrKind::Normal(normal) => &normal.item, AttrKind::DocComment(..) => panic!("unexpected doc comment"), } } @@ -298,28 +292,28 @@ impl Attribute { /// Extracts the MetaItem from inside this Attribute. pub fn meta(&self) -> Option<MetaItem> { - match self.kind { - AttrKind::Normal(ref normal) => normal.item.meta(self.span), + match &self.kind { + AttrKind::Normal(normal) => normal.item.meta(self.span), AttrKind::DocComment(..) => None, } } pub fn meta_kind(&self) -> Option<MetaItemKind> { - match self.kind { - AttrKind::Normal(ref normal) => normal.item.meta_kind(), + match &self.kind { + AttrKind::Normal(normal) => normal.item.meta_kind(), AttrKind::DocComment(..) => None, } } pub fn tokens(&self) -> TokenStream { - match self.kind { - AttrKind::Normal(ref normal) => normal + match &self.kind { + AttrKind::Normal(normal) => normal .tokens .as_ref() .unwrap_or_else(|| panic!("attribute is missing tokens: {:?}", self)) .to_attr_token_stream() .to_tokenstream(), - AttrKind::DocComment(comment_kind, data) => TokenStream::new(vec![TokenTree::Token( + &AttrKind::DocComment(comment_kind, data) => TokenStream::new(vec![TokenTree::Token( Token::new(token::DocComment(comment_kind, self.style, data), self.span), Spacing::Alone, )]), @@ -330,26 +324,13 @@ impl Attribute { /* Constructors */ pub fn mk_name_value_item_str(ident: Ident, str: Symbol, str_span: Span) -> MetaItem { - let lit_kind = LitKind::Str(str, ast::StrStyle::Cooked); - mk_name_value_item(ident, lit_kind, str_span) + mk_name_value_item(ident, LitKind::Str(str, ast::StrStyle::Cooked), str_span) } -pub fn mk_name_value_item(ident: Ident, lit_kind: LitKind, lit_span: Span) -> MetaItem { - let lit = Lit::from_lit_kind(lit_kind, lit_span); +pub fn mk_name_value_item(ident: Ident, kind: LitKind, lit_span: Span) -> MetaItem { + let lit = MetaItemLit { token_lit: kind.to_token_lit(), kind, span: lit_span }; let span = ident.span.to(lit_span); - MetaItem { path: Path::from_ident(ident), span, kind: MetaItemKind::NameValue(lit) } -} - -pub fn mk_list_item(ident: Ident, items: Vec<NestedMetaItem>) -> MetaItem { - MetaItem { path: Path::from_ident(ident), span: ident.span, kind: MetaItemKind::List(items) } -} - -pub fn mk_word_item(ident: Ident) -> MetaItem { - MetaItem { path: Path::from_ident(ident), span: ident.span, kind: MetaItemKind::Word } -} - -pub fn mk_nested_word_item(ident: Ident) -> NestedMetaItem { - NestedMetaItem::MetaItem(mk_word_item(ident)) + MetaItem { path: Path::from_ident(ident), kind: MetaItemKind::NameValue(lit), span } } pub struct AttrIdGenerator(WorkerLocal<Cell<u32>>); @@ -393,7 +374,7 @@ pub fn mk_attr( g: &AttrIdGenerator, style: AttrStyle, path: Path, - args: MacArgs, + args: AttrArgs, span: Span, ) -> Attribute { mk_attr_from_item(g, AttrItem { path, args, tokens: None }, None, style, span) @@ -407,21 +388,58 @@ pub fn mk_attr_from_item( span: Span, ) -> Attribute { Attribute { - kind: AttrKind::Normal(P(ast::NormalAttr { item, tokens })), + kind: AttrKind::Normal(P(NormalAttr { item, tokens })), id: g.mk_attr_id(), style, span, } } -/// Returns an inner attribute with the given value and span. -pub fn mk_attr_inner(g: &AttrIdGenerator, item: MetaItem) -> Attribute { - mk_attr(g, AttrStyle::Inner, item.path, item.kind.mac_args(item.span), item.span) +pub fn mk_attr_word(g: &AttrIdGenerator, style: AttrStyle, name: Symbol, span: Span) -> Attribute { + let path = Path::from_ident(Ident::new(name, span)); + let args = AttrArgs::Empty; + mk_attr(g, style, path, args, span) +} + +pub fn mk_attr_name_value_str( + g: &AttrIdGenerator, + style: AttrStyle, + name: Symbol, + val: Symbol, + span: Span, +) -> Attribute { + let lit = LitKind::Str(val, StrStyle::Cooked).to_token_lit(); + let expr = P(Expr { + id: DUMMY_NODE_ID, + kind: ExprKind::Lit(lit), + span, + attrs: AttrVec::new(), + tokens: None, + }); + let path = Path::from_ident(Ident::new(name, span)); + let args = AttrArgs::Eq(span, AttrArgsEq::Ast(expr)); + mk_attr(g, style, path, args, span) } -/// Returns an outer attribute with the given value and span. -pub fn mk_attr_outer(g: &AttrIdGenerator, item: MetaItem) -> Attribute { - mk_attr(g, AttrStyle::Outer, item.path, item.kind.mac_args(item.span), item.span) +pub fn mk_attr_nested_word( + g: &AttrIdGenerator, + style: AttrStyle, + outer: Symbol, + inner: Symbol, + span: Span, +) -> Attribute { + let inner_tokens = TokenStream::new(vec![TokenTree::Token( + Token::from_ast_ident(Ident::new(inner, span)), + Spacing::Alone, + )]); + let outer_ident = Ident::new(outer, span); + let path = Path::from_ident(outer_ident); + let attr_args = AttrArgs::Delimited(DelimArgs { + dspan: DelimSpan::from_single(span), + delim: MacDelimiter::Parenthesis, + tokens: inner_tokens, + }); + mk_attr(g, style, path, attr_args, span) } pub fn mk_doc_comment( @@ -439,23 +457,6 @@ pub fn list_contains_name(items: &[NestedMetaItem], name: Symbol) -> bool { } impl MetaItem { - fn token_trees(&self) -> Vec<TokenTree> { - let mut idents = vec![]; - let mut last_pos = BytePos(0_u32); - for (i, segment) in self.path.segments.iter().enumerate() { - let is_first = i == 0; - if !is_first { - let mod_sep_span = - Span::new(last_pos, segment.ident.span.lo(), segment.ident.span.ctxt(), None); - idents.push(TokenTree::token_alone(token::ModSep, mod_sep_span)); - } - idents.push(TokenTree::Token(Token::from_ast_ident(segment.ident), Spacing::Alone)); - last_pos = segment.ident.span.hi(); - } - idents.extend(self.kind.token_trees(self.span)); - idents - } - fn from_tokens<I>(tokens: &mut iter::Peekable<I>) -> Option<MetaItem> where I: Iterator<Item = TokenTree>, @@ -471,12 +472,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 }, _)) = @@ -497,17 +498,17 @@ impl MetaItem { let span = span.with_hi(segments.last().unwrap().ident.span.hi()); Path { span, segments, tokens: None } } - Some(TokenTree::Token(Token { kind: token::Interpolated(nt), .. }, _)) => match *nt { - token::Nonterminal::NtMeta(ref item) => return item.meta(item.path.span), - token::Nonterminal::NtPath(ref path) => (**path).clone(), + Some(TokenTree::Token(Token { kind: token::Interpolated(nt), .. }, _)) => match &*nt { + token::Nonterminal::NtMeta(item) => return item.meta(item.path.span), + token::Nonterminal::NtPath(path) => (**path).clone(), _ => return None, }, _ => return None, }; let list_closing_paren_pos = tokens.peek().map(|tt| tt.span().hi()); let kind = MetaItemKind::from_tokens(tokens)?; - let hi = match kind { - MetaItemKind::NameValue(ref lit) => lit.span.hi(), + let hi = match &kind { + MetaItemKind::NameValue(lit) => lit.span.hi(), MetaItemKind::List(..) => list_closing_paren_pos.unwrap_or(path.span.hi()), _ => path.span.hi(), }; @@ -519,70 +520,14 @@ impl MetaItem { impl MetaItemKind { pub fn value_str(&self) -> Option<Symbol> { match self { - MetaItemKind::NameValue(ref v) => match v.kind { - LitKind::Str(ref s, _) => Some(*s), + MetaItemKind::NameValue(v) => match v.kind { + LitKind::Str(s, _) => Some(s), _ => None, }, _ => None, } } - pub fn mac_args(&self, span: Span) -> MacArgs { - match self { - MetaItemKind::Word => MacArgs::Empty, - MetaItemKind::NameValue(lit) => { - let expr = P(ast::Expr { - id: ast::DUMMY_NODE_ID, - kind: ast::ExprKind::Lit(lit.clone()), - span: lit.span, - attrs: ast::AttrVec::new(), - tokens: None, - }); - MacArgs::Eq(span, MacArgsEq::Ast(expr)) - } - MetaItemKind::List(list) => { - let mut tts = Vec::new(); - for (i, item) in list.iter().enumerate() { - if i > 0 { - tts.push(TokenTree::token_alone(token::Comma, span)); - } - tts.extend(item.token_trees()) - } - MacArgs::Delimited( - DelimSpan::from_single(span), - MacDelimiter::Parenthesis, - TokenStream::new(tts), - ) - } - } - } - - fn token_trees(&self, span: Span) -> Vec<TokenTree> { - match *self { - MetaItemKind::Word => vec![], - MetaItemKind::NameValue(ref lit) => { - vec![ - TokenTree::token_alone(token::Eq, span), - TokenTree::Token(lit.to_token(), Spacing::Alone), - ] - } - MetaItemKind::List(ref list) => { - let mut tokens = Vec::new(); - for (i, item) in list.iter().enumerate() { - if i > 0 { - tokens.push(TokenTree::token_alone(token::Comma, span)); - } - tokens.extend(item.token_trees()) - } - vec![TokenTree::Delimited( - DelimSpan::from_single(span), - Delimiter::Parenthesis, - TokenStream::new(tokens), - )] - } - } - } - fn list_from_tokens(tokens: TokenStream) -> Option<MetaItemKind> { let mut tokens = tokens.into_trees().peekable(); let mut result = Vec::new(); @@ -605,24 +550,31 @@ impl MetaItemKind { MetaItemKind::name_value_from_tokens(&mut inner_tokens.into_trees()) } Some(TokenTree::Token(token, _)) => { - Lit::from_token(&token).ok().map(MetaItemKind::NameValue) + MetaItemLit::from_token(&token).map(MetaItemKind::NameValue) } _ => None, } } - fn from_mac_args(args: &MacArgs) -> Option<MetaItemKind> { + fn from_attr_args(args: &AttrArgs) -> Option<MetaItemKind> { match args { - MacArgs::Empty => Some(MetaItemKind::Word), - MacArgs::Delimited(_, MacDelimiter::Parenthesis, tokens) => { - MetaItemKind::list_from_tokens(tokens.clone()) - } - MacArgs::Delimited(..) => None, - MacArgs::Eq(_, MacArgsEq::Ast(expr)) => match &expr.kind { - ast::ExprKind::Lit(lit) => Some(MetaItemKind::NameValue(lit.clone())), + AttrArgs::Empty => Some(MetaItemKind::Word), + AttrArgs::Delimited(DelimArgs { + dspan: _, + delim: MacDelimiter::Parenthesis, + tokens, + }) => MetaItemKind::list_from_tokens(tokens.clone()), + AttrArgs::Delimited(..) => None, + AttrArgs::Eq(_, AttrArgsEq::Ast(expr)) => match expr.kind { + ExprKind::Lit(token_lit) => { + // Turn failures to `None`, we'll get parse errors elsewhere. + MetaItemLit::from_token_lit(token_lit, expr.span) + .ok() + .map(|lit| MetaItemKind::NameValue(lit)) + } _ => None, }, - MacArgs::Eq(_, MacArgsEq::Hir(lit)) => Some(MetaItemKind::NameValue(lit.clone())), + AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => Some(MetaItemKind::NameValue(lit.clone())), } } @@ -647,18 +599,9 @@ impl MetaItemKind { impl NestedMetaItem { pub fn span(&self) -> Span { - match *self { - NestedMetaItem::MetaItem(ref item) => item.span, - NestedMetaItem::Literal(ref lit) => lit.span, - } - } - - fn token_trees(&self) -> Vec<TokenTree> { - match *self { - NestedMetaItem::MetaItem(ref item) => item.token_trees(), - NestedMetaItem::Literal(ref lit) => { - vec![TokenTree::Token(lit.to_token(), Spacing::Alone)] - } + match self { + NestedMetaItem::MetaItem(item) => item.span, + NestedMetaItem::Lit(lit) => lit.span, } } @@ -668,10 +611,10 @@ impl NestedMetaItem { { match tokens.peek() { Some(TokenTree::Token(token, _)) - if let Ok(lit) = Lit::from_token(token) => + if let Some(lit) = MetaItemLit::from_token(token) => { tokens.next(); - return Some(NestedMetaItem::Literal(lit)); + return Some(NestedMetaItem::Lit(lit)); } Some(TokenTree::Delimited(_, Delimiter::Invisible, inner_tokens)) => { let inner_tokens = inner_tokens.clone(); diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs index eeb7e56e2..9c1dfeb1a 100644 --- a/compiler/rustc_ast/src/lib.rs +++ b/compiler/rustc_ast/src/lib.rs @@ -29,6 +29,7 @@ extern crate rustc_macros; extern crate tracing; pub mod util { + pub mod case; pub mod classify; pub mod comments; pub mod literal; diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index b970e57e0..a45ee6067 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -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); } @@ -367,23 +367,27 @@ pub fn visit_fn_sig<T: MutVisitor>(FnSig { header, decl, span }: &mut FnSig, vis } // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. -pub fn visit_mac_args<T: MutVisitor>(args: &mut MacArgs, vis: &mut T) { +pub fn visit_attr_args<T: MutVisitor>(args: &mut AttrArgs, vis: &mut T) { match args { - MacArgs::Empty => {} - MacArgs::Delimited(dspan, _delim, tokens) => { - visit_delim_span(dspan, vis); - visit_tts(tokens, vis); - } - MacArgs::Eq(eq_span, MacArgsEq::Ast(expr)) => { + AttrArgs::Empty => {} + AttrArgs::Delimited(args) => visit_delim_args(args, vis), + AttrArgs::Eq(eq_span, AttrArgsEq::Ast(expr)) => { vis.visit_span(eq_span); vis.visit_expr(expr); } - MacArgs::Eq(_, MacArgsEq::Hir(lit)) => { + AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => { unreachable!("in literal form when visiting mac args eq: {:?}", lit) } } } +// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. +pub fn visit_delim_args<T: MutVisitor>(args: &mut DelimArgs, vis: &mut T) { + let DelimArgs { dspan, delim: _, tokens } = args; + visit_delim_span(dspan, vis); + visit_tts(tokens, vis); +} + pub fn visit_delim_span<T: MutVisitor>(dspan: &mut DelimSpan, vis: &mut T) { vis.visit_span(&mut dspan.open); vis.visit_span(&mut dspan.close); @@ -406,11 +410,7 @@ pub fn noop_visit_use_tree<T: MutVisitor>(use_tree: &mut UseTree, vis: &mut T) { let UseTree { prefix, kind, span } = use_tree; vis.visit_path(prefix); match kind { - UseTreeKind::Simple(rename, id1, id2) => { - visit_opt(rename, |rename| vis.visit_ident(rename)); - vis.visit_id(id1); - vis.visit_id(id2); - } + UseTreeKind::Simple(rename) => visit_opt(rename, |rename| vis.visit_ident(rename)), UseTreeKind::Nested(items) => { for (tree, id) in items { vis.visit_use_tree(tree); @@ -439,15 +439,15 @@ pub fn noop_visit_constraint<T: MutVisitor>( ) { vis.visit_id(id); vis.visit_ident(ident); - if let Some(ref mut gen_args) = gen_args { + if let Some(gen_args) = gen_args { vis.visit_generic_args(gen_args); } match kind { - AssocConstraintKind::Equality { ref mut term } => match term { + AssocConstraintKind::Equality { term } => match term { Term::Ty(ty) => vis.visit_ty(ty), Term::Const(c) => vis.visit_anon_const(c), }, - AssocConstraintKind::Bound { ref mut bounds } => visit_bounds(bounds, vis), + AssocConstraintKind::Bound { bounds } => visit_bounds(bounds, vis), } vis.visit_span(span); } @@ -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); }) @@ -600,7 +601,7 @@ pub fn noop_visit_attribute<T: MutVisitor>(attr: &mut Attribute, vis: &mut T) { let NormalAttr { item: AttrItem { path, args, tokens }, tokens: attr_tokens } = &mut **normal; vis.visit_path(path); - visit_mac_args(args, vis); + visit_attr_args(args, vis); visit_lazy_tts(tokens, vis); visit_lazy_tts(attr_tokens, vis); } @@ -612,18 +613,18 @@ pub fn noop_visit_attribute<T: MutVisitor>(attr: &mut Attribute, vis: &mut T) { pub fn noop_visit_mac<T: MutVisitor>(mac: &mut MacCall, vis: &mut T) { let MacCall { path, args, prior_type_ascription: _ } = mac; vis.visit_path(path); - visit_mac_args(args, vis); + visit_delim_args(args, vis); } pub fn noop_visit_macro_def<T: MutVisitor>(macro_def: &mut MacroDef, vis: &mut T) { let MacroDef { body, macro_rules: _ } = macro_def; - visit_mac_args(body, vis); + visit_delim_args(body, vis); } pub fn noop_visit_meta_list_item<T: MutVisitor>(li: &mut NestedMetaItem, vis: &mut T) { match li { NestedMetaItem::MetaItem(mi) => vis.visit_meta_item(mi), - NestedMetaItem::Literal(_lit) => {} + NestedMetaItem::Lit(_lit) => {} } } @@ -720,10 +721,10 @@ pub fn visit_lazy_tts<T: MutVisitor>(lazy_tts: &mut Option<LazyAttrTokenStream>, visit_lazy_tts_opt_mut(lazy_tts.as_mut(), vis); } +/// Applies ident visitor if it's an ident; applies other visits to interpolated nodes. +/// In practice the ident part is not actually used by specific visitors right now, +/// but there's a test below checking that it works. // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. -// Applies ident visitor if it's an ident; applies other visits to interpolated nodes. -// In practice the ident part is not actually used by specific visitors right now, -// but there's a test below checking that it works. pub fn visit_token<T: MutVisitor>(t: &mut Token, vis: &mut T) { let Token { kind, span } = t; match kind { @@ -735,8 +736,7 @@ pub fn visit_token<T: MutVisitor>(t: &mut Token, vis: &mut T) { return; // Avoid visiting the span for the second time. } token::Interpolated(nt) => { - let mut nt = Lrc::make_mut(nt); - visit_nonterminal(&mut nt, vis); + visit_nonterminal(Lrc::make_mut(nt), vis); } _ => {} } @@ -791,7 +791,7 @@ pub fn visit_nonterminal<T: MutVisitor>(nt: &mut token::Nonterminal, vis: &mut T token::NtMeta(item) => { let AttrItem { path, args, tokens } = item.deref_mut(); vis.visit_path(path); - visit_mac_args(args, vis); + visit_attr_args(args, vis); visit_lazy_tts(tokens, vis); } token::NtPath(path) => vis.visit_path(path), @@ -879,7 +879,7 @@ pub fn noop_flat_map_generic_param<T: MutVisitor>( let GenericParam { id, ident, attrs, bounds, kind, colon_span, is_placeholder: _ } = &mut param; vis.visit_id(id); vis.visit_ident(ident); - if let Some(ref mut colon_span) = colon_span { + if let Some(colon_span) = colon_span { vis.visit_span(colon_span); } visit_attrs(attrs, vis); @@ -1303,12 +1303,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) => { @@ -1345,20 +1350,30 @@ pub fn noop_visit_expr<T: MutVisitor>( vis.visit_block(body); visit_opt(label, |label| vis.visit_label(label)); } - ExprKind::Loop(body, label) => { + ExprKind::Loop(body, label, span) => { vis.visit_block(body); visit_opt(label, |label| vis.visit_label(label)); + vis.visit_span(span); } ExprKind::Match(expr, arms) => { 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, + fn_arg_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); @@ -1428,7 +1443,7 @@ pub fn noop_visit_expr<T: MutVisitor>( } ExprKind::Try(expr) => vis.visit_expr(expr), ExprKind::TryBlock(body) => vis.visit_block(body), - ExprKind::Lit(_) | ExprKind::Err => {} + ExprKind::Lit(_) | ExprKind::IncludedBytes(..) | ExprKind::Err => {} } vis.visit_id(id); vis.visit_span(span); diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index 83b10d906..c0cc4e79a 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -5,6 +5,7 @@ pub use TokenKind::*; use crate::ast; use crate::ptr::P; +use crate::util::case::Case; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::Lrc; @@ -58,13 +59,17 @@ pub enum Delimiter { Invisible, } +// Note that the suffix is *not* considered when deciding the `LitKind` in this +// type. This means that float literals like `1f32` are classified by this type +// as `Int`. Only upon conversion to `ast::LitKind` will such a literal be +// given the `Float` kind. #[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)] pub enum LitKind { Bool, // AST only, must never appear in a `Token` Byte, Char, - Integer, - Float, + Integer, // e.g. `1`, `1u8`, `1f32` + Float, // e.g. `1.`, `1.0`, `1e3f32` Str, StrRaw(u8), // raw string delimited by `n` hash symbols ByteStr, @@ -80,6 +85,42 @@ pub struct Lit { pub suffix: Option<Symbol>, } +impl Lit { + pub fn new(kind: LitKind, symbol: Symbol, suffix: Option<Symbol>) -> Lit { + Lit { kind, symbol, suffix } + } + + /// Returns `true` if this is semantically a float literal. This includes + /// ones like `1f32` that have an `Integer` kind but a float suffix. + pub fn is_semantic_float(&self) -> bool { + match self.kind { + LitKind::Float => true, + LitKind::Integer => match self.suffix { + Some(sym) => sym == sym::f32 || sym == sym::f64, + None => false, + }, + _ => false, + } + } + + /// Keep this in sync with `Token::can_begin_literal_or_bool` excluding unary negation. + pub fn from_token(token: &Token) -> Option<Lit> { + match token.uninterpolate().kind { + Ident(name, false) if name.is_bool_lit() => { + Some(Lit::new(Bool, name, None)) + } + Literal(token_lit) => Some(token_lit), + Interpolated(ref nt) + if let NtExpr(expr) | NtLiteral(expr) = &**nt + && let ast::ExprKind::Lit(token_lit) = expr.kind => + { + Some(token_lit.clone()) + } + _ => None, + } + } +} + impl fmt::Display for Lit { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let Lit { kind, symbol, suffix } = *self; @@ -138,12 +179,6 @@ impl LitKind { } } -impl Lit { - pub fn new(kind: LitKind, symbol: Symbol, suffix: Option<Symbol>) -> Lit { - Lit { kind, symbol, suffix } - } -} - pub fn ident_can_begin_expr(name: Symbol, span: Span, is_raw: bool) -> bool { let ident_token = Token::new(Ident(name, is_raw), span); @@ -267,9 +302,9 @@ impl TokenKind { Literal(Lit::new(kind, symbol, suffix)) } - // An approximation to proc-macro-style single-character operators used by rustc parser. - // If the operator token can be broken into two tokens, the first of which is single-character, - // then this function performs that operation, otherwise it returns `None`. + /// An approximation to proc-macro-style single-character operators used by rustc parser. + /// If the operator token can be broken into two tokens, the first of which is single-character, + /// then this function performs that operation, otherwise it returns `None`. pub fn break_two_token_op(&self) -> Option<(TokenKind, TokenKind)> { Some(match *self { Le => (Lt, Eq), @@ -503,10 +538,10 @@ impl Token { } } - // A convenience function for matching on identifiers during parsing. - // Turns interpolated identifier (`$i: ident`) or lifetime (`$l: lifetime`) token - // into the regular identifier or lifetime token it refers to, - // otherwise returns the original token. + /// A convenience function for matching on identifiers during parsing. + /// Turns interpolated identifier (`$i: ident`) or lifetime (`$l: lifetime`) token + /// into the regular identifier or lifetime token it refers to, + /// otherwise returns the original token. pub fn uninterpolate(&self) -> Cow<'_, Token> { match &self.kind { Interpolated(nt) => match **nt { @@ -566,9 +601,10 @@ impl Token { /// Returns `true` if the token is an interpolated path. fn is_path(&self) -> bool { - if let Interpolated(ref nt) = self.kind && let NtPath(..) = **nt { + if let Interpolated(nt) = &self.kind && let NtPath(..) = **nt { return true; } + false } @@ -576,7 +612,7 @@ impl Token { /// That is, is this a pre-parsed expression dropped into the token stream /// (which happens while parsing the result of macro expansion)? pub fn is_whole_expr(&self) -> bool { - if let Interpolated(ref nt) = self.kind + if let Interpolated(nt) = &self.kind && let NtExpr(_) | NtLiteral(_) | NtPath(_) | NtBlock(_) = **nt { return true; @@ -585,11 +621,12 @@ impl Token { false } - // Is the token an interpolated block (`$b:block`)? + /// Is the token an interpolated block (`$b:block`)? pub fn is_whole_block(&self) -> bool { - if let Interpolated(ref nt) = self.kind && let NtBlock(..) = **nt { + if let Interpolated(nt) = &self.kind && let NtBlock(..) = **nt { return true; } + false } @@ -615,12 +652,21 @@ impl Token { self.is_non_raw_ident_where(|id| id.name == kw) } + /// Returns `true` if the token is a given keyword, `kw` or if `case` is `Insensitive` and this token is an identifier equal to `kw` ignoring the case. + pub fn is_keyword_case(&self, kw: Symbol, case: Case) -> bool { + self.is_keyword(kw) + || (case == Case::Insensitive + && self.is_non_raw_ident_where(|id| { + id.name.as_str().to_lowercase() == kw.as_str().to_lowercase() + })) + } + pub fn is_path_segment_keyword(&self) -> bool { self.is_non_raw_ident_where(Ident::is_path_segment_keyword) } - // Returns true for reserved identifiers used internally for elided lifetimes, - // unnamed method parameters, crate root module, error recovery etc. + /// Returns true for reserved identifiers used internally for elided lifetimes, + /// unnamed method parameters, crate root module, error recovery etc. pub fn is_special_ident(&self) -> bool { self.is_non_raw_ident_where(Ident::is_special) } diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index 015f5c1ee..482c30295 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs @@ -64,7 +64,7 @@ impl TokenTree { match (self, other) { (TokenTree::Token(token, _), TokenTree::Token(token2, _)) => token.kind == token2.kind, (TokenTree::Delimited(_, delim, tts), TokenTree::Delimited(_, delim2, tts2)) => { - delim == delim2 && tts.eq_unspanned(&tts2) + delim == delim2 && tts.eq_unspanned(tts2) } _ => false, } @@ -86,12 +86,12 @@ impl TokenTree { } } - // Create a `TokenTree::Token` with alone spacing. + /// Create a `TokenTree::Token` with alone spacing. pub fn token_alone(kind: TokenKind, span: Span) -> TokenTree { TokenTree::Token(Token::new(kind, span), Spacing::Alone) } - // Create a `TokenTree::Token` with joint spacing. + /// Create a `TokenTree::Token` with joint spacing. pub fn token_joint(kind: TokenKind, span: Span) -> TokenTree { TokenTree::Token(Token::new(kind, span), Spacing::Joint) } @@ -402,7 +402,7 @@ impl TokenStream { let mut t1 = self.trees(); let mut t2 = other.trees(); for (t1, t2) in iter::zip(&mut t1, &mut t2) { - if !t1.eq_unspanned(&t2) { + if !t1.eq_unspanned(t2) { return false; } } @@ -413,17 +413,17 @@ impl TokenStream { TokenStream(Lrc::new(self.0.iter().enumerate().map(|(i, tree)| f(i, tree)).collect())) } - // Create a token stream containing a single token with alone spacing. + /// Create a token stream containing a single token with alone spacing. pub fn token_alone(kind: TokenKind, span: Span) -> TokenStream { TokenStream::new(vec![TokenTree::token_alone(kind, span)]) } - // Create a token stream containing a single token with joint spacing. + /// Create a token stream containing a single token with joint spacing. pub fn token_joint(kind: TokenKind, span: Span) -> TokenStream { TokenStream::new(vec![TokenTree::token_joint(kind, span)]) } - // Create a token stream containing a single `Delimited`. + /// Create a token stream containing a single `Delimited`. pub fn delimited(span: DelimSpan, delim: Delimiter, tts: TokenStream) -> TokenStream { TokenStream::new(vec![TokenTree::Delimited(span, delim, tts)]) } @@ -475,7 +475,7 @@ impl TokenStream { token::Interpolated(nt) => TokenTree::Delimited( DelimSpan::from_single(token.span), Delimiter::Invisible, - TokenStream::from_nonterminal_ast(&nt).flattened(), + TokenStream::from_nonterminal_ast(nt).flattened(), ), _ => TokenTree::Token(token.clone(), spacing), } @@ -511,7 +511,7 @@ impl TokenStream { fn try_glue_to_last(vec: &mut Vec<TokenTree>, tt: &TokenTree) -> bool { if let Some(TokenTree::Token(last_tok, Spacing::Joint)) = vec.last() && let TokenTree::Token(tok, spacing) = tt - && let Some(glued_tok) = last_tok.glue(&tok) + && let Some(glued_tok) = last_tok.glue(tok) { // ...then overwrite the last token tree in `vec` with the // glued token, and skip the first token tree from `stream`. @@ -522,8 +522,8 @@ impl TokenStream { } } - // Push `tt` onto the end of the stream, possibly gluing it to the last - // token. Uses `make_mut` to maximize efficiency. + /// Push `tt` onto the end of the stream, possibly gluing it to the last + /// token. Uses `make_mut` to maximize efficiency. pub fn push_tree(&mut self, tt: TokenTree) { let vec_mut = Lrc::make_mut(&mut self.0); @@ -534,9 +534,9 @@ impl TokenStream { } } - // Push `stream` onto the end of the stream, possibly gluing the first - // token tree to the last token. (No other token trees will be glued.) - // Uses `make_mut` to maximize efficiency. + /// Push `stream` onto the end of the stream, possibly gluing the first + /// token tree to the last token. (No other token trees will be glued.) + /// Uses `make_mut` to maximize efficiency. pub fn push_stream(&mut self, stream: TokenStream) { let vec_mut = Lrc::make_mut(&mut self.0); diff --git a/compiler/rustc_ast/src/util/case.rs b/compiler/rustc_ast/src/util/case.rs new file mode 100644 index 000000000..1afd7dea7 --- /dev/null +++ b/compiler/rustc_ast/src/util/case.rs @@ -0,0 +1,6 @@ +/// Whatever to ignore case (`fn` vs `Fn` vs `FN`) or not. Used for recovering. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub enum Case { + Sensitive, + Insensitive, +} diff --git a/compiler/rustc_ast/src/util/classify.rs b/compiler/rustc_ast/src/util/classify.rs index 6ea3db6d3..cdc244c12 100644 --- a/compiler/rustc_ast/src/util/classify.rs +++ b/compiler/rustc_ast/src/util/classify.rs @@ -21,6 +21,7 @@ pub fn expr_requires_semi_to_be_stmt(e: &ast::Expr) -> bool { | ast::ExprKind::Loop(..) | ast::ExprKind::ForLoop(..) | ast::ExprKind::TryBlock(..) + | ast::ExprKind::ConstBlock(..) ) } @@ -36,7 +37,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 +44,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, diff --git a/compiler/rustc_ast/src/util/comments.rs b/compiler/rustc_ast/src/util/comments.rs index c96474ccb..35454c3a6 100644 --- a/compiler/rustc_ast/src/util/comments.rs +++ b/compiler/rustc_ast/src/util/comments.rs @@ -110,7 +110,7 @@ pub fn beautify_doc_string(data: Symbol, kind: CommentKind) -> Symbol { } else { &mut lines }; - if let Some(horizontal) = get_horizontal_trim(&lines, kind) { + if let Some(horizontal) = get_horizontal_trim(lines, kind) { changes = true; // remove a "[ \t]*\*" block from each line, if possible for line in lines.iter_mut() { @@ -147,7 +147,7 @@ fn all_whitespace(s: &str, col: CharPos) -> Option<usize> { fn trim_whitespace_prefix(s: &str, col: CharPos) -> &str { let len = s.len(); - match all_whitespace(&s, col) { + match all_whitespace(s, col) { Some(col) => { if col < len { &s[col..] diff --git a/compiler/rustc_ast/src/util/literal.rs b/compiler/rustc_ast/src/util/literal.rs index 536b38560..f6f186b51 100644 --- a/compiler/rustc_ast/src/util/literal.rs +++ b/compiler/rustc_ast/src/util/literal.rs @@ -1,17 +1,14 @@ //! Code related to parsing literals. -use crate::ast::{self, Lit, LitKind}; +use crate::ast::{self, LitKind, MetaItemLit}; use crate::token::{self, Token}; - -use rustc_lexer::unescape::{unescape_byte, unescape_char}; -use rustc_lexer::unescape::{unescape_byte_literal, unescape_literal, Mode}; +use rustc_lexer::unescape::{byte_from_char, unescape_byte, unescape_char, unescape_literal, Mode}; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::Span; - use std::ascii; +#[derive(Debug)] pub enum LitError { - NotLiteral, LexerError, InvalidSuffix, InvalidIntSuffix, @@ -55,14 +52,14 @@ impl LitKind { // new symbol because the string in the LitKind is different to the // string in the token. let s = symbol.as_str(); - let symbol = if s.contains(&['\\', '\r']) { + let symbol = if s.contains(['\\', '\r']) { let mut buf = String::with_capacity(s.len()); let mut error = Ok(()); // Force-inlining here is aggressive but the closure is // called on every char in the string, so it can be // hot in programs with many long strings. unescape_literal( - &s, + s, Mode::Str, &mut #[inline(always)] |_, unescaped_char| match unescaped_char { @@ -88,7 +85,7 @@ impl LitKind { if s.contains('\r') { let mut buf = String::with_capacity(s.len()); let mut error = Ok(()); - unescape_literal(&s, Mode::RawStr, &mut |_, unescaped_char| { + unescape_literal(s, Mode::RawStr, &mut |_, unescaped_char| { match unescaped_char { Ok(c) => buf.push(c), Err(err) => { @@ -109,13 +106,11 @@ impl LitKind { let s = symbol.as_str(); let mut buf = Vec::with_capacity(s.len()); let mut error = Ok(()); - unescape_byte_literal(&s, Mode::ByteStr, &mut |_, unescaped_byte| { - match unescaped_byte { - Ok(c) => buf.push(c), - Err(err) => { - if err.is_fatal() { - error = Err(LitError::LexerError); - } + unescape_literal(s, Mode::ByteStr, &mut |_, c| match c { + Ok(c) => buf.push(byte_from_char(c)), + Err(err) => { + if err.is_fatal() { + error = Err(LitError::LexerError); } } }); @@ -127,13 +122,11 @@ impl LitKind { let bytes = if s.contains('\r') { let mut buf = Vec::with_capacity(s.len()); let mut error = Ok(()); - unescape_byte_literal(&s, Mode::RawByteStr, &mut |_, unescaped_byte| { - match unescaped_byte { - Ok(c) => buf.push(c), - Err(err) => { - if err.is_fatal() { - error = Err(LitError::LexerError); - } + unescape_literal(s, Mode::RawByteStr, &mut |_, c| match c { + Ok(c) => buf.push(byte_from_char(c)), + Err(err) => { + if err.is_fatal() { + error = Err(LitError::LexerError); } } }); @@ -202,49 +195,16 @@ impl LitKind { } } -impl Lit { - /// Converts literal token into an AST literal. - pub fn from_token_lit(token_lit: token::Lit, span: Span) -> Result<Lit, LitError> { - Ok(Lit { token_lit, kind: LitKind::from_token_lit(token_lit)?, span }) - } - - /// Converts arbitrary token into an AST literal. - /// - /// Keep this in sync with `Token::can_begin_literal_or_bool` excluding unary negation. - pub fn from_token(token: &Token) -> Result<Lit, LitError> { - let lit = match token.uninterpolate().kind { - token::Ident(name, false) if name.is_bool_lit() => { - token::Lit::new(token::Bool, name, None) - } - token::Literal(lit) => lit, - token::Interpolated(ref nt) => { - if let token::NtExpr(expr) | token::NtLiteral(expr) = &**nt - && let ast::ExprKind::Lit(lit) = &expr.kind - { - return Ok(lit.clone()); - } - return Err(LitError::NotLiteral); - } - _ => return Err(LitError::NotLiteral), - }; - - Lit::from_token_lit(lit, token.span) - } - - /// Attempts to recover an AST literal from semantic literal. - /// This function is used when the original token doesn't exist (e.g. the literal is created - /// by an AST-based macro) or unavailable (e.g. from HIR pretty-printing). - pub fn from_lit_kind(kind: LitKind, span: Span) -> Lit { - Lit { token_lit: kind.to_token_lit(), kind, span } +impl MetaItemLit { + /// Converts token literal into a meta item literal. + pub fn from_token_lit(token_lit: token::Lit, span: Span) -> Result<MetaItemLit, LitError> { + Ok(MetaItemLit { token_lit, kind: LitKind::from_token_lit(token_lit)?, span }) } - /// Losslessly convert an AST literal into a token. - pub fn to_token(&self) -> Token { - let kind = match self.token_lit.kind { - token::Bool => token::Ident(self.token_lit.symbol, false), - _ => token::Literal(self.token_lit), - }; - Token::new(kind, self.span) + /// Converts an arbitrary token into meta item literal. + pub fn from_token(token: &Token) -> Option<MetaItemLit> { + token::Lit::from_token(token) + .and_then(|token_lit| MetaItemLit::from_token_lit(token_lit, token.span).ok()) } } diff --git a/compiler/rustc_ast/src/util/parser.rs b/compiler/rustc_ast/src/util/parser.rs index b40ad6f70..819f1884a 100644 --- a/compiler/rustc_ast/src/util/parser.rs +++ b/compiler/rustc_ast/src/util/parser.rs @@ -377,28 +377,28 @@ pub fn needs_par_as_let_scrutinee(order: i8) -> bool { /// parens or other delimiters, e.g., `X { y: 1 }`, `X { y: 1 }.method()`, `foo == X { y: 1 }` and /// `X { y: 1 } == foo` all do, but `(X { y: 1 }) == foo` does not. pub fn contains_exterior_struct_lit(value: &ast::Expr) -> bool { - match value.kind { + match &value.kind { ast::ExprKind::Struct(..) => true, - ast::ExprKind::Assign(ref lhs, ref rhs, _) - | ast::ExprKind::AssignOp(_, ref lhs, ref rhs) - | ast::ExprKind::Binary(_, ref lhs, ref rhs) => { + ast::ExprKind::Assign(lhs, rhs, _) + | ast::ExprKind::AssignOp(_, lhs, rhs) + | ast::ExprKind::Binary(_, lhs, rhs) => { // X { y: 1 } + X { y: 2 } - contains_exterior_struct_lit(&lhs) || contains_exterior_struct_lit(&rhs) + contains_exterior_struct_lit(lhs) || contains_exterior_struct_lit(rhs) } - ast::ExprKind::Await(ref x) - | ast::ExprKind::Unary(_, ref x) - | ast::ExprKind::Cast(ref x, _) - | ast::ExprKind::Type(ref x, _) - | ast::ExprKind::Field(ref x, _) - | ast::ExprKind::Index(ref x, _) => { + ast::ExprKind::Await(x) + | ast::ExprKind::Unary(_, x) + | ast::ExprKind::Cast(x, _) + | ast::ExprKind::Type(x, _) + | ast::ExprKind::Field(x, _) + | ast::ExprKind::Index(x, _) => { // &X { y: 1 }, X { y: 1 }.y - contains_exterior_struct_lit(&x) + contains_exterior_struct_lit(x) } - ast::ExprKind::MethodCall(_, ref receiver, _, _) => { + ast::ExprKind::MethodCall(box ast::MethodCall { receiver, .. }) => { // X { y: 1 }.bar(...) - contains_exterior_struct_lit(&receiver) + contains_exterior_struct_lit(receiver) } _ => false, diff --git a/compiler/rustc_ast/src/util/unicode.rs b/compiler/rustc_ast/src/util/unicode.rs index f009f7b30..0eae791b2 100644 --- a/compiler/rustc_ast/src/util/unicode.rs +++ b/compiler/rustc_ast/src/util/unicode.rs @@ -17,7 +17,7 @@ pub fn contains_text_flow_control_chars(s: &str) -> bool { // U+2069 - E2 81 A9 let mut bytes = s.as_bytes(); loop { - match core::slice::memchr::memchr(0xE2, &bytes) { + match core::slice::memchr::memchr(0xE2, bytes) { Some(idx) => { // bytes are valid UTF-8 -> E2 must be followed by two bytes let ch = &bytes[idx..idx + 3]; diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 6f56c1ef0..991eb489f 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -251,7 +251,7 @@ pub trait Visitor<'ast>: Sized { macro_rules! walk_list { ($visitor: expr, $method: ident, $list: expr $(, $($extra_args: expr),* )?) => { { - #[cfg_attr(not(bootstrap), allow(for_loops_over_fallibles))] + #[allow(for_loops_over_fallibles)] for elem in $list { $visitor.$method(elem $(, $($extra_args,)* )?) } @@ -299,74 +299,68 @@ pub fn walk_trait_ref<'a, V: Visitor<'a>>(visitor: &mut V, trait_ref: &'a TraitR pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) { visitor.visit_vis(&item.vis); visitor.visit_ident(item.ident); - match item.kind { + match &item.kind { ItemKind::ExternCrate(_) => {} - ItemKind::Use(ref use_tree) => visitor.visit_use_tree(use_tree, item.id, false), - ItemKind::Static(ref typ, _, ref expr) | ItemKind::Const(_, ref typ, ref expr) => { + ItemKind::Use(use_tree) => visitor.visit_use_tree(use_tree, item.id, false), + ItemKind::Static(typ, _, expr) | ItemKind::Const(_, typ, expr) => { visitor.visit_ty(typ); walk_list!(visitor, visit_expr, expr); } - ItemKind::Fn(box Fn { defaultness: _, ref generics, ref sig, ref body }) => { + ItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => { let kind = FnKind::Fn(FnCtxt::Free, item.ident, sig, &item.vis, generics, body.as_deref()); visitor.visit_fn(kind, item.span, item.id) } - ItemKind::Mod(_unsafety, ref mod_kind) => match mod_kind { + ItemKind::Mod(_unsafety, mod_kind) => match mod_kind { ModKind::Loaded(items, _inline, _inner_span) => { walk_list!(visitor, visit_item, items) } ModKind::Unloaded => {} }, - ItemKind::ForeignMod(ref foreign_module) => { + ItemKind::ForeignMod(foreign_module) => { walk_list!(visitor, visit_foreign_item, &foreign_module.items); } - ItemKind::GlobalAsm(ref asm) => visitor.visit_inline_asm(asm), - ItemKind::TyAlias(box TyAlias { ref generics, ref bounds, ref ty, .. }) => { + ItemKind::GlobalAsm(asm) => visitor.visit_inline_asm(asm), + ItemKind::TyAlias(box TyAlias { generics, bounds, ty, .. }) => { visitor.visit_generics(generics); walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); walk_list!(visitor, visit_ty, ty); } - ItemKind::Enum(ref enum_definition, ref generics) => { + ItemKind::Enum(enum_definition, generics) => { visitor.visit_generics(generics); visitor.visit_enum_def(enum_definition) } ItemKind::Impl(box Impl { defaultness: _, unsafety: _, - ref generics, + generics, constness: _, polarity: _, - ref of_trait, - ref self_ty, - ref items, + of_trait, + self_ty, + items, }) => { visitor.visit_generics(generics); walk_list!(visitor, visit_trait_ref, of_trait); visitor.visit_ty(self_ty); walk_list!(visitor, visit_assoc_item, items, AssocCtxt::Impl); } - ItemKind::Struct(ref struct_definition, ref generics) - | ItemKind::Union(ref struct_definition, ref generics) => { + ItemKind::Struct(struct_definition, generics) + | ItemKind::Union(struct_definition, generics) => { visitor.visit_generics(generics); visitor.visit_variant_data(struct_definition); } - ItemKind::Trait(box Trait { - unsafety: _, - is_auto: _, - ref generics, - ref bounds, - ref items, - }) => { + ItemKind::Trait(box Trait { unsafety: _, is_auto: _, generics, bounds, items }) => { visitor.visit_generics(generics); walk_list!(visitor, visit_param_bound, bounds, BoundKind::SuperTraits); walk_list!(visitor, visit_assoc_item, items, AssocCtxt::Trait); } - ItemKind::TraitAlias(ref generics, ref bounds) => { + ItemKind::TraitAlias(generics, bounds) => { visitor.visit_generics(generics); walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); } - ItemKind::MacCall(ref mac) => visitor.visit_mac_call(mac), - ItemKind::MacroDef(ref ts) => visitor.visit_mac_def(ts, item.id), + ItemKind::MacCall(mac) => visitor.visit_mac_call(mac), + ItemKind::MacroDef(ts) => visitor.visit_mac_def(ts, item.id), } walk_list!(visitor, visit_attribute, &item.attrs); } @@ -399,39 +393,39 @@ pub fn walk_pat_field<'a, V: Visitor<'a>>(visitor: &mut V, fp: &'a PatField) { } pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) { - match typ.kind { - TyKind::Slice(ref ty) | TyKind::Paren(ref ty) => visitor.visit_ty(ty), - TyKind::Ptr(ref mutable_type) => visitor.visit_ty(&mutable_type.ty), - TyKind::Rptr(ref opt_lifetime, ref mutable_type) => { + match &typ.kind { + TyKind::Slice(ty) | TyKind::Paren(ty) => visitor.visit_ty(ty), + TyKind::Ptr(mutable_type) => visitor.visit_ty(&mutable_type.ty), + TyKind::Rptr(opt_lifetime, mutable_type) => { walk_list!(visitor, visit_lifetime, opt_lifetime, LifetimeCtxt::Rptr); visitor.visit_ty(&mutable_type.ty) } - TyKind::Tup(ref tuple_element_types) => { + TyKind::Tup(tuple_element_types) => { walk_list!(visitor, visit_ty, tuple_element_types); } - TyKind::BareFn(ref function_declaration) => { + TyKind::BareFn(function_declaration) => { walk_list!(visitor, visit_generic_param, &function_declaration.generic_params); walk_fn_decl(visitor, &function_declaration.decl); } - TyKind::Path(ref maybe_qself, ref path) => { - if let Some(ref qself) = *maybe_qself { + TyKind::Path(maybe_qself, path) => { + if let Some(qself) = maybe_qself { visitor.visit_ty(&qself.ty); } visitor.visit_path(path, typ.id); } - TyKind::Array(ref ty, ref length) => { + TyKind::Array(ty, length) => { visitor.visit_ty(ty); visitor.visit_anon_const(length) } - TyKind::TraitObject(ref bounds, ..) => { + TyKind::TraitObject(bounds, ..) => { walk_list!(visitor, visit_param_bound, bounds, BoundKind::TraitObject); } - TyKind::ImplTrait(_, ref bounds) => { + TyKind::ImplTrait(_, bounds) => { walk_list!(visitor, visit_param_bound, bounds, BoundKind::Impl); } - TyKind::Typeof(ref expression) => visitor.visit_anon_const(expression), + TyKind::Typeof(expression) => visitor.visit_anon_const(expression), TyKind::Infer | TyKind::ImplicitSelf | TyKind::Err => {} - TyKind::MacCall(ref mac) => visitor.visit_mac_call(mac), + TyKind::MacCall(mac) => visitor.visit_mac_call(mac), TyKind::Never | TyKind::CVarArgs => {} } } @@ -444,15 +438,15 @@ pub fn walk_path<'a, V: Visitor<'a>>(visitor: &mut V, path: &'a Path) { pub fn walk_use_tree<'a, V: Visitor<'a>>(visitor: &mut V, use_tree: &'a UseTree, id: NodeId) { visitor.visit_path(&use_tree.prefix, id); - match use_tree.kind { - UseTreeKind::Simple(rename, ..) => { + match &use_tree.kind { + UseTreeKind::Simple(rename) => { // The extra IDs are handled during HIR lowering. - if let Some(rename) = rename { + if let &Some(rename) = rename { visitor.visit_ident(rename); } } UseTreeKind::Glob => {} - UseTreeKind::Nested(ref use_trees) => { + UseTreeKind::Nested(use_trees) => { for &(ref nested_tree, nested_id) in use_trees { visitor.visit_use_tree(nested_tree, nested_id, true); } @@ -462,7 +456,7 @@ pub fn walk_use_tree<'a, V: Visitor<'a>>(visitor: &mut V, use_tree: &'a UseTree, pub fn walk_path_segment<'a, V: Visitor<'a>>(visitor: &mut V, segment: &'a PathSegment) { visitor.visit_ident(segment.ident); - if let Some(ref args) = segment.args { + if let Some(args) = &segment.args { visitor.visit_generic_args(args); } } @@ -471,8 +465,8 @@ pub fn walk_generic_args<'a, V>(visitor: &mut V, generic_args: &'a GenericArgs) where V: Visitor<'a>, { - match *generic_args { - GenericArgs::AngleBracketed(ref data) => { + match generic_args { + GenericArgs::AngleBracketed(data) => { for arg in &data.args { match arg { AngleBracketedArg::Arg(a) => visitor.visit_generic_arg(a), @@ -480,7 +474,7 @@ where } } } - GenericArgs::Parenthesized(ref data) => { + GenericArgs::Parenthesized(data) => { walk_list!(visitor, visit_ty, &data.inputs); walk_fn_ret_ty(visitor, &data.output); } @@ -500,64 +494,64 @@ where pub fn walk_assoc_constraint<'a, V: Visitor<'a>>(visitor: &mut V, constraint: &'a AssocConstraint) { visitor.visit_ident(constraint.ident); - if let Some(ref gen_args) = constraint.gen_args { + if let Some(gen_args) = &constraint.gen_args { visitor.visit_generic_args(gen_args); } - match constraint.kind { - AssocConstraintKind::Equality { ref term } => match term { + match &constraint.kind { + AssocConstraintKind::Equality { term } => match term { Term::Ty(ty) => visitor.visit_ty(ty), Term::Const(c) => visitor.visit_anon_const(c), }, - AssocConstraintKind::Bound { ref bounds } => { + AssocConstraintKind::Bound { bounds } => { walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); } } } pub fn walk_pat<'a, V: Visitor<'a>>(visitor: &mut V, pattern: &'a Pat) { - match pattern.kind { - PatKind::TupleStruct(ref opt_qself, ref path, ref elems) => { - if let Some(ref qself) = *opt_qself { + match &pattern.kind { + PatKind::TupleStruct(opt_qself, path, elems) => { + if let Some(qself) = opt_qself { visitor.visit_ty(&qself.ty); } visitor.visit_path(path, pattern.id); walk_list!(visitor, visit_pat, elems); } - PatKind::Path(ref opt_qself, ref path) => { - if let Some(ref qself) = *opt_qself { + PatKind::Path(opt_qself, path) => { + if let Some(qself) = opt_qself { visitor.visit_ty(&qself.ty); } visitor.visit_path(path, pattern.id) } - PatKind::Struct(ref opt_qself, ref path, ref fields, _) => { - if let Some(ref qself) = *opt_qself { + PatKind::Struct(opt_qself, path, fields, _) => { + if let Some(qself) = opt_qself { visitor.visit_ty(&qself.ty); } visitor.visit_path(path, pattern.id); walk_list!(visitor, visit_pat_field, fields); } - PatKind::Box(ref subpattern) - | PatKind::Ref(ref subpattern, _) - | PatKind::Paren(ref subpattern) => visitor.visit_pat(subpattern), - PatKind::Ident(_, ident, ref optional_subpattern) => { - visitor.visit_ident(ident); + PatKind::Box(subpattern) | PatKind::Ref(subpattern, _) | PatKind::Paren(subpattern) => { + visitor.visit_pat(subpattern) + } + PatKind::Ident(_, ident, optional_subpattern) => { + visitor.visit_ident(*ident); walk_list!(visitor, visit_pat, optional_subpattern); } - PatKind::Lit(ref expression) => visitor.visit_expr(expression), - PatKind::Range(ref lower_bound, ref upper_bound, _) => { + PatKind::Lit(expression) => visitor.visit_expr(expression), + PatKind::Range(lower_bound, upper_bound, _) => { walk_list!(visitor, visit_expr, lower_bound); walk_list!(visitor, visit_expr, upper_bound); } PatKind::Wild | PatKind::Rest => {} - PatKind::Tuple(ref elems) | PatKind::Slice(ref elems) | PatKind::Or(ref elems) => { + PatKind::Tuple(elems) | PatKind::Slice(elems) | PatKind::Or(elems) => { walk_list!(visitor, visit_pat, elems); } - PatKind::MacCall(ref mac) => visitor.visit_mac_call(mac), + PatKind::MacCall(mac) => visitor.visit_mac_call(mac), } } pub fn walk_foreign_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a ForeignItem) { - let Item { id, span, ident, ref vis, ref attrs, ref kind, tokens: _ } = *item; + let &Item { id, span, ident, ref vis, ref attrs, ref kind, tokens: _ } = item; visitor.visit_vis(vis); visitor.visit_ident(ident); walk_list!(visitor, visit_attribute, attrs); @@ -566,7 +560,7 @@ pub fn walk_foreign_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a ForeignI visitor.visit_ty(ty); walk_list!(visitor, visit_expr, expr); } - ForeignItemKind::Fn(box Fn { defaultness: _, ref generics, ref sig, ref body }) => { + ForeignItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => { let kind = FnKind::Fn(FnCtxt::Foreign, ident, sig, vis, generics, body.as_deref()); visitor.visit_fn(kind, span, id); } @@ -582,11 +576,9 @@ pub fn walk_foreign_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a ForeignI } pub fn walk_param_bound<'a, V: Visitor<'a>>(visitor: &mut V, bound: &'a GenericBound) { - match *bound { - GenericBound::Trait(ref typ, ref _modifier) => visitor.visit_poly_trait_ref(typ), - GenericBound::Outlives(ref lifetime) => { - visitor.visit_lifetime(lifetime, LifetimeCtxt::Bound) - } + match bound { + GenericBound::Trait(typ, _modifier) => visitor.visit_poly_trait_ref(typ), + GenericBound::Outlives(lifetime) => visitor.visit_lifetime(lifetime, LifetimeCtxt::Bound), } } @@ -594,10 +586,10 @@ pub fn walk_generic_param<'a, V: Visitor<'a>>(visitor: &mut V, param: &'a Generi visitor.visit_ident(param.ident); walk_list!(visitor, visit_attribute, param.attrs.iter()); walk_list!(visitor, visit_param_bound, ¶m.bounds, BoundKind::Bound); - match param.kind { + match ¶m.kind { GenericParamKind::Lifetime => (), - GenericParamKind::Type { ref default } => walk_list!(visitor, visit_ty, default), - GenericParamKind::Const { ref ty, ref default, .. } => { + GenericParamKind::Type { default } => walk_list!(visitor, visit_ty, default), + GenericParamKind::Const { ty, default, .. } => { visitor.visit_ty(ty); if let Some(default) = default { visitor.visit_anon_const(default); @@ -621,24 +613,22 @@ pub fn walk_closure_binder<'a, V: Visitor<'a>>(visitor: &mut V, binder: &'a Clos } pub fn walk_where_predicate<'a, V: Visitor<'a>>(visitor: &mut V, predicate: &'a WherePredicate) { - match *predicate { + match predicate { WherePredicate::BoundPredicate(WhereBoundPredicate { - ref bounded_ty, - ref bounds, - ref bound_generic_params, + bounded_ty, + bounds, + bound_generic_params, .. }) => { visitor.visit_ty(bounded_ty); walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); walk_list!(visitor, visit_generic_param, bound_generic_params); } - WherePredicate::RegionPredicate(WhereRegionPredicate { - ref lifetime, ref bounds, .. - }) => { + WherePredicate::RegionPredicate(WhereRegionPredicate { lifetime, bounds, .. }) => { visitor.visit_lifetime(lifetime, LifetimeCtxt::Bound); walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); } - WherePredicate::EqPredicate(WhereEqPredicate { ref lhs_ty, ref rhs_ty, .. }) => { + WherePredicate::EqPredicate(WhereEqPredicate { lhs_ty, rhs_ty, .. }) => { visitor.visit_ty(lhs_ty); visitor.visit_ty(rhs_ty); } @@ -646,7 +636,7 @@ pub fn walk_where_predicate<'a, V: Visitor<'a>>(visitor: &mut V, predicate: &'a } pub fn walk_fn_ret_ty<'a, V: Visitor<'a>>(visitor: &mut V, ret_ty: &'a FnRetTy) { - if let FnRetTy::Ty(ref output_ty) = *ret_ty { + if let FnRetTy::Ty(output_ty) = ret_ty { visitor.visit_ty(output_ty) } } @@ -675,7 +665,7 @@ pub fn walk_fn<'a, V: Visitor<'a>>(visitor: &mut V, kind: FnKind<'a>) { } pub fn walk_assoc_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a AssocItem, ctxt: AssocCtxt) { - let Item { id, span, ident, ref vis, ref attrs, ref kind, tokens: _ } = *item; + let &Item { id, span, ident, ref vis, ref attrs, ref kind, tokens: _ } = item; visitor.visit_vis(vis); visitor.visit_ident(ident); walk_list!(visitor, visit_attribute, attrs); @@ -684,7 +674,7 @@ pub fn walk_assoc_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a AssocItem, visitor.visit_ty(ty); walk_list!(visitor, visit_expr, expr); } - AssocItemKind::Fn(box Fn { defaultness: _, ref generics, ref sig, ref body }) => { + AssocItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => { let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), ident, sig, vis, generics, body.as_deref()); visitor.visit_fn(kind, span, id); } @@ -717,13 +707,13 @@ pub fn walk_block<'a, V: Visitor<'a>>(visitor: &mut V, block: &'a Block) { } pub fn walk_stmt<'a, V: Visitor<'a>>(visitor: &mut V, statement: &'a Stmt) { - match statement.kind { - StmtKind::Local(ref local) => visitor.visit_local(local), - StmtKind::Item(ref item) => visitor.visit_item(item), - StmtKind::Expr(ref expr) | StmtKind::Semi(ref expr) => visitor.visit_expr(expr), + match &statement.kind { + StmtKind::Local(local) => visitor.visit_local(local), + StmtKind::Item(item) => visitor.visit_item(item), + StmtKind::Expr(expr) | StmtKind::Semi(expr) => visitor.visit_expr(expr), StmtKind::Empty => {} - StmtKind::MacCall(ref mac) => { - let MacCallStmt { ref mac, style: _, ref attrs, tokens: _ } = **mac; + StmtKind::MacCall(mac) => { + let MacCallStmt { mac, attrs, style: _, tokens: _ } = &**mac; visitor.visit_mac_call(mac); for attr in attrs.iter() { visitor.visit_attribute(attr); @@ -760,7 +750,7 @@ pub fn walk_inline_asm<'a, V: Visitor<'a>>(visitor: &mut V, asm: &'a InlineAsm) } pub fn walk_inline_asm_sym<'a, V: Visitor<'a>>(visitor: &mut V, sym: &'a InlineAsmSym) { - if let Some(ref qself) = sym.qself { + if let Some(qself) = &sym.qself { visitor.visit_ty(&qself.ty); } visitor.visit_path(&sym.path, sym.id); @@ -769,18 +759,18 @@ pub fn walk_inline_asm_sym<'a, V: Visitor<'a>>(visitor: &mut V, sym: &'a InlineA pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) { walk_list!(visitor, visit_attribute, expression.attrs.iter()); - match expression.kind { - ExprKind::Box(ref subexpression) => visitor.visit_expr(subexpression), - ExprKind::Array(ref subexpressions) => { + match &expression.kind { + ExprKind::Box(subexpression) => visitor.visit_expr(subexpression), + ExprKind::Array(subexpressions) => { walk_list!(visitor, visit_expr, subexpressions); } - ExprKind::ConstBlock(ref anon_const) => visitor.visit_anon_const(anon_const), - ExprKind::Repeat(ref element, ref count) => { + ExprKind::ConstBlock(anon_const) => visitor.visit_anon_const(anon_const), + ExprKind::Repeat(element, count) => { visitor.visit_expr(element); visitor.visit_anon_const(count) } - ExprKind::Struct(ref se) => { - if let Some(ref qself) = se.qself { + ExprKind::Struct(se) => { + if let Some(qself) = &se.qself { visitor.visit_ty(&qself.ty); } visitor.visit_path(&se.path, expression.id); @@ -791,117 +781,126 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) { StructRest::None => {} } } - ExprKind::Tup(ref subexpressions) => { + ExprKind::Tup(subexpressions) => { walk_list!(visitor, visit_expr, subexpressions); } - ExprKind::Call(ref callee_expression, ref arguments) => { + ExprKind::Call(callee_expression, arguments) => { 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 { seg, receiver, 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) => { + ExprKind::Binary(_, left_expression, right_expression) => { visitor.visit_expr(left_expression); visitor.visit_expr(right_expression) } - ExprKind::AddrOf(_, _, ref subexpression) | ExprKind::Unary(_, ref subexpression) => { + ExprKind::AddrOf(_, _, subexpression) | ExprKind::Unary(_, subexpression) => { visitor.visit_expr(subexpression) } - ExprKind::Cast(ref subexpression, ref typ) | ExprKind::Type(ref subexpression, ref typ) => { + ExprKind::Cast(subexpression, typ) | ExprKind::Type(subexpression, typ) => { visitor.visit_expr(subexpression); visitor.visit_ty(typ) } - ExprKind::Let(ref pat, ref expr, _) => { + ExprKind::Let(pat, expr, _) => { visitor.visit_pat(pat); visitor.visit_expr(expr); } - ExprKind::If(ref head_expression, ref if_block, ref optional_else) => { + ExprKind::If(head_expression, if_block, optional_else) => { visitor.visit_expr(head_expression); visitor.visit_block(if_block); walk_list!(visitor, visit_expr, optional_else); } - ExprKind::While(ref subexpression, ref block, ref opt_label) => { + ExprKind::While(subexpression, block, opt_label) => { walk_list!(visitor, visit_label, opt_label); visitor.visit_expr(subexpression); visitor.visit_block(block); } - ExprKind::ForLoop(ref pattern, ref subexpression, ref block, ref opt_label) => { + ExprKind::ForLoop(pattern, subexpression, block, opt_label) => { walk_list!(visitor, visit_label, opt_label); visitor.visit_pat(pattern); visitor.visit_expr(subexpression); visitor.visit_block(block); } - ExprKind::Loop(ref block, ref opt_label) => { + ExprKind::Loop(block, opt_label, _) => { walk_list!(visitor, visit_label, opt_label); visitor.visit_block(block); } - ExprKind::Match(ref subexpression, ref arms) => { + ExprKind::Match(subexpression, arms) => { 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 { + binder, + capture_clause: _, + asyncness: _, + movability: _, + fn_decl, + body, + fn_decl_span: _, + fn_arg_span: _, + }) => { + visitor.visit_fn(FnKind::Closure(binder, fn_decl, body), expression.span, expression.id) } - ExprKind::Block(ref block, ref opt_label) => { + ExprKind::Block(block, opt_label) => { walk_list!(visitor, visit_label, opt_label); visitor.visit_block(block); } - ExprKind::Async(_, _, ref body) => { + ExprKind::Async(_, _, body) => { visitor.visit_block(body); } - ExprKind::Await(ref expr) => visitor.visit_expr(expr), - ExprKind::Assign(ref lhs, ref rhs, _) => { + ExprKind::Await(expr) => visitor.visit_expr(expr), + ExprKind::Assign(lhs, rhs, _) => { visitor.visit_expr(lhs); visitor.visit_expr(rhs); } - ExprKind::AssignOp(_, ref left_expression, ref right_expression) => { + ExprKind::AssignOp(_, left_expression, right_expression) => { visitor.visit_expr(left_expression); visitor.visit_expr(right_expression); } - ExprKind::Field(ref subexpression, ident) => { + ExprKind::Field(subexpression, ident) => { visitor.visit_expr(subexpression); - visitor.visit_ident(ident); + visitor.visit_ident(*ident); } - ExprKind::Index(ref main_expression, ref index_expression) => { + ExprKind::Index(main_expression, index_expression) => { visitor.visit_expr(main_expression); visitor.visit_expr(index_expression) } - ExprKind::Range(ref start, ref end, _) => { + ExprKind::Range(start, end, _) => { walk_list!(visitor, visit_expr, start); walk_list!(visitor, visit_expr, end); } ExprKind::Underscore => {} - ExprKind::Path(ref maybe_qself, ref path) => { - if let Some(ref qself) = *maybe_qself { + ExprKind::Path(maybe_qself, path) => { + if let Some(qself) = maybe_qself { visitor.visit_ty(&qself.ty); } visitor.visit_path(path, expression.id) } - ExprKind::Break(ref opt_label, ref opt_expr) => { + ExprKind::Break(opt_label, opt_expr) => { walk_list!(visitor, visit_label, opt_label); walk_list!(visitor, visit_expr, opt_expr); } - ExprKind::Continue(ref opt_label) => { + ExprKind::Continue(opt_label) => { walk_list!(visitor, visit_label, opt_label); } - ExprKind::Ret(ref optional_expression) => { + ExprKind::Ret(optional_expression) => { walk_list!(visitor, visit_expr, optional_expression); } - ExprKind::Yeet(ref optional_expression) => { + ExprKind::Yeet(optional_expression) => { walk_list!(visitor, visit_expr, optional_expression); } - ExprKind::MacCall(ref mac) => visitor.visit_mac_call(mac), - ExprKind::Paren(ref subexpression) => visitor.visit_expr(subexpression), - ExprKind::InlineAsm(ref asm) => visitor.visit_inline_asm(asm), - ExprKind::Yield(ref optional_expression) => { + ExprKind::MacCall(mac) => visitor.visit_mac_call(mac), + ExprKind::Paren(subexpression) => visitor.visit_expr(subexpression), + ExprKind::InlineAsm(asm) => visitor.visit_inline_asm(asm), + ExprKind::Yield(optional_expression) => { walk_list!(visitor, visit_expr, optional_expression); } - ExprKind::Try(ref subexpression) => visitor.visit_expr(subexpression), - ExprKind::TryBlock(ref body) => visitor.visit_block(body), - ExprKind::Lit(_) | ExprKind::Err => {} + ExprKind::Try(subexpression) => visitor.visit_expr(subexpression), + ExprKind::TryBlock(body) => visitor.visit_block(body), + ExprKind::Lit(_) | ExprKind::IncludedBytes(..) | ExprKind::Err => {} } visitor.visit_expr_post(expression) @@ -927,18 +926,18 @@ pub fn walk_vis<'a, V: Visitor<'a>>(visitor: &mut V, vis: &'a Visibility) { } pub fn walk_attribute<'a, V: Visitor<'a>>(visitor: &mut V, attr: &'a Attribute) { - match attr.kind { - AttrKind::Normal(ref normal) => walk_mac_args(visitor, &normal.item.args), + match &attr.kind { + AttrKind::Normal(normal) => walk_attr_args(visitor, &normal.item.args), AttrKind::DocComment(..) => {} } } -pub fn walk_mac_args<'a, V: Visitor<'a>>(visitor: &mut V, args: &'a MacArgs) { +pub fn walk_attr_args<'a, V: Visitor<'a>>(visitor: &mut V, args: &'a AttrArgs) { match args { - MacArgs::Empty => {} - MacArgs::Delimited(_dspan, _delim, _tokens) => {} - MacArgs::Eq(_eq_span, MacArgsEq::Ast(expr)) => visitor.visit_expr(expr), - MacArgs::Eq(_, MacArgsEq::Hir(lit)) => { + AttrArgs::Empty => {} + AttrArgs::Delimited(_) => {} + AttrArgs::Eq(_eq_span, AttrArgsEq::Ast(expr)) => visitor.visit_expr(expr), + AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => { unreachable!("in literal form when walking mac args eq: {:?}", lit) } } diff --git a/compiler/rustc_ast_lowering/Cargo.toml b/compiler/rustc_ast_lowering/Cargo.toml index ce1c8d499..6a59b9e61 100644 --- a/compiler/rustc_ast_lowering/Cargo.toml +++ b/compiler/rustc_ast_lowering/Cargo.toml @@ -21,5 +21,5 @@ rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } -thin-vec = "0.2.8" +thin-vec = "0.2.9" tracing = "0.1" diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs index 450cdf246..dfef6ec70 100644 --- a/compiler/rustc_ast_lowering/src/asm.rs +++ b/compiler/rustc_ast_lowering/src/asm.rs @@ -11,7 +11,7 @@ use super::LoweringContext; use rustc_ast::ptr::P; use rustc_ast::*; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::definitions::DefPathData; @@ -71,7 +71,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { .emit(); } - let mut clobber_abis = FxHashMap::default(); + let mut clobber_abis = FxIndexMap::default(); if let Some(asm_arch) = asm_arch { for (abi_name, abi_span) in &asm.clobber_abis { match asm::InlineAsmClobberAbi::parse(asm_arch, &self.tcx.sess.target, *abi_name) { @@ -123,7 +123,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { .operands .iter() .map(|(op, op_sp)| { - let lower_reg = |reg| match reg { + let lower_reg = |®: &_| match reg { InlineAsmRegOrRegClass::Reg(reg) => { asm::InlineAsmRegOrRegClass::Reg(if let Some(asm_arch) = asm_arch { asm::InlineAsmReg::parse(asm_arch, reg).unwrap_or_else(|error| { @@ -152,32 +152,30 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } }; - let op = match *op { - InlineAsmOperand::In { reg, ref expr } => hir::InlineAsmOperand::In { + let op = match op { + InlineAsmOperand::In { reg, expr } => hir::InlineAsmOperand::In { reg: lower_reg(reg), expr: self.lower_expr(expr), }, - InlineAsmOperand::Out { reg, late, ref expr } => hir::InlineAsmOperand::Out { + InlineAsmOperand::Out { reg, late, expr } => hir::InlineAsmOperand::Out { reg: lower_reg(reg), - late, + late: *late, expr: expr.as_ref().map(|expr| self.lower_expr(expr)), }, - InlineAsmOperand::InOut { reg, late, ref expr } => { - hir::InlineAsmOperand::InOut { - reg: lower_reg(reg), - late, - expr: self.lower_expr(expr), - } - } - InlineAsmOperand::SplitInOut { reg, late, ref in_expr, ref out_expr } => { + InlineAsmOperand::InOut { reg, late, expr } => hir::InlineAsmOperand::InOut { + reg: lower_reg(reg), + late: *late, + expr: self.lower_expr(expr), + }, + InlineAsmOperand::SplitInOut { reg, late, in_expr, out_expr } => { hir::InlineAsmOperand::SplitInOut { reg: lower_reg(reg), - late, + late: *late, in_expr: self.lower_expr(in_expr), out_expr: out_expr.as_ref().map(|expr| self.lower_expr(expr)), } } - InlineAsmOperand::Const { ref anon_const } => { + InlineAsmOperand::Const { anon_const } => { if !self.tcx.features().asm_const { feature_err( &sess.parse_sess, @@ -191,7 +189,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { anon_const: self.lower_anon_const(anon_const), } } - InlineAsmOperand::Sym { ref sym } => { + InlineAsmOperand::Sym { sym } => { let static_def_id = self .resolver .get_partial_res(sym.id) @@ -224,7 +222,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // Wrap the expression in an AnonConst. let parent_def_id = self.current_hir_id_owner; let node_id = self.next_node_id(); - self.create_def(parent_def_id.def_id, node_id, DefPathData::AnonConst); + self.create_def( + parent_def_id.def_id, + node_id, + DefPathData::AnonConst, + *op_sp, + ); let anon_const = AnonConst { id: node_id, value: P(expr) }; hir::InlineAsmOperand::SymFn { anon_const: self.lower_anon_const(&anon_const), @@ -347,7 +350,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { skip = true; let idx2 = *o.get(); - let &(ref op2, op_sp2) = &operands[idx2]; + let (ref op2, op_sp2) = operands[idx2]; let Some(asm::InlineAsmRegOrRegClass::Reg(reg2)) = op2.reg() else { unreachable!(); }; diff --git a/compiler/rustc_ast_lowering/src/block.rs b/compiler/rustc_ast_lowering/src/block.rs index 12a0cc0d2..d310f72f7 100644 --- a/compiler/rustc_ast_lowering/src/block.rs +++ b/compiler/rustc_ast_lowering/src/block.rs @@ -31,8 +31,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let mut stmts = SmallVec::<[hir::Stmt<'hir>; 8]>::new(); let mut expr = None; while let [s, tail @ ..] = ast_stmts { - match s.kind { - StmtKind::Local(ref local) => { + match &s.kind { + StmtKind::Local(local) => { let hir_id = self.lower_node_id(s.id); let local = self.lower_local(local); self.alias_attrs(hir_id, local.hir_id); @@ -40,7 +40,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let span = self.lower_span(s.span); stmts.push(hir::Stmt { hir_id, kind, span }); } - StmtKind::Item(ref it) => { + StmtKind::Item(it) => { stmts.extend(self.lower_item_ref(it).into_iter().enumerate().map( |(i, item_id)| { let hir_id = match i { @@ -53,7 +53,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { }, )); } - StmtKind::Expr(ref e) => { + StmtKind::Expr(e) => { let e = self.lower_expr(e); if tail.is_empty() { expr = Some(e); @@ -65,7 +65,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { stmts.push(hir::Stmt { hir_id, kind, span }); } } - StmtKind::Semi(ref e) => { + StmtKind::Semi(e) => { let e = self.lower_expr(e); let hir_id = self.lower_node_id(s.id); self.alias_attrs(hir_id, e.hir_id); diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs index 157f46501..21c6a2d26 100644 --- a/compiler/rustc_ast_lowering/src/errors.rs +++ b/compiler/rustc_ast_lowering/src/errors.rs @@ -277,8 +277,9 @@ pub struct RegisterConflict<'a> { pub struct SubTupleBinding<'a> { #[primary_span] #[label] - #[suggestion_verbose( + #[suggestion( ast_lowering_sub_tuple_binding_suggestion, + style = "verbose", code = "..", applicability = "maybe-incorrect" )] diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index ec9c39350..7dd6d5acc 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -14,6 +14,7 @@ use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_hir as hir; use rustc_hir::def::Res; use rustc_hir::definitions::DefPathData; +use rustc_session::errors::report_lit_error; use rustc_span::source_map::{respan, DesugaringKind, Span, Spanned}; use rustc_span::symbol::{sym, Ident}; use rustc_span::DUMMY_SP; @@ -30,20 +31,20 @@ impl<'hir> LoweringContext<'_, 'hir> { pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'hir> { ensure_sufficient_stack(|| { - let kind = match e.kind { - ExprKind::Box(ref inner) => hir::ExprKind::Box(self.lower_expr(inner)), - ExprKind::Array(ref exprs) => hir::ExprKind::Array(self.lower_exprs(exprs)), - ExprKind::ConstBlock(ref anon_const) => { + let kind = match &e.kind { + ExprKind::Box(inner) => hir::ExprKind::Box(self.lower_expr(inner)), + ExprKind::Array(exprs) => hir::ExprKind::Array(self.lower_exprs(exprs)), + ExprKind::ConstBlock(anon_const) => { let anon_const = self.lower_anon_const(anon_const); hir::ExprKind::ConstBlock(anon_const) } - ExprKind::Repeat(ref expr, ref count) => { + ExprKind::Repeat(expr, count) => { let expr = self.lower_expr(expr); let count = self.lower_array_length(count); hir::ExprKind::Repeat(expr, count) } - ExprKind::Tup(ref elts) => hir::ExprKind::Tup(self.lower_exprs(elts)), - ExprKind::Call(ref f, ref args) => { + ExprKind::Tup(elts) => hir::ExprKind::Tup(self.lower_exprs(elts)), + ExprKind::Call(f, args) => { if e.attrs.get(0).map_or(false, |a| a.has_name(sym::rustc_box)) { if let [inner] = &args[..] && e.attrs.len() == 1 { let kind = hir::ExprKind::Box(self.lower_expr(&inner)); @@ -60,7 +61,7 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::ExprKind::Call(f, self.lower_exprs(args)) } } - ExprKind::MethodCall(ref seg, ref receiver, ref args, span) => { + ExprKind::MethodCall(box MethodCall { seg, receiver, args, span }) => { let hir_seg = self.arena.alloc(self.lower_path_segment( e.span, seg, @@ -71,81 +72,89 @@ impl<'hir> LoweringContext<'_, 'hir> { let receiver = self.lower_expr(receiver); let args = self.arena.alloc_from_iter(args.iter().map(|x| self.lower_expr_mut(x))); - hir::ExprKind::MethodCall(hir_seg, receiver, args, self.lower_span(span)) + hir::ExprKind::MethodCall(hir_seg, receiver, args, self.lower_span(*span)) } - ExprKind::Binary(binop, ref lhs, ref rhs) => { - let binop = self.lower_binop(binop); + ExprKind::Binary(binop, lhs, rhs) => { + let binop = self.lower_binop(*binop); let lhs = self.lower_expr(lhs); let rhs = self.lower_expr(rhs); hir::ExprKind::Binary(binop, lhs, rhs) } - ExprKind::Unary(op, ref ohs) => { - let op = self.lower_unop(op); + ExprKind::Unary(op, ohs) => { + let op = self.lower_unop(*op); let ohs = self.lower_expr(ohs); hir::ExprKind::Unary(op, ohs) } - ExprKind::Lit(ref l) => { - hir::ExprKind::Lit(respan(self.lower_span(l.span), l.kind.clone())) + ExprKind::Lit(token_lit) => { + let lit_kind = match LitKind::from_token_lit(*token_lit) { + Ok(lit_kind) => lit_kind, + Err(err) => { + report_lit_error(&self.tcx.sess.parse_sess, err, *token_lit, e.span); + LitKind::Err + } + }; + hir::ExprKind::Lit(respan(self.lower_span(e.span), lit_kind)) } - ExprKind::Cast(ref expr, ref ty) => { + ExprKind::IncludedBytes(bytes) => hir::ExprKind::Lit(respan( + self.lower_span(e.span), + LitKind::ByteStr(bytes.clone()), + )), + ExprKind::Cast(expr, ty) => { let expr = self.lower_expr(expr); let ty = self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)); hir::ExprKind::Cast(expr, ty) } - ExprKind::Type(ref expr, ref ty) => { + ExprKind::Type(expr, ty) => { let expr = self.lower_expr(expr); let ty = self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)); hir::ExprKind::Type(expr, ty) } - ExprKind::AddrOf(k, m, ref ohs) => { + ExprKind::AddrOf(k, m, ohs) => { let ohs = self.lower_expr(ohs); - hir::ExprKind::AddrOf(k, m, ohs) + hir::ExprKind::AddrOf(*k, *m, ohs) } - ExprKind::Let(ref pat, ref scrutinee, span) => { + ExprKind::Let(pat, scrutinee, span) => { hir::ExprKind::Let(self.arena.alloc(hir::Let { hir_id: self.next_id(), - span: self.lower_span(span), + span: self.lower_span(*span), pat: self.lower_pat(pat), ty: None, init: self.lower_expr(scrutinee), })) } - ExprKind::If(ref cond, ref then, ref else_opt) => { + ExprKind::If(cond, then, else_opt) => { self.lower_expr_if(cond, then, else_opt.as_deref()) } - ExprKind::While(ref cond, ref body, opt_label) => { - self.with_loop_scope(e.id, |this| { - let span = - this.mark_span_with_reason(DesugaringKind::WhileLoop, e.span, None); - this.lower_expr_while_in_loop_scope(span, cond, body, opt_label) - }) - } - ExprKind::Loop(ref body, opt_label) => self.with_loop_scope(e.id, |this| { + ExprKind::While(cond, body, opt_label) => self.with_loop_scope(e.id, |this| { + let span = this.mark_span_with_reason(DesugaringKind::WhileLoop, e.span, None); + this.lower_expr_while_in_loop_scope(span, cond, body, *opt_label) + }), + ExprKind::Loop(body, opt_label, span) => self.with_loop_scope(e.id, |this| { hir::ExprKind::Loop( this.lower_block(body, false), - this.lower_label(opt_label), + this.lower_label(*opt_label), hir::LoopSource::Loop, - DUMMY_SP, + this.lower_span(*span), ) }), - ExprKind::TryBlock(ref body) => self.lower_expr_try_block(body), - ExprKind::Match(ref expr, ref arms) => hir::ExprKind::Match( + ExprKind::TryBlock(body) => self.lower_expr_try_block(body), + ExprKind::Match(expr, arms) => hir::ExprKind::Match( self.lower_expr(expr), self.arena.alloc_from_iter(arms.iter().map(|x| self.lower_arm(x))), hir::MatchSource::Normal, ), - ExprKind::Async(capture_clause, closure_node_id, ref block) => self - .make_async_expr( - capture_clause, - closure_node_id, - None, - block.span, - hir::AsyncGeneratorKind::Block, - |this| this.with_new_scopes(|this| this.lower_block_expr(block)), - ), - ExprKind::Await(ref expr) => { + ExprKind::Async(capture_clause, closure_node_id, block) => self.make_async_expr( + *capture_clause, + None, + *closure_node_id, + None, + e.span, + hir::AsyncGeneratorKind::Block, + |this| this.with_new_scopes(|this| this.lower_block_expr(block)), + ), + ExprKind::Await(expr) => { let dot_await_span = if expr.span.hi() < e.span.hi() { let span_with_whitespace = self .tcx @@ -160,66 +169,67 @@ impl<'hir> LoweringContext<'_, 'hir> { }; self.lower_expr_await(dot_await_span, expr) } - ExprKind::Closure( - ref binder, + ExprKind::Closure(box Closure { + binder, capture_clause, asyncness, movability, - ref decl, - ref body, + fn_decl, + body, fn_decl_span, - ) => { + fn_arg_span, + }) => { if let Async::Yes { closure_id, .. } = asyncness { self.lower_expr_async_closure( binder, - capture_clause, + *capture_clause, e.id, - closure_id, - decl, + *closure_id, + fn_decl, body, - fn_decl_span, + *fn_decl_span, + *fn_arg_span, ) } else { self.lower_expr_closure( binder, - capture_clause, + *capture_clause, e.id, - movability, - decl, + *movability, + fn_decl, body, - fn_decl_span, + *fn_decl_span, + *fn_arg_span, ) } } - ExprKind::Block(ref blk, opt_label) => { - let opt_label = self.lower_label(opt_label); + ExprKind::Block(blk, opt_label) => { + let opt_label = self.lower_label(*opt_label); hir::ExprKind::Block(self.lower_block(blk, opt_label.is_some()), opt_label) } - ExprKind::Assign(ref el, ref er, span) => { - self.lower_expr_assign(el, er, span, e.span) - } - ExprKind::AssignOp(op, ref el, ref er) => hir::ExprKind::AssignOp( - self.lower_binop(op), + ExprKind::Assign(el, er, span) => self.lower_expr_assign(el, er, *span, e.span), + ExprKind::AssignOp(op, el, er) => hir::ExprKind::AssignOp( + self.lower_binop(*op), self.lower_expr(el), self.lower_expr(er), ), - ExprKind::Field(ref el, ident) => { - hir::ExprKind::Field(self.lower_expr(el), self.lower_ident(ident)) + ExprKind::Field(el, ident) => { + hir::ExprKind::Field(self.lower_expr(el), self.lower_ident(*ident)) } - ExprKind::Index(ref el, ref er) => { + ExprKind::Index(el, er) => { hir::ExprKind::Index(self.lower_expr(el), self.lower_expr(er)) } - ExprKind::Range(Some(ref e1), Some(ref e2), RangeLimits::Closed) => { + ExprKind::Range(Some(e1), Some(e2), RangeLimits::Closed) => { self.lower_expr_range_closed(e.span, e1, e2) } - ExprKind::Range(ref e1, ref e2, lims) => { - self.lower_expr_range(e.span, e1.as_deref(), e2.as_deref(), lims) + ExprKind::Range(e1, e2, lims) => { + self.lower_expr_range(e.span, e1.as_deref(), e2.as_deref(), *lims) } ExprKind::Underscore => { self.tcx.sess.emit_err(UnderscoreExprLhsAssign { span: e.span }); hir::ExprKind::Err } - ExprKind::Path(ref qself, ref path) => { + ExprKind::Path(qself, path) => { let qpath = self.lower_qpath( e.id, qself, @@ -229,22 +239,22 @@ impl<'hir> LoweringContext<'_, 'hir> { ); hir::ExprKind::Path(qpath) } - ExprKind::Break(opt_label, ref opt_expr) => { + ExprKind::Break(opt_label, opt_expr) => { let opt_expr = opt_expr.as_ref().map(|x| self.lower_expr(x)); - hir::ExprKind::Break(self.lower_jump_destination(e.id, opt_label), opt_expr) + hir::ExprKind::Break(self.lower_jump_destination(e.id, *opt_label), opt_expr) } ExprKind::Continue(opt_label) => { - hir::ExprKind::Continue(self.lower_jump_destination(e.id, opt_label)) + hir::ExprKind::Continue(self.lower_jump_destination(e.id, *opt_label)) } - ExprKind::Ret(ref e) => { + ExprKind::Ret(e) => { let e = e.as_ref().map(|x| self.lower_expr(x)); hir::ExprKind::Ret(e) } - ExprKind::Yeet(ref sub_expr) => self.lower_expr_yeet(e.span, sub_expr.as_deref()), - ExprKind::InlineAsm(ref asm) => { + ExprKind::Yeet(sub_expr) => self.lower_expr_yeet(e.span, sub_expr.as_deref()), + ExprKind::InlineAsm(asm) => { hir::ExprKind::InlineAsm(self.lower_inline_asm(e.span, asm)) } - ExprKind::Struct(ref se) => { + ExprKind::Struct(se) => { let rest = match &se.rest { StructRest::Base(e) => Some(self.lower_expr(e)), StructRest::Rest(sp) => { @@ -266,10 +276,10 @@ impl<'hir> LoweringContext<'_, 'hir> { rest, ) } - ExprKind::Yield(ref opt_expr) => self.lower_expr_yield(e.span, opt_expr.as_deref()), + ExprKind::Yield(opt_expr) => self.lower_expr_yield(e.span, opt_expr.as_deref()), ExprKind::Err => hir::ExprKind::Err, - ExprKind::Try(ref sub_expr) => self.lower_expr_try(e.span, sub_expr), - ExprKind::Paren(ref ex) => { + ExprKind::Try(sub_expr) => self.lower_expr_try(e.span, sub_expr), + ExprKind::Paren(ex) => { let mut ex = self.lower_expr_mut(ex); // Include parens in span, but only if it is a super-span. if e.span.contains(ex.span) { @@ -294,8 +304,8 @@ impl<'hir> LoweringContext<'_, 'hir> { // Desugar `ExprForLoop` // from: `[opt_ident]: for <pat> in <head> <body>` - ExprKind::ForLoop(ref pat, ref head, ref body, opt_label) => { - return self.lower_expr_for(e, pat, head, body, opt_label); + ExprKind::ForLoop(pat, head, body, opt_label) => { + return self.lower_expr_for(e, pat, head, body, *opt_label); } ExprKind::MacCall(_) => panic!("{:?} shouldn't exist here", e.span), }; @@ -346,7 +356,7 @@ impl<'hir> LoweringContext<'_, 'hir> { args: Vec<AstP<Expr>>, legacy_args_idx: &[usize], ) -> hir::ExprKind<'hir> { - let ExprKind::Path(None, ref mut path) = f.kind else { + let ExprKind::Path(None, path) = &mut f.kind else { unreachable!(); }; @@ -359,7 +369,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let node_id = self.next_node_id(); // Add a definition for the in-band const def. - self.create_def(parent_def_id.def_id, node_id, DefPathData::AnonConst); + self.create_def(parent_def_id.def_id, node_id, DefPathData::AnonConst, f.span); let anon_const = AnonConst { id: node_id, value: arg }; generic_args.push(AngleBracketedArg::Arg(GenericArg::Const(anon_const))); @@ -426,18 +436,14 @@ impl<'hir> LoweringContext<'_, 'hir> { let lhs = self.lower_cond(lhs); let rhs = self.lower_cond(rhs); - self.arena.alloc(self.expr( - cond.span, - hir::ExprKind::Binary(op, lhs, rhs), - AttrVec::new(), - )) + self.arena.alloc(self.expr(cond.span, hir::ExprKind::Binary(op, lhs, rhs))) } ExprKind::Let(..) => self.lower_expr(cond), _ => { let cond = self.lower_expr(cond); let reason = DesugaringKind::CondTemporary; let span_block = self.mark_span_with_reason(reason, cond.span, None); - self.expr_drop_temps(span_block, cond, AttrVec::new()) + self.expr_drop_temps(span_block, cond) } } } @@ -467,12 +473,12 @@ impl<'hir> LoweringContext<'_, 'hir> { ) -> hir::ExprKind<'hir> { let lowered_cond = self.with_loop_condition_scope(|t| t.lower_cond(cond)); let then = self.lower_block_expr(body); - let expr_break = self.expr_break(span, AttrVec::new()); + let expr_break = self.expr_break(span); let stmt_break = self.stmt_expr(span, expr_break); let else_blk = self.block_all(span, arena_vec![self; stmt_break], None); - let else_expr = self.arena.alloc(self.expr_block(else_blk, AttrVec::new())); + let else_expr = self.arena.alloc(self.expr_block(else_blk)); let if_kind = hir::ExprKind::If(lowered_cond, self.arena.alloc(then), Some(else_expr)); - let if_expr = self.expr(span, if_kind, AttrVec::new()); + let if_expr = self.expr(span, if_kind); let block = self.block_expr(self.arena.alloc(if_expr)); let span = self.lower_span(span.with_hi(cond.span.hi())); let opt_label = self.lower_label(opt_label); @@ -528,22 +534,17 @@ impl<'hir> LoweringContext<'_, 'hir> { expr: &'hir hir::Expr<'hir>, overall_span: Span, ) -> &'hir hir::Expr<'hir> { - let constructor = self.arena.alloc(self.expr_lang_item_path( - method_span, - lang_item, - AttrVec::new(), - None, - )); + let constructor = self.arena.alloc(self.expr_lang_item_path(method_span, lang_item, None)); self.expr_call(overall_span, constructor, std::slice::from_ref(expr)) } fn lower_arm(&mut self, arm: &Arm) -> hir::Arm<'hir> { let pat = self.lower_pat(&arm.pat); let guard = arm.guard.as_ref().map(|cond| { - if let ExprKind::Let(ref pat, ref scrutinee, span) = cond.kind { + if let ExprKind::Let(pat, scrutinee, span) = &cond.kind { hir::Guard::IfLet(self.arena.alloc(hir::Let { hir_id: self.next_id(), - span: self.lower_span(span), + span: self.lower_span(*span), pat: self.lower_pat(pat), ty: None, init: self.lower_expr(scrutinee), @@ -563,37 +564,35 @@ impl<'hir> LoweringContext<'_, 'hir> { } } - /// Lower an `async` construct to a generator that is then wrapped so it implements `Future`. + /// Lower an `async` construct to a generator that implements `Future`. /// /// This results in: /// /// ```text - /// std::future::from_generator(static move? |_task_context| -> <ret_ty> { + /// std::future::identity_future(static move? |_task_context| -> <ret_ty> { /// <body> /// }) /// ``` pub(super) fn make_async_expr( &mut self, capture_clause: CaptureBy, + outer_hir_id: Option<hir::HirId>, closure_node_id: NodeId, - ret_ty: Option<AstP<Ty>>, + ret_ty: Option<hir::FnRetTy<'hir>>, span: Span, async_gen_kind: hir::AsyncGeneratorKind, body: impl FnOnce(&mut Self) -> hir::Expr<'hir>, ) -> hir::ExprKind<'hir> { - let output = match ret_ty { - Some(ty) => hir::FnRetTy::Return( - self.lower_ty(&ty, &ImplTraitContext::Disallowed(ImplTraitPosition::AsyncBlock)), - ), - None => hir::FnRetTy::DefaultReturn(self.lower_span(span)), - }; + let output = ret_ty.unwrap_or_else(|| hir::FnRetTy::DefaultReturn(self.lower_span(span))); - // Resume argument type. We let the compiler infer this to simplify the lowering. It is - // fully constrained by `future::from_generator`. + // Resume argument type: `ResumeTy` + let unstable_span = + self.mark_span_with_reason(DesugaringKind::Async, span, self.allow_gen_future.clone()); + let resume_ty = hir::QPath::LangItem(hir::LangItem::ResumeTy, unstable_span, None); let input_ty = hir::Ty { hir_id: self.next_id(), - kind: hir::TyKind::Infer, - span: self.lower_span(span), + kind: hir::TyKind::Path(resume_ty), + span: unstable_span, }; // The closure/generator `FnDecl` takes a single (resume) argument of type `input_ty`. @@ -602,6 +601,7 @@ impl<'hir> LoweringContext<'_, 'hir> { output, c_variadic: false, implicit_self: hir::ImplicitSelfKind::None, + lifetime_elision_allowed: false, }); // Lower the argument pattern/ident. The ident is used again in the `.await` lowering. @@ -631,35 +631,63 @@ impl<'hir> LoweringContext<'_, 'hir> { // `static |_task_context| -> <ret_ty> { body }`: let generator_kind = { let c = self.arena.alloc(hir::Closure { + def_id: self.local_def_id(closure_node_id), binder: hir::ClosureBinder::Default, capture_clause, bound_generic_params: &[], fn_decl, body, fn_decl_span: self.lower_span(span), + fn_arg_span: None, movability: Some(hir::Movability::Static), }); hir::ExprKind::Closure(c) }; - let generator = hir::Expr { - hir_id: self.lower_node_id(closure_node_id), - kind: generator_kind, - span: self.lower_span(span), - }; - // `future::from_generator`: + let hir_id = self.lower_node_id(closure_node_id); let unstable_span = self.mark_span_with_reason(DesugaringKind::Async, span, self.allow_gen_future.clone()); - let gen_future = self.expr_lang_item_path( - unstable_span, - hir::LangItem::FromGenerator, - AttrVec::new(), - None, - ); - // `future::from_generator(generator)`: - hir::ExprKind::Call(self.arena.alloc(gen_future), arena_vec![self; generator]) + if self.tcx.features().closure_track_caller + && let Some(outer_hir_id) = outer_hir_id + && let Some(attrs) = self.attrs.get(&outer_hir_id.local_id) + && attrs.into_iter().any(|attr| attr.has_name(sym::track_caller)) + { + self.lower_attrs( + hir_id, + &[Attribute { + kind: AttrKind::Normal(ptr::P(NormalAttr { + item: AttrItem { + path: Path::from_ident(Ident::new(sym::track_caller, span)), + args: AttrArgs::Empty, + tokens: None, + }, + tokens: None, + })), + id: self.tcx.sess.parse_sess.attr_id_generator.mk_attr_id(), + style: AttrStyle::Outer, + span: unstable_span, + }], + ); + } + + let generator = hir::Expr { hir_id, kind: generator_kind, span: self.lower_span(span) }; + + // FIXME(swatinem): + // For some reason, the async block needs to flow through *any* + // call (like the identity function), as otherwise type and lifetime + // inference have a hard time figuring things out. + // Without this, we would get: + // E0720 in src/test/ui/impl-trait/in-trait/default-body-with-rpit.rs + // E0700 in src/test/ui/self/self_lifetime-async.rs + + // `future::identity_future`: + let identity_future = + self.expr_lang_item_path(unstable_span, hir::LangItem::IdentityFuture, None); + + // `future::identity_future(generator)`: + hir::ExprKind::Call(self.arena.alloc(identity_future), arena_vec![self; generator]) } /// Desugar `<expr>.await` into: @@ -759,7 +787,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let break_x = self.with_loop_scope(loop_node_id, move |this| { let expr_break = hir::ExprKind::Break(this.lower_loop_destination(None), Some(x_expr)); - this.arena.alloc(this.expr(gen_future_span, expr_break, AttrVec::new())) + this.arena.alloc(this.expr(gen_future_span, expr_break)) }); self.arm(ready_pat, break_x) }; @@ -792,17 +820,13 @@ impl<'hir> LoweringContext<'_, 'hir> { let yield_expr = self.expr( span, hir::ExprKind::Yield(unit, hir::YieldSource::Await { expr: Some(expr_hir_id) }), - AttrVec::new(), ); let yield_expr = self.arena.alloc(yield_expr); if let Some(task_context_hid) = self.task_context { let lhs = self.expr_ident(span, task_context_ident, task_context_hid); - let assign = self.expr( - span, - hir::ExprKind::Assign(lhs, yield_expr, self.lower_span(span)), - AttrVec::new(), - ); + let assign = + self.expr(span, hir::ExprKind::Assign(lhs, yield_expr, self.lower_span(span))); self.stmt_expr(span, assign) } else { // Use of `await` outside of an async context. Return `yield_expr` so that we can @@ -860,6 +884,7 @@ impl<'hir> LoweringContext<'_, 'hir> { decl: &FnDecl, body: &Expr, fn_decl_span: Span, + fn_arg_span: Span, ) -> hir::ExprKind<'hir> { let (binder_clause, generic_params) = self.lower_closure_binder(binder); @@ -880,15 +905,17 @@ impl<'hir> LoweringContext<'_, 'hir> { let bound_generic_params = self.lower_lifetime_binder(closure_id, generic_params); // Lower outside new scope to preserve `is_in_loop_condition`. - let fn_decl = self.lower_fn_decl(decl, None, fn_decl_span, FnDeclKind::Closure, None); + let fn_decl = self.lower_fn_decl(decl, closure_id, fn_decl_span, FnDeclKind::Closure, None); let c = self.arena.alloc(hir::Closure { + def_id: self.local_def_id(closure_id), binder: binder_clause, capture_clause, bound_generic_params, fn_decl, body: body_id, fn_decl_span: self.lower_span(fn_decl_span), + fn_arg_span: Some(self.lower_span(fn_arg_span)), movability: generator_option, }); @@ -927,8 +954,8 @@ impl<'hir> LoweringContext<'_, 'hir> { ) -> (hir::ClosureBinder, &'c [GenericParam]) { let (binder, params) = match binder { ClosureBinder::NotPresent => (hir::ClosureBinder::Default, &[][..]), - &ClosureBinder::For { span, ref generic_params } => { - let span = self.lower_span(span); + ClosureBinder::For { span, generic_params } => { + let span = self.lower_span(*span); (hir::ClosureBinder::For { span }, &**generic_params) } }; @@ -945,6 +972,7 @@ impl<'hir> LoweringContext<'_, 'hir> { decl: &FnDecl, body: &Expr, fn_decl_span: Span, + fn_arg_span: Span, ) -> hir::ExprKind<'hir> { if let &ClosureBinder::For { span, .. } = binder { self.tcx.sess.emit_err(NotSupportedForLifetimeBinderAsyncClosure { span }); @@ -962,19 +990,27 @@ impl<'hir> LoweringContext<'_, 'hir> { } // Transform `async |x: u8| -> X { ... }` into - // `|x: u8| future_from_generator(|| -> X { ... })`. + // `|x: u8| identity_future(|| -> X { ... })`. let body_id = this.lower_fn_body(&outer_decl, |this| { - let async_ret_ty = - if let FnRetTy::Ty(ty) = &decl.output { Some(ty.clone()) } else { None }; + let async_ret_ty = if let FnRetTy::Ty(ty) = &decl.output { + let itctx = ImplTraitContext::Disallowed(ImplTraitPosition::AsyncBlock); + Some(hir::FnRetTy::Return(this.lower_ty(&ty, &itctx))) + } else { + None + }; + let async_body = this.make_async_expr( capture_clause, + // FIXME(nbdd0121): This should also use a proper HIR id so `#[track_caller]` + // can be applied on async closures as well. + None, inner_closure_id, async_ret_ty, body.span, hir::AsyncGeneratorKind::Closure, |this| this.with_new_scopes(|this| this.lower_expr_mut(body)), ); - this.expr(fn_decl_span, async_body, AttrVec::new()) + this.expr(fn_decl_span, async_body) }); body_id }); @@ -984,15 +1020,17 @@ impl<'hir> LoweringContext<'_, 'hir> { // have to conserve the state of being inside a loop condition for the // closure argument types. let fn_decl = - self.lower_fn_decl(&outer_decl, None, fn_decl_span, FnDeclKind::Closure, None); + self.lower_fn_decl(&outer_decl, closure_id, fn_decl_span, FnDeclKind::Closure, None); let c = self.arena.alloc(hir::Closure { + def_id: self.local_def_id(closure_id), binder: binder_clause, capture_clause, bound_generic_params, fn_decl, body, fn_decl_span: self.lower_span(fn_decl_span), + fn_arg_span: Some(self.lower_span(fn_arg_span)), movability: None, }); hir::ExprKind::Closure(c) @@ -1065,7 +1103,7 @@ impl<'hir> LoweringContext<'_, 'hir> { fn extract_tuple_struct_path<'a>( &mut self, expr: &'a Expr, - ) -> Option<(&'a Option<QSelf>, &'a Path)> { + ) -> Option<(&'a Option<AstP<QSelf>>, &'a Path)> { if let ExprKind::Path(qself, path) = &expr.kind { // Does the path resolve to something disallowed in a tuple struct/variant pattern? if let Some(partial_res) = self.resolver.get_partial_res(expr.id) { @@ -1085,7 +1123,7 @@ impl<'hir> LoweringContext<'_, 'hir> { fn extract_unit_struct_path<'a>( &mut self, expr: &'a Expr, - ) -> Option<(&'a Option<QSelf>, &'a Path)> { + ) -> Option<(&'a Option<AstP<QSelf>>, &'a Path)> { if let ExprKind::Path(qself, path) = &expr.kind { // Does the path resolve to something disallowed in a unit struct/variant pattern? if let Some(partial_res) = self.resolver.get_partial_res(expr.id) { @@ -1232,7 +1270,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let ident = self.expr_ident(lhs.span, ident, binding); let assign = hir::ExprKind::Assign(self.lower_expr(lhs), ident, self.lower_span(eq_sign_span)); - let expr = self.expr(lhs.span, assign, AttrVec::new()); + let expr = self.expr(lhs.span, assign); assignments.push(self.stmt_expr(lhs.span, expr)); pat } @@ -1273,8 +1311,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let e2 = self.lower_expr_mut(e2); let fn_path = hir::QPath::LangItem(hir::LangItem::RangeInclusiveNew, self.lower_span(span), None); - let fn_expr = - self.arena.alloc(self.expr(span, hir::ExprKind::Path(fn_path), AttrVec::new())); + let fn_expr = self.arena.alloc(self.expr(span, hir::ExprKind::Path(fn_path))); hir::ExprKind::Call(fn_expr, arena_vec![self; e1, e2]) } @@ -1446,8 +1483,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // `None => break` let none_arm = { - let break_expr = - self.with_loop_scope(e.id, |this| this.expr_break_alloc(for_span, AttrVec::new())); + let break_expr = self.with_loop_scope(e.id, |this| this.expr_break_alloc(for_span)); let pat = self.pat_none(for_span); self.arm(pat, break_expr) }; @@ -1456,7 +1492,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let some_arm = { let some_pat = self.pat_some(pat_span, pat); let body_block = self.with_loop_scope(e.id, |this| this.lower_block(body, false)); - let body_expr = self.arena.alloc(self.expr_block(body_block, AttrVec::new())); + let body_expr = self.arena.alloc(self.expr_block(body_block)); self.arm(some_pat, body_expr) }; @@ -1519,7 +1555,9 @@ impl<'hir> LoweringContext<'_, 'hir> { // surrounding scope of the `match` since the `match` is not a terminating scope. // // Also, add the attributes to the outer returned expr node. - self.expr_drop_temps_mut(for_span, match_expr, e.attrs.clone()) + let expr = self.expr_drop_temps_mut(for_span, match_expr); + self.lower_attrs(expr.hir_id, &e.attrs); + expr } /// Desugar `ExprKind::Try` from: `<expr>?` into: @@ -1561,28 +1599,21 @@ impl<'hir> LoweringContext<'_, 'hir> { }; // `#[allow(unreachable_code)]` - let attr = { - // `allow(unreachable_code)` - let allow = { - let allow_ident = Ident::new(sym::allow, self.lower_span(span)); - let uc_ident = Ident::new(sym::unreachable_code, self.lower_span(span)); - let uc_nested = attr::mk_nested_word_item(uc_ident); - attr::mk_list_item(allow_ident, vec![uc_nested]) - }; - attr::mk_attr_outer(&self.tcx.sess.parse_sess.attr_id_generator, allow) - }; + let attr = attr::mk_attr_nested_word( + &self.tcx.sess.parse_sess.attr_id_generator, + AttrStyle::Outer, + sym::allow, + sym::unreachable_code, + self.lower_span(span), + ); let attrs: AttrVec = thin_vec![attr]; // `ControlFlow::Continue(val) => #[allow(unreachable_code)] val,` let continue_arm = { let val_ident = Ident::with_dummy_span(sym::val); let (val_pat, val_pat_nid) = self.pat_ident(span, val_ident); - let val_expr = self.arena.alloc(self.expr_ident_with_attrs( - span, - val_ident, - val_pat_nid, - attrs.clone(), - )); + let val_expr = self.expr_ident(span, val_ident, val_pat_nid); + self.lower_attrs(val_expr.hir_id, &attrs); let continue_pat = self.pat_cf_continue(unstable_span, val_pat); self.arm(continue_pat, val_expr) }; @@ -1608,15 +1639,11 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::Destination { label: None, target_id }, Some(from_residual_expr), ), - attrs, )) } else { - self.arena.alloc(self.expr( - try_span, - hir::ExprKind::Ret(Some(from_residual_expr)), - attrs, - )) + self.arena.alloc(self.expr(try_span, hir::ExprKind::Ret(Some(from_residual_expr)))) }; + self.lower_attrs(ret_expr.hir_id, &attrs); let break_pat = self.pat_cf_break(try_span, residual_local); self.arm(break_pat, ret_expr) @@ -1681,18 +1708,16 @@ impl<'hir> LoweringContext<'_, 'hir> { &mut self, span: Span, expr: &'hir hir::Expr<'hir>, - attrs: AttrVec, ) -> &'hir hir::Expr<'hir> { - self.arena.alloc(self.expr_drop_temps_mut(span, expr, attrs)) + self.arena.alloc(self.expr_drop_temps_mut(span, expr)) } pub(super) fn expr_drop_temps_mut( &mut self, span: Span, expr: &'hir hir::Expr<'hir>, - attrs: AttrVec, ) -> hir::Expr<'hir> { - self.expr(span, hir::ExprKind::DropTemps(expr), attrs) + self.expr(span, hir::ExprKind::DropTemps(expr)) } fn expr_match( @@ -1702,29 +1727,25 @@ impl<'hir> LoweringContext<'_, 'hir> { arms: &'hir [hir::Arm<'hir>], source: hir::MatchSource, ) -> hir::Expr<'hir> { - self.expr(span, hir::ExprKind::Match(arg, arms, source), AttrVec::new()) + self.expr(span, hir::ExprKind::Match(arg, arms, source)) } - fn expr_break(&mut self, span: Span, attrs: AttrVec) -> hir::Expr<'hir> { + fn expr_break(&mut self, span: Span) -> hir::Expr<'hir> { let expr_break = hir::ExprKind::Break(self.lower_loop_destination(None), None); - self.expr(span, expr_break, attrs) + self.expr(span, expr_break) } - fn expr_break_alloc(&mut self, span: Span, attrs: AttrVec) -> &'hir hir::Expr<'hir> { - let expr_break = self.expr_break(span, attrs); + fn expr_break_alloc(&mut self, span: Span) -> &'hir hir::Expr<'hir> { + let expr_break = self.expr_break(span); self.arena.alloc(expr_break) } fn expr_mut_addr_of(&mut self, span: Span, e: &'hir hir::Expr<'hir>) -> hir::Expr<'hir> { - self.expr( - span, - hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Mut, e), - AttrVec::new(), - ) + self.expr(span, hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Mut, e)) } fn expr_unit(&mut self, sp: Span) -> &'hir hir::Expr<'hir> { - self.arena.alloc(self.expr(sp, hir::ExprKind::Tup(&[]), AttrVec::new())) + self.arena.alloc(self.expr(sp, hir::ExprKind::Tup(&[]))) } fn expr_call_mut( @@ -1733,7 +1754,7 @@ impl<'hir> LoweringContext<'_, 'hir> { e: &'hir hir::Expr<'hir>, args: &'hir [hir::Expr<'hir>], ) -> hir::Expr<'hir> { - self.expr(span, hir::ExprKind::Call(e, args), AttrVec::new()) + self.expr(span, hir::ExprKind::Call(e, args)) } fn expr_call( @@ -1752,8 +1773,7 @@ impl<'hir> LoweringContext<'_, 'hir> { args: &'hir [hir::Expr<'hir>], hir_id: Option<hir::HirId>, ) -> hir::Expr<'hir> { - let path = - self.arena.alloc(self.expr_lang_item_path(span, lang_item, AttrVec::new(), hir_id)); + let path = self.arena.alloc(self.expr_lang_item_path(span, lang_item, hir_id)); self.expr_call_mut(span, path, args) } @@ -1771,13 +1791,11 @@ impl<'hir> LoweringContext<'_, 'hir> { &mut self, span: Span, lang_item: hir::LangItem, - attrs: AttrVec, hir_id: Option<hir::HirId>, ) -> hir::Expr<'hir> { self.expr( span, hir::ExprKind::Path(hir::QPath::LangItem(lang_item, self.lower_span(span), hir_id)), - attrs, ) } @@ -1792,19 +1810,9 @@ impl<'hir> LoweringContext<'_, 'hir> { pub(super) fn expr_ident_mut( &mut self, - sp: Span, - ident: Ident, - binding: hir::HirId, - ) -> hir::Expr<'hir> { - self.expr_ident_with_attrs(sp, ident, binding, AttrVec::new()) - } - - fn expr_ident_with_attrs( - &mut self, span: Span, ident: Ident, binding: hir::HirId, - attrs: AttrVec, ) -> hir::Expr<'hir> { let hir_id = self.next_id(); let res = Res::Local(binding); @@ -1817,7 +1825,7 @@ impl<'hir> LoweringContext<'_, 'hir> { }), )); - self.expr(span, expr_path, attrs) + self.expr(span, expr_path) } fn expr_unsafe(&mut self, expr: &'hir hir::Expr<'hir>) -> hir::Expr<'hir> { @@ -1836,32 +1844,21 @@ impl<'hir> LoweringContext<'_, 'hir> { }), None, ), - AttrVec::new(), ) } fn expr_block_empty(&mut self, span: Span) -> &'hir hir::Expr<'hir> { let blk = self.block_all(span, &[], None); - let expr = self.expr_block(blk, AttrVec::new()); + let expr = self.expr_block(blk); self.arena.alloc(expr) } - pub(super) fn expr_block( - &mut self, - b: &'hir hir::Block<'hir>, - attrs: AttrVec, - ) -> hir::Expr<'hir> { - self.expr(b.span, hir::ExprKind::Block(b, None), attrs) + pub(super) fn expr_block(&mut self, b: &'hir hir::Block<'hir>) -> hir::Expr<'hir> { + self.expr(b.span, hir::ExprKind::Block(b, None)) } - pub(super) fn expr( - &mut self, - span: Span, - kind: hir::ExprKind<'hir>, - attrs: AttrVec, - ) -> hir::Expr<'hir> { + pub(super) fn expr(&mut self, span: Span, kind: hir::ExprKind<'hir>) -> hir::Expr<'hir> { let hir_id = self.next_id(); - self.lower_attrs(hir_id, &attrs); hir::Expr { hir_id, kind, span: self.lower_span(span) } } diff --git a/compiler/rustc_ast_lowering/src/index.rs b/compiler/rustc_ast_lowering/src/index.rs index f1851d7b4..fe0bd4381 100644 --- a/compiler/rustc_ast_lowering/src/index.rs +++ b/compiler/rustc_ast_lowering/src/index.rs @@ -77,7 +77,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> { if hir_id.owner != self.owner { span_bug!( span, - "inconsistent DepNode at `{:?}` for `{:?}`: \ + "inconsistent HirId at `{:?}` for `{:?}`: \ current_dep_node_owner={} ({:?}), hir_id.owner={} ({:?})", self.source_map.span_to_diagnostic_string(span), node, @@ -145,7 +145,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { fn visit_item(&mut self, i: &'hir Item<'hir>) { debug_assert_eq!(i.owner_id, self.owner); self.with_parent(i.hir_id(), |this| { - if let ItemKind::Struct(ref struct_def, _) = i.kind { + if let ItemKind::Struct(struct_def, _) = &i.kind { // If this is a tuple or unit-like struct, register the constructor. if let Some(ctor_hir_id) = struct_def.ctor_hir_id() { this.insert(i.span, ctor_hir_id, Node::Ctor(struct_def)); @@ -303,12 +303,12 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { } fn visit_lifetime(&mut self, lifetime: &'hir Lifetime) { - self.insert(lifetime.span, lifetime.hir_id, Node::Lifetime(lifetime)); + self.insert(lifetime.ident.span, lifetime.hir_id, Node::Lifetime(lifetime)); } fn visit_variant(&mut self, v: &'hir Variant<'hir>) { - self.insert(v.span, v.id, Node::Variant(v)); - self.with_parent(v.id, |this| { + self.insert(v.span, v.hir_id, Node::Variant(v)); + self.with_parent(v.hir_id, |this| { // Register the constructor of this variant. if let Some(ctor_hir_id) = v.data.ctor_hir_id() { this.insert(v.span, ctor_hir_id, Node::Ctor(&v.data)); diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 76316a574..d73d6d391 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -6,7 +6,6 @@ use super::{FnDeclKind, LoweringContext, ParamMode}; use rustc_ast::ptr::P; use rustc_ast::visit::AssocCtxt; use rustc_ast::*; -use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sorted_map::SortedMap; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; @@ -20,8 +19,7 @@ use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::{Span, Symbol}; use rustc_target::spec::abi; use smallvec::{smallvec, SmallVec}; - -use std::iter; +use thin_vec::ThinVec; pub(super) struct ItemLowerer<'a, 'hir> { pub(super) tcx: TyCtxt<'hir>, @@ -67,7 +65,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> { // HirId handling. bodies: Vec::new(), attrs: SortedMap::default(), - children: FxHashMap::default(), + children: Vec::default(), current_hir_id_owner: hir::CRATE_OWNER_ID, item_local_id_counter: hir::ItemLocalId::new(0), node_id_to_local_id: Default::default(), @@ -86,7 +84,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> { impl_trait_defs: Vec::new(), impl_trait_bounds: Vec::new(), allow_try_trait: Some([sym::try_trait_v2, sym::yeet_desugar_details][..].into()), - allow_gen_future: Some([sym::gen_future][..].into()), + allow_gen_future: Some([sym::gen_future, sym::closure_track_caller][..].into()), allow_into_future: Some([sym::into_future][..].into()), generics_def_id_map: Default::default(), }; @@ -143,7 +141,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> { // This is used to track which lifetimes have already been defined, // and which need to be replicated when lowering an async fn. match parent_hir.node().expect_item().kind { - hir::ItemKind::Impl(hir::Impl { ref of_trait, .. }) => { + hir::ItemKind::Impl(hir::Impl { of_trait, .. }) => { lctx.is_in_trait_impl = of_trait.is_some(); } _ => {} @@ -179,37 +177,23 @@ impl<'hir> LoweringContext<'_, 'hir> { pub(super) fn lower_item_ref(&mut self, i: &Item) -> SmallVec<[hir::ItemId; 1]> { let mut node_ids = smallvec![hir::ItemId { owner_id: hir::OwnerId { def_id: self.local_def_id(i.id) } }]; - if let ItemKind::Use(ref use_tree) = &i.kind { - self.lower_item_id_use_tree(use_tree, i.id, &mut node_ids); + if let ItemKind::Use(use_tree) = &i.kind { + self.lower_item_id_use_tree(use_tree, &mut node_ids); } node_ids } - fn lower_item_id_use_tree( - &mut self, - tree: &UseTree, - base_id: NodeId, - vec: &mut SmallVec<[hir::ItemId; 1]>, - ) { - match tree.kind { - UseTreeKind::Nested(ref nested_vec) => { + fn lower_item_id_use_tree(&mut self, tree: &UseTree, vec: &mut SmallVec<[hir::ItemId; 1]>) { + match &tree.kind { + UseTreeKind::Nested(nested_vec) => { for &(ref nested, id) in nested_vec { vec.push(hir::ItemId { owner_id: hir::OwnerId { def_id: self.local_def_id(id) }, }); - self.lower_item_id_use_tree(nested, id, vec); - } - } - UseTreeKind::Glob => {} - UseTreeKind::Simple(_, id1, id2) => { - for (_, &id) in - iter::zip(self.expect_full_res_from_use(base_id).skip(1), &[id1, id2]) - { - vec.push(hir::ItemId { - owner_id: hir::OwnerId { def_id: self.local_def_id(id) }, - }); + self.lower_item_id_use_tree(nested, vec); } } + UseTreeKind::Simple(..) | UseTreeKind::Glob => {} } } @@ -239,26 +223,26 @@ impl<'hir> LoweringContext<'_, 'hir> { vis_span: Span, i: &ItemKind, ) -> hir::ItemKind<'hir> { - match *i { - ItemKind::ExternCrate(orig_name) => hir::ItemKind::ExternCrate(orig_name), - ItemKind::Use(ref use_tree) => { + match i { + ItemKind::ExternCrate(orig_name) => hir::ItemKind::ExternCrate(*orig_name), + ItemKind::Use(use_tree) => { // Start with an empty prefix. - let prefix = Path { segments: vec![], span: use_tree.span, tokens: None }; + let prefix = Path { segments: ThinVec::new(), span: use_tree.span, tokens: None }; self.lower_use_tree(use_tree, &prefix, id, vis_span, ident, attrs) } - ItemKind::Static(ref t, m, ref e) => { + ItemKind::Static(t, m, e) => { let (ty, body_id) = self.lower_const_item(t, span, e.as_deref()); - hir::ItemKind::Static(ty, m, body_id) + hir::ItemKind::Static(ty, *m, body_id) } - ItemKind::Const(_, ref t, ref e) => { + ItemKind::Const(_, t, e) => { let (ty, body_id) = self.lower_const_item(t, span, e.as_deref()); hir::ItemKind::Const(ty, body_id) } ItemKind::Fn(box Fn { - sig: FnSig { ref decl, header, span: fn_sig_span }, - ref generics, - ref body, + sig: FnSig { decl, header, span: fn_sig_span }, + generics, + body, .. }) => { self.with_new_scopes(|this| { @@ -269,43 +253,41 @@ impl<'hir> LoweringContext<'_, 'hir> { // only cares about the input argument patterns in the function // declaration (decl), not the return types. let asyncness = header.asyncness; - let body_id = - this.lower_maybe_async_body(span, &decl, asyncness, body.as_deref()); + let body_id = this.lower_maybe_async_body( + span, + hir_id, + &decl, + asyncness, + body.as_deref(), + ); let mut itctx = ImplTraitContext::Universal; let (generics, decl) = this.lower_generics(generics, id, &mut itctx, |this| { let ret_id = asyncness.opt_return_id(); - this.lower_fn_decl(&decl, Some(id), fn_sig_span, FnDeclKind::Fn, ret_id) + this.lower_fn_decl(&decl, id, *fn_sig_span, FnDeclKind::Fn, ret_id) }); let sig = hir::FnSig { decl, - header: this.lower_fn_header(header), - span: this.lower_span(fn_sig_span), + header: this.lower_fn_header(*header), + span: this.lower_span(*fn_sig_span), }; hir::ItemKind::Fn(sig, generics, body_id) }) } - ItemKind::Mod(_, ref mod_kind) => match mod_kind { + ItemKind::Mod(_, mod_kind) => match mod_kind { ModKind::Loaded(items, _, spans) => { hir::ItemKind::Mod(self.lower_mod(items, spans)) } ModKind::Unloaded => panic!("`mod` items should have been loaded by now"), }, - ItemKind::ForeignMod(ref fm) => hir::ItemKind::ForeignMod { + ItemKind::ForeignMod(fm) => hir::ItemKind::ForeignMod { abi: fm.abi.map_or(abi::Abi::FALLBACK, |abi| self.lower_abi(abi)), items: self .arena .alloc_from_iter(fm.items.iter().map(|x| self.lower_foreign_item_ref(x))), }, - ItemKind::GlobalAsm(ref asm) => { - hir::ItemKind::GlobalAsm(self.lower_inline_asm(span, asm)) - } - ItemKind::TyAlias(box TyAlias { - ref generics, - where_clauses, - ty: Some(ref ty), - .. - }) => { + ItemKind::GlobalAsm(asm) => hir::ItemKind::GlobalAsm(self.lower_inline_asm(span, asm)), + ItemKind::TyAlias(box TyAlias { generics, where_clauses, ty: Some(ty), .. }) => { // We lower // // type Foo = impl Trait @@ -315,7 +297,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // type Foo = Foo1 // opaque type Foo1: Trait let mut generics = generics.clone(); - add_ty_alias_where_clause(&mut generics, where_clauses, true); + add_ty_alias_where_clause(&mut generics, *where_clauses, true); let (generics, ty) = self.lower_generics( &generics, id, @@ -324,9 +306,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ); hir::ItemKind::TyAlias(ty, generics) } - ItemKind::TyAlias(box TyAlias { - ref generics, ref where_clauses, ty: None, .. - }) => { + ItemKind::TyAlias(box TyAlias { generics, where_clauses, ty: None, .. }) => { let mut generics = generics.clone(); add_ty_alias_where_clause(&mut generics, *where_clauses, true); let (generics, ty) = self.lower_generics( @@ -337,7 +317,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ); hir::ItemKind::TyAlias(ty, generics) } - ItemKind::Enum(ref enum_definition, ref generics) => { + ItemKind::Enum(enum_definition, generics) => { let (generics, variants) = self.lower_generics( generics, id, @@ -350,7 +330,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ); hir::ItemKind::Enum(hir::EnumDef { variants }, generics) } - ItemKind::Struct(ref struct_def, ref generics) => { + ItemKind::Struct(struct_def, generics) => { let (generics, struct_def) = self.lower_generics( generics, id, @@ -359,7 +339,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ); hir::ItemKind::Struct(struct_def, generics) } - ItemKind::Union(ref vdata, ref generics) => { + ItemKind::Union(vdata, generics) => { let (generics, vdata) = self.lower_generics( generics, id, @@ -373,10 +353,10 @@ impl<'hir> LoweringContext<'_, 'hir> { polarity, defaultness, constness, - generics: ref ast_generics, - of_trait: ref trait_ref, - self_ty: ref ty, - items: ref impl_items, + generics: ast_generics, + of_trait: trait_ref, + self_ty: ty, + items: impl_items, }) => { // Lower the "impl header" first. This ordering is important // for in-band lifetimes! Consider `'a` here: @@ -414,30 +394,24 @@ impl<'hir> LoweringContext<'_, 'hir> { // `defaultness.has_value()` is never called for an `impl`, always `true` in order // to not cause an assertion failure inside the `lower_defaultness` function. let has_val = true; - let (defaultness, defaultness_span) = self.lower_defaultness(defaultness, has_val); + let (defaultness, defaultness_span) = self.lower_defaultness(*defaultness, has_val); let polarity = match polarity { ImplPolarity::Positive => ImplPolarity::Positive, - ImplPolarity::Negative(s) => ImplPolarity::Negative(self.lower_span(s)), + ImplPolarity::Negative(s) => ImplPolarity::Negative(self.lower_span(*s)), }; hir::ItemKind::Impl(self.arena.alloc(hir::Impl { - unsafety: self.lower_unsafety(unsafety), + unsafety: self.lower_unsafety(*unsafety), polarity, defaultness, defaultness_span, - constness: self.lower_constness(constness), + constness: self.lower_constness(*constness), generics, of_trait: trait_ref, self_ty: lowered_ty, items: new_impl_items, })) } - ItemKind::Trait(box Trait { - is_auto, - unsafety, - ref generics, - ref bounds, - ref items, - }) => { + ItemKind::Trait(box Trait { is_auto, unsafety, generics, bounds, items }) => { let (generics, (unsafety, items, bounds)) = self.lower_generics( generics, id, @@ -450,13 +424,13 @@ impl<'hir> LoweringContext<'_, 'hir> { let items = this.arena.alloc_from_iter( items.iter().map(|item| this.lower_trait_item_ref(item)), ); - let unsafety = this.lower_unsafety(unsafety); + let unsafety = this.lower_unsafety(*unsafety); (unsafety, items, bounds) }, ); - hir::ItemKind::Trait(is_auto, unsafety, generics, bounds, items) + hir::ItemKind::Trait(*is_auto, unsafety, generics, bounds, items) } - ItemKind::TraitAlias(ref generics, ref bounds) => { + ItemKind::TraitAlias(generics, bounds) => { let (generics, bounds) = self.lower_generics( generics, id, @@ -470,10 +444,10 @@ impl<'hir> LoweringContext<'_, 'hir> { ); hir::ItemKind::TraitAlias(generics, bounds) } - ItemKind::MacroDef(MacroDef { ref body, macro_rules }) => { - let body = P(self.lower_mac_args(body)); + ItemKind::MacroDef(MacroDef { body, macro_rules }) => { + let body = P(self.lower_delim_args(body)); let macro_kind = self.resolver.decl_macro_kind(self.local_def_id(id)); - hir::ItemKind::Macro(ast::MacroDef { body, macro_rules }, macro_kind) + hir::ItemKind::Macro(ast::MacroDef { body, macro_rules: *macro_rules }, macro_kind) } ItemKind::MacCall(..) => { panic!("`TyMac` should have been expanded by now") @@ -505,7 +479,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let segments = prefix.segments.iter().chain(path.segments.iter()).cloned().collect(); match tree.kind { - UseTreeKind::Simple(rename, id1, id2) => { + UseTreeKind::Simple(rename) => { *ident = tree.ident(); // First, apply the prefix to the path. @@ -521,66 +495,16 @@ impl<'hir> LoweringContext<'_, 'hir> { } } - let mut resolutions = self.expect_full_res_from_use(id).fuse(); - // We want to return *something* from this function, so hold onto the first item - // for later. - let ret_res = self.lower_res(resolutions.next().unwrap_or(Res::Err)); - - // Here, we are looping over namespaces, if they exist for the definition - // being imported. We only handle type and value namespaces because we - // won't be dealing with macros in the rest of the compiler. - // Essentially a single `use` which imports two names is desugared into - // two imports. - for new_node_id in [id1, id2] { - let new_id = self.local_def_id(new_node_id); - let Some(res) = resolutions.next() else { - // Associate an HirId to both ids even if there is no resolution. - let _old = self.children.insert( - new_id, - hir::MaybeOwner::NonOwner(hir::HirId::make_owner(new_id)), - ); - debug_assert!(_old.is_none()); - continue; - }; - let ident = *ident; - let mut path = path.clone(); - for seg in &mut path.segments { - // Give the cloned segment the same resolution information - // as the old one (this is needed for stability checking). - let new_id = self.next_node_id(); - self.resolver.clone_res(seg.id, new_id); - seg.id = new_id; - } - let span = path.span; - - self.with_hir_id_owner(new_node_id, |this| { - let res = this.lower_res(res); - let path = this.lower_path_extra(res, &path, ParamMode::Explicit); - let kind = hir::ItemKind::Use(path, hir::UseKind::Single); - if let Some(attrs) = attrs { - this.attrs.insert(hir::ItemLocalId::new(0), attrs); - } - - let item = hir::Item { - owner_id: hir::OwnerId { def_id: new_id }, - ident: this.lower_ident(ident), - kind, - vis_span, - span: this.lower_span(span), - }; - hir::OwnerNode::Item(this.arena.alloc(item)) - }); - } - - let path = self.lower_path_extra(ret_res, &path, ParamMode::Explicit); + let res = + self.expect_full_res_from_use(id).map(|res| self.lower_res(res)).collect(); + let path = self.lower_use_path(res, &path, ParamMode::Explicit); hir::ItemKind::Use(path, hir::UseKind::Single) } UseTreeKind::Glob => { - let path = self.lower_path( - id, - &Path { segments, span: path.span, tokens: None }, - ParamMode::Explicit, - ); + let res = self.expect_full_res(id); + let res = smallvec![self.lower_res(res)]; + let path = Path { segments, span: path.span, tokens: None }; + let path = self.lower_use_path(res, &path, ParamMode::Explicit); hir::ItemKind::Use(path, hir::UseKind::Glob) } UseTreeKind::Nested(ref trees) => { @@ -650,9 +574,9 @@ impl<'hir> LoweringContext<'_, 'hir> { }); } - let res = self.expect_full_res_from_use(id).next().unwrap_or(Res::Err); - let res = self.lower_res(res); - let path = self.lower_path_extra(res, &prefix, ParamMode::Explicit); + let res = + self.expect_full_res_from_use(id).map(|res| self.lower_res(res)).collect(); + let path = self.lower_use_path(res, &prefix, ParamMode::Explicit); hir::ItemKind::Use(path, hir::UseKind::ListStem) } } @@ -665,8 +589,8 @@ impl<'hir> LoweringContext<'_, 'hir> { let item = hir::ForeignItem { owner_id, ident: self.lower_ident(i.ident), - kind: match i.kind { - ForeignItemKind::Fn(box Fn { ref sig, ref generics, .. }) => { + kind: match &i.kind { + ForeignItemKind::Fn(box Fn { sig, generics, .. }) => { let fdec = &sig.decl; let mut itctx = ImplTraitContext::Universal; let (generics, (fn_dec, fn_args)) = @@ -675,7 +599,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // Disallow `impl Trait` in foreign items. this.lower_fn_decl( fdec, - None, + i.id, sig.span, FnDeclKind::ExternFn, None, @@ -686,10 +610,10 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::ForeignItemKind::Fn(fn_dec, fn_args, generics) } - ForeignItemKind::Static(ref t, m, _) => { + ForeignItemKind::Static(t, m, _) => { let ty = self.lower_ty(t, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)); - hir::ForeignItemKind::Static(ty, m) + hir::ForeignItemKind::Static(ty, *m) } ForeignItemKind::TyAlias(..) => hir::ForeignItemKind::Type, ForeignItemKind::MacCall(_) => panic!("macro shouldn't exist here"), @@ -709,11 +633,12 @@ impl<'hir> LoweringContext<'_, 'hir> { } fn lower_variant(&mut self, v: &Variant) -> hir::Variant<'hir> { - let id = self.lower_node_id(v.id); - self.lower_attrs(id, &v.attrs); + let hir_id = self.lower_node_id(v.id); + self.lower_attrs(hir_id, &v.attrs); hir::Variant { - id, - data: self.lower_variant_data(id, &v.data), + hir_id, + def_id: self.local_def_id(v.id), + data: self.lower_variant_data(hir_id, &v.data), disr_expr: v.disr_expr.as_ref().map(|e| self.lower_anon_const(e)), ident: self.lower_ident(v.ident), span: self.lower_span(v.span), @@ -725,32 +650,33 @@ impl<'hir> LoweringContext<'_, 'hir> { parent_id: hir::HirId, vdata: &VariantData, ) -> hir::VariantData<'hir> { - match *vdata { - VariantData::Struct(ref fields, recovered) => hir::VariantData::Struct( + match vdata { + VariantData::Struct(fields, recovered) => hir::VariantData::Struct( self.arena .alloc_from_iter(fields.iter().enumerate().map(|f| self.lower_field_def(f))), - recovered, + *recovered, ), - VariantData::Tuple(ref fields, id) => { - let ctor_id = self.lower_node_id(id); + VariantData::Tuple(fields, id) => { + let ctor_id = self.lower_node_id(*id); self.alias_attrs(ctor_id, parent_id); hir::VariantData::Tuple( self.arena.alloc_from_iter( fields.iter().enumerate().map(|f| self.lower_field_def(f)), ), ctor_id, + self.local_def_id(*id), ) } VariantData::Unit(id) => { - let ctor_id = self.lower_node_id(id); + let ctor_id = self.lower_node_id(*id); self.alias_attrs(ctor_id, parent_id); - hir::VariantData::Unit(ctor_id) + hir::VariantData::Unit(ctor_id, self.local_def_id(*id)) } } } fn lower_field_def(&mut self, (index, f): (usize, &FieldDef)) -> hir::FieldDef<'hir> { - let ty = if let TyKind::Path(ref qself, ref path) = f.ty.kind { + let ty = if let TyKind::Path(qself, path) = &f.ty.kind { let t = self.lower_path_ty( &f.ty, qself, @@ -767,6 +693,7 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::FieldDef { span: self.lower_span(f.span), hir_id, + def_id: self.local_def_id(f.id), ident: match f.ident { Some(ident) => self.lower_ident(ident), // FIXME(jseyfried): positional field hygiene. @@ -779,15 +706,16 @@ impl<'hir> LoweringContext<'_, 'hir> { fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> { let hir_id = self.lower_node_id(i.id); + self.lower_attrs(hir_id, &i.attrs); let trait_item_def_id = hir_id.expect_owner(); - let (generics, kind, has_default) = match i.kind { - AssocItemKind::Const(_, ref ty, ref default) => { + let (generics, kind, has_default) = match &i.kind { + AssocItemKind::Const(_, ty, default) => { let ty = self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)); let body = default.as_ref().map(|x| self.lower_const_body(i.span, Some(x))); (hir::Generics::empty(), hir::TraitItemKind::Const(ty, body), body.is_some()) } - AssocItemKind::Fn(box Fn { ref sig, ref generics, body: None, .. }) => { + AssocItemKind::Fn(box Fn { sig, generics, body: None, .. }) => { let asyncness = sig.header.asyncness; let names = self.lower_fn_params_to_names(&sig.decl); let (generics, sig) = self.lower_method_sig( @@ -799,10 +727,10 @@ impl<'hir> LoweringContext<'_, 'hir> { ); (generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(names)), false) } - AssocItemKind::Fn(box Fn { ref sig, ref generics, body: Some(ref body), .. }) => { + AssocItemKind::Fn(box Fn { sig, generics, body: Some(body), .. }) => { let asyncness = sig.header.asyncness; let body_id = - self.lower_maybe_async_body(i.span, &sig.decl, asyncness, Some(&body)); + self.lower_maybe_async_body(i.span, hir_id, &sig.decl, asyncness, Some(&body)); let (generics, sig) = self.lower_method_sig( generics, sig, @@ -812,15 +740,9 @@ impl<'hir> LoweringContext<'_, 'hir> { ); (generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id)), true) } - AssocItemKind::Type(box TyAlias { - ref generics, - where_clauses, - ref bounds, - ref ty, - .. - }) => { + AssocItemKind::Type(box TyAlias { generics, where_clauses, bounds, ty, .. }) => { let mut generics = generics.clone(); - add_ty_alias_where_clause(&mut generics, where_clauses, false); + add_ty_alias_where_clause(&mut generics, *where_clauses, false); let (generics, kind) = self.lower_generics( &generics, i.id, @@ -843,7 +765,6 @@ impl<'hir> LoweringContext<'_, 'hir> { AssocItemKind::MacCall(..) => panic!("macro item shouldn't exist at this point"), }; - self.lower_attrs(hir_id, &i.attrs); let item = hir::TraitItem { owner_id: trait_item_def_id, ident: self.lower_ident(i.ident), @@ -875,13 +796,15 @@ impl<'hir> LoweringContext<'_, 'hir> { /// Construct `ExprKind::Err` for the given `span`. pub(crate) fn expr_err(&mut self, span: Span) -> hir::Expr<'hir> { - self.expr(span, hir::ExprKind::Err, AttrVec::new()) + self.expr(span, hir::ExprKind::Err) } fn lower_impl_item(&mut self, i: &AssocItem) -> &'hir hir::ImplItem<'hir> { // Since `default impl` is not yet implemented, this is always true in impls. let has_value = true; let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value); + let hir_id = self.lower_node_id(i.id); + self.lower_attrs(hir_id, &i.attrs); let (generics, kind) = match &i.kind { AssocItemKind::Const(_, ty, expr) => { @@ -894,8 +817,13 @@ impl<'hir> LoweringContext<'_, 'hir> { AssocItemKind::Fn(box Fn { sig, generics, body, .. }) => { self.current_item = Some(i.span); let asyncness = sig.header.asyncness; - let body_id = - self.lower_maybe_async_body(i.span, &sig.decl, asyncness, body.as_deref()); + let body_id = self.lower_maybe_async_body( + i.span, + hir_id, + &sig.decl, + asyncness, + body.as_deref(), + ); let (generics, sig) = self.lower_method_sig( generics, sig, @@ -928,8 +856,6 @@ impl<'hir> LoweringContext<'_, 'hir> { AssocItemKind::MacCall(..) => panic!("`TyMac` should have been expanded by now"), }; - let hir_id = self.lower_node_id(i.id); - self.lower_attrs(hir_id, &i.attrs); let item = hir::ImplItem { owner_id: hir_id.expect_owner(), ident: self.lower_ident(i.ident), @@ -1062,6 +988,7 @@ impl<'hir> LoweringContext<'_, 'hir> { fn lower_maybe_async_body( &mut self, span: Span, + fn_id: hir::HirId, decl: &FnDecl, asyncness: Async, body: Option<&Block>, @@ -1212,6 +1139,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let async_expr = this.make_async_expr( CaptureBy::Value, + Some(fn_id), closure_id, None, body.span, @@ -1223,11 +1151,8 @@ impl<'hir> LoweringContext<'_, 'hir> { // Transform into `drop-temps { <user-body> }`, an expression: let desugared_span = this.mark_span_with_reason(DesugaringKind::Async, user_body.span, None); - let user_body = this.expr_drop_temps( - desugared_span, - this.arena.alloc(user_body), - AttrVec::new(), - ); + let user_body = + this.expr_drop_temps(desugared_span, this.arena.alloc(user_body)); // As noted above, create the final block like // @@ -1244,14 +1169,11 @@ impl<'hir> LoweringContext<'_, 'hir> { Some(user_body), ); - this.expr_block(body, AttrVec::new()) + this.expr_block(body) }, ); - ( - this.arena.alloc_from_iter(parameters), - this.expr(body.span, async_expr, AttrVec::new()), - ) + (this.arena.alloc_from_iter(parameters), this.expr(body.span, async_expr)) }) } @@ -1266,7 +1188,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let header = self.lower_fn_header(sig.header); let mut itctx = ImplTraitContext::Universal; let (generics, decl) = self.lower_generics(generics, id, &mut itctx, |this| { - this.lower_fn_decl(&sig.decl, Some(id), sig.span, kind, is_async) + this.lower_fn_decl(&sig.decl, id, sig.span, kind, is_async) }); (generics, hir::FnSig { header, decl, span: self.lower_span(sig.span) }) } @@ -1352,7 +1274,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // keep track of the Span info. Now, `add_implicitly_sized` in `AstConv` checks both param bounds and // where clauses for `?Sized`. for pred in &generics.where_clause.predicates { - let WherePredicate::BoundPredicate(ref bound_pred) = *pred else { + let WherePredicate::BoundPredicate(bound_pred) = pred else { continue; }; let compute_is_param = || { @@ -1498,10 +1420,9 @@ impl<'hir> LoweringContext<'_, 'hir> { })) } GenericParamKind::Lifetime => { - let ident_span = self.lower_span(ident.span); let ident = self.lower_ident(ident); let lt_id = self.next_node_id(); - let lifetime = self.new_named_lifetime(id, lt_id, ident_span, ident); + let lifetime = self.new_named_lifetime(id, lt_id, ident); Some(hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate { lifetime, span, @@ -1513,11 +1434,11 @@ impl<'hir> LoweringContext<'_, 'hir> { } fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicate<'hir> { - match *pred { + match pred { WherePredicate::BoundPredicate(WhereBoundPredicate { - ref bound_generic_params, - ref bounded_ty, - ref bounds, + bound_generic_params, + bounded_ty, + bounds, span, }) => hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate { hir_id: self.next_id(), @@ -1530,29 +1451,27 @@ impl<'hir> LoweringContext<'_, 'hir> { &ImplTraitContext::Disallowed(ImplTraitPosition::Bound), ) })), - span: self.lower_span(span), + span: self.lower_span(*span), origin: PredicateOrigin::WhereClause, }), - WherePredicate::RegionPredicate(WhereRegionPredicate { - ref lifetime, - ref bounds, - span, - }) => hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate { - span: self.lower_span(span), - lifetime: self.lower_lifetime(lifetime), - bounds: self.lower_param_bounds( - bounds, - &ImplTraitContext::Disallowed(ImplTraitPosition::Bound), - ), - in_where_clause: true, - }), - WherePredicate::EqPredicate(WhereEqPredicate { ref lhs_ty, ref rhs_ty, span }) => { + WherePredicate::RegionPredicate(WhereRegionPredicate { lifetime, bounds, span }) => { + hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate { + span: self.lower_span(*span), + lifetime: self.lower_lifetime(lifetime), + bounds: self.lower_param_bounds( + bounds, + &ImplTraitContext::Disallowed(ImplTraitPosition::Bound), + ), + in_where_clause: true, + }) + } + WherePredicate::EqPredicate(WhereEqPredicate { lhs_ty, rhs_ty, span }) => { hir::WherePredicate::EqPredicate(hir::WhereEqPredicate { lhs_ty: self .lower_ty(lhs_ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)), rhs_ty: self .lower_ty(rhs_ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)), - span: self.lower_span(span), + span: self.lower_span(*span), }) } } diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index ff29d15f1..4fa18907f 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -34,7 +34,6 @@ #![feature(let_chains)] #![feature(never_type)] #![recursion_limit = "256"] -#![allow(rustc::potential_query_instability)] #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] @@ -61,8 +60,8 @@ use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID}; use rustc_hir::definitions::DefPathData; use rustc_hir::{ConstArg, GenericArg, ItemLocalId, ParamName, TraitCandidate}; use rustc_index::vec::{Idx, IndexVec}; +use rustc_middle::span_bug; use rustc_middle::ty::{ResolverAstLowering, TyCtxt}; -use rustc_middle::{bug, span_bug}; use rustc_session::parse::feature_err; use rustc_span::hygiene::MacroKind; use rustc_span::source_map::DesugaringKind; @@ -107,7 +106,7 @@ struct LoweringContext<'a, 'hir> { /// Attributes inside the owner being lowered. attrs: SortedMap<hir::ItemLocalId, &'hir [Attribute]>, /// Collect items that were created by lowering the current owner. - children: FxHashMap<LocalDefId, hir::MaybeOwner<&'hir hir::OwnerInfo<'hir>>>, + children: Vec<(LocalDefId, hir::MaybeOwner<&'hir hir::OwnerInfo<'hir>>)>, generator_kind: Option<hir::GeneratorKind>, @@ -260,6 +259,8 @@ enum ImplTraitContext { }, /// Impl trait in type aliases. TypeAliasesOpaqueTy, + /// `impl Trait` is unstably accepted in this position. + FeatureGated(ImplTraitPosition, Symbol), /// `impl Trait` is not accepted in this position. Disallowed(ImplTraitPosition), } @@ -328,7 +329,14 @@ enum FnDeclKind { } impl FnDeclKind { - fn impl_trait_allowed(&self, tcx: TyCtxt<'_>) -> bool { + fn param_impl_trait_allowed(&self) -> bool { + match self { + FnDeclKind::Fn | FnDeclKind::Inherent | FnDeclKind::Impl | FnDeclKind::Trait => true, + _ => false, + } + } + + fn return_impl_trait_allowed(&self, tcx: TyCtxt<'_>) -> bool { match self { FnDeclKind::Fn | FnDeclKind::Inherent => true, FnDeclKind::Impl if tcx.features().return_position_impl_trait_in_trait => true, @@ -481,6 +489,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { parent: LocalDefId, node_id: ast::NodeId, data: DefPathData, + span: Span, ) -> LocalDefId { debug_assert_ne!(node_id, ast::DUMMY_NODE_ID); assert!( @@ -491,7 +500,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.tcx.hir().def_key(self.local_def_id(node_id)), ); - let def_id = self.tcx.create_def(parent, data); + let def_id = self.tcx.at(span).create_def(parent, data).def_id(); debug!("create_def: def_id_to_node_id[{:?}] <-> {:?}", def_id, node_id); self.resolver.node_id_to_def_id.insert(node_id, def_id); @@ -611,8 +620,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.impl_trait_defs = current_impl_trait_defs; self.impl_trait_bounds = current_impl_trait_bounds; - let _old = self.children.insert(def_id, hir::MaybeOwner::Owner(info)); - debug_assert!(_old.is_none()) + debug_assert!(self.children.iter().find(|(id, _)| id == &def_id).is_none()); + self.children.push((def_id, hir::MaybeOwner::Owner(info))); } /// Installs the remapping `remap` in scope while `f` is being executed. @@ -719,8 +728,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { assert_ne!(local_id, hir::ItemLocalId::new(0)); if let Some(def_id) = self.opt_local_def_id(ast_node_id) { - // Do not override a `MaybeOwner::Owner` that may already here. - self.children.entry(def_id).or_insert(hir::MaybeOwner::NonOwner(hir_id)); + self.children.push((def_id, hir::MaybeOwner::NonOwner(hir_id))); self.local_id_to_def_id.insert(local_id, def_id); } @@ -818,6 +826,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.current_hir_id_owner.def_id, param, DefPathData::LifetimeNs(kw::UnderscoreLifetime), + ident.span, ); debug!(?_def_id); @@ -830,8 +839,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ), }; let hir_id = self.lower_node_id(node_id); + let def_id = self.local_def_id(node_id); Some(hir::GenericParam { hir_id, + def_id, name, span: self.lower_span(ident.span), pure_wrt_drop: false, @@ -911,7 +922,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { AttrKind::Normal(ref normal) => AttrKind::Normal(P(NormalAttr { item: AttrItem { path: normal.item.path.clone(), - args: self.lower_mac_args(&normal.item.args), + args: self.lower_attr_args(&normal.item.args), tokens: None, }, tokens: None, @@ -931,51 +942,39 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } - fn lower_mac_args(&self, args: &MacArgs) -> MacArgs { - match *args { - MacArgs::Empty => MacArgs::Empty, - MacArgs::Delimited(dspan, delim, ref tokens) => { - // This is either a non-key-value attribute, or a `macro_rules!` body. - // We either not have any nonterminals present (in the case of an attribute), - // or have tokens available for all nonterminals in the case of a nested - // `macro_rules`: e.g: - // - // ```rust - // macro_rules! outer { - // ($e:expr) => { - // macro_rules! inner { - // () => { $e } - // } - // } - // } - // ``` - // - // In both cases, we don't want to synthesize any tokens - MacArgs::Delimited(dspan, delim, tokens.flattened()) - } + fn lower_attr_args(&self, args: &AttrArgs) -> AttrArgs { + match args { + AttrArgs::Empty => AttrArgs::Empty, + AttrArgs::Delimited(args) => AttrArgs::Delimited(self.lower_delim_args(args)), // This is an inert key-value attribute - it will never be visible to macros // after it gets lowered to HIR. Therefore, we can extract literals to handle // nonterminals in `#[doc]` (e.g. `#[doc = $e]`). - MacArgs::Eq(eq_span, MacArgsEq::Ast(ref expr)) => { + AttrArgs::Eq(eq_span, AttrArgsEq::Ast(expr)) => { // In valid code the value always ends up as a single literal. Otherwise, a dummy // literal suffices because the error is handled elsewhere. - let lit = if let ExprKind::Lit(lit) = &expr.kind { - lit.clone() + let lit = if let ExprKind::Lit(token_lit) = expr.kind + && let Ok(lit) = MetaItemLit::from_token_lit(token_lit, expr.span) + { + lit } else { - Lit { + MetaItemLit { token_lit: token::Lit::new(token::LitKind::Err, kw::Empty, None), kind: LitKind::Err, span: DUMMY_SP, } }; - MacArgs::Eq(eq_span, MacArgsEq::Hir(lit)) + AttrArgs::Eq(*eq_span, AttrArgsEq::Hir(lit)) } - MacArgs::Eq(_, MacArgsEq::Hir(ref lit)) => { + AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => { unreachable!("in literal form when lowering mac args eq: {:?}", lit) } } } + fn lower_delim_args(&self, args: &DelimArgs) -> DelimArgs { + DelimArgs { dspan: args.dspan, delim: args.delim, tokens: args.tokens.flattened() } + } + /// Given an associated type constraint like one of these: /// /// ```ignore (illustrative) @@ -994,12 +993,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ) -> hir::TypeBinding<'hir> { debug!("lower_assoc_ty_constraint(constraint={:?}, itctx={:?})", constraint, itctx); // lower generic arguments of identifier in constraint - let gen_args = if let Some(ref gen_args) = constraint.gen_args { + let gen_args = if let Some(gen_args) = &constraint.gen_args { let gen_args_ctor = match gen_args { - GenericArgs::AngleBracketed(ref data) => { + GenericArgs::AngleBracketed(data) => { self.lower_angle_bracketed_parameter_data(data, ParamMode::Explicit, itctx).0 } - GenericArgs::Parenthesized(ref data) => { + GenericArgs::Parenthesized(data) => { self.emit_bad_parenthesized_trait_in_assoc_ty(data); let aba = self.ast_arena.aba.alloc(data.as_angle_bracketed_args()); self.lower_angle_bracketed_parameter_data(aba, ParamMode::Explicit, itctx).0 @@ -1011,15 +1010,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { }; let itctx_tait = &ImplTraitContext::TypeAliasesOpaqueTy; - let kind = match constraint.kind { - AssocConstraintKind::Equality { ref term } => { + let kind = match &constraint.kind { + AssocConstraintKind::Equality { term } => { let term = match term { - Term::Ty(ref ty) => self.lower_ty(ty, itctx).into(), - Term::Const(ref c) => self.lower_anon_const(c).into(), + Term::Ty(ty) => self.lower_ty(ty, itctx).into(), + Term::Const(c) => self.lower_anon_const(c).into(), }; hir::TypeBindingKind::Equality { term } } - AssocConstraintKind::Bound { ref bounds } => { + AssocConstraintKind::Bound { bounds } => { // Piggy-back on the `impl Trait` context to figure out the correct behavior. let (desugar_to_impl_trait, itctx) = match itctx { // We are in the return position: @@ -1129,7 +1128,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { match arg { ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(<)), ast::GenericArg::Type(ty) => { - match ty.kind { + match &ty.kind { TyKind::Infer if self.tcx.features().generic_arg_infer => { return GenericArg::Infer(hir::InferArg { hir_id: self.lower_node_id(ty.id), @@ -1140,7 +1139,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // parsing. We try to resolve that ambiguity by attempting resolution in both the // type and value namespaces. If we resolved the path in the value namespace, we // transform it into a generic const argument. - TyKind::Path(ref qself, ref path) => { + TyKind::Path(qself, path) => { if let Some(res) = self .resolver .get_partial_res(ty.id) @@ -1156,15 +1155,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let parent_def_id = self.current_hir_id_owner; let node_id = self.next_node_id(); + let span = self.lower_span(ty.span); // Add a definition for the in-band const def. - self.create_def( + let def_id = self.create_def( parent_def_id.def_id, node_id, DefPathData::AnonConst, + span, ); - let span = self.lower_span(ty.span); let path_expr = Expr { id: ty.id, kind: ExprKind::Path(qself.clone(), path.clone()), @@ -1174,6 +1174,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { }; let ct = self.with_new_scopes(|this| hir::AnonConst { + def_id, hir_id: this.lower_node_id(node_id), body: this.lower_const_body(path_expr.span, Some(&path_expr)), }); @@ -1200,7 +1201,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn lower_path_ty( &mut self, t: &Ty, - qself: &Option<QSelf>, + qself: &Option<ptr::P<QSelf>>, path: &Path, param_mode: ParamMode, itctx: &ImplTraitContext, @@ -1246,12 +1247,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } fn lower_ty_direct(&mut self, t: &Ty, itctx: &ImplTraitContext) -> hir::Ty<'hir> { - let kind = match t.kind { + let kind = match &t.kind { TyKind::Infer => hir::TyKind::Infer, TyKind::Err => hir::TyKind::Err, - TyKind::Slice(ref ty) => hir::TyKind::Slice(self.lower_ty(ty, itctx)), - TyKind::Ptr(ref mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)), - TyKind::Rptr(ref region, ref mt) => { + TyKind::Slice(ty) => hir::TyKind::Slice(self.lower_ty(ty, itctx)), + TyKind::Ptr(mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)), + TyKind::Rptr(region, mt) => { let region = region.unwrap_or_else(|| { let id = if let Some(LifetimeRes::ElidedAnchor { start, end }) = self.resolver.get_lifetime_res(t.id) @@ -1261,30 +1262,30 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } else { self.next_node_id() }; - let span = self.tcx.sess.source_map().start_point(t.span); + let span = self.tcx.sess.source_map().start_point(t.span).shrink_to_hi(); Lifetime { ident: Ident::new(kw::UnderscoreLifetime, span), id } }); let lifetime = self.lower_lifetime(®ion); hir::TyKind::Rptr(lifetime, self.lower_mt(mt, itctx)) } - TyKind::BareFn(ref f) => { + TyKind::BareFn(f) => { let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params); hir::TyKind::BareFn(self.arena.alloc(hir::BareFnTy { generic_params, unsafety: self.lower_unsafety(f.unsafety), abi: self.lower_extern(f.ext), - decl: self.lower_fn_decl(&f.decl, None, t.span, FnDeclKind::Pointer, None), + decl: self.lower_fn_decl(&f.decl, t.id, t.span, FnDeclKind::Pointer, None), param_names: self.lower_fn_params_to_names(&f.decl), })) } TyKind::Never => hir::TyKind::Never, - TyKind::Tup(ref tys) => hir::TyKind::Tup( + TyKind::Tup(tys) => hir::TyKind::Tup( self.arena.alloc_from_iter(tys.iter().map(|ty| self.lower_ty_direct(ty, itctx))), ), - TyKind::Paren(ref ty) => { + TyKind::Paren(ty) => { return self.lower_ty_direct(ty, itctx); } - TyKind::Path(ref qself, ref path) => { + TyKind::Path(qself, path) => { return self.lower_path_ty(t, qself, path, ParamMode::Explicit, itctx); } TyKind::ImplicitSelf => { @@ -1304,48 +1305,46 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { }), )) } - TyKind::Array(ref ty, ref length) => { + TyKind::Array(ty, length) => { hir::TyKind::Array(self.lower_ty(ty, itctx), self.lower_array_length(length)) } - TyKind::Typeof(ref expr) => hir::TyKind::Typeof(self.lower_anon_const(expr)), - TyKind::TraitObject(ref bounds, kind) => { + TyKind::Typeof(expr) => hir::TyKind::Typeof(self.lower_anon_const(expr)), + TyKind::TraitObject(bounds, kind) => { let mut lifetime_bound = None; let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| { let bounds = - this.arena.alloc_from_iter(bounds.iter().filter_map( - |bound| match *bound { - GenericBound::Trait( - ref ty, - TraitBoundModifier::None | TraitBoundModifier::MaybeConst, - ) => Some(this.lower_poly_trait_ref(ty, itctx)), - // `~const ?Bound` will cause an error during AST validation - // anyways, so treat it like `?Bound` as compilation proceeds. - GenericBound::Trait( - _, - TraitBoundModifier::Maybe | TraitBoundModifier::MaybeConstMaybe, - ) => None, - GenericBound::Outlives(ref lifetime) => { - if lifetime_bound.is_none() { - lifetime_bound = Some(this.lower_lifetime(lifetime)); - } - None + this.arena.alloc_from_iter(bounds.iter().filter_map(|bound| match bound { + GenericBound::Trait( + ty, + TraitBoundModifier::None | TraitBoundModifier::MaybeConst, + ) => Some(this.lower_poly_trait_ref(ty, itctx)), + // `~const ?Bound` will cause an error during AST validation + // anyways, so treat it like `?Bound` as compilation proceeds. + GenericBound::Trait( + _, + TraitBoundModifier::Maybe | TraitBoundModifier::MaybeConstMaybe, + ) => None, + GenericBound::Outlives(lifetime) => { + if lifetime_bound.is_none() { + lifetime_bound = Some(this.lower_lifetime(lifetime)); } - }, - )); + None + } + })); let lifetime_bound = lifetime_bound.unwrap_or_else(|| this.elided_dyn_bound(t.span)); (bounds, lifetime_bound) }); - hir::TyKind::TraitObject(bounds, lifetime_bound, kind) + hir::TyKind::TraitObject(bounds, lifetime_bound, *kind) } - TyKind::ImplTrait(def_node_id, ref bounds) => { + TyKind::ImplTrait(def_node_id, bounds) => { let span = t.span; match itctx { ImplTraitContext::ReturnPositionOpaqueTy { origin, in_trait } => self .lower_opaque_impl_trait( span, *origin, - def_node_id, + *def_node_id, bounds, *in_trait, itctx, @@ -1353,38 +1352,37 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ImplTraitContext::TypeAliasesOpaqueTy => self.lower_opaque_impl_trait( span, hir::OpaqueTyOrigin::TyAlias, - def_node_id, + *def_node_id, bounds, false, itctx, ), ImplTraitContext::Universal => { + let span = t.span; self.create_def( self.current_hir_id_owner.def_id, - def_node_id, + *def_node_id, DefPathData::ImplTrait, + span, ); - let span = t.span; let ident = Ident::from_str_and_span(&pprust::ty_to_string(t), span); let (param, bounds, path) = - self.lower_generic_and_bounds(def_node_id, span, ident, bounds); + self.lower_generic_and_bounds(*def_node_id, span, ident, bounds); self.impl_trait_defs.push(param); if let Some(bounds) = bounds { self.impl_trait_bounds.push(bounds); } path } - ImplTraitContext::Disallowed( - position @ (ImplTraitPosition::TraitReturn | ImplTraitPosition::ImplReturn), - ) => { + ImplTraitContext::FeatureGated(position, feature) => { self.tcx .sess .create_feature_err( MisplacedImplTrait { span: t.span, - position: DiagnosticArgFromDisplay(&position), + position: DiagnosticArgFromDisplay(position), }, - sym::return_position_impl_trait_in_trait, + *feature, ) .emit(); hir::TyKind::Err @@ -1392,7 +1390,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ImplTraitContext::Disallowed(position) => { self.tcx.sess.emit_err(MisplacedImplTrait { span: t.span, - position: DiagnosticArgFromDisplay(&position), + position: DiagnosticArgFromDisplay(position), }); hir::TyKind::Err } @@ -1457,17 +1455,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // frequently opened issues show. let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None); - let opaque_ty_def_id = match origin { - hir::OpaqueTyOrigin::TyAlias => self.create_def( - self.current_hir_id_owner.def_id, - opaque_ty_node_id, - DefPathData::ImplTrait, - ), - hir::OpaqueTyOrigin::FnReturn(fn_def_id) => { - self.create_def(fn_def_id, opaque_ty_node_id, DefPathData::ImplTrait) - } - hir::OpaqueTyOrigin::AsyncFn(..) => bug!("unreachable"), - }; + let opaque_ty_def_id = self.create_def( + self.current_hir_id_owner.def_id, + opaque_ty_node_id, + DefPathData::ImplTrait, + opaque_ty_span, + ); debug!(?opaque_ty_def_id); // Contains the new lifetime definitions created for the TAIT (if any). @@ -1521,6 +1514,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { hir::GenericParam { hir_id, + def_id: lctx.local_def_id(new_node_id), name, span: lifetime.ident.span, pure_wrt_drop: false, @@ -1559,15 +1553,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let lifetimes = self.arena.alloc_from_iter(collected_lifetimes.into_iter().map(|(_, lifetime)| { let id = self.next_node_id(); - let span = lifetime.ident.span; - - let ident = if lifetime.ident.name == kw::UnderscoreLifetime { - Ident::with_dummy_span(kw::UnderscoreLifetime) - } else { - lifetime.ident - }; - - let l = self.new_named_lifetime(lifetime.id, id, span, ident); + let l = self.new_named_lifetime(lifetime.id, id, lifetime.ident); hir::GenericArg::Lifetime(l) })); debug!(?lifetimes); @@ -1627,6 +1613,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { parent_def_id, node_id, DefPathData::LifetimeNs(lifetime.ident.name), + lifetime.ident.span, ); remapping.insert(old_def_id, new_def_id); @@ -1643,6 +1630,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { parent_def_id, node_id, DefPathData::LifetimeNs(kw::UnderscoreLifetime), + lifetime.ident.span, ); remapping.insert(old_def_id, new_def_id); @@ -1692,7 +1680,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn lower_fn_decl( &mut self, decl: &FnDecl, - fn_node_id: Option<NodeId>, + fn_node_id: NodeId, fn_span: Span, kind: FnDeclKind, make_ret_async: Option<(NodeId, Span)>, @@ -1707,23 +1695,21 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { inputs = &inputs[..inputs.len() - 1]; } let inputs = self.arena.alloc_from_iter(inputs.iter().map(|param| { - if fn_node_id.is_some() { - self.lower_ty_direct(¶m.ty, &ImplTraitContext::Universal) + let itctx = if kind.param_impl_trait_allowed() { + ImplTraitContext::Universal } else { - self.lower_ty_direct( - ¶m.ty, - &ImplTraitContext::Disallowed(match kind { - FnDeclKind::Fn | FnDeclKind::Inherent => { - unreachable!("fn should allow in-band lifetimes") - } - FnDeclKind::ExternFn => ImplTraitPosition::ExternFnParam, - FnDeclKind::Closure => ImplTraitPosition::ClosureParam, - FnDeclKind::Pointer => ImplTraitPosition::PointerParam, - FnDeclKind::Trait => ImplTraitPosition::TraitParam, - FnDeclKind::Impl => ImplTraitPosition::ImplParam, - }), - ) - } + ImplTraitContext::Disallowed(match kind { + FnDeclKind::Fn | FnDeclKind::Inherent => { + unreachable!("fn should allow APIT") + } + FnDeclKind::ExternFn => ImplTraitPosition::ExternFnParam, + FnDeclKind::Closure => ImplTraitPosition::ClosureParam, + FnDeclKind::Pointer => ImplTraitPosition::PointerParam, + FnDeclKind::Trait => ImplTraitPosition::TraitParam, + FnDeclKind::Impl => ImplTraitPosition::ImplParam, + }) + }; + self.lower_ty_direct(¶m.ty, &itctx) })); let output = if let Some((ret_id, span)) = make_ret_async { @@ -1746,22 +1732,21 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.lower_async_fn_ret_ty( &decl.output, - fn_node_id.expect("`make_ret_async` but no `fn_def_id`"), + fn_node_id, ret_id, matches!(kind, FnDeclKind::Trait), ) } else { - match decl.output { - FnRetTy::Ty(ref ty) => { - let mut context = match fn_node_id { - Some(fn_node_id) if kind.impl_trait_allowed(self.tcx) => { - let fn_def_id = self.local_def_id(fn_node_id); - ImplTraitContext::ReturnPositionOpaqueTy { - origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id), - in_trait: matches!(kind, FnDeclKind::Trait), - } + match &decl.output { + FnRetTy::Ty(ty) => { + let context = if kind.return_impl_trait_allowed(self.tcx) { + let fn_def_id = self.local_def_id(fn_node_id); + ImplTraitContext::ReturnPositionOpaqueTy { + origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id), + in_trait: matches!(kind, FnDeclKind::Trait), } - _ => ImplTraitContext::Disallowed(match kind { + } else { + let position = match kind { FnDeclKind::Fn | FnDeclKind::Inherent => { unreachable!("fn should allow in-band lifetimes") } @@ -1770,11 +1755,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { FnDeclKind::Pointer => ImplTraitPosition::PointerReturn, FnDeclKind::Trait => ImplTraitPosition::TraitReturn, FnDeclKind::Impl => ImplTraitPosition::ImplReturn, - }), + }; + match kind { + FnDeclKind::Trait | FnDeclKind::Impl => ImplTraitContext::FeatureGated( + position, + sym::return_position_impl_trait_in_trait, + ), + _ => ImplTraitContext::Disallowed(position), + } }; - hir::FnRetTy::Return(self.lower_ty(ty, &mut context)) + hir::FnRetTy::Return(self.lower_ty(ty, &context)) } - FnRetTy::Default(span) => hir::FnRetTy::DefaultReturn(self.lower_span(span)), + FnRetTy::Default(span) => hir::FnRetTy::DefaultReturn(self.lower_span(*span)), } }; @@ -1782,26 +1774,23 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { inputs, output, c_variadic, + lifetime_elision_allowed: self.resolver.lifetime_elision_allowed.contains(&fn_node_id), implicit_self: decl.inputs.get(0).map_or(hir::ImplicitSelfKind::None, |arg| { let is_mutable_pat = matches!( arg.pat.kind, PatKind::Ident(hir::BindingAnnotation(_, Mutability::Mut), ..) ); - match arg.ty.kind { + match &arg.ty.kind { TyKind::ImplicitSelf if is_mutable_pat => hir::ImplicitSelfKind::Mut, TyKind::ImplicitSelf => hir::ImplicitSelfKind::Imm, // Given we are only considering `ImplicitSelf` types, we needn't consider // the case where we have a mutable pattern to a reference as that would // no longer be an `ImplicitSelf`. - TyKind::Rptr(_, ref mt) - if mt.ty.kind.is_implicit_self() && mt.mutbl == ast::Mutability::Mut => - { - hir::ImplicitSelfKind::MutRef - } - TyKind::Rptr(_, ref mt) if mt.ty.kind.is_implicit_self() => { - hir::ImplicitSelfKind::ImmRef - } + TyKind::Rptr(_, mt) if mt.ty.kind.is_implicit_self() => match mt.mutbl { + hir::Mutability::Not => hir::ImplicitSelfKind::ImmRef, + hir::Mutability::Mut => hir::ImplicitSelfKind::MutRef, + }, _ => hir::ImplicitSelfKind::None, } }), @@ -1828,9 +1817,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::Async, span, None); - let opaque_ty_def_id = self.local_def_id(opaque_ty_node_id); let fn_def_id = self.local_def_id(fn_node_id); + let opaque_ty_def_id = + self.create_def(fn_def_id, opaque_ty_node_id, DefPathData::ImplTrait, opaque_ty_span); + // When we create the opaque type for this async fn, it is going to have // to capture all the lifetimes involved in the signature (including in the // return type). This is done by introducing lifetime parameters for: @@ -1889,6 +1880,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { opaque_ty_def_id, inner_node_id, DefPathData::LifetimeNs(ident.name), + ident.span, ); new_remapping.insert(outer_def_id, inner_def_id); @@ -1953,7 +1945,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { output, span, if in_trait && !this.tcx.features().return_position_impl_trait_in_trait { - ImplTraitContext::Disallowed(ImplTraitPosition::TraitReturn) + ImplTraitContext::FeatureGated( + ImplTraitPosition::TraitReturn, + sym::return_position_impl_trait_in_trait, + ) } else { ImplTraitContext::ReturnPositionOpaqueTy { origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id), @@ -1978,6 +1973,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { hir::GenericParam { hir_id, + def_id: this.local_def_id(new_node_id), name, span: lifetime.ident.span, pure_wrt_drop: false, @@ -2024,18 +2020,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let generic_args = self.arena.alloc_from_iter(collected_lifetimes.into_iter().map( |(_, lifetime, res)| { let id = self.next_node_id(); - let span = lifetime.ident.span; - - let ident = if lifetime.ident.name == kw::UnderscoreLifetime { - Ident::with_dummy_span(kw::UnderscoreLifetime) - } else { - lifetime.ident - }; - let res = res.unwrap_or( self.resolver.get_lifetime_res(lifetime.id).unwrap_or(LifetimeRes::Error), ); - hir::GenericArg::Lifetime(self.new_named_lifetime_with_res(id, span, ident, res)) + hir::GenericArg::Lifetime(self.new_named_lifetime_with_res(id, lifetime.ident, res)) }, )); @@ -2105,43 +2093,40 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } fn lower_lifetime(&mut self, l: &Lifetime) -> &'hir hir::Lifetime { - let span = self.lower_span(l.ident.span); let ident = self.lower_ident(l.ident); - self.new_named_lifetime(l.id, l.id, span, ident) + self.new_named_lifetime(l.id, l.id, ident) } #[instrument(level = "debug", skip(self))] fn new_named_lifetime_with_res( &mut self, id: NodeId, - span: Span, ident: Ident, res: LifetimeRes, ) -> &'hir hir::Lifetime { - let name = match res { + let res = match res { LifetimeRes::Param { param, .. } => { - let p_name = ParamName::Plain(ident); let param = self.get_remapped_def_id(param); - - hir::LifetimeName::Param(param, p_name) + hir::LifetimeName::Param(param) } LifetimeRes::Fresh { param, .. } => { - debug_assert_eq!(ident.name, kw::UnderscoreLifetime); let param = self.local_def_id(param); - - hir::LifetimeName::Param(param, ParamName::Fresh) + hir::LifetimeName::Param(param) } LifetimeRes::Infer => hir::LifetimeName::Infer, LifetimeRes::Static => hir::LifetimeName::Static, LifetimeRes::Error => hir::LifetimeName::Error, - res => panic!("Unexpected lifetime resolution {:?} for {:?} at {:?}", res, ident, span), + res => panic!( + "Unexpected lifetime resolution {:?} for {:?} at {:?}", + res, ident, ident.span + ), }; - debug!(?name); + debug!(?res); self.arena.alloc(hir::Lifetime { hir_id: self.lower_node_id(id), - span: self.lower_span(span), - name, + ident: self.lower_ident(ident), + res, }) } @@ -2150,11 +2135,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { &mut self, id: NodeId, new_id: NodeId, - span: Span, ident: Ident, ) -> &'hir hir::Lifetime { let res = self.resolver.get_lifetime_res(id).unwrap_or(LifetimeRes::Error); - self.new_named_lifetime_with_res(new_id, span, ident, res) + self.new_named_lifetime_with_res(new_id, ident, res) } fn lower_generic_params_mut<'s>( @@ -2176,6 +2160,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.lower_attrs(hir_id, ¶m.attrs); hir::GenericParam { hir_id, + def_id: self.local_def_id(param.id), name, span: self.lower_span(param.span()), pure_wrt_drop: self.tcx.sess.contains_name(¶m.attrs, sym::may_dangle), @@ -2188,7 +2173,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { &mut self, param: &GenericParam, ) -> (hir::ParamName, hir::GenericParamKind<'hir>) { - match param.kind { + match ¶m.kind { GenericParamKind::Lifetime => { // AST resolution emitted an error on those parameters, so we lower them using // `ParamName::Error`. @@ -2204,7 +2189,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { (param_name, kind) } - GenericParamKind::Type { ref default, .. } => { + GenericParamKind::Type { default, .. } => { let kind = hir::GenericParamKind::Type { default: default.as_ref().map(|x| { self.lower_ty(x, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)) @@ -2214,7 +2199,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { (hir::ParamName::Plain(self.lower_ident(param.ident)), kind) } - GenericParamKind::Const { ref ty, kw_span: _, ref default } => { + GenericParamKind::Const { ty, kw_span: _, default } => { let ty = self.lower_ty(&ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)); let default = default.as_ref().map(|def| self.lower_anon_const(def)); ( @@ -2280,6 +2265,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // Set the name to `impl Bound1 + Bound2`. let param = hir::GenericParam { hir_id: self.lower_node_id(node_id), + def_id, name: ParamName::Plain(self.lower_ident(ident)), pure_wrt_drop: false, span: self.lower_span(span), @@ -2315,7 +2301,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { /// has no attributes and is not targeted by a `break`. fn lower_block_expr(&mut self, b: &Block) -> hir::Expr<'hir> { let block = self.lower_block(b, false); - self.expr_block(block, AttrVec::new()) + self.expr_block(block) } fn lower_array_length(&mut self, c: &AnonConst) -> hir::ArrayLen { @@ -2340,6 +2326,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn lower_anon_const(&mut self, c: &AnonConst) -> hir::AnonConst { self.with_new_scopes(|this| hir::AnonConst { + def_id: this.local_def_id(c.id), hir_id: this.lower_node_id(c.id), body: this.lower_const_body(c.value.span, Some(&c.value)), }) @@ -2563,8 +2550,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn elided_dyn_bound(&mut self, span: Span) -> &'hir hir::Lifetime { let r = hir::Lifetime { hir_id: self.next_id(), - span: self.lower_span(span), - name: hir::LifetimeName::ImplicitObjectLifetimeDefault, + ident: Ident::new(kw::Empty, self.lower_span(span)), + res: hir::LifetimeName::ImplicitObjectLifetimeDefault, }; debug!("elided_dyn_bound: r={:?}", r); self.arena.alloc(r) diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs index 1af1633b5..16b012630 100644 --- a/compiler/rustc_ast_lowering/src/pat.rs +++ b/compiler/rustc_ast_lowering/src/pat.rs @@ -22,16 +22,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ensure_sufficient_stack(|| { // loop here to avoid recursion let node = loop { - match pattern.kind { + match &pattern.kind { PatKind::Wild => break hir::PatKind::Wild, - PatKind::Ident(binding_mode, ident, ref sub) => { - let lower_sub = |this: &mut Self| sub.as_ref().map(|s| this.lower_pat(&*s)); - break self.lower_pat_ident(pattern, binding_mode, ident, lower_sub); + PatKind::Ident(binding_mode, ident, sub) => { + let lower_sub = |this: &mut Self| sub.as_ref().map(|s| this.lower_pat(s)); + break self.lower_pat_ident(pattern, *binding_mode, *ident, lower_sub); } - PatKind::Lit(ref e) => { + PatKind::Lit(e) => { break hir::PatKind::Lit(self.lower_expr_within_pat(e, false)); } - PatKind::TupleStruct(ref qself, ref path, ref pats) => { + PatKind::TupleStruct(qself, path, pats) => { let qpath = self.lower_qpath( pattern.id, qself, @@ -42,12 +42,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let (pats, ddpos) = self.lower_pat_tuple(pats, "tuple struct"); break hir::PatKind::TupleStruct(qpath, pats, ddpos); } - PatKind::Or(ref pats) => { + PatKind::Or(pats) => { break hir::PatKind::Or( self.arena.alloc_from_iter(pats.iter().map(|x| self.lower_pat_mut(x))), ); } - PatKind::Path(ref qself, ref path) => { + PatKind::Path(qself, path) => { let qpath = self.lower_qpath( pattern.id, qself, @@ -57,7 +57,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ); break hir::PatKind::Path(qpath); } - PatKind::Struct(ref qself, ref path, ref fields, etc) => { + PatKind::Struct(qself, path, fields, etc) => { let qpath = self.lower_qpath( pattern.id, qself, @@ -78,32 +78,32 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { span: self.lower_span(f.span), } })); - break hir::PatKind::Struct(qpath, fs, etc); + break hir::PatKind::Struct(qpath, fs, *etc); } - PatKind::Tuple(ref pats) => { + PatKind::Tuple(pats) => { let (pats, ddpos) = self.lower_pat_tuple(pats, "tuple"); break hir::PatKind::Tuple(pats, ddpos); } - PatKind::Box(ref inner) => { + PatKind::Box(inner) => { break hir::PatKind::Box(self.lower_pat(inner)); } - PatKind::Ref(ref inner, mutbl) => { - break hir::PatKind::Ref(self.lower_pat(inner), mutbl); + PatKind::Ref(inner, mutbl) => { + break hir::PatKind::Ref(self.lower_pat(inner), *mutbl); } - PatKind::Range(ref e1, ref e2, Spanned { node: ref end, .. }) => { + PatKind::Range(e1, e2, Spanned { node: end, .. }) => { break hir::PatKind::Range( e1.as_deref().map(|e| self.lower_expr_within_pat(e, true)), e2.as_deref().map(|e| self.lower_expr_within_pat(e, true)), self.lower_range_end(end, e2.is_some()), ); } - PatKind::Slice(ref pats) => break self.lower_pat_slice(pats), + PatKind::Slice(pats) => break self.lower_pat_slice(pats), PatKind::Rest => { // If we reach here the `..` pattern is not semantically allowed. break self.ban_illegal_rest_pat(pattern.span); } // return inner to be processed in next loop - PatKind::Paren(ref inner) => pattern = inner, + PatKind::Paren(inner) => pattern = inner, PatKind::MacCall(_) => panic!("{:?} shouldn't exist here", pattern.span), } }; @@ -126,7 +126,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // Note that unlike for slice patterns, // where `xs @ ..` is a legal sub-slice pattern, // it is not a legal sub-tuple pattern. - match pat.kind { + match &pat.kind { // Found a sub-tuple rest pattern PatKind::Rest => { rest = Some((idx, pat.span)); @@ -134,12 +134,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } // Found a sub-tuple pattern `$binding_mode $ident @ ..`. // This is not allowed as a sub-tuple pattern - PatKind::Ident(ref _bm, ident, Some(ref sub)) if sub.is_rest() => { + PatKind::Ident(_, ident, Some(sub)) if sub.is_rest() => { let sp = pat.span; self.tcx.sess.emit_err(SubTupleBinding { span: sp, ident_name: ident.name, - ident, + ident: *ident, ctx, }); } @@ -176,7 +176,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let mut prev_rest_span = None; // Lowers `$bm $ident @ ..` to `$bm $ident @ _`. - let lower_rest_sub = |this: &mut Self, pat, ann, ident, sub| { + let lower_rest_sub = |this: &mut Self, pat, &ann, &ident, sub| { let lower_sub = |this: &mut Self| Some(this.pat_wild_with_node_id_of(sub)); let node = this.lower_pat_ident(pat, ann, ident, lower_sub); this.pat_with_node_id_of(pat, node) @@ -185,7 +185,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let mut iter = pats.iter(); // Lower all the patterns until the first occurrence of a sub-slice pattern. for pat in iter.by_ref() { - match pat.kind { + match &pat.kind { // Found a sub-slice pattern `..`. Record, lower it to `_`, and stop here. PatKind::Rest => { prev_rest_span = Some(pat.span); @@ -194,7 +194,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } // Found a sub-slice pattern `$binding_mode $ident @ ..`. // Record, lower it to `$binding_mode $ident @ _`, and stop here. - PatKind::Ident(ann, ident, Some(ref sub)) if sub.is_rest() => { + PatKind::Ident(ann, ident, Some(sub)) if sub.is_rest() => { prev_rest_span = Some(sub.span); slice = Some(self.arena.alloc(lower_rest_sub(self, pat, ann, ident, sub))); break; @@ -207,9 +207,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // Lower all the patterns after the first sub-slice pattern. for pat in iter { // There was a previous subslice pattern; make sure we don't allow more. - let rest_span = match pat.kind { + let rest_span = match &pat.kind { PatKind::Rest => Some(pat.span), - PatKind::Ident(ann, ident, Some(ref sub)) if sub.is_rest() => { + PatKind::Ident(ann, ident, Some(sub)) if sub.is_rest() => { // #69103: Lower into `binding @ _` as above to avoid ICEs. after.push(lower_rest_sub(self, pat, ann, ident, sub)); Some(sub.span) @@ -322,10 +322,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // m!(S); // ``` fn lower_expr_within_pat(&mut self, expr: &Expr, allow_paths: bool) -> &'hir hir::Expr<'hir> { - match expr.kind { - ExprKind::Lit(..) | ExprKind::ConstBlock(..) | ExprKind::Err => {} + match &expr.kind { + ExprKind::Lit(..) + | ExprKind::ConstBlock(..) + | ExprKind::IncludedBytes(..) + | ExprKind::Err => {} ExprKind::Path(..) if allow_paths => {} - ExprKind::Unary(UnOp::Neg, ref inner) if matches!(inner.kind, ExprKind::Lit(_)) => {} + ExprKind::Unary(UnOp::Neg, inner) if matches!(inner.kind, ExprKind::Lit(_)) => {} _ => { self.tcx.sess.emit_err(ArbitraryExpressionInPattern { span: expr.span }); return self.arena.alloc(self.expr_err(expr.span)); diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index 888776ccc..592fc5aa6 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -9,17 +9,17 @@ use rustc_ast::{self as ast, *}; use rustc_hir as hir; use rustc_hir::def::{DefKind, PartialRes, Res}; use rustc_hir::GenericArg; -use rustc_span::symbol::{kw, Ident}; +use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::{BytePos, Span, DUMMY_SP}; -use smallvec::smallvec; +use smallvec::{smallvec, SmallVec}; impl<'a, 'hir> LoweringContext<'a, 'hir> { #[instrument(level = "trace", skip(self))] pub(crate) fn lower_qpath( &mut self, id: NodeId, - qself: &Option<QSelf>, + qself: &Option<ptr::P<QSelf>>, p: &Path, param_mode: ParamMode, itctx: &ImplTraitContext, @@ -144,13 +144,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ); } - pub(crate) fn lower_path_extra( + pub(crate) fn lower_use_path( &mut self, - res: Res, + res: SmallVec<[Res; 3]>, p: &Path, param_mode: ParamMode, - ) -> &'hir hir::Path<'hir> { - self.arena.alloc(hir::Path { + ) -> &'hir hir::UsePath<'hir> { + self.arena.alloc(hir::UsePath { res, segments: self.arena.alloc_from_iter(p.segments.iter().map(|segment| { self.lower_path_segment( @@ -165,17 +165,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { }) } - pub(crate) fn lower_path( - &mut self, - id: NodeId, - p: &Path, - param_mode: ParamMode, - ) -> &'hir hir::Path<'hir> { - let res = self.expect_full_res(id); - let res = self.lower_res(res); - self.lower_path_extra(res, p, param_mode) - } - pub(crate) fn lower_path_segment( &mut self, path_span: Span, @@ -185,13 +174,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { itctx: &ImplTraitContext, ) -> hir::PathSegment<'hir> { debug!("path_span: {:?}, lower_path_segment(segment: {:?})", path_span, segment,); - let (mut generic_args, infer_args) = if let Some(ref generic_args) = segment.args { - match **generic_args { - GenericArgs::AngleBracketed(ref data) => { + let (mut generic_args, infer_args) = if let Some(generic_args) = segment.args.as_deref() { + match generic_args { + GenericArgs::AngleBracketed(data) => { self.lower_angle_bracketed_parameter_data(data, param_mode, itctx) } - GenericArgs::Parenthesized(ref data) => match parenthesized_generic_args { - ParenthesizedGenericArgs::Ok => self.lower_parenthesized_parameter_data(data), + GenericArgs::Parenthesized(data) => match parenthesized_generic_args { + ParenthesizedGenericArgs::Ok => { + self.lower_parenthesized_parameter_data(data, itctx) + } ParenthesizedGenericArgs::Err => { // Suggest replacing parentheses with angle brackets `Trait(params...)` to `Trait<params...>` let sub = if !data.inputs.is_empty() { @@ -307,7 +298,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let id = NodeId::from_u32(i); let l = self.lower_lifetime(&Lifetime { id, - ident: Ident::new(kw::UnderscoreLifetime, elided_lifetime_span), + ident: Ident::new(kw::Empty, elided_lifetime_span), }); GenericArg::Lifetime(l) }), @@ -344,6 +335,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn lower_parenthesized_parameter_data( &mut self, data: &ParenthesizedArgs, + itctx: &ImplTraitContext, ) -> (GenericArgsCtor<'hir>, bool) { // Switch to `PassThrough` mode for anonymous lifetimes; this // means that we permit things like `&Ref<T>`, where `Ref` has @@ -355,6 +347,24 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.lower_ty_direct(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitParam)) })); let output_ty = match output { + // Only allow `impl Trait` in return position. i.e.: + // ```rust + // fn f(_: impl Fn() -> impl Debug) -> impl Fn() -> impl Debug + // // disallowed --^^^^^^^^^^ allowed --^^^^^^^^^^ + // ``` + FnRetTy::Ty(ty) if matches!(itctx, ImplTraitContext::ReturnPositionOpaqueTy { .. }) => { + if self.tcx.features().impl_trait_in_fn_trait_return { + self.lower_ty(&ty, itctx) + } else { + self.lower_ty( + &ty, + &ImplTraitContext::FeatureGated( + ImplTraitPosition::FnTraitReturn, + sym::impl_trait_in_fn_trait_return, + ), + ) + } + } FnRetTy::Ty(ty) => { self.lower_ty(&ty, &ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitReturn)) } diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 036643244..eb9c841d8 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -209,7 +209,7 @@ impl<'a> AstValidator<'a> { // Mirrors `visit::walk_ty`, but tracks relevant state. fn walk_ty(&mut self, t: &'a Ty) { - match t.kind { + match &t.kind { TyKind::ImplTrait(..) => { self.with_impl_trait(Some(t.span), |this| visit::walk_ty(this, t)) } @@ -217,7 +217,7 @@ impl<'a> AstValidator<'a> { .with_banned_tilde_const(DisallowTildeConstContext::TraitObject, |this| { visit::walk_ty(this, t) }), - TyKind::Path(ref qself, ref path) => { + TyKind::Path(qself, path) => { // We allow these: // - `Option<impl Trait>` // - `option::Option<impl Trait>` @@ -231,7 +231,7 @@ impl<'a> AstValidator<'a> { // (for cases like `<impl Trait>::Foo>`) // but we allow `impl Trait` in `GenericArgs` // iff there are no more PathSegments. - if let Some(ref qself) = *qself { + if let Some(qself) = qself { // `impl Trait` in `qself` is always illegal self.with_banned_impl_trait(|this| this.visit_ty(&qself.ty)); } @@ -738,8 +738,8 @@ impl<'a> AstValidator<'a> { } fn visit_ty_common(&mut self, ty: &'a Ty) { - match ty.kind { - TyKind::BareFn(ref bfty) => { + match &ty.kind { + TyKind::BareFn(bfty) => { self.check_fn_decl(&bfty.decl, SelfSemantic::No); Self::check_decl_no_pat(&bfty.decl, |span, _, _| { struct_span_err!( @@ -756,10 +756,10 @@ impl<'a> AstValidator<'a> { self.maybe_lint_missing_abi(sig_span, ty.id); } } - TyKind::TraitObject(ref bounds, ..) => { + TyKind::TraitObject(bounds, ..) => { let mut any_lifetime_bounds = false; for bound in bounds { - if let GenericBound::Outlives(ref lifetime) = *bound { + if let GenericBound::Outlives(lifetime) = bound { if any_lifetime_bounds { struct_span_err!( self.session, @@ -774,7 +774,7 @@ impl<'a> AstValidator<'a> { } } } - TyKind::ImplTrait(_, ref bounds) => { + TyKind::ImplTrait(_, bounds) => { if self.is_impl_trait_banned { struct_span_err!( self.session, @@ -842,8 +842,8 @@ fn validate_generic_param_order( let (kind, bounds, span) = (¶m.kind, ¶m.bounds, ident.span); let (ord_kind, ident) = match ¶m.kind { GenericParamKind::Lifetime => (ParamKindOrd::Lifetime, ident.to_string()), - GenericParamKind::Type { default: _ } => (ParamKindOrd::TypeOrConst, ident.to_string()), - GenericParamKind::Const { ref ty, kw_span: _, default: _ } => { + GenericParamKind::Type { .. } => (ParamKindOrd::TypeOrConst, ident.to_string()), + GenericParamKind::Const { ty, .. } => { let ty = pprust::ty_to_string(ty); (ParamKindOrd::TypeOrConst, format!("const {}: {}", ident, ty)) } @@ -912,7 +912,7 @@ fn validate_generic_param_order( impl<'a> Visitor<'a> for AstValidator<'a> { fn visit_attribute(&mut self, attr: &Attribute) { - validate_attr::check_meta(&self.session.parse_sess, attr); + validate_attr::check_attr(&self.session.parse_sess, attr); } fn visit_expr(&mut self, expr: &'a Expr) { @@ -948,8 +948,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } ExprKind::Paren(local_expr) => { fn has_let_expr(expr: &Expr) -> bool { - match expr.kind { - ExprKind::Binary(_, ref lhs, ref rhs) => has_let_expr(lhs) || has_let_expr(rhs), + match &expr.kind { + ExprKind::Binary(_, lhs, rhs) => has_let_expr(lhs) || has_let_expr(rhs), ExprKind::Let(..) => true, _ => false, } @@ -1005,18 +1005,18 @@ impl<'a> Visitor<'a> for AstValidator<'a> { self.check_nomangle_item_asciionly(item.ident, item.span); } - match item.kind { + match &item.kind { ItemKind::Impl(box Impl { unsafety, polarity, defaultness: _, constness, - ref generics, - of_trait: Some(ref t), - ref self_ty, - ref items, + generics, + of_trait: Some(t), + self_ty, + items, }) => { - self.with_in_trait_impl(true, Some(constness), |this| { + self.with_in_trait_impl(true, Some(*constness), |this| { this.invalid_visibility(&item.vis, None); if let TyKind::Err = self_ty.kind { this.err_handler() @@ -1027,7 +1027,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> { .help("use `auto trait Trait {}` instead") .emit(); } - if let (Unsafe::Yes(span), ImplPolarity::Negative(sp)) = (unsafety, polarity) { + if let (&Unsafe::Yes(span), &ImplPolarity::Negative(sp)) = (unsafety, polarity) + { struct_span_err!( this.session, sp.to(t.path.span), @@ -1051,6 +1052,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { walk_list!(this, visit_assoc_item, items, AssocCtxt::Impl); }); + walk_list!(self, visit_attribute, &item.attrs); return; // Avoid visiting again. } ItemKind::Impl(box Impl { @@ -1060,7 +1062,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { constness, generics: _, of_trait: None, - ref self_ty, + self_ty, items: _, }) => { let error = |annotation_span, annotation| { @@ -1077,25 +1079,25 @@ impl<'a> Visitor<'a> for AstValidator<'a> { &item.vis, Some(InvalidVisibilityNote::IndividualImplItems), ); - if let Unsafe::Yes(span) = unsafety { + if let &Unsafe::Yes(span) = unsafety { error(span, "unsafe").code(error_code!(E0197)).emit(); } - if let ImplPolarity::Negative(span) = polarity { + if let &ImplPolarity::Negative(span) = polarity { error(span, "negative").emit(); } - if let Defaultness::Default(def_span) = defaultness { + if let &Defaultness::Default(def_span) = defaultness { error(def_span, "`default`") .note("only trait implementations may be annotated with `default`") .emit(); } - if let Const::Yes(span) = constness { + if let &Const::Yes(span) = constness { error(span, "`const`") .note("only trait implementations may be annotated with `const`") .emit(); } } - ItemKind::Fn(box Fn { defaultness, ref sig, ref generics, ref body }) => { - self.check_defaultness(item.span, defaultness); + ItemKind::Fn(box Fn { defaultness, sig, generics, body }) => { + self.check_defaultness(item.span, *defaultness); if body.is_none() { self.session.emit_err(FnWithoutBody { @@ -1131,7 +1133,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { &item.vis, Some(InvalidVisibilityNote::IndividualForeignItems), ); - if let Unsafe::Yes(span) = unsafety { + if let &Unsafe::Yes(span) = unsafety { self.err_handler().span_err(span, "extern block cannot be declared unsafe"); } if abi.is_none() { @@ -1141,7 +1143,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { self.extern_mod = old_item; return; // Avoid visiting again. } - ItemKind::Enum(ref def, _) => { + ItemKind::Enum(def, _) => { for variant in &def.variants { self.invalid_visibility(&variant.vis, None); for field in variant.data.fields() { @@ -1149,8 +1151,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } } } - ItemKind::Trait(box Trait { is_auto, ref generics, ref bounds, ref items, .. }) => { - if is_auto == IsAuto::Yes { + ItemKind::Trait(box Trait { is_auto, generics, bounds, items, .. }) => { + if *is_auto == IsAuto::Yes { // Auto traits cannot have generics, super traits nor contain items. self.deny_generic_params(generics, item.ident.span); self.deny_super_traits(bounds, item.ident.span); @@ -1168,10 +1170,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> { }); walk_list!(self, visit_assoc_item, items, AssocCtxt::Trait); walk_list!(self, visit_attribute, &item.attrs); - return; + return; // Avoid visiting again } - ItemKind::Mod(unsafety, ref mod_kind) => { - if let Unsafe::Yes(span) = unsafety { + ItemKind::Mod(unsafety, mod_kind) => { + if let &Unsafe::Yes(span) = unsafety { self.err_handler().span_err(span, "module cannot be declared unsafe"); } // Ensure that `path` attributes on modules are recorded as used (cf. issue #35584). @@ -1181,13 +1183,13 @@ impl<'a> Visitor<'a> for AstValidator<'a> { self.check_mod_file_item_asciionly(item.ident); } } - ItemKind::Union(ref vdata, ..) => { + ItemKind::Union(vdata, ..) => { if vdata.fields().is_empty() { self.err_handler().span_err(item.span, "unions cannot have zero fields"); } } ItemKind::Const(def, .., None) => { - self.check_defaultness(item.span, def); + self.check_defaultness(item.span, *def); self.session.emit_err(ConstWithoutBody { span: item.span, replace_span: self.ending_semi_or_hi(item.span), @@ -1199,14 +1201,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> { replace_span: self.ending_semi_or_hi(item.span), }); } - ItemKind::TyAlias(box TyAlias { - defaultness, - where_clauses, - ref bounds, - ref ty, - .. - }) => { - self.check_defaultness(item.span, defaultness); + ItemKind::TyAlias(box TyAlias { defaultness, where_clauses, bounds, ty, .. }) => { + self.check_defaultness(item.span, *defaultness); if ty.is_none() { self.session.emit_err(TyAliasWithoutBody { span: item.span, @@ -1265,8 +1261,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> { // Mirrors `visit::walk_generic_args`, but tracks relevant state. fn visit_generic_args(&mut self, generic_args: &'a GenericArgs) { - match *generic_args { - GenericArgs::AngleBracketed(ref data) => { + match generic_args { + GenericArgs::AngleBracketed(data) => { self.check_generic_args_before_constraints(data); for arg in &data.args { @@ -1282,7 +1278,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } } } - GenericArgs::Parenthesized(ref data) => { + GenericArgs::Parenthesized(data) => { walk_list!(self, visit_ty, &data.inputs); if let FnRetTy::Ty(ty) = &data.output { // `-> Foo` syntax is essentially an associated type binding, @@ -1318,7 +1314,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { validate_generic_param_order(self.err_handler(), &generics.params, generics.span); for predicate in &generics.where_clause.predicates { - if let WherePredicate::EqPredicate(ref predicate) = *predicate { + if let WherePredicate::EqPredicate(predicate) = predicate { deny_equality_constraints(self, predicate, generics); } } @@ -1367,7 +1363,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } fn visit_param_bound(&mut self, bound: &'a GenericBound, ctxt: BoundKind) { - if let GenericBound::Trait(ref poly, modify) = *bound { + if let GenericBound::Trait(poly, modify) = bound { match (ctxt, modify) { (BoundKind::SuperTraits, TraitBoundModifier::Maybe) => { let mut err = self @@ -1572,8 +1568,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> { self.check_item_named(item.ident, "const"); } - match item.kind { - AssocItemKind::Type(box TyAlias { ref generics, ref bounds, ref ty, .. }) + match &item.kind { + AssocItemKind::Type(box TyAlias { generics, bounds, ty, .. }) if ctxt == AssocCtxt::Trait => { self.visit_vis(&item.vis); @@ -1585,7 +1581,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { }); walk_list!(self, visit_ty, ty); } - AssocItemKind::Fn(box Fn { ref sig, ref generics, ref body, .. }) + AssocItemKind::Fn(box Fn { sig, generics, body, .. }) if self.in_const_trait_impl || ctxt == AssocCtxt::Trait || matches!(sig.header.constness, Const::Yes(_)) => @@ -1636,7 +1632,7 @@ fn deny_equality_constraints( // Remove `Bar` from `Foo::Bar`. assoc_path.segments.pop(); let len = assoc_path.segments.len() - 1; - let gen_args = args.as_ref().map(|p| (**p).clone()); + let gen_args = args.as_deref().cloned(); // Build `<Bar = RhsTy>`. let arg = AngleBracketedArg::Constraint(AssocConstraint { id: rustc_ast::node_id::DUMMY_NODE_ID, diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 546010135..32f45f8b5 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -198,8 +198,8 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } fn visit_item(&mut self, i: &'a ast::Item) { - match i.kind { - ast::ItemKind::ForeignMod(ref foreign_module) => { + match &i.kind { + ast::ItemKind::ForeignMod(foreign_module) => { if let Some(abi) = foreign_module.abi { self.check_abi(abi, ast::Const::No); } @@ -233,8 +233,8 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } } - ast::ItemKind::Impl(box ast::Impl { polarity, defaultness, ref of_trait, .. }) => { - if let ast::ImplPolarity::Negative(span) = polarity { + ast::ItemKind::Impl(box ast::Impl { polarity, defaultness, of_trait, .. }) => { + if let &ast::ImplPolarity::Negative(span) = polarity { gate_feature_post!( &self, negative_impls, @@ -267,7 +267,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { gate_feature_post!(&self, decl_macro, i.span, msg); } - ast::ItemKind::TyAlias(box ast::TyAlias { ty: Some(ref ty), .. }) => { + ast::ItemKind::TyAlias(box ast::TyAlias { ty: Some(ty), .. }) => { self.check_impl_trait(&ty) } @@ -302,8 +302,8 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } fn visit_ty(&mut self, ty: &'a ast::Ty) { - match ty.kind { - ast::TyKind::BareFn(ref bare_fn_ty) => { + match &ty.kind { + ast::TyKind::BareFn(bare_fn_ty) => { // Function pointers cannot be `const` self.check_extern(bare_fn_ty.ext, ast::Const::No); } @@ -319,7 +319,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } fn visit_fn_ret_ty(&mut self, ret_ty: &'a ast::FnRetTy) { - if let ast::FnRetTy::Ty(ref output_ty) = *ret_ty { + if let ast::FnRetTy::Ty(output_ty) = ret_ty { if let ast::TyKind::Never = output_ty.kind { // Do nothing. } else { @@ -455,9 +455,9 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } fn visit_assoc_item(&mut self, i: &'a ast::AssocItem, ctxt: AssocCtxt) { - let is_fn = match i.kind { + let is_fn = match &i.kind { ast::AssocItemKind::Fn(_) => true, - ast::AssocItemKind::Type(box ast::TyAlias { ref ty, .. }) => { + ast::AssocItemKind::Type(box ast::TyAlias { ty, .. }) => { if let (Some(_), AssocCtxt::Trait) = (ty, ctxt) { gate_feature_post!( &self, diff --git a/compiler/rustc_ast_pretty/src/helpers.rs b/compiler/rustc_ast_pretty/src/helpers.rs index 5ec71cddf..c3e0eccd3 100644 --- a/compiler/rustc_ast_pretty/src/helpers.rs +++ b/compiler/rustc_ast_pretty/src/helpers.rs @@ -36,8 +36,8 @@ impl Printer { self.nbsp() } - // Synthesizes a comment that was not textually present in the original - // source file. + /// Synthesizes a comment that was not textually present in the original + /// source file. pub fn synth_comment(&mut self, text: impl Into<Cow<'static, str>>) { self.word("/*"); self.space(); diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index b87c6f78d..d3d8431c1 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -11,16 +11,15 @@ use rustc_ast::tokenstream::{TokenStream, TokenTree}; use rustc_ast::util::classify; use rustc_ast::util::comments::{gather_comments, Comment, CommentStyle}; use rustc_ast::util::parser; -use rustc_ast::{self as ast, BlockCheckMode, Mutability, PatKind, RangeEnd, RangeSyntax}; -use rustc_ast::{attr, BindingAnnotation, ByRef, Term}; -use rustc_ast::{GenericArg, MacArgs, MacArgsEq}; -use rustc_ast::{GenericBound, SelfKind, TraitBoundModifier}; +use rustc_ast::{self as ast, AttrArgs, AttrArgsEq, BlockCheckMode, PatKind}; +use rustc_ast::{attr, BindingAnnotation, ByRef, DelimArgs, RangeEnd, RangeSyntax, Term}; +use rustc_ast::{GenericArg, GenericBound, SelfKind, TraitBoundModifier}; use rustc_ast::{InlineAsmOperand, InlineAsmRegOrRegClass}; use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_span::edition::Edition; use rustc_span::source_map::{SourceMap, Spanned}; use rustc_span::symbol::{kw, sym, Ident, IdentPrinter, Symbol}; -use rustc_span::{BytePos, FileName, Span}; +use rustc_span::{BytePos, FileName, Span, DUMMY_SP}; use rustc_ast::attr::AttrIdGenerator; use std::borrow::Cow; @@ -65,6 +64,7 @@ impl<'a> Comments<'a> { Comments { sm, comments, current: 0 } } + // FIXME: This shouldn't probably clone lmao pub fn next(&self) -> Option<Comment> { self.comments.get(self.current).cloned() } @@ -120,17 +120,20 @@ pub fn print_crate<'a>( // of the feature gate, so we fake them up here. // `#![feature(prelude_import)]` - let pi_nested = attr::mk_nested_word_item(Ident::with_dummy_span(sym::prelude_import)); - let list = attr::mk_list_item(Ident::with_dummy_span(sym::feature), vec![pi_nested]); - let fake_attr = attr::mk_attr_inner(g, list); + let fake_attr = attr::mk_attr_nested_word( + g, + ast::AttrStyle::Inner, + sym::feature, + sym::prelude_import, + DUMMY_SP, + ); s.print_attribute(&fake_attr); // Currently, in Rust 2018 we don't have `extern crate std;` at the crate // root, so this is not needed, and actually breaks things. if edition == Edition::Edition2015 { // `#![no_std]` - let no_std_meta = attr::mk_word_item(Ident::with_dummy_span(sym::no_std)); - let fake_attr = attr::mk_attr_inner(g, no_std_meta); + let fake_attr = attr::mk_attr_word(g, ast::AttrStyle::Inner, sym::no_std, DUMMY_SP); s.print_attribute(&fake_attr); } } @@ -269,10 +272,10 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere fn maybe_print_comment(&mut self, pos: BytePos) -> bool { let mut has_comment = false; - while let Some(ref cmnt) = self.next_comment() { + while let Some(cmnt) = self.next_comment() { if cmnt.pos < pos { has_comment = true; - self.print_comment(cmnt); + self.print_comment(&cmnt); } else { break; } @@ -367,14 +370,18 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere if self.next_comment().is_none() { self.hardbreak(); } - while let Some(ref cmnt) = self.next_comment() { - self.print_comment(cmnt) + while let Some(cmnt) = self.next_comment() { + self.print_comment(&cmnt) } } - fn print_literal(&mut self, lit: &ast::Lit) { - self.maybe_print_comment(lit.span.lo()); - self.word(lit.token_lit.to_string()) + fn print_meta_item_lit(&mut self, lit: &ast::MetaItemLit) { + self.print_token_literal(lit.token_lit, lit.span) + } + + fn print_token_literal(&mut self, token_lit: token::Lit, span: Span) { + self.maybe_print_comment(span.lo()); + self.word(token_lit.to_string()) } fn print_string(&mut self, st: &str, style: ast::StrStyle) { @@ -443,8 +450,8 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere self.hardbreak_if_not_bol(); } self.maybe_print_comment(attr.span.lo()); - match attr.kind { - ast::AttrKind::Normal(ref normal) => { + match &attr.kind { + ast::AttrKind::Normal(normal) => { match attr.style { ast::AttrStyle::Inner => self.word("#!["), ast::AttrStyle::Outer => self.word("#["), @@ -453,7 +460,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere self.word("]"); } ast::AttrKind::DocComment(comment_kind, data) => { - self.word(doc_comment_to_string(comment_kind, attr.style, data)); + self.word(doc_comment_to_string(*comment_kind, attr.style, *data)); self.hardbreak() } } @@ -462,30 +469,30 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere fn print_attr_item(&mut self, item: &ast::AttrItem, span: Span) { self.ibox(0); match &item.args { - MacArgs::Delimited(_, delim, tokens) => self.print_mac_common( + AttrArgs::Delimited(DelimArgs { dspan: _, delim, tokens }) => self.print_mac_common( Some(MacHeader::Path(&item.path)), false, None, - Some(delim.to_token()), + delim.to_token(), tokens, true, span, ), - MacArgs::Empty => { + AttrArgs::Empty => { self.print_path(&item.path, false, 0); } - MacArgs::Eq(_, MacArgsEq::Ast(expr)) => { + AttrArgs::Eq(_, AttrArgsEq::Ast(expr)) => { self.print_path(&item.path, false, 0); self.space(); self.word_space("="); let token_str = self.expr_to_string(expr); self.word(token_str); } - MacArgs::Eq(_, MacArgsEq::Hir(lit)) => { + AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => { self.print_path(&item.path, false, 0); self.space(); self.word_space("="); - let token_str = self.literal_to_string(lit); + let token_str = self.meta_item_lit_to_string(lit); self.word(token_str); } } @@ -494,25 +501,25 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere fn print_meta_list_item(&mut self, item: &ast::NestedMetaItem) { match item { - ast::NestedMetaItem::MetaItem(ref mi) => self.print_meta_item(mi), - ast::NestedMetaItem::Literal(ref lit) => self.print_literal(lit), + ast::NestedMetaItem::MetaItem(mi) => self.print_meta_item(mi), + ast::NestedMetaItem::Lit(lit) => self.print_meta_item_lit(lit), } } fn print_meta_item(&mut self, item: &ast::MetaItem) { self.ibox(INDENT_UNIT); - match item.kind { + match &item.kind { ast::MetaItemKind::Word => self.print_path(&item.path, false, 0), - ast::MetaItemKind::NameValue(ref value) => { + ast::MetaItemKind::NameValue(value) => { self.print_path(&item.path, false, 0); self.space(); self.word_space("="); - self.print_literal(value); + self.print_meta_item_lit(value); } - ast::MetaItemKind::List(ref items) => { + ast::MetaItemKind::List(items) => { self.print_path(&item.path, false, 0); self.popen(); - self.commasep(Consistent, &items, |s, i| s.print_meta_list_item(i)); + self.commasep(Consistent, items, |s, i| s.print_meta_list_item(i)); self.pclose(); } } @@ -529,7 +536,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere fn print_tt(&mut self, tt: &TokenTree, convert_dollar_crate: bool) { match tt { TokenTree::Token(token, _) => { - let token_str = self.token_to_string_ext(&token, convert_dollar_crate); + let token_str = self.token_to_string_ext(token, convert_dollar_crate); self.word(token_str); if let token::DocComment(..) = token.kind { self.hardbreak() @@ -540,7 +547,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere None, false, None, - Some(*delim), + *delim, tts, convert_dollar_crate, dspan.entire(), @@ -566,12 +573,12 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere header: Option<MacHeader<'_>>, has_bang: bool, ident: Option<Ident>, - delim: Option<Delimiter>, + delim: Delimiter, tts: &TokenStream, convert_dollar_crate: bool, span: Span, ) { - if delim == Some(Delimiter::Brace) { + if delim == Delimiter::Brace { self.cbox(INDENT_UNIT); } match header { @@ -587,7 +594,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere self.print_ident(ident); } match delim { - Some(Delimiter::Brace) => { + Delimiter::Brace => { if header.is_some() || has_bang || ident.is_some() { self.nbsp(); } @@ -601,7 +608,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere let empty = tts.is_empty(); self.bclose(span, empty); } - Some(delim) => { + delim => { let token_str = self.token_kind_to_string(&token::OpenDelim(delim)); self.word(token_str); self.ibox(0); @@ -610,11 +617,6 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere let token_str = self.token_kind_to_string(&token::CloseDelim(delim)); self.word(token_str); } - None => { - self.ibox(0); - self.print_tts(tts, convert_dollar_crate); - self.end(); - } } } @@ -635,8 +637,8 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere Some(MacHeader::Keyword(kw)), has_bang, Some(*ident), - macro_def.body.delim(), - ¯o_def.body.inner_tokens(), + macro_def.body.delim.to_token(), + ¯o_def.body.tokens.clone(), true, sp, ); @@ -659,7 +661,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere fn print_path_segment(&mut self, segment: &ast::PathSegment, colons_before_params: bool) { if segment.ident.name != kw::PathRoot { self.print_ident(segment.ident); - if let Some(ref args) = segment.args { + if let Some(args) = &segment.args { self.print_generic_args(args, colons_before_params); } } @@ -714,19 +716,19 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere } fn nonterminal_to_string(&self, nt: &Nonterminal) -> String { - match *nt { - token::NtExpr(ref e) => self.expr_to_string(e), - token::NtMeta(ref e) => self.attr_item_to_string(e), - token::NtTy(ref e) => self.ty_to_string(e), - token::NtPath(ref e) => self.path_to_string(e), - token::NtItem(ref e) => self.item_to_string(e), - token::NtBlock(ref e) => self.block_to_string(e), - token::NtStmt(ref e) => self.stmt_to_string(e), - token::NtPat(ref e) => self.pat_to_string(e), - token::NtIdent(e, is_raw) => IdentPrinter::for_ast_ident(e, is_raw).to_string(), + match nt { + token::NtExpr(e) => self.expr_to_string(e), + token::NtMeta(e) => self.attr_item_to_string(e), + token::NtTy(e) => self.ty_to_string(e), + token::NtPath(e) => self.path_to_string(e), + token::NtItem(e) => self.item_to_string(e), + token::NtBlock(e) => self.block_to_string(e), + token::NtStmt(e) => self.stmt_to_string(e), + token::NtPat(e) => self.pat_to_string(e), + token::NtIdent(e, is_raw) => IdentPrinter::for_ast_ident(*e, *is_raw).to_string(), token::NtLifetime(e) => e.to_string(), - token::NtLiteral(ref e) => self.expr_to_string(e), - token::NtVis(ref e) => self.vis_to_string(e), + token::NtLiteral(e) => self.expr_to_string(e), + token::NtVis(e) => self.vis_to_string(e), } } @@ -827,8 +829,8 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere Self::to_string(|s| s.print_expr(e)) } - fn literal_to_string(&self, lit: &ast::Lit) -> String { - Self::to_string(|s| s.print_literal(lit)) + fn meta_item_lit_to_string(&self, lit: &ast::MetaItemLit) -> String { + Self::to_string(|s| s.print_meta_item_lit(lit)) } fn tt_to_string(&self, tt: &TokenTree) -> String { @@ -919,8 +921,8 @@ impl<'a> PrintState<'a> for State<'a> { self.word("::") } - match *args { - ast::GenericArgs::AngleBracketed(ref data) => { + match args { + ast::GenericArgs::AngleBracketed(data) => { self.word("<"); self.commasep(Inconsistent, &data.args, |s, arg| match arg { ast::AngleBracketedArg::Arg(a) => s.print_generic_arg(a), @@ -929,7 +931,7 @@ impl<'a> PrintState<'a> for State<'a> { self.word(">") } - ast::GenericArgs::Parenthesized(ref data) => { + ast::GenericArgs::Parenthesized(data) => { self.word("("); self.commasep(Inconsistent, &data.inputs, |s, ty| s.print_type(ty)); self.word(")"); @@ -996,7 +998,7 @@ impl<'a> State<'a> { ast::AssocConstraintKind::Bound { bounds } => { if !bounds.is_empty() { self.word_nbsp(":"); - self.print_type_bounds(&bounds); + self.print_type_bounds(bounds); } } } @@ -1013,17 +1015,17 @@ impl<'a> State<'a> { pub fn print_type(&mut self, ty: &ast::Ty) { self.maybe_print_comment(ty.span.lo()); self.ibox(0); - match ty.kind { - ast::TyKind::Slice(ref ty) => { + match &ty.kind { + ast::TyKind::Slice(ty) => { self.word("["); self.print_type(ty); self.word("]"); } - ast::TyKind::Ptr(ref mt) => { + ast::TyKind::Ptr(mt) => { self.word("*"); self.print_mt(mt, true); } - ast::TyKind::Rptr(ref lifetime, ref mt) => { + ast::TyKind::Rptr(lifetime, mt) => { self.word("&"); self.print_opt_lifetime(lifetime); self.print_mt(mt, false); @@ -1031,44 +1033,44 @@ impl<'a> State<'a> { ast::TyKind::Never => { self.word("!"); } - ast::TyKind::Tup(ref elts) => { + ast::TyKind::Tup(elts) => { self.popen(); - self.commasep(Inconsistent, &elts, |s, ty| s.print_type(ty)); + self.commasep(Inconsistent, elts, |s, ty| s.print_type(ty)); if elts.len() == 1 { self.word(","); } self.pclose(); } - ast::TyKind::Paren(ref typ) => { + ast::TyKind::Paren(typ) => { self.popen(); self.print_type(typ); self.pclose(); } - ast::TyKind::BareFn(ref f) => { + ast::TyKind::BareFn(f) => { self.print_ty_fn(f.ext, f.unsafety, &f.decl, None, &f.generic_params); } - ast::TyKind::Path(None, ref path) => { + ast::TyKind::Path(None, path) => { self.print_path(path, false, 0); } - ast::TyKind::Path(Some(ref qself), ref path) => self.print_qpath(path, qself, false), - ast::TyKind::TraitObject(ref bounds, syntax) => { - if syntax == ast::TraitObjectSyntax::Dyn { + ast::TyKind::Path(Some(qself), path) => self.print_qpath(path, qself, false), + ast::TyKind::TraitObject(bounds, syntax) => { + if *syntax == ast::TraitObjectSyntax::Dyn { self.word_nbsp("dyn"); } self.print_type_bounds(bounds); } - ast::TyKind::ImplTrait(_, ref bounds) => { + ast::TyKind::ImplTrait(_, bounds) => { self.word_nbsp("impl"); self.print_type_bounds(bounds); } - ast::TyKind::Array(ref ty, ref length) => { + ast::TyKind::Array(ty, length) => { self.word("["); self.print_type(ty); self.word("; "); self.print_expr(&length.value); self.word("]"); } - ast::TyKind::Typeof(ref e) => { + ast::TyKind::Typeof(e) => { self.word("typeof("); self.print_expr(&e.value); self.word(")"); @@ -1084,7 +1086,7 @@ impl<'a> State<'a> { ast::TyKind::ImplicitSelf => { self.word("Self"); } - ast::TyKind::MacCall(ref m) => { + ast::TyKind::MacCall(m) => { self.print_mac(m); } ast::TyKind::CVarArgs => { @@ -1113,8 +1115,8 @@ impl<'a> State<'a> { pub(crate) fn print_stmt(&mut self, st: &ast::Stmt) { self.maybe_print_comment(st.span.lo()); - match st.kind { - ast::StmtKind::Local(ref loc) => { + match &st.kind { + ast::StmtKind::Local(loc) => { self.print_outer_attributes(&loc.attrs); self.space_if_not_bol(); self.ibox(INDENT_UNIT); @@ -1137,15 +1139,15 @@ impl<'a> State<'a> { self.word(";"); self.end(); // `let` ibox } - ast::StmtKind::Item(ref item) => self.print_item(item), - ast::StmtKind::Expr(ref expr) => { + ast::StmtKind::Item(item) => self.print_item(item), + ast::StmtKind::Expr(expr) => { self.space_if_not_bol(); self.print_expr_outer_attr_style(expr, false); if classify::expr_requires_semi_to_be_stmt(expr) { self.word(";"); } } - ast::StmtKind::Semi(ref expr) => { + ast::StmtKind::Semi(expr) => { self.space_if_not_bol(); self.print_expr_outer_attr_style(expr, false); self.word(";"); @@ -1154,7 +1156,7 @@ impl<'a> State<'a> { self.space_if_not_bol(); self.word(";"); } - ast::StmtKind::MacCall(ref mac) => { + ast::StmtKind::MacCall(mac) => { self.space_if_not_bol(); self.print_outer_attributes(&mac.attrs); self.print_mac(&mac.mac); @@ -1195,8 +1197,8 @@ impl<'a> State<'a> { let has_attrs = self.print_inner_attributes(attrs); for (i, st) in blk.stmts.iter().enumerate() { - match st.kind { - ast::StmtKind::Expr(ref expr) if i == blk.stmts.len() - 1 => { + match &st.kind { + ast::StmtKind::Expr(expr) if i == blk.stmts.len() - 1 => { self.maybe_print_comment(st.span.lo()); self.space_if_not_bol(); self.print_expr_outer_attr_style(expr, false); @@ -1226,8 +1228,8 @@ impl<'a> State<'a> { Some(MacHeader::Path(&m.path)), true, None, - m.args.delim(), - &m.args.inner_tokens(), + m.args.delim.to_token(), + &m.args.tokens.clone(), true, m.span(), ); @@ -1252,7 +1254,7 @@ impl<'a> State<'a> { self.popen(); self.commasep(Consistent, &args, |s, arg| match arg { - AsmArg::Template(template) => s.print_string(&template, ast::StrStyle::Cooked), + AsmArg::Template(template) => s.print_string(template, ast::StrStyle::Cooked), AsmArg::Operand(op) => { let print_reg_or_class = |s: &mut Self, r: &InlineAsmRegOrRegClass| match r { InlineAsmRegOrRegClass::Reg(r) => s.print_symbol(*r, ast::StrStyle::Cooked), @@ -1364,7 +1366,7 @@ impl<'a> State<'a> { pub(crate) fn print_local_decl(&mut self, loc: &ast::Local) { self.print_pat(&loc.pat); - if let Some(ref ty) = loc.ty { + if let Some(ty) = &loc.ty { self.word_space(":"); self.print_type(ty); } @@ -1388,7 +1390,7 @@ impl<'a> State<'a> { for item_segment in &path.segments[qself.position..] { self.word("::"); self.print_ident(item_segment.ident); - if let Some(ref args) = item_segment.args { + if let Some(args) = &item_segment.args { self.print_generic_args(args, colons_before_params) } } @@ -1399,42 +1401,42 @@ impl<'a> State<'a> { self.ann.pre(self, AnnNode::Pat(pat)); /* Pat isn't normalized, but the beauty of it is that it doesn't matter */ - match pat.kind { + match &pat.kind { PatKind::Wild => self.word("_"), - PatKind::Ident(BindingAnnotation(by_ref, mutbl), ident, ref sub) => { - if by_ref == ByRef::Yes { + PatKind::Ident(BindingAnnotation(by_ref, mutbl), ident, sub) => { + if *by_ref == ByRef::Yes { self.word_nbsp("ref"); } - if mutbl == Mutability::Mut { + if mutbl.is_mut() { self.word_nbsp("mut"); } - self.print_ident(ident); - if let Some(ref p) = *sub { + self.print_ident(*ident); + if let Some(p) = sub { self.space(); self.word_space("@"); self.print_pat(p); } } - PatKind::TupleStruct(ref qself, ref path, ref elts) => { + PatKind::TupleStruct(qself, path, elts) => { if let Some(qself) = qself { self.print_qpath(path, qself, true); } else { self.print_path(path, true, 0); } self.popen(); - self.commasep(Inconsistent, &elts, |s, p| s.print_pat(p)); + self.commasep(Inconsistent, elts, |s, p| s.print_pat(p)); self.pclose(); } - PatKind::Or(ref pats) => { - self.strsep("|", true, Inconsistent, &pats, |s, p| s.print_pat(p)); + PatKind::Or(pats) => { + self.strsep("|", true, Inconsistent, pats, |s, p| s.print_pat(p)); } - PatKind::Path(None, ref path) => { + PatKind::Path(None, path) => { self.print_path(path, true, 0); } - PatKind::Path(Some(ref qself), ref path) => { + PatKind::Path(Some(qself), path) => { self.print_qpath(path, qself, false); } - PatKind::Struct(ref qself, ref path, ref fields, etc) => { + PatKind::Struct(qself, path, fields, etc) => { if let Some(qself) = qself { self.print_qpath(path, qself, true); } else { @@ -1448,7 +1450,7 @@ impl<'a> State<'a> { } self.commasep_cmnt( Consistent, - &fields, + fields, |s, f| { s.cbox(INDENT_UNIT); if !f.is_shorthand { @@ -1460,7 +1462,7 @@ impl<'a> State<'a> { }, |f| f.pat.span, ); - if etc { + if *etc { if !fields.is_empty() { self.word_space(","); } @@ -1471,21 +1473,21 @@ impl<'a> State<'a> { } self.word("}"); } - PatKind::Tuple(ref elts) => { + PatKind::Tuple(elts) => { self.popen(); - self.commasep(Inconsistent, &elts, |s, p| s.print_pat(p)); + self.commasep(Inconsistent, elts, |s, p| s.print_pat(p)); if elts.len() == 1 { self.word(","); } self.pclose(); } - PatKind::Box(ref inner) => { + PatKind::Box(inner) => { self.word("box "); self.print_pat(inner); } - PatKind::Ref(ref inner, mutbl) => { + PatKind::Ref(inner, mutbl) => { self.word("&"); - if mutbl == Mutability::Mut { + if mutbl.is_mut() { self.word("mut "); } if let PatKind::Ident(ast::BindingAnnotation::MUT, ..) = inner.kind { @@ -1496,12 +1498,12 @@ impl<'a> State<'a> { self.print_pat(inner); } } - PatKind::Lit(ref e) => self.print_expr(&**e), - PatKind::Range(ref begin, ref end, Spanned { node: ref end_kind, .. }) => { + PatKind::Lit(e) => self.print_expr(e), + PatKind::Range(begin, end, Spanned { node: end_kind, .. }) => { if let Some(e) = begin { self.print_expr(e); } - match *end_kind { + match end_kind { RangeEnd::Included(RangeSyntax::DotDotDot) => self.word("..."), RangeEnd::Included(RangeSyntax::DotDotEq) => self.word("..="), RangeEnd::Excluded => self.word(".."), @@ -1510,36 +1512,36 @@ impl<'a> State<'a> { self.print_expr(e); } } - PatKind::Slice(ref elts) => { + PatKind::Slice(elts) => { self.word("["); - self.commasep(Inconsistent, &elts, |s, p| s.print_pat(p)); + self.commasep(Inconsistent, elts, |s, p| s.print_pat(p)); self.word("]"); } PatKind::Rest => self.word(".."), - PatKind::Paren(ref inner) => { + PatKind::Paren(inner) => { self.popen(); self.print_pat(inner); self.pclose(); } - PatKind::MacCall(ref m) => self.print_mac(m), + PatKind::MacCall(m) => self.print_mac(m), } self.ann.post(self, AnnNode::Pat(pat)) } fn print_explicit_self(&mut self, explicit_self: &ast::ExplicitSelf) { - match explicit_self.node { + match &explicit_self.node { SelfKind::Value(m) => { - self.print_mutability(m, false); + self.print_mutability(*m, false); self.word("self") } - SelfKind::Region(ref lt, m) => { + SelfKind::Region(lt, m) => { self.word("&"); self.print_opt_lifetime(lt); - self.print_mutability(m, false); + self.print_mutability(*m, false); self.word("self") } - SelfKind::Explicit(ref typ, m) => { - self.print_mutability(m, false); + SelfKind::Explicit(typ, m) => { + self.print_mutability(*m, false); self.word("self"); self.word_space(":"); self.print_type(typ) @@ -1598,10 +1600,10 @@ impl<'a> State<'a> { self.word("<"); - self.commasep(Inconsistent, &generic_params, |s, param| { + self.commasep(Inconsistent, generic_params, |s, param| { s.print_outer_attributes_inline(¶m.attrs); - match param.kind { + match ¶m.kind { ast::GenericParamKind::Lifetime => { let lt = ast::Lifetime { id: param.id, ident: param.ident }; s.print_lifetime(lt); @@ -1610,19 +1612,19 @@ impl<'a> State<'a> { s.print_lifetime_bounds(¶m.bounds) } } - ast::GenericParamKind::Type { ref default } => { + ast::GenericParamKind::Type { default } => { s.print_ident(param.ident); if !param.bounds.is_empty() { s.word_nbsp(":"); s.print_type_bounds(¶m.bounds); } - if let Some(ref default) = default { + if let Some(default) = default { s.space(); s.word_space("="); s.print_type(default) } } - ast::GenericParamKind::Const { ref ty, kw_span: _, ref default } => { + ast::GenericParamKind::Const { ty, default, .. } => { s.word_space("const"); s.print_ident(param.ident); s.space(); @@ -1632,7 +1634,7 @@ impl<'a> State<'a> { s.word_nbsp(":"); s.print_type_bounds(¶m.bounds); } - if let Some(ref default) = default { + if let Some(default) = default { s.space(); s.word_space("="); s.print_expr(&default.value); @@ -1714,9 +1716,9 @@ impl<'a> State<'a> { where_clause: ast::WhereClause { has_where_token: false, predicates: Vec::new(), - span: rustc_span::DUMMY_SP, + span: DUMMY_SP, }, - span: rustc_span::DUMMY_SP, + span: DUMMY_SP, }; let header = ast::FnHeader { unsafety, ext, ..ast::FnHeader::default() }; self.print_fn(decl, header, name, &generics); @@ -1735,7 +1737,7 @@ impl<'a> State<'a> { } ast::Extern::Explicit(abi, _) => { self.word_nbsp("extern"); - self.print_literal(&abi.as_lit()); + self.print_token_literal(abi.as_token_lit(), abi.span); self.nbsp(); } } diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs index bcefa8ce0..4ed16e337 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs @@ -8,9 +8,9 @@ use rustc_ast::{self as ast, BlockCheckMode}; impl<'a> State<'a> { fn print_else(&mut self, els: Option<&ast::Expr>) { if let Some(_else) = els { - match _else.kind { + match &_else.kind { // Another `else if` block. - ast::ExprKind::If(ref i, ref then, ref e) => { + ast::ExprKind::If(i, then, e) => { self.cbox(INDENT_UNIT - 1); self.ibox(0); self.word(" else if "); @@ -20,7 +20,7 @@ impl<'a> State<'a> { self.print_else(e.as_deref()) } // Final `else` block. - ast::ExprKind::Block(ref b, _) => { + ast::ExprKind::Block(b, _) => { self.cbox(INDENT_UNIT - 1); self.ibox(0); self.word(" else "); @@ -58,10 +58,10 @@ impl<'a> State<'a> { self.print_expr_cond_paren(expr, Self::cond_needs_par(expr)) } - // Does `expr` need parentheses when printed in a condition position? - // - // These cases need parens due to the parse error observed in #26461: `if return {}` - // parses as the erroneous construct `if (return {})`, not `if (return) {}`. + /// Does `expr` need parentheses when printed in a condition position? + /// + /// These cases need parens due to the parse error observed in #26461: `if return {}` + /// parses as the erroneous construct `if (return {})`, not `if (return) {}`. pub(super) fn cond_needs_par(expr: &ast::Expr) -> bool { match expr.kind { ast::ExprKind::Break(..) @@ -121,7 +121,7 @@ impl<'a> State<'a> { fn print_expr_struct( &mut self, - qself: &Option<ast::QSelf>, + qself: &Option<P<ast::QSelf>>, path: &ast::Path, fields: &[ast::ExprField], rest: &ast::StructRest, @@ -202,7 +202,7 @@ impl<'a> State<'a> { self.print_expr_maybe_paren(receiver, parser::PREC_POSTFIX); self.word("."); self.print_ident(segment.ident); - if let Some(ref args) = segment.args { + if let Some(args) = &segment.args { self.print_generic_args(args, true); } self.print_call_post(base_args) @@ -284,64 +284,66 @@ impl<'a> State<'a> { self.ibox(INDENT_UNIT); self.ann.pre(self, AnnNode::Expr(expr)); - match expr.kind { - ast::ExprKind::Box(ref expr) => { + match &expr.kind { + ast::ExprKind::Box(expr) => { self.word_space("box"); self.print_expr_maybe_paren(expr, parser::PREC_PREFIX); } - ast::ExprKind::Array(ref exprs) => { + ast::ExprKind::Array(exprs) => { self.print_expr_vec(exprs); } - ast::ExprKind::ConstBlock(ref anon_const) => { + ast::ExprKind::ConstBlock(anon_const) => { self.print_expr_anon_const(anon_const, attrs); } - ast::ExprKind::Repeat(ref element, ref count) => { + ast::ExprKind::Repeat(element, count) => { self.print_expr_repeat(element, count); } - ast::ExprKind::Struct(ref se) => { + ast::ExprKind::Struct(se) => { self.print_expr_struct(&se.qself, &se.path, &se.fields, &se.rest); } - ast::ExprKind::Tup(ref exprs) => { + ast::ExprKind::Tup(exprs) => { self.print_expr_tup(exprs); } - ast::ExprKind::Call(ref func, ref args) => { - self.print_expr_call(func, &args); + ast::ExprKind::Call(func, args) => { + self.print_expr_call(func, args); + } + ast::ExprKind::MethodCall(box ast::MethodCall { seg, receiver, args, .. }) => { + self.print_expr_method_call(seg, receiver, args); } - ast::ExprKind::MethodCall(ref segment, ref receiver, ref args, _) => { - self.print_expr_method_call(segment, &receiver, &args); + ast::ExprKind::Binary(op, lhs, rhs) => { + self.print_expr_binary(*op, lhs, rhs); } - ast::ExprKind::Binary(op, ref lhs, ref rhs) => { - self.print_expr_binary(op, lhs, rhs); + ast::ExprKind::Unary(op, expr) => { + self.print_expr_unary(*op, expr); } - ast::ExprKind::Unary(op, ref expr) => { - self.print_expr_unary(op, expr); + ast::ExprKind::AddrOf(k, m, expr) => { + self.print_expr_addr_of(*k, *m, expr); } - ast::ExprKind::AddrOf(k, m, ref expr) => { - self.print_expr_addr_of(k, m, expr); + ast::ExprKind::Lit(token_lit) => { + self.print_token_literal(*token_lit, expr.span); } - ast::ExprKind::Lit(ref lit) => { - self.print_literal(lit); + ast::ExprKind::IncludedBytes(bytes) => { + let lit = ast::LitKind::ByteStr(bytes.clone()).to_token_lit(); + self.print_token_literal(lit, expr.span) } - ast::ExprKind::Cast(ref expr, ref ty) => { + ast::ExprKind::Cast(expr, ty) => { let prec = AssocOp::As.precedence() as i8; self.print_expr_maybe_paren(expr, prec); self.space(); self.word_space("as"); self.print_type(ty); } - ast::ExprKind::Type(ref expr, ref ty) => { + ast::ExprKind::Type(expr, ty) => { let prec = AssocOp::Colon.precedence() as i8; self.print_expr_maybe_paren(expr, prec); self.word_space(":"); self.print_type(ty); } - ast::ExprKind::Let(ref pat, ref scrutinee, _) => { + ast::ExprKind::Let(pat, scrutinee, _) => { self.print_let(pat, scrutinee); } - ast::ExprKind::If(ref test, ref blk, ref elseopt) => { - self.print_if(test, blk, elseopt.as_deref()) - } - ast::ExprKind::While(ref test, ref blk, opt_label) => { + ast::ExprKind::If(test, blk, elseopt) => self.print_if(test, blk, elseopt.as_deref()), + ast::ExprKind::While(test, blk, opt_label) => { if let Some(label) = opt_label { self.print_ident(label.ident); self.word_space(":"); @@ -353,7 +355,7 @@ impl<'a> State<'a> { self.space(); self.print_block_with_attrs(blk, attrs); } - ast::ExprKind::ForLoop(ref pat, ref iter, ref blk, opt_label) => { + ast::ExprKind::ForLoop(pat, iter, blk, opt_label) => { if let Some(label) = opt_label { self.print_ident(label.ident); self.word_space(":"); @@ -368,7 +370,7 @@ impl<'a> State<'a> { self.space(); self.print_block_with_attrs(blk, attrs); } - ast::ExprKind::Loop(ref blk, opt_label) => { + ast::ExprKind::Loop(blk, opt_label, _) => { if let Some(label) = opt_label { self.print_ident(label.ident); self.word_space(":"); @@ -378,7 +380,7 @@ impl<'a> State<'a> { self.word_nbsp("loop"); self.print_block_with_attrs(blk, attrs); } - ast::ExprKind::Match(ref expr, ref arms) => { + ast::ExprKind::Match(expr, arms) => { self.cbox(0); self.ibox(0); self.word_nbsp("match"); @@ -392,21 +394,22 @@ impl<'a> State<'a> { let empty = attrs.is_empty() && arms.is_empty(); self.bclose(expr.span, empty); } - ast::ExprKind::Closure( - ref binder, + ast::ExprKind::Closure(box ast::Closure { + binder, capture_clause, asyncness, movability, - ref decl, - ref body, - _, - ) => { + fn_decl, + body, + fn_decl_span: _, + fn_arg_span: _, + }) => { self.print_closure_binder(binder); - self.print_movability(movability); - self.print_asyncness(asyncness); - self.print_capture_clause(capture_clause); + self.print_movability(*movability); + self.print_asyncness(*asyncness); + self.print_capture_clause(*capture_clause); - self.print_fn_params_and_ret(decl, true); + self.print_fn_params_and_ret(fn_decl, true); self.space(); self.print_expr(body); self.end(); // need to close a box @@ -416,7 +419,7 @@ impl<'a> State<'a> { // empty box to satisfy the close. self.ibox(0); } - ast::ExprKind::Block(ref blk, opt_label) => { + ast::ExprKind::Block(blk, opt_label) => { if let Some(label) = opt_label { self.print_ident(label.ident); self.word_space(":"); @@ -427,26 +430,26 @@ impl<'a> State<'a> { self.ibox(0); self.print_block_with_attrs(blk, attrs); } - ast::ExprKind::Async(capture_clause, _, ref blk) => { + ast::ExprKind::Async(capture_clause, _, blk) => { self.word_nbsp("async"); - self.print_capture_clause(capture_clause); + self.print_capture_clause(*capture_clause); // cbox/ibox in analogy to the `ExprKind::Block` arm above self.cbox(0); self.ibox(0); self.print_block_with_attrs(blk, attrs); } - ast::ExprKind::Await(ref expr) => { + ast::ExprKind::Await(expr) => { self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX); self.word(".await"); } - ast::ExprKind::Assign(ref lhs, ref rhs, _) => { + ast::ExprKind::Assign(lhs, rhs, _) => { let prec = AssocOp::Assign.precedence() as i8; self.print_expr_maybe_paren(lhs, prec + 1); self.space(); self.word_space("="); self.print_expr_maybe_paren(rhs, prec); } - ast::ExprKind::AssignOp(op, ref lhs, ref rhs) => { + ast::ExprKind::AssignOp(op, lhs, rhs) => { let prec = AssocOp::Assign.precedence() as i8; self.print_expr_maybe_paren(lhs, prec + 1); self.space(); @@ -454,45 +457,44 @@ impl<'a> State<'a> { self.word_space("="); self.print_expr_maybe_paren(rhs, prec); } - ast::ExprKind::Field(ref expr, ident) => { + ast::ExprKind::Field(expr, ident) => { self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX); self.word("."); - self.print_ident(ident); + self.print_ident(*ident); } - ast::ExprKind::Index(ref expr, ref index) => { + ast::ExprKind::Index(expr, index) => { self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX); self.word("["); self.print_expr(index); self.word("]"); } - ast::ExprKind::Range(ref start, ref end, limits) => { + ast::ExprKind::Range(start, end, limits) => { // Special case for `Range`. `AssocOp` claims that `Range` has higher precedence // than `Assign`, but `x .. x = x` gives a parse error instead of `x .. (x = x)`. // Here we use a fake precedence value so that any child with lower precedence than // a "normal" binop gets parenthesized. (`LOr` is the lowest-precedence binop.) let fake_prec = AssocOp::LOr.precedence() as i8; - if let Some(ref e) = *start { + if let Some(e) = start { self.print_expr_maybe_paren(e, fake_prec); } - if limits == ast::RangeLimits::HalfOpen { - self.word(".."); - } else { - self.word("..="); + match limits { + ast::RangeLimits::HalfOpen => self.word(".."), + ast::RangeLimits::Closed => self.word("..="), } - if let Some(ref e) = *end { + if let Some(e) = end { self.print_expr_maybe_paren(e, fake_prec); } } ast::ExprKind::Underscore => self.word("_"), - ast::ExprKind::Path(None, ref path) => self.print_path(path, true, 0), - ast::ExprKind::Path(Some(ref qself), ref path) => self.print_qpath(path, qself, true), - ast::ExprKind::Break(opt_label, ref opt_expr) => { + ast::ExprKind::Path(None, path) => self.print_path(path, true, 0), + ast::ExprKind::Path(Some(qself), path) => self.print_qpath(path, qself, true), + ast::ExprKind::Break(opt_label, opt_expr) => { self.word("break"); if let Some(label) = opt_label { self.space(); self.print_ident(label.ident); } - if let Some(ref expr) = *opt_expr { + if let Some(expr) = opt_expr { self.space(); self.print_expr_maybe_paren(expr, parser::PREC_JUMP); } @@ -504,45 +506,45 @@ impl<'a> State<'a> { self.print_ident(label.ident); } } - ast::ExprKind::Ret(ref result) => { + ast::ExprKind::Ret(result) => { self.word("return"); - if let Some(ref expr) = *result { + if let Some(expr) = result { self.word(" "); self.print_expr_maybe_paren(expr, parser::PREC_JUMP); } } - ast::ExprKind::Yeet(ref result) => { + ast::ExprKind::Yeet(result) => { self.word("do"); self.word(" "); self.word("yeet"); - if let Some(ref expr) = *result { + if let Some(expr) = result { self.word(" "); self.print_expr_maybe_paren(expr, parser::PREC_JUMP); } } - ast::ExprKind::InlineAsm(ref a) => { + ast::ExprKind::InlineAsm(a) => { self.word("asm!"); self.print_inline_asm(a); } - ast::ExprKind::MacCall(ref m) => self.print_mac(m), - ast::ExprKind::Paren(ref e) => { + ast::ExprKind::MacCall(m) => self.print_mac(m), + ast::ExprKind::Paren(e) => { self.popen(); self.print_expr(e); self.pclose(); } - ast::ExprKind::Yield(ref e) => { + ast::ExprKind::Yield(e) => { self.word("yield"); - if let Some(ref expr) = *e { + if let Some(expr) = e { self.space(); self.print_expr_maybe_paren(expr, parser::PREC_JUMP); } } - ast::ExprKind::Try(ref e) => { + ast::ExprKind::Try(e) => { self.print_expr_maybe_paren(e, parser::PREC_POSTFIX); self.word("?") } - ast::ExprKind::TryBlock(ref blk) => { + ast::ExprKind::TryBlock(blk) => { self.cbox(0); self.ibox(0); self.word_nbsp("try"); @@ -569,15 +571,15 @@ impl<'a> State<'a> { self.print_outer_attributes(&arm.attrs); self.print_pat(&arm.pat); self.space(); - if let Some(ref e) = arm.guard { + if let Some(e) = &arm.guard { self.word_space("if"); self.print_expr(e); self.space(); } self.word_space("=>"); - match arm.body.kind { - ast::ExprKind::Block(ref blk, opt_label) => { + match &arm.body.kind { + ast::ExprKind::Block(blk, opt_label) => { if let Some(label) = opt_label { self.print_ident(label.ident); self.word_space(":"); @@ -604,7 +606,7 @@ impl<'a> State<'a> { match binder { ast::ClosureBinder::NotPresent => {} ast::ClosureBinder::For { generic_params, .. } => { - self.print_formal_generic_params(&generic_params) + self.print_formal_generic_params(generic_params) } } } diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs index 159853c9e..5b6a07721 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs @@ -136,10 +136,10 @@ impl<'a> State<'a> { self.maybe_print_comment(item.span.lo()); self.print_outer_attributes(&item.attrs); self.ann.pre(self, AnnNode::Item(item)); - match item.kind { + match &item.kind { ast::ItemKind::ExternCrate(orig_name) => { self.head(visibility_qualified(&item.vis, "extern crate")); - if let Some(orig_name) = orig_name { + if let &Some(orig_name) = orig_name { self.print_name(orig_name); self.space(); self.word("as"); @@ -150,35 +150,41 @@ impl<'a> State<'a> { self.end(); // end inner head-block self.end(); // end outer head-block } - ast::ItemKind::Use(ref tree) => { + ast::ItemKind::Use(tree) => { self.print_visibility(&item.vis); self.word_nbsp("use"); self.print_use_tree(tree); self.word(";"); } - ast::ItemKind::Static(ref ty, mutbl, ref body) => { + ast::ItemKind::Static(ty, mutbl, body) => { let def = ast::Defaultness::Final; - self.print_item_const(item.ident, Some(mutbl), ty, body.as_deref(), &item.vis, def); + self.print_item_const( + item.ident, + Some(*mutbl), + ty, + body.as_deref(), + &item.vis, + def, + ); } - ast::ItemKind::Const(def, ref ty, ref body) => { - self.print_item_const(item.ident, None, ty, body.as_deref(), &item.vis, def); + ast::ItemKind::Const(def, ty, body) => { + self.print_item_const(item.ident, None, ty, body.as_deref(), &item.vis, *def); } - ast::ItemKind::Fn(box ast::Fn { defaultness, ref sig, ref generics, ref body }) => { - let body = body.as_deref(); + ast::ItemKind::Fn(box ast::Fn { defaultness, sig, generics, body }) => { self.print_fn_full( sig, item.ident, generics, &item.vis, - defaultness, - body, + *defaultness, + body.as_deref(), &item.attrs, ); } - ast::ItemKind::Mod(unsafety, ref mod_kind) => { + ast::ItemKind::Mod(unsafety, mod_kind) => { self.head(Self::to_string(|s| { s.print_visibility(&item.vis); - s.print_unsafety(unsafety); + s.print_unsafety(*unsafety); s.word("mod"); })); self.print_ident(item.ident); @@ -201,13 +207,13 @@ impl<'a> State<'a> { } } } - ast::ItemKind::ForeignMod(ref nmod) => { + ast::ItemKind::ForeignMod(nmod) => { self.head(Self::to_string(|s| { s.print_unsafety(nmod.unsafety); s.word("extern"); })); if let Some(abi) = nmod.abi { - self.print_literal(&abi.as_lit()); + self.print_token_literal(abi.as_token_lit(), abi.span); self.nbsp(); } self.bopen(); @@ -215,7 +221,7 @@ impl<'a> State<'a> { let empty = item.attrs.is_empty() && nmod.items.is_empty(); self.bclose(item.span, empty); } - ast::ItemKind::GlobalAsm(ref asm) => { + ast::ItemKind::GlobalAsm(asm) => { self.head(visibility_qualified(&item.vis, "global_asm!")); self.print_inline_asm(asm); self.word(";"); @@ -224,32 +230,31 @@ impl<'a> State<'a> { } ast::ItemKind::TyAlias(box ast::TyAlias { defaultness, - ref generics, + generics, where_clauses, where_predicates_split, - ref bounds, - ref ty, + bounds, + ty, }) => { - let ty = ty.as_deref(); self.print_associated_type( item.ident, generics, - where_clauses, - where_predicates_split, + *where_clauses, + *where_predicates_split, bounds, - ty, + ty.as_deref(), &item.vis, - defaultness, + *defaultness, ); } - ast::ItemKind::Enum(ref enum_definition, ref params) => { + ast::ItemKind::Enum(enum_definition, params) => { self.print_enum_def(enum_definition, params, item.ident, item.span, &item.vis); } - ast::ItemKind::Struct(ref struct_def, ref generics) => { + ast::ItemKind::Struct(struct_def, generics) => { self.head(visibility_qualified(&item.vis, "struct")); self.print_struct(struct_def, generics, item.ident, item.span, true); } - ast::ItemKind::Union(ref struct_def, ref generics) => { + ast::ItemKind::Union(struct_def, generics) => { self.head(visibility_qualified(&item.vis, "union")); self.print_struct(struct_def, generics, item.ident, item.span, true); } @@ -258,15 +263,15 @@ impl<'a> State<'a> { polarity, defaultness, constness, - ref generics, - ref of_trait, - ref self_ty, - ref items, + generics, + of_trait, + self_ty, + items, }) => { self.head(""); self.print_visibility(&item.vis); - self.print_defaultness(defaultness); - self.print_unsafety(unsafety); + self.print_defaultness(*defaultness); + self.print_unsafety(*unsafety); self.word("impl"); if generics.params.is_empty() { @@ -276,13 +281,13 @@ impl<'a> State<'a> { self.space(); } - self.print_constness(constness); + self.print_constness(*constness); if let ast::ImplPolarity::Negative(_) = polarity { self.word("!"); } - if let Some(ref t) = *of_trait { + if let Some(t) = of_trait { self.print_trait_ref(t); self.space(); self.word_space("for"); @@ -303,21 +308,21 @@ impl<'a> State<'a> { ast::ItemKind::Trait(box ast::Trait { is_auto, unsafety, - ref generics, - ref bounds, - ref items, + generics, + bounds, + items, .. }) => { self.head(""); self.print_visibility(&item.vis); - self.print_unsafety(unsafety); - self.print_is_auto(is_auto); + self.print_unsafety(*unsafety); + self.print_is_auto(*is_auto); self.word_nbsp("trait"); self.print_ident(item.ident); self.print_generic_params(&generics.params); let mut real_bounds = Vec::with_capacity(bounds.len()); for b in bounds.iter() { - if let GenericBound::Trait(ref ptr, ast::TraitBoundModifier::Maybe) = *b { + if let GenericBound::Trait(ptr, ast::TraitBoundModifier::Maybe) = b { self.space(); self.word_space("for ?"); self.print_trait_ref(&ptr.trait_ref); @@ -339,38 +344,27 @@ impl<'a> State<'a> { let empty = item.attrs.is_empty() && items.is_empty(); self.bclose(item.span, empty); } - ast::ItemKind::TraitAlias(ref generics, ref bounds) => { + ast::ItemKind::TraitAlias(generics, bounds) => { self.head(visibility_qualified(&item.vis, "trait")); self.print_ident(item.ident); self.print_generic_params(&generics.params); - let mut real_bounds = Vec::with_capacity(bounds.len()); - // FIXME(durka) this seems to be some quite outdated syntax - for b in bounds.iter() { - if let GenericBound::Trait(ref ptr, ast::TraitBoundModifier::Maybe) = *b { - self.space(); - self.word_space("for ?"); - self.print_trait_ref(&ptr.trait_ref); - } else { - real_bounds.push(b.clone()); - } - } self.nbsp(); - if !real_bounds.is_empty() { + if !bounds.is_empty() { self.word_nbsp("="); - self.print_type_bounds(&real_bounds); + self.print_type_bounds(&bounds); } self.print_where_clause(&generics.where_clause); self.word(";"); self.end(); // end inner head-block self.end(); // end outer head-block } - ast::ItemKind::MacCall(ref mac) => { + ast::ItemKind::MacCall(mac) => { self.print_mac(mac); if mac.args.need_semicolon() { self.word(";"); } } - ast::ItemKind::MacroDef(ref macro_def) => { + ast::ItemKind::MacroDef(macro_def) => { self.print_mac_def(macro_def, &item.ident, item.span, |state| { state.print_visibility(&item.vis) }); @@ -412,11 +406,11 @@ impl<'a> State<'a> { } pub(crate) fn print_visibility(&mut self, vis: &ast::Visibility) { - match vis.kind { + match &vis.kind { ast::VisibilityKind::Public => self.word_nbsp("pub"), - ast::VisibilityKind::Restricted { ref path, id: _, shorthand } => { + ast::VisibilityKind::Restricted { path, shorthand, .. } => { let path = Self::to_string(|s| s.print_path(path, false, 0)); - if shorthand && (path == "crate" || path == "self" || path == "super") { + if *shorthand && (path == "crate" || path == "self" || path == "super") { self.word_nbsp(format!("pub({})", path)) } else { self.word_nbsp(format!("pub(in {})", path)) @@ -465,7 +459,7 @@ impl<'a> State<'a> { ) { self.print_ident(ident); self.print_generic_params(&generics.params); - match struct_def { + match &struct_def { ast::VariantData::Tuple(..) | ast::VariantData::Unit(..) => { if let ast::VariantData::Tuple(..) = struct_def { self.popen(); @@ -484,7 +478,7 @@ impl<'a> State<'a> { self.end(); self.end(); // Close the outer-box. } - ast::VariantData::Struct(ref fields, ..) => { + ast::VariantData::Struct(fields, ..) => { self.print_where_clause(&generics.where_clause); self.print_record_struct_body(fields, span); } @@ -496,7 +490,7 @@ impl<'a> State<'a> { self.print_visibility(&v.vis); let generics = ast::Generics::default(); self.print_struct(&v.data, &generics, v.ident, v.span, false); - if let Some(ref d) = v.disr_expr { + if let Some(d) = &v.disr_expr { self.space(); self.word_space("="); self.print_expr(&d.value) @@ -657,10 +651,10 @@ impl<'a> State<'a> { } fn print_use_tree(&mut self, tree: &ast::UseTree) { - match tree.kind { - ast::UseTreeKind::Simple(rename, ..) => { + match &tree.kind { + ast::UseTreeKind::Simple(rename) => { self.print_path(&tree.prefix, false, 0); - if let Some(rename) = rename { + if let &Some(rename) = rename { self.nbsp(); self.word_nbsp("as"); self.print_ident(rename); @@ -673,7 +667,7 @@ impl<'a> State<'a> { } self.word("*"); } - ast::UseTreeKind::Nested(ref items) => { + ast::UseTreeKind::Nested(items) => { if !tree.prefix.segments.is_empty() { self.print_path(&tree.prefix, false, 0); self.word("::"); |