diff options
Diffstat (limited to 'compiler/rustc_ast/src')
-rw-r--r-- | compiler/rustc_ast/src/ast.rs | 266 | ||||
-rw-r--r-- | compiler/rustc_ast/src/ast_traits.rs | 90 | ||||
-rw-r--r-- | compiler/rustc_ast/src/attr/mod.rs | 153 | ||||
-rw-r--r-- | compiler/rustc_ast/src/lib.rs | 8 | ||||
-rw-r--r-- | compiler/rustc_ast/src/mut_visit.rs | 77 | ||||
-rw-r--r-- | compiler/rustc_ast/src/node_id.rs | 2 | ||||
-rw-r--r-- | compiler/rustc_ast/src/token.rs | 49 | ||||
-rw-r--r-- | compiler/rustc_ast/src/tokenstream.rs | 127 | ||||
-rw-r--r-- | compiler/rustc_ast/src/util/literal.rs | 32 | ||||
-rw-r--r-- | compiler/rustc_ast/src/util/parser.rs | 68 | ||||
-rw-r--r-- | compiler/rustc_ast/src/visit.rs | 66 |
11 files changed, 497 insertions, 441 deletions
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 870a7c0be..d86db8f8b 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -24,22 +24,19 @@ pub use UnsafeSource::*; use crate::ptr::P; use crate::token::{self, CommentKind, Delimiter}; -use crate::tokenstream::{DelimSpan, LazyTokenStream, TokenStream}; - +use crate::tokenstream::{DelimSpan, LazyAttrTokenStream, TokenStream}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_data_structures::sync::Lrc; -use rustc_data_structures::thin_vec::ThinVec; use rustc_macros::HashStable_Generic; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use rustc_span::source_map::{respan, Spanned}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{Span, DUMMY_SP}; - -use std::cmp::Ordering; use std::convert::TryFrom; use std::fmt; use std::mem; +use thin_vec::ThinVec; /// A "Label" is an identifier of some point in sources, /// e.g. in the following code: @@ -94,7 +91,7 @@ pub struct Path { /// The segments in the path: the things separated by `::`. /// Global paths begin with `kw::PathRoot`. pub segments: Vec<PathSegment>, - pub tokens: Option<LazyTokenStream>, + pub tokens: Option<LazyAttrTokenStream>, } impl PartialEq<Symbol> for Path { @@ -326,46 +323,17 @@ pub type GenericBounds = Vec<GenericBound>; /// Specifies the enforced ordering for generic parameters. In the future, /// if we wanted to relax this order, we could override `PartialEq` and /// `PartialOrd`, to allow the kinds to be unordered. -#[derive(Hash, Clone, Copy)] +#[derive(Hash, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub enum ParamKindOrd { Lifetime, - Type, - Const, - // `Infer` is not actually constructed directly from the AST, but is implicitly constructed - // during HIR lowering, and `ParamKindOrd` will implicitly order inferred variables last. - Infer, -} - -impl Ord for ParamKindOrd { - fn cmp(&self, other: &Self) -> Ordering { - use ParamKindOrd::*; - let to_int = |v| match v { - Lifetime => 0, - Infer | Type | Const => 1, - }; - - to_int(*self).cmp(&to_int(*other)) - } -} -impl PartialOrd for ParamKindOrd { - fn partial_cmp(&self, other: &Self) -> Option<Ordering> { - Some(self.cmp(other)) - } + TypeOrConst, } -impl PartialEq for ParamKindOrd { - fn eq(&self, other: &Self) -> bool { - self.cmp(other) == Ordering::Equal - } -} -impl Eq for ParamKindOrd {} impl fmt::Display for ParamKindOrd { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { ParamKindOrd::Lifetime => "lifetime".fmt(f), - ParamKindOrd::Type => "type".fmt(f), - ParamKindOrd::Const { .. } => "const".fmt(f), - ParamKindOrd::Infer => "infer".fmt(f), + ParamKindOrd::TypeOrConst => "type and const".fmt(f), } } } @@ -497,7 +465,6 @@ pub struct WhereRegionPredicate { /// E.g., `T = int`. #[derive(Clone, Encodable, Decodable, Debug)] pub struct WhereEqPredicate { - pub id: NodeId, pub span: Span, pub lhs_ty: P<Ty>, pub rhs_ty: P<Ty>, @@ -505,7 +472,7 @@ pub struct WhereEqPredicate { #[derive(Clone, Encodable, Decodable, Debug)] pub struct Crate { - pub attrs: Vec<Attribute>, + pub attrs: AttrVec, pub items: Vec<P<Item>>, pub spans: ModSpans, /// Must be equal to `CRATE_NODE_ID` after the crate root is expanded, but may hold @@ -567,7 +534,7 @@ pub struct Block { /// Distinguishes between `unsafe { ... }` and `{ ... }`. pub rules: BlockCheckMode, pub span: Span, - pub tokens: Option<LazyTokenStream>, + pub tokens: Option<LazyAttrTokenStream>, /// The following *isn't* a parse error, but will cause multiple errors in following stages. /// ```compile_fail /// let x = { @@ -586,7 +553,7 @@ pub struct Pat { pub id: NodeId, pub kind: PatKind, pub span: Span, - pub tokens: Option<LazyTokenStream>, + pub tokens: Option<LazyAttrTokenStream>, } impl Pat { @@ -597,7 +564,7 @@ impl Pat { // In a type expression `_` is an inference variable. PatKind::Wild => TyKind::Infer, // An IDENT pattern with no binding mode would be valid as path to a type. E.g. `u32`. - PatKind::Ident(BindingMode::ByValue(Mutability::Not), ident, None) => { + PatKind::Ident(BindingAnnotation::NONE, ident, None) => { TyKind::Path(None, Path::from_ident(*ident)) } PatKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()), @@ -684,10 +651,43 @@ pub struct PatField { pub is_placeholder: bool, } -#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy)] -pub enum BindingMode { - ByRef(Mutability), - ByValue(Mutability), +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +#[derive(Encodable, Decodable, HashStable_Generic)] +pub enum ByRef { + Yes, + No, +} + +impl From<bool> for ByRef { + fn from(b: bool) -> ByRef { + match b { + false => ByRef::No, + true => ByRef::Yes, + } + } +} + +/// Explicit binding annotations given in the HIR for a binding. Note +/// that this is not the final binding *mode* that we infer after type +/// inference. +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +#[derive(Encodable, Decodable, HashStable_Generic)] +pub struct BindingAnnotation(pub ByRef, pub Mutability); + +impl BindingAnnotation { + pub const NONE: Self = Self(ByRef::No, Mutability::Not); + pub const REF: Self = Self(ByRef::Yes, Mutability::Not); + pub const MUT: Self = Self(ByRef::No, Mutability::Mut); + pub const REF_MUT: Self = Self(ByRef::Yes, Mutability::Mut); + + pub fn prefix_str(self) -> &'static str { + match self { + Self::NONE => "", + Self::REF => "ref ", + Self::MUT => "mut ", + Self::REF_MUT => "ref mut ", + } + } } #[derive(Clone, Encodable, Decodable, Debug)] @@ -716,7 +716,7 @@ pub enum PatKind { /// or a unit struct/variant pattern, or a const pattern (in the last two cases the third /// field must be `None`). Disambiguation cannot be done with parser alone, so it happens /// during name resolution. - Ident(BindingMode, Ident, Option<P<Pat>>), + Ident(BindingAnnotation, Ident, Option<P<Pat>>), /// A struct or struct variant pattern (e.g., `Variant {x, y, ..}`). /// The `bool` is `true` in the presence of a `..`. @@ -771,7 +771,7 @@ pub enum PatKind { Paren(P<Pat>), /// A macro pattern; pre-expansion. - MacCall(MacCall), + MacCall(P<MacCall>), } #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Copy)] @@ -937,8 +937,8 @@ impl Stmt { /// a trailing semicolon. /// /// This only modifies the parsed AST struct, not the attached - /// `LazyTokenStream`. The parser is responsible for calling - /// `CreateTokenStream::add_trailing_semi` when there is actually + /// `LazyAttrTokenStream`. The parser is responsible for calling + /// `ToAttrTokenStream::add_trailing_semi` when there is actually /// a semicolon in the tokenstream. pub fn add_trailing_semicolon(mut self) -> Self { self.kind = match self.kind { @@ -981,10 +981,10 @@ pub enum StmtKind { #[derive(Clone, Encodable, Decodable, Debug)] pub struct MacCallStmt { - pub mac: MacCall, + pub mac: P<MacCall>, pub style: MacStmtStyle, pub attrs: AttrVec, - pub tokens: Option<LazyTokenStream>, + pub tokens: Option<LazyAttrTokenStream>, } #[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug)] @@ -1009,7 +1009,7 @@ pub struct Local { pub kind: LocalKind, pub span: Span, pub attrs: AttrVec, - pub tokens: Option<LazyTokenStream>, + pub tokens: Option<LazyAttrTokenStream>, } #[derive(Clone, Encodable, Decodable, Debug)] @@ -1108,7 +1108,7 @@ pub struct Expr { pub kind: ExprKind, pub span: Span, pub attrs: AttrVec, - pub tokens: Option<LazyTokenStream>, + pub tokens: Option<LazyAttrTokenStream>, } impl Expr { @@ -1269,7 +1269,7 @@ impl Expr { id: DUMMY_NODE_ID, kind: ExprKind::Err, span: DUMMY_SP, - attrs: ThinVec::new(), + attrs: AttrVec::new(), tokens: None, }, ) @@ -1439,7 +1439,7 @@ pub enum ExprKind { InlineAsm(P<InlineAsm>), /// A macro invocation; pre-expansion. - MacCall(MacCall), + MacCall(P<MacCall>), /// A struct literal expression. /// @@ -1691,7 +1691,7 @@ pub enum StrStyle { #[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)] pub struct Lit { /// The original literal token as written in source code. - pub token: token::Lit, + 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. @@ -1719,7 +1719,7 @@ impl StrLit { StrStyle::Raw(n) => token::StrRaw(n), }; Lit { - token: token::Lit::new(token_kind, self.symbol, self.suffix), + token_lit: token::Lit::new(token_kind, self.symbol, self.suffix), span: self.span, kind: LitKind::Str(self.symbol_unescaped, self.style), } @@ -1753,7 +1753,8 @@ pub enum LitFloatType { /// E.g., `"foo"`, `42`, `12.34`, or `bool`. #[derive(Clone, Encodable, Decodable, Debug, Hash, Eq, PartialEq, HashStable_Generic)] pub enum LitKind { - /// A string literal (`"foo"`). + /// A string literal (`"foo"`). The symbol is unescaped, and so may differ + /// from the original token's symbol. Str(Symbol, StrStyle), /// A byte string (`b"foo"`). ByteStr(Lrc<[u8]>), @@ -1763,12 +1764,13 @@ pub enum LitKind { Char(char), /// An integer literal (`1`). Int(u128, LitIntType), - /// A float literal (`1f64` or `1E10f64`). + /// A float literal (`1f64` or `1E10f64`). Stored as a symbol rather than + /// `f64` so that `LitKind` can impl `Eq` and `Hash`. Float(Symbol, LitFloatType), /// A boolean literal. Bool(bool), /// Placeholder for a literal that wasn't well-formed in some way. - Err(Symbol), + Err, } impl LitKind { @@ -1807,7 +1809,7 @@ impl LitKind { | LitKind::Int(_, LitIntType::Unsuffixed) | LitKind::Float(_, LitFloatType::Unsuffixed) | LitKind::Bool(..) - | LitKind::Err(..) => false, + | LitKind::Err => false, } } } @@ -1966,7 +1968,7 @@ pub struct Ty { pub id: NodeId, pub kind: TyKind, pub span: Span, - pub tokens: Option<LazyTokenStream>, + pub tokens: Option<LazyAttrTokenStream>, } impl Clone for Ty { @@ -2042,7 +2044,7 @@ pub enum TyKind { /// Inferred type of a `self` or `&self` argument in a method. ImplicitSelf, /// A macro in the type position. - MacCall(MacCall), + MacCall(P<MacCall>), /// Placeholder for a kind that has failed to be defined. Err, /// Placeholder for a `va_list`. @@ -2059,8 +2061,11 @@ impl TyKind { } pub fn is_simple_path(&self) -> Option<Symbol> { - if let TyKind::Path(None, Path { segments, .. }) = &self && segments.len() == 1 { - Some(segments[0].ident.name) + if let TyKind::Path(None, Path { segments, .. }) = &self + && let [segment] = &segments[..] + && segment.args.is_none() + { + Some(segment.ident.name) } else { None } @@ -2071,6 +2076,7 @@ impl TyKind { #[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)] pub enum TraitObjectSyntax { Dyn, + DynStar, None, } @@ -2086,15 +2092,15 @@ pub enum InlineAsmRegOrRegClass { bitflags::bitflags! { #[derive(Encodable, Decodable, HashStable_Generic)] pub struct InlineAsmOptions: u16 { - const PURE = 1 << 0; - const NOMEM = 1 << 1; - const READONLY = 1 << 2; + const PURE = 1 << 0; + const NOMEM = 1 << 1; + const READONLY = 1 << 2; const PRESERVES_FLAGS = 1 << 3; - const NORETURN = 1 << 4; - const NOSTACK = 1 << 5; - const ATT_SYNTAX = 1 << 6; - const RAW = 1 << 7; - const MAY_UNWIND = 1 << 8; + const NORETURN = 1 << 4; + const NOSTACK = 1 << 5; + const ATT_SYNTAX = 1 << 6; + const RAW = 1 << 7; + const MAY_UNWIND = 1 << 8; } } @@ -2230,7 +2236,7 @@ pub type ExplicitSelf = Spanned<SelfKind>; impl Param { /// Attempts to cast parameter to `ExplicitSelf`. pub fn to_self(&self) -> Option<ExplicitSelf> { - if let PatKind::Ident(BindingMode::ByValue(mutbl), ident, _) = self.pat.kind { + if let PatKind::Ident(BindingAnnotation(ByRef::No, mutbl), ident, _) = self.pat.kind { if ident.name == kw::SelfLower { return match self.ty.kind { TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))), @@ -2260,11 +2266,24 @@ impl Param { pub fn from_self(attrs: AttrVec, eself: ExplicitSelf, eself_ident: Ident) -> Param { let span = eself.span.to(eself_ident.span); let infer_ty = P(Ty { id: DUMMY_NODE_ID, kind: TyKind::ImplicitSelf, span, tokens: None }); - let param = |mutbl, ty| Param { + let (mutbl, ty) = match eself.node { + SelfKind::Explicit(ty, mutbl) => (mutbl, ty), + SelfKind::Value(mutbl) => (mutbl, infer_ty), + SelfKind::Region(lt, mutbl) => ( + Mutability::Not, + P(Ty { + id: DUMMY_NODE_ID, + kind: TyKind::Rptr(lt, MutTy { ty: infer_ty, mutbl }), + span, + tokens: None, + }), + ), + }; + Param { attrs, pat: P(Pat { id: DUMMY_NODE_ID, - kind: PatKind::Ident(BindingMode::ByValue(mutbl), eself_ident, None), + kind: PatKind::Ident(BindingAnnotation(ByRef::No, mutbl), eself_ident, None), span, tokens: None, }), @@ -2272,19 +2291,6 @@ impl Param { ty, id: DUMMY_NODE_ID, is_placeholder: false, - }; - match eself.node { - SelfKind::Explicit(ty, mutbl) => param(mutbl, ty), - SelfKind::Value(mutbl) => param(mutbl, infer_ty), - SelfKind::Region(lt, mutbl) => param( - Mutability::Not, - P(Ty { - id: DUMMY_NODE_ID, - kind: TyKind::Rptr(lt, MutTy { ty: infer_ty, mutbl }), - span, - tokens: None, - }), - ), } } } @@ -2336,9 +2342,9 @@ impl Async { } /// In this case this is an `async` return, the `NodeId` for the generated `impl Trait` item. - pub fn opt_return_id(self) -> Option<NodeId> { + pub fn opt_return_id(self) -> Option<(NodeId, Span)> { match self { - Async::Yes { return_impl_trait_id, .. } => Some(return_impl_trait_id), + Async::Yes { return_impl_trait_id, span, .. } => Some((return_impl_trait_id, span)), Async::No => None, } } @@ -2522,8 +2528,8 @@ impl<S: Encoder> Encodable<S> for AttrId { } impl<D: Decoder> Decodable<D> for AttrId { - fn decode(_: &mut D) -> AttrId { - crate::attr::mk_attr_id() + default fn decode(_: &mut D) -> AttrId { + panic!("cannot decode `AttrId` with `{}`", std::any::type_name::<D>()); } } @@ -2531,7 +2537,7 @@ impl<D: Decoder> Decodable<D> for AttrId { pub struct AttrItem { pub path: Path, pub args: MacArgs, - pub tokens: Option<LazyTokenStream>, + pub tokens: Option<LazyAttrTokenStream>, } /// A list of attributes. @@ -2549,9 +2555,15 @@ 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(AttrItem, Option<LazyTokenStream>), + Normal(P<NormalAttr>), /// A doc comment (e.g. `/// ...`, `//! ...`, `/** ... */`, `/*! ... */`). /// Doc attributes (e.g. `#[doc="..."]`) are represented with the `Normal` @@ -2596,13 +2608,13 @@ impl PolyTraitRef { pub struct Visibility { pub kind: VisibilityKind, pub span: Span, - pub tokens: Option<LazyTokenStream>, + pub tokens: Option<LazyAttrTokenStream>, } #[derive(Clone, Encodable, Decodable, Debug)] pub enum VisibilityKind { Public, - Restricted { path: P<Path>, id: NodeId }, + Restricted { path: P<Path>, id: NodeId, shorthand: bool }, Inherited, } @@ -2665,7 +2677,7 @@ impl VariantData { /// An item definition. #[derive(Clone, Encodable, Decodable, Debug)] pub struct Item<K = ItemKind> { - pub attrs: Vec<Attribute>, + pub attrs: AttrVec, pub id: NodeId, pub span: Span, pub vis: Visibility, @@ -2682,7 +2694,7 @@ pub struct Item<K = ItemKind> { /// /// Note that the tokens here do not include the outer attributes, but will /// include inner attributes. - pub tokens: Option<LazyTokenStream>, + pub tokens: Option<LazyAttrTokenStream>, } impl Item { @@ -2873,7 +2885,7 @@ pub enum ItemKind { /// A macro invocation. /// /// E.g., `foo!(..)`. - MacCall(MacCall), + MacCall(P<MacCall>), /// A macro definition. MacroDef(MacroDef), @@ -2947,7 +2959,7 @@ pub enum AssocItemKind { /// An associated type. TyAlias(Box<TyAlias>), /// A macro expanding to associated items. - MacCall(MacCall), + MacCall(P<MacCall>), } impl AssocItemKind { @@ -2996,7 +3008,7 @@ pub enum ForeignItemKind { /// An foreign type. TyAlias(Box<TyAlias>), /// A macro expanding to foreign items. - MacCall(MacCall), + MacCall(P<MacCall>), } impl From<ForeignItemKind> for ItemKind { @@ -3030,22 +3042,34 @@ pub type ForeignItem = Item<ForeignItemKind>; #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] mod size_asserts { use super::*; + use rustc_data_structures::static_assert_size; // These are in alphabetical order, which is easy to maintain. - rustc_data_structures::static_assert_size!(AssocItemKind, 72); - rustc_data_structures::static_assert_size!(Attribute, 152); - rustc_data_structures::static_assert_size!(Block, 48); - rustc_data_structures::static_assert_size!(Expr, 104); - rustc_data_structures::static_assert_size!(Fn, 192); - rustc_data_structures::static_assert_size!(ForeignItemKind, 72); - rustc_data_structures::static_assert_size!(GenericBound, 88); - rustc_data_structures::static_assert_size!(Generics, 72); - rustc_data_structures::static_assert_size!(Impl, 200); - rustc_data_structures::static_assert_size!(Item, 200); - rustc_data_structures::static_assert_size!(ItemKind, 112); - rustc_data_structures::static_assert_size!(Lit, 48); - rustc_data_structures::static_assert_size!(Pat, 120); - rustc_data_structures::static_assert_size!(Path, 40); - rustc_data_structures::static_assert_size!(PathSegment, 24); - rustc_data_structures::static_assert_size!(Stmt, 32); - rustc_data_structures::static_assert_size!(Ty, 96); + static_assert_size!(AssocItem, 104); + 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); + #[cfg(not(bootstrap))] + 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!(Generics, 72); + static_assert_size!(Impl, 200); + static_assert_size!(Item, 184); + static_assert_size!(ItemKind, 112); + static_assert_size!(Lit, 48); + static_assert_size!(LitKind, 24); + static_assert_size!(Local, 72); + static_assert_size!(Param, 40); + static_assert_size!(Pat, 120); + static_assert_size!(PatKind, 96); + static_assert_size!(Path, 40); + static_assert_size!(PathSegment, 24); + static_assert_size!(Stmt, 32); + static_assert_size!(StmtKind, 16); + static_assert_size!(Ty, 96); + static_assert_size!(TyKind, 72); } diff --git a/compiler/rustc_ast/src/ast_traits.rs b/compiler/rustc_ast/src/ast_traits.rs index 5c30a75a1..1b31be07f 100644 --- a/compiler/rustc_ast/src/ast_traits.rs +++ b/compiler/rustc_ast/src/ast_traits.rs @@ -4,7 +4,7 @@ use crate::ptr::P; use crate::token::Nonterminal; -use crate::tokenstream::LazyTokenStream; +use crate::tokenstream::LazyAttrTokenStream; use crate::{Arm, Crate, ExprField, FieldDef, GenericParam, Param, PatField, Variant}; use crate::{AssocItem, Expr, ForeignItem, Item, NodeId}; use crate::{AttrItem, AttrKind, Block, Pat, Path, Ty, Visibility}; @@ -124,18 +124,18 @@ impl HasSpan for AttrItem { /// A trait for AST nodes having (or not having) collected tokens. pub trait HasTokens { - fn tokens(&self) -> Option<&LazyTokenStream>; - fn tokens_mut(&mut self) -> Option<&mut Option<LazyTokenStream>>; + fn tokens(&self) -> Option<&LazyAttrTokenStream>; + fn tokens_mut(&mut self) -> Option<&mut Option<LazyAttrTokenStream>>; } macro_rules! impl_has_tokens { ($($T:ty),+ $(,)?) => { $( impl HasTokens for $T { - fn tokens(&self) -> Option<&LazyTokenStream> { + fn tokens(&self) -> Option<&LazyAttrTokenStream> { self.tokens.as_ref() } - fn tokens_mut(&mut self) -> Option<&mut Option<LazyTokenStream>> { + fn tokens_mut(&mut self) -> Option<&mut Option<LazyAttrTokenStream>> { Some(&mut self.tokens) } } @@ -147,10 +147,10 @@ macro_rules! impl_has_tokens_none { ($($T:ty),+ $(,)?) => { $( impl HasTokens for $T { - fn tokens(&self) -> Option<&LazyTokenStream> { + fn tokens(&self) -> Option<&LazyAttrTokenStream> { None } - fn tokens_mut(&mut self) -> Option<&mut Option<LazyTokenStream>> { + fn tokens_mut(&mut self) -> Option<&mut Option<LazyAttrTokenStream>> { None } } @@ -162,25 +162,25 @@ impl_has_tokens!(AssocItem, AttrItem, Block, Expr, ForeignItem, Item, Pat, Path, impl_has_tokens_none!(Arm, ExprField, FieldDef, GenericParam, Param, PatField, Variant); impl<T: AstDeref<Target: HasTokens>> HasTokens for T { - fn tokens(&self) -> Option<&LazyTokenStream> { + fn tokens(&self) -> Option<&LazyAttrTokenStream> { self.ast_deref().tokens() } - fn tokens_mut(&mut self) -> Option<&mut Option<LazyTokenStream>> { + fn tokens_mut(&mut self) -> Option<&mut Option<LazyAttrTokenStream>> { self.ast_deref_mut().tokens_mut() } } impl<T: HasTokens> HasTokens for Option<T> { - fn tokens(&self) -> Option<&LazyTokenStream> { + fn tokens(&self) -> Option<&LazyAttrTokenStream> { self.as_ref().and_then(|inner| inner.tokens()) } - fn tokens_mut(&mut self) -> Option<&mut Option<LazyTokenStream>> { + fn tokens_mut(&mut self) -> Option<&mut Option<LazyAttrTokenStream>> { self.as_mut().and_then(|inner| inner.tokens_mut()) } } impl HasTokens for StmtKind { - fn tokens(&self) -> Option<&LazyTokenStream> { + fn tokens(&self) -> Option<&LazyAttrTokenStream> { match self { StmtKind::Local(local) => local.tokens.as_ref(), StmtKind::Item(item) => item.tokens(), @@ -189,7 +189,7 @@ impl HasTokens for StmtKind { StmtKind::MacCall(mac) => mac.tokens.as_ref(), } } - fn tokens_mut(&mut self) -> Option<&mut Option<LazyTokenStream>> { + fn tokens_mut(&mut self) -> Option<&mut Option<LazyAttrTokenStream>> { match self { StmtKind::Local(local) => Some(&mut local.tokens), StmtKind::Item(item) => item.tokens_mut(), @@ -201,26 +201,26 @@ impl HasTokens for StmtKind { } impl HasTokens for Stmt { - fn tokens(&self) -> Option<&LazyTokenStream> { + fn tokens(&self) -> Option<&LazyAttrTokenStream> { self.kind.tokens() } - fn tokens_mut(&mut self) -> Option<&mut Option<LazyTokenStream>> { + fn tokens_mut(&mut self) -> Option<&mut Option<LazyAttrTokenStream>> { self.kind.tokens_mut() } } impl HasTokens for Attribute { - fn tokens(&self) -> Option<&LazyTokenStream> { + fn tokens(&self) -> Option<&LazyAttrTokenStream> { match &self.kind { - AttrKind::Normal(_, tokens) => tokens.as_ref(), + AttrKind::Normal(normal) => normal.tokens.as_ref(), kind @ AttrKind::DocComment(..) => { panic!("Called tokens on doc comment attr {:?}", kind) } } } - fn tokens_mut(&mut self) -> Option<&mut Option<LazyTokenStream>> { + fn tokens_mut(&mut self) -> Option<&mut Option<LazyAttrTokenStream>> { Some(match &mut self.kind { - AttrKind::Normal(_, tokens) => tokens, + AttrKind::Normal(normal) => &mut normal.tokens, kind @ AttrKind::DocComment(..) => { panic!("Called tokens_mut on doc comment attr {:?}", kind) } @@ -229,7 +229,7 @@ impl HasTokens for Attribute { } impl HasTokens for Nonterminal { - fn tokens(&self) -> Option<&LazyTokenStream> { + fn tokens(&self) -> Option<&LazyAttrTokenStream> { match self { Nonterminal::NtItem(item) => item.tokens(), Nonterminal::NtStmt(stmt) => stmt.tokens(), @@ -243,7 +243,7 @@ impl HasTokens for Nonterminal { Nonterminal::NtIdent(..) | Nonterminal::NtLifetime(..) => None, } } - fn tokens_mut(&mut self) -> Option<&mut Option<LazyTokenStream>> { + fn tokens_mut(&mut self) -> Option<&mut Option<LazyAttrTokenStream>> { match self { Nonterminal::NtItem(item) => item.tokens_mut(), Nonterminal::NtStmt(stmt) => stmt.tokens_mut(), @@ -270,7 +270,7 @@ pub trait HasAttrs { /// during token collection. const SUPPORTS_CUSTOM_INNER_ATTRS: bool; fn attrs(&self) -> &[Attribute]; - fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)); + fn visit_attrs(&mut self, f: impl FnOnce(&mut AttrVec)); } macro_rules! impl_has_attrs { @@ -279,12 +279,13 @@ macro_rules! impl_has_attrs { impl HasAttrs for $T { const SUPPORTS_CUSTOM_INNER_ATTRS: bool = $inner; + #[inline] fn attrs(&self) -> &[Attribute] { &self.attrs } - fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) { - VecOrAttrVec::visit(&mut self.attrs, f) + fn visit_attrs(&mut self, f: impl FnOnce(&mut AttrVec)) { + f(&mut self.attrs) } } )+ @@ -299,7 +300,7 @@ macro_rules! impl_has_attrs_none { fn attrs(&self) -> &[Attribute] { &[] } - fn visit_attrs(&mut self, _f: impl FnOnce(&mut Vec<Attribute>)) {} + fn visit_attrs(&mut self, _f: impl FnOnce(&mut AttrVec)) {} } )+ }; @@ -330,7 +331,7 @@ impl<T: AstDeref<Target: HasAttrs>> HasAttrs for T { fn attrs(&self) -> &[Attribute] { self.ast_deref().attrs() } - fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) { + fn visit_attrs(&mut self, f: impl FnOnce(&mut AttrVec)) { self.ast_deref_mut().visit_attrs(f) } } @@ -340,7 +341,7 @@ impl<T: HasAttrs> HasAttrs for Option<T> { fn attrs(&self) -> &[Attribute] { self.as_ref().map(|inner| inner.attrs()).unwrap_or(&[]) } - fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) { + fn visit_attrs(&mut self, f: impl FnOnce(&mut AttrVec)) { if let Some(inner) = self.as_mut() { inner.visit_attrs(f); } @@ -362,13 +363,13 @@ impl HasAttrs for StmtKind { } } - fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) { + fn visit_attrs(&mut self, f: impl FnOnce(&mut AttrVec)) { match self { - StmtKind::Local(local) => visit_attrvec(&mut local.attrs, f), + StmtKind::Local(local) => f(&mut local.attrs), StmtKind::Expr(expr) | StmtKind::Semi(expr) => expr.visit_attrs(f), StmtKind::Item(item) => item.visit_attrs(f), StmtKind::Empty => {} - StmtKind::MacCall(mac) => visit_attrvec(&mut mac.attrs, f), + StmtKind::MacCall(mac) => f(&mut mac.attrs), } } } @@ -378,38 +379,11 @@ impl HasAttrs for Stmt { fn attrs(&self) -> &[Attribute] { self.kind.attrs() } - fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) { + fn visit_attrs(&mut self, f: impl FnOnce(&mut AttrVec)) { self.kind.visit_attrs(f); } } -/// Helper trait for the impls above. Abstracts over -/// the two types of attribute fields that AST nodes -/// may have (`Vec<Attribute>` or `AttrVec`). -trait VecOrAttrVec { - fn visit(&mut self, f: impl FnOnce(&mut Vec<Attribute>)); -} - -impl VecOrAttrVec for Vec<Attribute> { - fn visit(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) { - f(self) - } -} - -impl VecOrAttrVec for AttrVec { - fn visit(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) { - visit_attrvec(self, f) - } -} - -fn visit_attrvec(attrs: &mut AttrVec, f: impl FnOnce(&mut Vec<Attribute>)) { - crate::mut_visit::visit_clobber(attrs, |attrs| { - let mut vec = attrs.into(); - f(&mut vec); - vec.into() - }); -} - /// A newtype around an AST node that implements the traits above if the node implements them. pub struct AstNodeWrapper<Wrapped, Tag> { pub wrapped: Wrapped, diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 86af7769d..990f4f8f1 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -7,18 +7,22 @@ use crate::ast::{MacArgs, MacArgsEq, MacDelimiter, MetaItem, MetaItemKind, Neste use crate::ast::{Path, PathSegment}; use crate::ptr::P; use crate::token::{self, CommentKind, Delimiter, Token}; -use crate::tokenstream::{AttrAnnotatedTokenStream, AttrAnnotatedTokenTree}; use crate::tokenstream::{DelimSpan, Spacing, TokenTree}; -use crate::tokenstream::{LazyTokenStream, TokenStream}; +use crate::tokenstream::{LazyAttrTokenStream, TokenStream}; use crate::util::comments; -use rustc_data_structures::thin_vec::ThinVec; +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}; pub struct MarkedAttrs(GrowableBitSet<AttrId>); @@ -114,7 +118,7 @@ impl Attribute { #[inline] pub fn has_name(&self, name: Symbol) -> bool { match self.kind { - AttrKind::Normal(ref item, _) => item.path == name, + AttrKind::Normal(ref normal) => normal.item.path == name, AttrKind::DocComment(..) => false, } } @@ -122,9 +126,9 @@ impl Attribute { /// For a single-segment attribute, returns its name; otherwise, returns `None`. pub fn ident(&self) -> Option<Ident> { match self.kind { - AttrKind::Normal(ref item, _) => { - if item.path.segments.len() == 1 { - Some(item.path.segments[0].ident) + AttrKind::Normal(ref normal) => { + if normal.item.path.segments.len() == 1 { + Some(normal.item.path.segments[0].ident) } else { None } @@ -138,14 +142,16 @@ impl Attribute { pub fn value_str(&self) -> Option<Symbol> { match self.kind { - AttrKind::Normal(ref item, _) => item.meta_kind().and_then(|kind| kind.value_str()), + AttrKind::Normal(ref 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 item, _) => match item.meta_kind() { + AttrKind::Normal(ref normal) => match normal.item.meta_kind() { Some(MetaItemKind::List(list)) => Some(list), _ => None, }, @@ -154,8 +160,8 @@ impl Attribute { } pub fn is_word(&self) -> bool { - if let AttrKind::Normal(item, _) = &self.kind { - matches!(item.args, MacArgs::Empty) + if let AttrKind::Normal(normal) = &self.kind { + matches!(normal.item.args, MacArgs::Empty) } else { false } @@ -182,13 +188,7 @@ impl MetaItem { } pub fn value_str(&self) -> Option<Symbol> { - match self.kind { - MetaItemKind::NameValue(ref v) => match v.kind { - LitKind::Str(ref s, _) => Some(*s), - _ => None, - }, - _ => None, - } + self.kind.value_str() } pub fn meta_item_list(&self) -> Option<&[NestedMetaItem]> { @@ -237,6 +237,9 @@ impl AttrItem { } impl Attribute { + /// Returns `true` if it is a sugared doc comment (`///` or `//!` for example). + /// So `#[doc = "doc"]` (which is a doc comment) and `#[doc(...)]` (which is not + /// a doc comment) will return `false`. pub fn is_doc_comment(&self) -> bool { match self.kind { AttrKind::Normal(..) => false, @@ -244,10 +247,16 @@ impl Attribute { } } + /// Returns the documentation and its kind if this is a doc comment or a sugared doc comment. + /// * `///doc` returns `Some(("doc", CommentKind::Line))`. + /// * `/** doc */` returns `Some(("doc", CommentKind::Block))`. + /// * `#[doc = "doc"]` returns `Some(("doc", CommentKind::Line))`. + /// * `#[doc(...)]` returns `None`. pub fn doc_str_and_comment_kind(&self) -> Option<(Symbol, CommentKind)> { match self.kind { AttrKind::DocComment(kind, data) => Some((data, kind)), - AttrKind::Normal(ref item, _) if item.path == sym::doc => item + AttrKind::Normal(ref normal) if normal.item.path == sym::doc => normal + .item .meta_kind() .and_then(|kind| kind.value_str()) .map(|data| (data, CommentKind::Line)), @@ -255,11 +264,15 @@ impl Attribute { } } + /// Returns the documentation if this is a doc comment or a sugared doc comment. + /// * `///doc` returns `Some("doc")`. + /// * `#[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 item, _) if item.path == sym::doc => { - item.meta_kind().and_then(|kind| kind.value_str()) + AttrKind::Normal(ref normal) if normal.item.path == sym::doc => { + normal.item.meta_kind().and_then(|kind| kind.value_str()) } _ => None, } @@ -271,14 +284,14 @@ impl Attribute { pub fn get_normal_item(&self) -> &AttrItem { match self.kind { - AttrKind::Normal(ref item, _) => item, + AttrKind::Normal(ref normal) => &normal.item, AttrKind::DocComment(..) => panic!("unexpected doc comment"), } } pub fn unwrap_normal_item(self) -> AttrItem { match self.kind { - AttrKind::Normal(item, _) => item, + AttrKind::Normal(normal) => normal.into_inner().item, AttrKind::DocComment(..) => panic!("unexpected doc comment"), } } @@ -286,31 +299,30 @@ impl Attribute { /// Extracts the MetaItem from inside this Attribute. pub fn meta(&self) -> Option<MetaItem> { match self.kind { - AttrKind::Normal(ref item, _) => item.meta(self.span), + AttrKind::Normal(ref normal) => normal.item.meta(self.span), AttrKind::DocComment(..) => None, } } pub fn meta_kind(&self) -> Option<MetaItemKind> { match self.kind { - AttrKind::Normal(ref item, _) => item.meta_kind(), + AttrKind::Normal(ref normal) => normal.item.meta_kind(), AttrKind::DocComment(..) => None, } } - pub fn tokens(&self) -> AttrAnnotatedTokenStream { + pub fn tokens(&self) -> TokenStream { match self.kind { - AttrKind::Normal(_, ref tokens) => tokens + AttrKind::Normal(ref normal) => normal + .tokens .as_ref() .unwrap_or_else(|| panic!("attribute is missing tokens: {:?}", self)) - .create_token_stream(), - AttrKind::DocComment(comment_kind, data) => AttrAnnotatedTokenStream::from(( - AttrAnnotatedTokenTree::Token(Token::new( - token::DocComment(comment_kind, self.style, data), - self.span, - )), + .to_attr_token_stream() + .to_tokenstream(), + AttrKind::DocComment(comment_kind, data) => TokenStream::new(vec![TokenTree::Token( + Token::new(token::DocComment(comment_kind, self.style, data), self.span), Spacing::Alone, - )), + )]), } } } @@ -340,47 +352,86 @@ pub fn mk_nested_word_item(ident: Ident) -> NestedMetaItem { NestedMetaItem::MetaItem(mk_word_item(ident)) } -pub(crate) fn mk_attr_id() -> AttrId { - use std::sync::atomic::AtomicU32; - use std::sync::atomic::Ordering; +pub struct AttrIdGenerator(WorkerLocal<Cell<u32>>); - static NEXT_ATTR_ID: AtomicU32 = AtomicU32::new(0); +#[cfg(debug_assertions)] +static MAX_ATTR_ID: AtomicU32 = AtomicU32::new(u32::MAX); - let id = NEXT_ATTR_ID.fetch_add(1, Ordering::SeqCst); - assert!(id != u32::MAX); - AttrId::from_u32(id) +impl AttrIdGenerator { + pub fn new() -> Self { + // We use `(index as u32).reverse_bits()` to initialize the + // starting value of AttrId in each worker thread. + // The `index` is the index of the worker thread. + // This ensures that the AttrId generated in each thread is unique. + AttrIdGenerator(WorkerLocal::new(|index| { + let index: u32 = index.try_into().unwrap(); + + #[cfg(debug_assertions)] + { + let max_id = ((index + 1).next_power_of_two() - 1).bitxor(u32::MAX).reverse_bits(); + MAX_ATTR_ID.fetch_min(max_id, Ordering::Release); + } + + Cell::new(index.reverse_bits()) + })) + } + + pub fn mk_attr_id(&self) -> AttrId { + let id = self.0.get(); + + // Ensure the assigned attr_id does not overlap the bits + // representing the number of threads. + #[cfg(debug_assertions)] + assert!(id <= MAX_ATTR_ID.load(Ordering::Acquire)); + + self.0.set(id + 1); + AttrId::from_u32(id) + } } -pub fn mk_attr(style: AttrStyle, path: Path, args: MacArgs, span: Span) -> Attribute { - mk_attr_from_item(AttrItem { path, args, tokens: None }, None, style, span) +pub fn mk_attr( + g: &AttrIdGenerator, + style: AttrStyle, + path: Path, + args: MacArgs, + span: Span, +) -> Attribute { + mk_attr_from_item(g, AttrItem { path, args, tokens: None }, None, style, span) } pub fn mk_attr_from_item( + g: &AttrIdGenerator, item: AttrItem, - tokens: Option<LazyTokenStream>, + tokens: Option<LazyAttrTokenStream>, style: AttrStyle, span: Span, ) -> Attribute { - Attribute { kind: AttrKind::Normal(item, tokens), id: mk_attr_id(), style, span } + Attribute { + kind: AttrKind::Normal(P(ast::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(item: MetaItem) -> Attribute { - mk_attr(AttrStyle::Inner, item.path, item.kind.mac_args(item.span), item.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) } /// Returns an outer attribute with the given value and span. -pub fn mk_attr_outer(item: MetaItem) -> Attribute { - mk_attr(AttrStyle::Outer, item.path, item.kind.mac_args(item.span), item.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_doc_comment( + g: &AttrIdGenerator, comment_kind: CommentKind, style: AttrStyle, data: Symbol, span: Span, ) -> Attribute { - Attribute { kind: AttrKind::DocComment(comment_kind, data), id: mk_attr_id(), style, span } + Attribute { kind: AttrKind::DocComment(comment_kind, data), id: g.mk_attr_id(), style, span } } pub fn list_contains_name(items: &[NestedMetaItem], name: Symbol) -> bool { @@ -484,7 +535,7 @@ impl MetaItemKind { id: ast::DUMMY_NODE_ID, kind: ast::ExprKind::Lit(lit.clone()), span: lit.span, - attrs: ThinVec::new(), + attrs: ast::AttrVec::new(), tokens: None, }); MacArgs::Eq(span, MacArgsEq::Ast(expr)) diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs index 4b94ec0d6..bd7a85b07 100644 --- a/compiler/rustc_ast/src/lib.rs +++ b/compiler/rustc_ast/src/lib.rs @@ -13,17 +13,23 @@ #![feature(const_default_impls)] #![feature(const_trait_impl)] #![feature(if_let_guard)] -#![feature(label_break_value)] +#![cfg_attr(bootstrap, feature(label_break_value))] #![feature(let_chains)] +#![cfg_attr(bootstrap, feature(let_else))] #![feature(min_specialization)] #![feature(negative_impls)] #![feature(slice_internals)] #![feature(stmt_expr_attributes)] #![recursion_limit = "256"] +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] #[macro_use] extern crate rustc_macros; +#[macro_use] +extern crate tracing; + pub mod util { pub mod classify; pub mod comments; diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 01bd498b3..9fd0b63c4 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -14,7 +14,6 @@ use crate::tokenstream::*; use rustc_data_structures::map_in_place::MapInPlace; use rustc_data_structures::sync::Lrc; -use rustc_data_structures::thin_vec::ThinVec; use rustc_span::source_map::Spanned; use rustc_span::symbol::Ident; use rustc_span::Span; @@ -338,12 +337,7 @@ where } // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. -pub fn visit_attrs<T: MutVisitor>(attrs: &mut Vec<Attribute>, vis: &mut T) { - visit_vec(attrs, |attr| vis.visit_attribute(attr)); -} - -// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. -pub fn visit_thin_attrs<T: MutVisitor>(attrs: &mut AttrVec, vis: &mut T) { +pub fn visit_attrs<T: MutVisitor>(attrs: &mut AttrVec, vis: &mut T) { for attr in attrs.iter_mut() { vis.visit_attribute(attr); } @@ -398,7 +392,7 @@ pub fn noop_flat_map_pat_field<T: MutVisitor>( vis.visit_ident(ident); vis.visit_pat(pat); vis.visit_span(span); - visit_thin_attrs(attrs, vis); + visit_attrs(attrs, vis); smallvec![fp] } @@ -424,7 +418,7 @@ pub fn noop_visit_use_tree<T: MutVisitor>(use_tree: &mut UseTree, vis: &mut T) { pub fn noop_flat_map_arm<T: MutVisitor>(mut arm: Arm, vis: &mut T) -> SmallVec<[Arm; 1]> { let Arm { attrs, pat, guard, body, span, id, is_placeholder: _ } = &mut arm; - visit_thin_attrs(attrs, vis); + visit_attrs(attrs, vis); vis.visit_id(id); vis.visit_pat(pat); visit_opt(guard, |guard| vis.visit_expr(guard)); @@ -507,7 +501,7 @@ pub fn noop_flat_map_variant<T: MutVisitor>( let Variant { ident, vis, attrs, id, data, disr_expr, span, is_placeholder: _ } = &mut variant; visitor.visit_ident(ident); visitor.visit_vis(vis); - visit_thin_attrs(attrs, visitor); + visit_attrs(attrs, visitor); visitor.visit_id(id); visitor.visit_variant_data(data); visit_opt(disr_expr, |disr_expr| visitor.visit_anon_const(disr_expr)); @@ -589,14 +583,16 @@ pub fn noop_visit_local<T: MutVisitor>(local: &mut P<Local>, vis: &mut T) { } } vis.visit_span(span); - visit_thin_attrs(attrs, vis); + visit_attrs(attrs, vis); visit_lazy_tts(tokens, vis); } pub fn noop_visit_attribute<T: MutVisitor>(attr: &mut Attribute, vis: &mut T) { let Attribute { kind, id: _, style: _, span } = attr; match kind { - AttrKind::Normal(AttrItem { path, args, tokens }, attr_tokens) => { + AttrKind::Normal(normal) => { + let NormalAttr { item: AttrItem { path, args, tokens }, tokens: attr_tokens } = + &mut **normal; vis.visit_path(path); visit_mac_args(args, vis); visit_lazy_tts(tokens, vis); @@ -638,7 +634,7 @@ pub fn noop_visit_meta_item<T: MutVisitor>(mi: &mut MetaItem, vis: &mut T) { pub fn noop_flat_map_param<T: MutVisitor>(mut param: Param, vis: &mut T) -> SmallVec<[Param; 1]> { let Param { attrs, id, pat, span, ty, is_placeholder: _ } = &mut param; vis.visit_id(id); - visit_thin_attrs(attrs, vis); + visit_attrs(attrs, vis); vis.visit_pat(pat); vis.visit_span(span); vis.visit_ty(ty); @@ -646,21 +642,21 @@ pub fn noop_flat_map_param<T: MutVisitor>(mut param: Param, vis: &mut T) -> Smal } // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. -pub fn visit_attr_annotated_tt<T: MutVisitor>(tt: &mut AttrAnnotatedTokenTree, vis: &mut T) { +pub fn visit_attr_tt<T: MutVisitor>(tt: &mut AttrTokenTree, vis: &mut T) { match tt { - AttrAnnotatedTokenTree::Token(token) => { + AttrTokenTree::Token(token, _) => { visit_token(token, vis); } - AttrAnnotatedTokenTree::Delimited(DelimSpan { open, close }, _delim, tts) => { + AttrTokenTree::Delimited(DelimSpan { open, close }, _delim, tts) => { vis.visit_span(open); vis.visit_span(close); - visit_attr_annotated_tts(tts, vis); + visit_attr_tts(tts, vis); } - AttrAnnotatedTokenTree::Attributes(data) => { + AttrTokenTree::Attributes(data) => { for attr in &mut *data.attrs { match &mut attr.kind { - AttrKind::Normal(_, attr_tokens) => { - visit_lazy_tts(attr_tokens, vis); + AttrKind::Normal(normal) => { + visit_lazy_tts(&mut normal.tokens, vis); } AttrKind::DocComment(..) => { vis.visit_span(&mut attr.span); @@ -694,27 +690,27 @@ pub fn visit_tts<T: MutVisitor>(TokenStream(tts): &mut TokenStream, vis: &mut T) } } -pub fn visit_attr_annotated_tts<T: MutVisitor>( - AttrAnnotatedTokenStream(tts): &mut AttrAnnotatedTokenStream, - vis: &mut T, -) { +pub fn visit_attr_tts<T: MutVisitor>(AttrTokenStream(tts): &mut AttrTokenStream, vis: &mut T) { if T::VISIT_TOKENS && !tts.is_empty() { let tts = Lrc::make_mut(tts); - visit_vec(tts, |(tree, _is_joint)| visit_attr_annotated_tt(tree, vis)); + visit_vec(tts, |tree| visit_attr_tt(tree, vis)); } } -pub fn visit_lazy_tts_opt_mut<T: MutVisitor>(lazy_tts: Option<&mut LazyTokenStream>, vis: &mut T) { +pub fn visit_lazy_tts_opt_mut<T: MutVisitor>( + lazy_tts: Option<&mut LazyAttrTokenStream>, + vis: &mut T, +) { if T::VISIT_TOKENS { if let Some(lazy_tts) = lazy_tts { - let mut tts = lazy_tts.create_token_stream(); - visit_attr_annotated_tts(&mut tts, vis); - *lazy_tts = LazyTokenStream::new(tts); + let mut tts = lazy_tts.to_attr_token_stream(); + visit_attr_tts(&mut tts, vis); + *lazy_tts = LazyAttrTokenStream::new(tts); } } } -pub fn visit_lazy_tts<T: MutVisitor>(lazy_tts: &mut Option<LazyTokenStream>, vis: &mut T) { +pub fn visit_lazy_tts<T: MutVisitor>(lazy_tts: &mut Option<LazyAttrTokenStream>, vis: &mut T) { visit_lazy_tts_opt_mut(lazy_tts.as_mut(), vis); } @@ -880,7 +876,7 @@ pub fn noop_flat_map_generic_param<T: MutVisitor>( if let Some(ref mut colon_span) = colon_span { vis.visit_span(colon_span); } - visit_thin_attrs(attrs, vis); + visit_attrs(attrs, vis); visit_vec(bounds, |bound| noop_visit_param_bound(bound, vis)); match kind { GenericParamKind::Lifetime => {} @@ -933,8 +929,7 @@ pub fn noop_visit_where_predicate<T: MutVisitor>(pred: &mut WherePredicate, vis: visit_vec(bounds, |bound| noop_visit_param_bound(bound, vis)); } WherePredicate::EqPredicate(ep) => { - let WhereEqPredicate { id, span, lhs_ty, rhs_ty } = ep; - vis.visit_id(id); + let WhereEqPredicate { span, lhs_ty, rhs_ty } = ep; vis.visit_span(span); vis.visit_ty(lhs_ty); vis.visit_ty(rhs_ty); @@ -977,7 +972,7 @@ pub fn noop_flat_map_field_def<T: MutVisitor>( visitor.visit_vis(vis); visitor.visit_id(id); visitor.visit_ty(ty); - visit_thin_attrs(attrs, visitor); + visit_attrs(attrs, visitor); smallvec![fd] } @@ -990,7 +985,7 @@ pub fn noop_flat_map_expr_field<T: MutVisitor>( vis.visit_expr(expr); vis.visit_id(id); vis.visit_span(span); - visit_thin_attrs(attrs, vis); + visit_attrs(attrs, vis); smallvec![f] } @@ -1430,7 +1425,7 @@ pub fn noop_visit_expr<T: MutVisitor>( } vis.visit_id(id); vis.visit_span(span); - visit_thin_attrs(attrs, vis); + visit_attrs(attrs, vis); visit_lazy_tts(tokens, vis); } @@ -1476,7 +1471,7 @@ pub fn noop_flat_map_stmt_kind<T: MutVisitor>( StmtKind::MacCall(mut mac) => { let MacCallStmt { mac: mac_, style: _, attrs, tokens } = mac.deref_mut(); vis.visit_mac_call(mac_); - visit_thin_attrs(attrs, vis); + visit_attrs(attrs, vis); visit_lazy_tts(tokens, vis); smallvec![StmtKind::MacCall(mac)] } @@ -1486,7 +1481,7 @@ pub fn noop_flat_map_stmt_kind<T: MutVisitor>( pub fn noop_visit_vis<T: MutVisitor>(visibility: &mut Visibility, vis: &mut T) { match &mut visibility.kind { VisibilityKind::Public | VisibilityKind::Inherited => {} - VisibilityKind::Restricted { path, id } => { + VisibilityKind::Restricted { path, id, shorthand: _ } => { vis.visit_path(path); vis.visit_id(id); } @@ -1511,12 +1506,6 @@ impl<T: DummyAstNode + 'static> DummyAstNode for P<T> { } } -impl<T> DummyAstNode for ThinVec<T> { - fn dummy() -> Self { - Default::default() - } -} - impl DummyAstNode for Item { fn dummy() -> Self { Item { diff --git a/compiler/rustc_ast/src/node_id.rs b/compiler/rustc_ast/src/node_id.rs index 7f928cb57..7b5acc3f4 100644 --- a/compiler/rustc_ast/src/node_id.rs +++ b/compiler/rustc_ast/src/node_id.rs @@ -13,7 +13,7 @@ rustc_index::newtype_index! { } } -rustc_data_structures::define_id_collections!(NodeMap, NodeSet, NodeId); +rustc_data_structures::define_id_collections!(NodeMap, NodeSet, NodeMapEntry, NodeId); /// The [`NodeId`] used to represent the root of the crate. pub const CRATE_NODE_ID: NodeId = NodeId::from_u32(0); diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index 85d9687c6..97dfb7837 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -398,6 +398,30 @@ impl Token { } } + /// Returns `true` if the token can appear at the start of an pattern. + /// + /// Shamelessly borrowed from `can_begin_expr`, only used for diagnostics right now. + pub fn can_begin_pattern(&self) -> bool { + match self.uninterpolate().kind { + Ident(name, is_raw) => + ident_can_begin_expr(name, self.span, is_raw), // value name or keyword + | OpenDelim(Delimiter::Bracket | Delimiter::Parenthesis) // tuple or array + | Literal(..) // literal + | BinOp(Minus) // unary minus + | BinOp(And) // reference + | AndAnd // double reference + // DotDotDot is no longer supported + | DotDot | DotDotDot | DotDotEq // ranges + | Lt | BinOp(Shl) // associated path + | ModSep => true, // global path + Interpolated(ref nt) => matches!(**nt, NtLiteral(..) | + NtPat(..) | + NtBlock(..) | + NtPath(..)), + _ => false, + } + } + /// Returns `true` if the token can appear at the start of a type. pub fn can_begin_type(&self) -> bool { match self.uninterpolate().kind { @@ -436,6 +460,31 @@ impl Token { || self == &OpenDelim(Delimiter::Parenthesis) } + /// Returns `true` if the token can appear at the start of an item. + pub fn can_begin_item(&self) -> bool { + match self.kind { + Ident(name, _) => [ + kw::Fn, + kw::Use, + kw::Struct, + kw::Enum, + kw::Pub, + kw::Trait, + kw::Extern, + kw::Impl, + kw::Unsafe, + kw::Const, + kw::Static, + kw::Union, + kw::Macro, + kw::Mod, + kw::Type, + ] + .contains(&name), + _ => false, + } + } + /// Returns `true` if the token is any literal. pub fn is_lit(&self) -> bool { matches!(self.kind, Literal(..)) diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index 9e4a22e1f..875cd620d 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs @@ -121,12 +121,12 @@ where } } -pub trait CreateTokenStream: sync::Send + sync::Sync { - fn create_token_stream(&self) -> AttrAnnotatedTokenStream; +pub trait ToAttrTokenStream: sync::Send + sync::Sync { + fn to_attr_token_stream(&self) -> AttrTokenStream; } -impl CreateTokenStream for AttrAnnotatedTokenStream { - fn create_token_stream(&self) -> AttrAnnotatedTokenStream { +impl ToAttrTokenStream for AttrTokenStream { + fn to_attr_token_stream(&self) -> AttrTokenStream { self.clone() } } @@ -135,68 +135,68 @@ impl CreateTokenStream for AttrAnnotatedTokenStream { /// of an actual `TokenStream` until it is needed. /// `Box` is here only to reduce the structure size. #[derive(Clone)] -pub struct LazyTokenStream(Lrc<Box<dyn CreateTokenStream>>); +pub struct LazyAttrTokenStream(Lrc<Box<dyn ToAttrTokenStream>>); -impl LazyTokenStream { - pub fn new(inner: impl CreateTokenStream + 'static) -> LazyTokenStream { - LazyTokenStream(Lrc::new(Box::new(inner))) +impl LazyAttrTokenStream { + pub fn new(inner: impl ToAttrTokenStream + 'static) -> LazyAttrTokenStream { + LazyAttrTokenStream(Lrc::new(Box::new(inner))) } - pub fn create_token_stream(&self) -> AttrAnnotatedTokenStream { - self.0.create_token_stream() + pub fn to_attr_token_stream(&self) -> AttrTokenStream { + self.0.to_attr_token_stream() } } -impl fmt::Debug for LazyTokenStream { +impl fmt::Debug for LazyAttrTokenStream { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "LazyTokenStream({:?})", self.create_token_stream()) + write!(f, "LazyAttrTokenStream({:?})", self.to_attr_token_stream()) } } -impl<S: Encoder> Encodable<S> for LazyTokenStream { +impl<S: Encoder> Encodable<S> for LazyAttrTokenStream { fn encode(&self, s: &mut S) { // Used by AST json printing. - Encodable::encode(&self.create_token_stream(), s); + Encodable::encode(&self.to_attr_token_stream(), s); } } -impl<D: Decoder> Decodable<D> for LazyTokenStream { +impl<D: Decoder> Decodable<D> for LazyAttrTokenStream { fn decode(_d: &mut D) -> Self { - panic!("Attempted to decode LazyTokenStream"); + panic!("Attempted to decode LazyAttrTokenStream"); } } -impl<CTX> HashStable<CTX> for LazyTokenStream { +impl<CTX> HashStable<CTX> for LazyAttrTokenStream { fn hash_stable(&self, _hcx: &mut CTX, _hasher: &mut StableHasher) { - panic!("Attempted to compute stable hash for LazyTokenStream"); + panic!("Attempted to compute stable hash for LazyAttrTokenStream"); } } -/// A `AttrAnnotatedTokenStream` is similar to a `TokenStream`, but with extra +/// An `AttrTokenStream` is similar to a `TokenStream`, but with extra /// information about the tokens for attribute targets. This is used /// during expansion to perform early cfg-expansion, and to process attributes /// during proc-macro invocations. #[derive(Clone, Debug, Default, Encodable, Decodable)] -pub struct AttrAnnotatedTokenStream(pub Lrc<Vec<(AttrAnnotatedTokenTree, Spacing)>>); +pub struct AttrTokenStream(pub Lrc<Vec<AttrTokenTree>>); -/// Like `TokenTree`, but for `AttrAnnotatedTokenStream` +/// Like `TokenTree`, but for `AttrTokenStream`. #[derive(Clone, Debug, Encodable, Decodable)] -pub enum AttrAnnotatedTokenTree { - Token(Token), - Delimited(DelimSpan, Delimiter, AttrAnnotatedTokenStream), +pub enum AttrTokenTree { + Token(Token, Spacing), + Delimited(DelimSpan, Delimiter, AttrTokenStream), /// Stores the attributes for an attribute target, /// along with the tokens for that attribute target. /// See `AttributesData` for more information Attributes(AttributesData), } -impl AttrAnnotatedTokenStream { - pub fn new(tokens: Vec<(AttrAnnotatedTokenTree, Spacing)>) -> AttrAnnotatedTokenStream { - AttrAnnotatedTokenStream(Lrc::new(tokens)) +impl AttrTokenStream { + pub fn new(tokens: Vec<AttrTokenTree>) -> AttrTokenStream { + AttrTokenStream(Lrc::new(tokens)) } - /// Converts this `AttrAnnotatedTokenStream` to a plain `TokenStream - /// During conversion, `AttrAnnotatedTokenTree::Attributes` get 'flattened' + /// Converts this `AttrTokenStream` to a plain `TokenStream`. + /// During conversion, `AttrTokenTree::Attributes` get 'flattened' /// back to a `TokenStream` of the form `outer_attr attr_target`. /// If there are inner attributes, they are inserted into the proper /// place in the attribute target tokens. @@ -204,31 +204,27 @@ impl AttrAnnotatedTokenStream { let trees: Vec<_> = self .0 .iter() - .flat_map(|tree| match &tree.0 { - AttrAnnotatedTokenTree::Token(inner) => { - smallvec![TokenTree::Token(inner.clone(), tree.1)].into_iter() + .flat_map(|tree| match &tree { + AttrTokenTree::Token(inner, spacing) => { + smallvec![TokenTree::Token(inner.clone(), *spacing)].into_iter() } - AttrAnnotatedTokenTree::Delimited(span, delim, stream) => { + AttrTokenTree::Delimited(span, delim, stream) => { smallvec![TokenTree::Delimited(*span, *delim, stream.to_tokenstream()),] .into_iter() } - AttrAnnotatedTokenTree::Attributes(data) => { + AttrTokenTree::Attributes(data) => { let mut outer_attrs = Vec::new(); let mut inner_attrs = Vec::new(); for attr in &data.attrs { match attr.style { - crate::AttrStyle::Outer => { - outer_attrs.push(attr); - } - crate::AttrStyle::Inner => { - inner_attrs.push(attr); - } + crate::AttrStyle::Outer => outer_attrs.push(attr), + crate::AttrStyle::Inner => inner_attrs.push(attr), } } let mut target_tokens: Vec<_> = data .tokens - .create_token_stream() + .to_attr_token_stream() .to_tokenstream() .0 .iter() @@ -239,9 +235,9 @@ impl AttrAnnotatedTokenStream { // Check the last two trees (to account for a trailing semi) for tree in target_tokens.iter_mut().rev().take(2) { if let TokenTree::Delimited(span, delim, delim_tokens) = tree { - // Inner attributes are only supported on extern blocks, functions, impls, - // and modules. All of these have their inner attributes placed at - // the beginning of the rightmost outermost braced group: + // Inner attributes are only supported on extern blocks, functions, + // impls, and modules. All of these have their inner attributes + // placed at the beginning of the rightmost outermost braced group: // e.g. fn foo() { #![my_attr} } // // Therefore, we can insert them back into the right location @@ -255,7 +251,7 @@ impl AttrAnnotatedTokenStream { let mut builder = TokenStreamBuilder::new(); for inner_attr in inner_attrs { - builder.push(inner_attr.tokens().to_tokenstream()); + builder.push(inner_attr.tokens()); } builder.push(delim_tokens.clone()); *tree = TokenTree::Delimited(*span, *delim, builder.build()); @@ -273,7 +269,7 @@ impl AttrAnnotatedTokenStream { let mut flat: SmallVec<[_; 1]> = SmallVec::new(); for attr in outer_attrs { // FIXME: Make this more efficient - flat.extend(attr.tokens().to_tokenstream().0.clone().iter().cloned()); + flat.extend(attr.tokens().0.clone().iter().cloned()); } flat.extend(target_tokens); flat.into_iter() @@ -300,7 +296,7 @@ pub struct AttributesData { pub attrs: AttrVec, /// The underlying tokens for the attribute target that `attrs` /// are applied to - pub tokens: LazyTokenStream, + pub tokens: LazyAttrTokenStream, } /// A `TokenStream` is an abstract sequence of tokens, organized into [`TokenTree`]s. @@ -363,12 +359,6 @@ impl TokenStream { } } -impl From<(AttrAnnotatedTokenTree, Spacing)> for AttrAnnotatedTokenStream { - fn from((tree, spacing): (AttrAnnotatedTokenTree, Spacing)) -> AttrAnnotatedTokenStream { - AttrAnnotatedTokenStream::new(vec![(tree, spacing)]) - } -} - impl iter::FromIterator<TokenTree> for TokenStream { fn from_iter<I: IntoIterator<Item = TokenTree>>(iter: I) -> Self { TokenStream::new(iter.into_iter().collect::<Vec<TokenTree>>()) @@ -420,21 +410,6 @@ impl TokenStream { TokenStream(Lrc::new(self.0.iter().enumerate().map(|(i, tree)| f(i, tree)).collect())) } - fn opt_from_ast(node: &(impl HasAttrs + HasTokens)) -> Option<TokenStream> { - let tokens = node.tokens()?; - let attrs = node.attrs(); - let attr_annotated = if attrs.is_empty() { - tokens.create_token_stream() - } else { - let attr_data = AttributesData { attrs: attrs.to_vec().into(), tokens: tokens.clone() }; - AttrAnnotatedTokenStream::new(vec![( - AttrAnnotatedTokenTree::Attributes(attr_data), - Spacing::Alone, - )]) - }; - Some(attr_annotated.to_tokenstream()) - } - // 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)]) @@ -451,8 +426,18 @@ impl TokenStream { } pub fn from_ast(node: &(impl HasAttrs + HasSpan + HasTokens + fmt::Debug)) -> TokenStream { - TokenStream::opt_from_ast(node) - .unwrap_or_else(|| panic!("missing tokens for node at {:?}: {:?}", node.span(), node)) + let Some(tokens) = node.tokens() else { + panic!("missing tokens for node at {:?}: {:?}", node.span(), node); + }; + let attrs = node.attrs(); + let attr_stream = if attrs.is_empty() { + tokens.to_attr_token_stream() + } else { + let attr_data = + AttributesData { attrs: attrs.iter().cloned().collect(), tokens: tokens.clone() }; + AttrTokenStream::new(vec![AttrTokenTree::Attributes(attr_data)]) + }; + attr_stream.to_tokenstream() } pub fn from_nonterminal_ast(nt: &Nonterminal) -> TokenStream { @@ -555,7 +540,7 @@ impl TokenStreamBuilder { // Get the first stream, which will become the result stream. // If it's `None`, create an empty stream. - let mut iter = streams.drain(..); + let mut iter = streams.into_iter(); let mut res_stream_lrc = iter.next().unwrap().0; // Append the subsequent elements to the result stream, after diff --git a/compiler/rustc_ast/src/util/literal.rs b/compiler/rustc_ast/src/util/literal.rs index 9c18f55c0..536b38560 100644 --- a/compiler/rustc_ast/src/util/literal.rs +++ b/compiler/rustc_ast/src/util/literal.rs @@ -9,7 +9,6 @@ use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::Span; use std::ascii; -use tracing::debug; pub enum LitError { NotLiteral, @@ -23,7 +22,7 @@ pub enum LitError { impl LitKind { /// Converts literal token into a semantic literal. - pub fn from_lit_token(lit: token::Lit) -> Result<LitKind, LitError> { + pub fn from_token_lit(lit: token::Lit) -> Result<LitKind, LitError> { let token::Lit { kind, symbol, suffix } = lit; if suffix.is_some() && !kind.may_have_suffix() { return Err(LitError::InvalidSuffix); @@ -146,14 +145,14 @@ impl LitKind { LitKind::ByteStr(bytes.into()) } - token::Err => LitKind::Err(symbol), + token::Err => LitKind::Err, }) } /// Attempts to recover a token 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 to_lit_token(&self) -> token::Lit { + pub fn to_token_lit(&self) -> token::Lit { let (kind, symbol, suffix) = match *self { LitKind::Str(symbol, ast::StrStyle::Cooked) => { // Don't re-intern unless the escaped string is different. @@ -164,12 +163,7 @@ impl LitKind { } LitKind::Str(symbol, ast::StrStyle::Raw(n)) => (token::StrRaw(n), symbol, None), LitKind::ByteStr(ref bytes) => { - let string = bytes - .iter() - .cloned() - .flat_map(ascii::escape_default) - .map(Into::<char>::into) - .collect::<String>(); + let string = bytes.escape_ascii().to_string(); (token::ByteStr, Symbol::intern(&string), None) } LitKind::Byte(byte) => { @@ -199,7 +193,9 @@ impl LitKind { let symbol = if value { kw::True } else { kw::False }; (token::Bool, symbol, None) } - LitKind::Err(symbol) => (token::Err, symbol, None), + // This only shows up in places like `-Zunpretty=hir` output, so we + // don't bother to produce something useful. + LitKind::Err => (token::Err, Symbol::intern("<bad-literal>"), None), }; token::Lit::new(kind, symbol, suffix) @@ -208,8 +204,8 @@ impl LitKind { impl Lit { /// Converts literal token into an AST literal. - pub fn from_lit_token(token: token::Lit, span: Span) -> Result<Lit, LitError> { - Ok(Lit { token, kind: LitKind::from_lit_token(token)?, span }) + 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. @@ -232,21 +228,21 @@ impl Lit { _ => return Err(LitError::NotLiteral), }; - Lit::from_lit_token(lit, token.span) + 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: kind.to_lit_token(), kind, span } + Lit { token_lit: kind.to_token_lit(), kind, span } } /// Losslessly convert an AST literal into a token. pub fn to_token(&self) -> Token { - let kind = match self.token.kind { - token::Bool => token::Ident(self.token.symbol, false), - _ => token::Literal(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) } diff --git a/compiler/rustc_ast/src/util/parser.rs b/compiler/rustc_ast/src/util/parser.rs index 74b7fe9e2..6c5c7f66f 100644 --- a/compiler/rustc_ast/src/util/parser.rs +++ b/compiler/rustc_ast/src/util/parser.rs @@ -297,11 +297,11 @@ impl ExprPrecedence { match self { ExprPrecedence::Closure => PREC_CLOSURE, - ExprPrecedence::Break | - ExprPrecedence::Continue | - ExprPrecedence::Ret | - ExprPrecedence::Yield | - ExprPrecedence::Yeet => PREC_JUMP, + ExprPrecedence::Break + | ExprPrecedence::Continue + | ExprPrecedence::Ret + | ExprPrecedence::Yield + | ExprPrecedence::Yeet => PREC_JUMP, // `Range` claims to have higher precedence than `Assign`, but `x .. x = x` fails to // parse, instead of parsing as `(x .. x) = x`. Giving `Range` a lower precedence @@ -318,43 +318,43 @@ impl ExprPrecedence { ExprPrecedence::AssignOp => AssocOp::Assign.precedence() as i8, // Unary, prefix - ExprPrecedence::Box | - ExprPrecedence::AddrOf | + ExprPrecedence::Box + | ExprPrecedence::AddrOf // Here `let pats = expr` has `let pats =` as a "unary" prefix of `expr`. // However, this is not exactly right. When `let _ = a` is the LHS of a binop we // need parens sometimes. E.g. we can print `(let _ = a) && b` as `let _ = a && b` // but we need to print `(let _ = a) < b` as-is with parens. - ExprPrecedence::Let | - ExprPrecedence::Unary => PREC_PREFIX, + | ExprPrecedence::Let + | ExprPrecedence::Unary => PREC_PREFIX, // Unary, postfix - ExprPrecedence::Await | - ExprPrecedence::Call | - ExprPrecedence::MethodCall | - ExprPrecedence::Field | - ExprPrecedence::Index | - ExprPrecedence::Try | - ExprPrecedence::InlineAsm | - ExprPrecedence::Mac => PREC_POSTFIX, + ExprPrecedence::Await + | ExprPrecedence::Call + | ExprPrecedence::MethodCall + | ExprPrecedence::Field + | ExprPrecedence::Index + | ExprPrecedence::Try + | ExprPrecedence::InlineAsm + | ExprPrecedence::Mac => PREC_POSTFIX, // Never need parens - ExprPrecedence::Array | - ExprPrecedence::Repeat | - ExprPrecedence::Tup | - ExprPrecedence::Lit | - ExprPrecedence::Path | - ExprPrecedence::Paren | - ExprPrecedence::If | - ExprPrecedence::While | - ExprPrecedence::ForLoop | - ExprPrecedence::Loop | - ExprPrecedence::Match | - ExprPrecedence::ConstBlock | - ExprPrecedence::Block | - ExprPrecedence::TryBlock | - ExprPrecedence::Async | - ExprPrecedence::Struct | - ExprPrecedence::Err => PREC_PAREN, + ExprPrecedence::Array + | ExprPrecedence::Repeat + | ExprPrecedence::Tup + | ExprPrecedence::Lit + | ExprPrecedence::Path + | ExprPrecedence::Paren + | ExprPrecedence::If + | ExprPrecedence::While + | ExprPrecedence::ForLoop + | ExprPrecedence::Loop + | ExprPrecedence::Match + | ExprPrecedence::ConstBlock + | ExprPrecedence::Block + | ExprPrecedence::TryBlock + | ExprPrecedence::Async + | ExprPrecedence::Struct + | ExprPrecedence::Err => PREC_PAREN, } } } diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index d9594b323..1d0de5a4b 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -156,8 +156,8 @@ pub trait Visitor<'ast>: Sized { fn visit_where_predicate(&mut self, p: &'ast WherePredicate) { walk_where_predicate(self, p) } - fn visit_fn(&mut self, fk: FnKind<'ast>, s: Span, _: NodeId) { - walk_fn(self, fk, s) + fn visit_fn(&mut self, fk: FnKind<'ast>, _: Span, _: NodeId) { + walk_fn(self, fk) } fn visit_assoc_item(&mut self, i: &'ast AssocItem, ctxt: AssocCtxt) { walk_assoc_item(self, i, ctxt) @@ -168,8 +168,8 @@ pub trait Visitor<'ast>: Sized { fn visit_param_bound(&mut self, bounds: &'ast GenericBound, _ctxt: BoundKind) { walk_param_bound(self, bounds) } - fn visit_poly_trait_ref(&mut self, t: &'ast PolyTraitRef, m: &'ast TraitBoundModifier) { - walk_poly_trait_ref(self, t, m) + fn visit_poly_trait_ref(&mut self, t: &'ast PolyTraitRef) { + walk_poly_trait_ref(self, t) } fn visit_variant_data(&mut self, s: &'ast VariantData) { walk_struct_def(self, s) @@ -177,14 +177,8 @@ pub trait Visitor<'ast>: Sized { fn visit_field_def(&mut self, s: &'ast FieldDef) { walk_field_def(self, s) } - fn visit_enum_def( - &mut self, - enum_definition: &'ast EnumDef, - generics: &'ast Generics, - item_id: NodeId, - _: Span, - ) { - walk_enum_def(self, enum_definition, generics, item_id) + fn visit_enum_def(&mut self, enum_definition: &'ast EnumDef) { + walk_enum_def(self, enum_definition) } fn visit_variant(&mut self, v: &'ast Variant) { walk_variant(self, v) @@ -207,11 +201,11 @@ pub trait Visitor<'ast>: Sized { fn visit_use_tree(&mut self, use_tree: &'ast UseTree, id: NodeId, _nested: bool) { walk_use_tree(self, use_tree, id) } - fn visit_path_segment(&mut self, path_span: Span, path_segment: &'ast PathSegment) { - walk_path_segment(self, path_span, path_segment) + fn visit_path_segment(&mut self, path_segment: &'ast PathSegment) { + walk_path_segment(self, path_segment) } - fn visit_generic_args(&mut self, path_span: Span, generic_args: &'ast GenericArgs) { - walk_generic_args(self, path_span, generic_args) + fn visit_generic_args(&mut self, generic_args: &'ast GenericArgs) { + walk_generic_args(self, generic_args) } fn visit_generic_arg(&mut self, generic_arg: &'ast GenericArg) { walk_generic_arg(self, generic_arg) @@ -287,11 +281,8 @@ pub fn walk_lifetime<'a, V: Visitor<'a>>(visitor: &mut V, lifetime: &'a Lifetime visitor.visit_ident(lifetime.ident); } -pub fn walk_poly_trait_ref<'a, V>( - visitor: &mut V, - trait_ref: &'a PolyTraitRef, - _: &TraitBoundModifier, -) where +pub fn walk_poly_trait_ref<'a, V>(visitor: &mut V, trait_ref: &'a PolyTraitRef) +where V: Visitor<'a>, { walk_list!(visitor, visit_generic_param, &trait_ref.bound_generic_params); @@ -334,7 +325,7 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) { } ItemKind::Enum(ref enum_definition, ref generics) => { visitor.visit_generics(generics); - visitor.visit_enum_def(enum_definition, generics, item.id, item.span) + visitor.visit_enum_def(enum_definition) } ItemKind::Impl(box Impl { defaultness: _, @@ -377,12 +368,7 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) { walk_list!(visitor, visit_attribute, &item.attrs); } -pub fn walk_enum_def<'a, V: Visitor<'a>>( - visitor: &mut V, - enum_definition: &'a EnumDef, - _: &'a Generics, - _: NodeId, -) { +pub fn walk_enum_def<'a, V: Visitor<'a>>(visitor: &mut V, enum_definition: &'a EnumDef) { walk_list!(visitor, visit_variant, &enum_definition.variants); } @@ -449,7 +435,7 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) { pub fn walk_path<'a, V: Visitor<'a>>(visitor: &mut V, path: &'a Path) { for segment in &path.segments { - visitor.visit_path_segment(path.span, segment); + visitor.visit_path_segment(segment); } } @@ -471,18 +457,14 @@ 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, - path_span: Span, - segment: &'a PathSegment, -) { +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 { - visitor.visit_generic_args(path_span, args); + visitor.visit_generic_args(args); } } -pub fn walk_generic_args<'a, V>(visitor: &mut V, _path_span: Span, generic_args: &'a GenericArgs) +pub fn walk_generic_args<'a, V>(visitor: &mut V, generic_args: &'a GenericArgs) where V: Visitor<'a>, { @@ -516,7 +498,7 @@ 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 { - visitor.visit_generic_args(gen_args.span(), gen_args); + visitor.visit_generic_args(gen_args); } match constraint.kind { AssocConstraintKind::Equality { ref term } => match term { @@ -598,7 +580,7 @@ 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, modifier), + GenericBound::Trait(ref typ, ref _modifier) => visitor.visit_poly_trait_ref(typ), GenericBound::Outlives(ref lifetime) => { visitor.visit_lifetime(lifetime, LifetimeCtxt::Bound) } @@ -673,7 +655,7 @@ pub fn walk_fn_decl<'a, V: Visitor<'a>>(visitor: &mut V, function_declaration: & visitor.visit_fn_ret_ty(&function_declaration.output); } -pub fn walk_fn<'a, V: Visitor<'a>>(visitor: &mut V, kind: FnKind<'a>, _span: Span) { +pub fn walk_fn<'a, V: Visitor<'a>>(visitor: &mut V, kind: FnKind<'a>) { match kind { FnKind::Fn(_, _, sig, _, generics, body) => { visitor.visit_generics(generics); @@ -814,7 +796,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) { walk_list!(visitor, visit_expr, arguments); } ExprKind::MethodCall(ref segment, ref arguments, _span) => { - visitor.visit_path_segment(expression.span, segment); + visitor.visit_path_segment(segment); walk_list!(visitor, visit_expr, arguments); } ExprKind::Binary(_, ref left_expression, ref right_expression) => { @@ -935,14 +917,14 @@ pub fn walk_arm<'a, V: Visitor<'a>>(visitor: &mut V, arm: &'a Arm) { } pub fn walk_vis<'a, V: Visitor<'a>>(visitor: &mut V, vis: &'a Visibility) { - if let VisibilityKind::Restricted { ref path, id } = vis.kind { + if let VisibilityKind::Restricted { ref path, id, shorthand: _ } = vis.kind { visitor.visit_path(path, id); } } pub fn walk_attribute<'a, V: Visitor<'a>>(visitor: &mut V, attr: &'a Attribute) { match attr.kind { - AttrKind::Normal(ref item, ref _tokens) => walk_mac_args(visitor, &item.args), + AttrKind::Normal(ref normal) => walk_mac_args(visitor, &normal.item.args), AttrKind::DocComment(..) => {} } } |