summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_ast/src/ast.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_ast/src/ast.rs')
-rw-r--r--compiler/rustc_ast/src/ast.rs266
1 files changed, 145 insertions, 121 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);
}