rust/compiler/rustc_ast/src/ast.rs

2913 lines
88 KiB
Rust
Raw Normal View History

//! The Rust abstract syntax tree module.
//!
//! This module contains common structures forming the language AST.
//! Two main entities in the module are [`Item`] (which represents an AST element with
//! additional metadata), and [`ItemKind`] (which represents a concrete type and contains
//! information specific to the type of the item).
//!
//! Other module items worth mentioning:
//! - [`Ty`] and [`TyKind`]: A parsed Rust type.
//! - [`Expr`] and [`ExprKind`]: A parsed Rust expression.
//! - [`Pat`] and [`PatKind`]: A parsed Rust pattern. Patterns are often dual to expressions.
//! - [`Stmt`] and [`StmtKind`]: An executable action that does not return a value.
//! - [`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.
//! - [`MacroDef`], [`MacStmtStyle`], [`MacCall`], [`MacDelimiter`]: Macro definition and invocation.
//! - [`Attribute`]: Metadata associated with item.
//! - [`UnOp`], [`BinOp`], and [`BinOpKind`]: Unary and binary operators.
2019-12-22 23:42:04 +01:00
pub use crate::util::parser::ExprPrecedence;
2019-02-06 18:33:01 +01:00
pub use GenericArgs::*;
pub use UnsafeSource::*;
use crate::ptr::P;
use crate::token::{self, CommentKind, DelimToken, Token};
use crate::tokenstream::{DelimSpan, LazyTokenStream, TokenStream, TokenTree};
2019-10-08 13:38:14 +02:00
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
2020-09-20 22:19:51 +02:00
use rustc_data_structures::stack::ensure_sufficient_stack;
2018-02-27 17:11:14 +01:00
use rustc_data_structures::sync::Lrc;
2019-10-08 13:38:14 +02:00
use rustc_data_structures::thin_vec::ThinVec;
2019-11-16 11:53:44 +01:00
use rustc_macros::HashStable_Generic;
2019-12-22 23:42:04 +01:00
use rustc_serialize::{self, Decoder, Encoder};
use rustc_span::source_map::{respan, Spanned};
2020-04-19 13:00:18 +02:00
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{Span, DUMMY_SP};
use std::cmp::Ordering;
use std::convert::TryFrom;
2018-09-23 01:19:44 +02:00
use std::fmt;
#[cfg(test)]
mod tests;
/// A "Label" is an identifier of some point in sources,
/// e.g. in the following code:
///
/// ```rust
/// 'outer: loop {
/// break 'outer;
/// }
/// ```
///
/// `'outer` is a label.
#[derive(Clone, Encodable, Decodable, Copy, HashStable_Generic)]
pub struct Label {
pub ident: Ident,
}
impl fmt::Debug for Label {
2019-02-06 18:33:01 +01:00
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "label({:?})", self.ident)
}
}
/// A "Lifetime" is an annotation of the scope in which variable
/// can be used, e.g. `'a` in `&'a i32`.
#[derive(Clone, Encodable, Decodable, Copy)]
pub struct Lifetime {
pub id: NodeId,
2017-03-25 22:14:18 +01:00
pub ident: Ident,
}
impl fmt::Debug for Lifetime {
2019-02-06 18:33:01 +01:00
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2019-12-22 23:42:04 +01:00
write!(f, "lifetime({}: {})", self.id, self)
}
}
impl fmt::Display for Lifetime {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.ident.name)
}
}
/// A "Path" is essentially Rust's notion of a name.
///
/// It's represented as a sequence of identifiers,
2014-06-09 22:12:30 +02:00
/// along with a bunch of supporting information.
///
/// E.g., `std::cmp::PartialEq`.
#[derive(Clone, Encodable, Decodable, Debug)]
2013-03-27 01:00:35 +01:00
pub struct Path {
pub span: Span,
/// The segments in the path: the things separated by `::`.
2019-05-11 16:41:37 +02:00
/// Global paths begin with `kw::PathRoot`.
pub segments: Vec<PathSegment>,
Rewrite `collect_tokens` implementations to use a flattened buffer Instead of trying to collect tokens at each depth, we 'flatten' the stream as we go allong, pushing open/close delimiters to our buffer just like regular tokens. One capturing is complete, we reconstruct a nested `TokenTree::Delimited` structure, producing a normal `TokenStream`. The reconstructed `TokenStream` is not created immediately - instead, it is produced on-demand by a closure (wrapped in a new `LazyTokenStream` type). This closure stores a clone of the original `TokenCursor`, plus a record of the number of calls to `next()/next_desugared()`. This is sufficient to reconstruct the tokenstream seen by the callback without storing any additional state. If the tokenstream is never used (e.g. when a captured `macro_rules!` argument is never passed to a proc macro), we never actually create a `TokenStream`. This implementation has a number of advantages over the previous one: * It is significantly simpler, with no edge cases around capturing the start/end of a delimited group. * It can be easily extended to allow replacing tokens an an arbitrary 'depth' by just using `Vec::splice` at the proper position. This is important for PR #76130, which requires us to track information about attributes along with tokens. * The lazy approach to `TokenStream` construction allows us to easily parse an AST struct, and then decide after the fact whether we need a `TokenStream`. This will be useful when we start collecting tokens for `Attribute` - we can discard the `LazyTokenStream` if the parsed attribute doesn't need tokens (e.g. is a builtin attribute). The performance impact seems to be neglibile (see https://github.com/rust-lang/rust/pull/77250#issuecomment-703960604). There is a small slowdown on a few benchmarks, but it only rises above 1% for incremental builds, where it represents a larger fraction of the much smaller instruction count. There a ~1% speedup on a few other incremental benchmarks - my guess is that the speedups and slowdowns will usually cancel out in practice.
2020-09-27 03:56:29 +02:00
pub tokens: Option<LazyTokenStream>,
}
impl PartialEq<Symbol> for Path {
fn eq(&self, symbol: &Symbol) -> bool {
2019-12-22 23:42:04 +01:00
self.segments.len() == 1 && { self.segments[0].ident.name == *symbol }
}
}
impl<CTX> HashStable<CTX> for Path {
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
self.segments.len().hash_stable(hcx, hasher);
for segment in &self.segments {
segment.ident.name.hash_stable(hcx, hasher);
}
}
}
2016-03-29 11:12:01 +02:00
impl Path {
// Convert a span and an identifier to the corresponding
// one-segment path.
2018-03-19 01:54:56 +01:00
pub fn from_ident(ident: Ident) -> Path {
2020-08-22 00:51:23 +02:00
Path { segments: vec![PathSegment::from_ident(ident)], span: ident.span, tokens: None }
2016-03-29 11:12:01 +02:00
}
pub fn is_global(&self) -> bool {
2019-05-11 16:41:37 +02:00
!self.segments.is_empty() && self.segments[0].ident.name == kw::PathRoot
}
2016-03-29 11:12:01 +02:00
}
/// A segment of a path: an identifier, an optional lifetime, and a set of types.
///
/// E.g., `std`, `String` or `Box<T>`.
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct PathSegment {
/// The identifier portion of this path segment.
pub ident: Ident,
2018-08-31 02:01:26 +02:00
pub id: NodeId,
/// Type/lifetime parameters attached to this path. They come in
/// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`.
/// `None` means that no parameter list is supplied (`Path`),
/// `Some` means that parameter list is supplied (`Path<X, Y>`)
/// but it can be empty (`Path<>`).
/// `P` is used as a size optimization for the common case with no parameters.
2018-02-23 18:48:54 +01:00
pub args: Option<P<GenericArgs>>,
2016-12-10 07:45:58 +01:00
}
impl PathSegment {
2018-03-19 01:54:56 +01:00
pub fn from_ident(ident: Ident) -> Self {
2018-08-31 02:01:26 +02:00
PathSegment { ident, id: DUMMY_NODE_ID, args: None }
}
2018-12-02 13:15:42 +01:00
pub fn path_root(span: Span) -> Self {
2019-05-11 16:41:37 +02:00
PathSegment::from_ident(Ident::new(kw::PathRoot, span))
}
}
2019-02-08 14:53:55 +01:00
/// The arguments of a path segment.
///
/// E.g., `<A, B>` as in `Foo<A, B>` or `(A, B)` as in `Foo(A, B)`.
#[derive(Clone, Encodable, Decodable, Debug)]
pub enum GenericArgs {
2019-02-08 14:53:55 +01:00
/// The `<'a, A, B, C>` in `foo::bar::baz::<'a, A, B, C>`.
2018-02-23 18:48:54 +01:00
AngleBracketed(AngleBracketedArgs),
2019-02-08 14:53:55 +01:00
/// The `(A, B)` and `C` in `Foo(A, B) -> C`.
Parenthesized(ParenthesizedArgs),
}
impl GenericArgs {
pub fn is_angle_bracketed(&self) -> bool {
2020-12-24 02:55:21 +01:00
matches!(self, AngleBracketed(..))
}
pub fn span(&self) -> Span {
2017-07-20 01:39:34 +02:00
match *self {
AngleBracketed(ref data) => data.span,
Parenthesized(ref data) => data.span,
2017-07-20 01:39:34 +02:00
}
}
}
/// Concrete argument in the sequence of generic args.
#[derive(Clone, Encodable, Decodable, Debug)]
2018-05-27 21:07:09 +02:00
pub enum GenericArg {
/// `'a` in `Foo<'a>`
Lifetime(Lifetime),
/// `Bar` in `Foo<Bar>`
Type(P<Ty>),
/// `1` in `Foo<1>`
Const(AnonConst),
}
impl GenericArg {
pub fn span(&self) -> Span {
match self {
GenericArg::Lifetime(lt) => lt.ident.span,
GenericArg::Type(ty) => ty.span,
GenericArg::Const(ct) => ct.value.span,
}
}
}
2019-02-08 14:53:55 +01:00
/// A path like `Foo<'a, T>`.
#[derive(Clone, Encodable, Decodable, Debug, Default)]
2018-02-23 18:48:54 +01:00
pub struct AngleBracketedArgs {
2019-02-08 14:53:55 +01:00
/// The overall span.
pub span: Span,
/// The comma separated parts in the `<...>`.
pub args: Vec<AngleBracketedArg>,
}
/// Either an argument for a parameter e.g., `'a`, `Vec<u8>`, `0`,
/// or a constraint on an associated item, e.g., `Item = String` or `Item: Bound`.
#[derive(Clone, Encodable, Decodable, Debug)]
pub enum AngleBracketedArg {
/// Argument for a generic parameter.
Arg(GenericArg),
/// Constraint for an associated item.
Constraint(AssocTyConstraint),
2013-01-13 19:48:09 +01:00
}
impl AngleBracketedArg {
pub fn span(&self) -> Span {
match self {
AngleBracketedArg::Arg(arg) => arg.span(),
AngleBracketedArg::Constraint(constraint) => constraint.span,
}
}
}
2018-02-23 18:48:54 +01:00
impl Into<Option<P<GenericArgs>>> for AngleBracketedArgs {
fn into(self) -> Option<P<GenericArgs>> {
Some(P(GenericArgs::AngleBracketed(self)))
}
}
impl Into<Option<P<GenericArgs>>> for ParenthesizedArgs {
fn into(self) -> Option<P<GenericArgs>> {
Some(P(GenericArgs::Parenthesized(self)))
2017-07-20 01:39:34 +02:00
}
}
2019-02-08 14:53:55 +01:00
/// A path like `Foo(A, B) -> C`.
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct ParenthesizedArgs {
/// ```text
/// Foo(A, B) -> C
/// ^^^^^^^^^^^^^^
/// ```
pub span: Span,
/// `(A, B)`
pub inputs: Vec<P<Ty>>,
/// ```text
/// Foo(A, B) -> C
/// ^^^^^^
/// ```
pub inputs_span: Span,
/// `C`
2020-02-15 04:10:59 +01:00
pub output: FnRetTy,
}
impl ParenthesizedArgs {
pub fn as_angle_bracketed_args(&self) -> AngleBracketedArgs {
let args = self
.inputs
.iter()
.cloned()
.map(|input| AngleBracketedArg::Arg(GenericArg::Type(input)))
.collect();
AngleBracketedArgs { span: self.span, args }
}
}
pub use crate::node_id::{NodeId, CRATE_NODE_ID, DUMMY_NODE_ID};
/// A modifier on a bound, e.g., `?Sized` or `?const Trait`.
///
/// Negative bounds should also be handled here.
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug)]
2018-05-28 14:33:28 +02:00
pub enum TraitBoundModifier {
/// No modifiers
2018-05-28 14:33:28 +02:00
None,
/// `?Trait`
2018-05-28 14:33:28 +02:00
Maybe,
/// `?const Trait`
MaybeConst,
2020-01-20 10:20:45 +01:00
/// `?const ?Trait`
//
// This parses but will be rejected during AST validation.
MaybeConstMaybe,
2018-05-28 14:33:28 +02:00
}
2014-06-09 22:12:30 +02:00
/// The AST represents all type param bounds as types.
/// `typeck::collect::compute_bounds` matches these against
/// the "special" built-in traits (see `middle::lang_items`) and
/// detects `Copy`, `Send` and `Sync`.
#[derive(Clone, Encodable, Decodable, Debug)]
pub enum GenericBound {
Trait(PolyTraitRef, TraitBoundModifier),
2018-09-23 01:19:44 +02:00
Outlives(Lifetime),
}
impl GenericBound {
pub fn span(&self) -> Span {
match self {
GenericBound::Trait(ref t, ..) => t.span,
GenericBound::Outlives(ref l) => l.ident.span,
}
}
}
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.
2020-08-09 09:50:56 +02:00
#[derive(Hash, Clone, Copy)]
pub enum ParamKindOrd {
Lifetime,
Type,
// `unordered` is only `true` if `sess.has_features().const_generics`
// is active. Specifically, if it's only `min_const_generics`, it will still require
// ordering consts after types.
Const { unordered: bool },
}
impl Ord for ParamKindOrd {
fn cmp(&self, other: &Self) -> Ordering {
use ParamKindOrd::*;
let to_int = |v| match v {
Lifetime => 0,
Type | Const { unordered: true } => 1,
// technically both consts should be ordered equally,
// but only one is ever encountered at a time, so this is
// fine.
Const { unordered: false } => 2,
};
to_int(*self).cmp(&to_int(*other))
}
}
impl PartialOrd for ParamKindOrd {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
2020-08-09 09:50:56 +02:00
impl PartialEq for ParamKindOrd {
fn eq(&self, other: &Self) -> bool {
self.cmp(other) == Ordering::Equal
}
}
impl Eq for ParamKindOrd {}
impl fmt::Display for ParamKindOrd {
2019-02-07 10:27:56 +01:00
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),
}
}
}
#[derive(Clone, Encodable, Decodable, Debug)]
2018-05-27 21:07:09 +02:00
pub enum GenericParamKind {
/// A lifetime definition (e.g., `'a: 'b + 'c + 'd`).
Lifetime,
2019-12-22 23:42:04 +01:00
Type {
default: Option<P<Ty>>,
},
Const {
ty: P<Ty>,
/// Span of the `const` keyword.
kw_span: Span,
/// Optional default value for the const generic param
default: Option<AnonConst>,
2019-12-22 23:42:04 +01:00
},
}
#[derive(Clone, Encodable, Decodable, Debug)]
2018-05-27 21:07:09 +02:00
pub struct GenericParam {
2018-05-26 20:16:21 +02:00
pub id: NodeId,
pub ident: Ident,
2019-12-03 16:38:34 +01:00
pub attrs: AttrVec,
pub bounds: GenericBounds,
pub is_placeholder: bool,
2018-05-27 21:07:09 +02:00
pub kind: GenericParamKind,
}
/// Represents lifetime, type and const parameters attached to a declaration of
/// a function, enum, trait, etc.
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct Generics {
2018-05-27 21:07:09 +02:00
pub params: Vec<GenericParam>,
pub where_clause: WhereClause,
2016-08-10 19:39:12 +02:00
pub span: Span,
}
impl Default for Generics {
/// Creates an instance of `Generics`.
2018-09-23 01:19:44 +02:00
fn default() -> Generics {
Generics {
params: Vec::new(),
where_clause: WhereClause {
has_where_token: false,
predicates: Vec::new(),
span: DUMMY_SP,
},
2016-08-10 19:39:12 +02:00
span: DUMMY_SP,
}
}
}
2019-02-08 14:53:55 +01:00
/// A where-clause in a definition.
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct WhereClause {
/// `true` if we ate a `where` token: this can happen
2020-08-05 16:44:28 +02:00
/// if we parsed no predicates (e.g. `struct Foo where {}`).
/// This allows us to accurately pretty-print
/// in `nt_to_tokenstream`
pub has_where_token: bool,
pub predicates: Vec<WherePredicate>,
2017-07-27 06:37:35 +02:00
pub span: Span,
}
2019-02-08 14:53:55 +01:00
/// A single predicate in a where-clause.
#[derive(Clone, Encodable, Decodable, Debug)]
pub enum WherePredicate {
/// A type binding (e.g., `for<'c> Foo: Send + Clone + 'c`).
BoundPredicate(WhereBoundPredicate),
/// A lifetime predicate (e.g., `'a: 'b + 'c`).
RegionPredicate(WhereRegionPredicate),
/// An equality predicate (unsupported).
EqPredicate(WhereEqPredicate),
}
impl WherePredicate {
pub fn span(&self) -> Span {
match self {
WherePredicate::BoundPredicate(p) => p.span,
WherePredicate::RegionPredicate(p) => p.span,
WherePredicate::EqPredicate(p) => p.span,
}
}
}
/// A type bound.
///
/// E.g., `for<'c> Foo: Send + Clone + 'c`.
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct WhereBoundPredicate {
pub span: Span,
/// Any generics from a `for` binding.
2018-05-27 21:07:09 +02:00
pub bound_generic_params: Vec<GenericParam>,
/// The type being bounded.
pub bounded_ty: P<Ty>,
/// Trait and lifetime bounds (`Clone + Send + 'static`).
pub bounds: GenericBounds,
}
/// A lifetime predicate.
///
/// E.g., `'a: 'b + 'c`.
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct WhereRegionPredicate {
pub span: Span,
pub lifetime: Lifetime,
pub bounds: GenericBounds,
}
/// An equality predicate (unsupported).
///
/// 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>,
}
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct Crate {
pub attrs: Vec<Attribute>,
pub items: Vec<P<Item>>,
pub span: Span,
2020-02-15 21:51:40 +01:00
/// The order of items in the HIR is unrelated to the order of
/// items in the AST. However, we generate proc macro harnesses
/// based on the AST order, and later refer to these harnesses
/// from the HIR. This field keeps track of the order in which
/// we generated proc macros harnesses, so that we can map
/// HIR proc macros items back to their harness items.
pub proc_macros: Vec<NodeId>,
2013-01-15 04:06:59 +01:00
}
/// 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.
///
/// E.g., `#[test]`, `#[derive(..)]`, `#[rustfmt::skip]` or `#[feature = "foo"]`.
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
pub struct MetaItem {
pub path: Path,
pub kind: MetaItemKind,
pub span: Span,
}
/// A compile-time attribute item.
///
/// E.g., `#[test]`, `#[derive(..)]` or `#[feature = "foo"]`.
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
pub enum MetaItemKind {
/// Word meta item.
///
/// E.g., `test` as in `#[test]`.
Word,
/// List meta item.
///
/// E.g., `derive(..)` as in `#[derive(..)]`.
List(Vec<NestedMetaItem>),
/// Name value meta item.
///
/// E.g., `feature = "foo"` as in `#[feature = "foo"]`.
2018-09-23 01:19:44 +02:00
NameValue(Lit),
}
/// A block (`{ .. }`).
///
/// E.g., `{ .. }` as in `fn foo() { .. }`.
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct Block {
/// The statements in the block.
pub stmts: Vec<Stmt>,
pub id: NodeId,
/// Distinguishes between `unsafe { ... }` and `{ ... }`.
pub rules: BlockCheckMode,
pub span: Span,
Rewrite `collect_tokens` implementations to use a flattened buffer Instead of trying to collect tokens at each depth, we 'flatten' the stream as we go allong, pushing open/close delimiters to our buffer just like regular tokens. One capturing is complete, we reconstruct a nested `TokenTree::Delimited` structure, producing a normal `TokenStream`. The reconstructed `TokenStream` is not created immediately - instead, it is produced on-demand by a closure (wrapped in a new `LazyTokenStream` type). This closure stores a clone of the original `TokenCursor`, plus a record of the number of calls to `next()/next_desugared()`. This is sufficient to reconstruct the tokenstream seen by the callback without storing any additional state. If the tokenstream is never used (e.g. when a captured `macro_rules!` argument is never passed to a proc macro), we never actually create a `TokenStream`. This implementation has a number of advantages over the previous one: * It is significantly simpler, with no edge cases around capturing the start/end of a delimited group. * It can be easily extended to allow replacing tokens an an arbitrary 'depth' by just using `Vec::splice` at the proper position. This is important for PR #76130, which requires us to track information about attributes along with tokens. * The lazy approach to `TokenStream` construction allows us to easily parse an AST struct, and then decide after the fact whether we need a `TokenStream`. This will be useful when we start collecting tokens for `Attribute` - we can discard the `LazyTokenStream` if the parsed attribute doesn't need tokens (e.g. is a builtin attribute). The performance impact seems to be neglibile (see https://github.com/rust-lang/rust/pull/77250#issuecomment-703960604). There is a small slowdown on a few benchmarks, but it only rises above 1% for incremental builds, where it represents a larger fraction of the much smaller instruction count. There a ~1% speedup on a few other incremental benchmarks - my guess is that the speedups and slowdowns will usually cancel out in practice.
2020-09-27 03:56:29 +02:00
pub tokens: Option<LazyTokenStream>,
2013-01-15 04:35:08 +01:00
}
2020-07-03 00:11:03 +02:00
/// A match pattern.
///
/// Patterns appear in match statements and some other contexts, such as `let` and `if let`.
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct Pat {
pub id: NodeId,
2019-09-26 17:18:31 +02:00
pub kind: PatKind,
pub span: Span,
Rewrite `collect_tokens` implementations to use a flattened buffer Instead of trying to collect tokens at each depth, we 'flatten' the stream as we go allong, pushing open/close delimiters to our buffer just like regular tokens. One capturing is complete, we reconstruct a nested `TokenTree::Delimited` structure, producing a normal `TokenStream`. The reconstructed `TokenStream` is not created immediately - instead, it is produced on-demand by a closure (wrapped in a new `LazyTokenStream` type). This closure stores a clone of the original `TokenCursor`, plus a record of the number of calls to `next()/next_desugared()`. This is sufficient to reconstruct the tokenstream seen by the callback without storing any additional state. If the tokenstream is never used (e.g. when a captured `macro_rules!` argument is never passed to a proc macro), we never actually create a `TokenStream`. This implementation has a number of advantages over the previous one: * It is significantly simpler, with no edge cases around capturing the start/end of a delimited group. * It can be easily extended to allow replacing tokens an an arbitrary 'depth' by just using `Vec::splice` at the proper position. This is important for PR #76130, which requires us to track information about attributes along with tokens. * The lazy approach to `TokenStream` construction allows us to easily parse an AST struct, and then decide after the fact whether we need a `TokenStream`. This will be useful when we start collecting tokens for `Attribute` - we can discard the `LazyTokenStream` if the parsed attribute doesn't need tokens (e.g. is a builtin attribute). The performance impact seems to be neglibile (see https://github.com/rust-lang/rust/pull/77250#issuecomment-703960604). There is a small slowdown on a few benchmarks, but it only rises above 1% for incremental builds, where it represents a larger fraction of the much smaller instruction count. There a ~1% speedup on a few other incremental benchmarks - my guess is that the speedups and slowdowns will usually cancel out in practice.
2020-09-27 03:56:29 +02:00
pub tokens: Option<LazyTokenStream>,
}
2016-04-24 05:26:10 +02:00
impl Pat {
/// Attempt reparsing the pattern as a type.
/// This is intended for use by diagnostics.
pub fn to_ty(&self) -> Option<P<Ty>> {
2019-09-26 18:25:31 +02:00
let kind = match &self.kind {
// 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) => {
2018-09-23 01:19:44 +02:00
TyKind::Path(None, Path::from_ident(*ident))
}
PatKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
2020-02-29 17:32:20 +01:00
PatKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
// `&mut? P` can be reinterpreted as `&mut? T` where `T` is `P` reparsed as a type.
2019-12-22 23:42:04 +01:00
PatKind::Ref(pat, mutbl) => {
pat.to_ty().map(|ty| TyKind::Rptr(None, MutTy { ty, mutbl: *mutbl }))?
}
// A slice/array pattern `[P]` can be reparsed as `[T]`, an unsized array,
// when `P` can be reparsed as a type `T`.
PatKind::Slice(pats) if pats.len() == 1 => pats[0].to_ty().map(TyKind::Slice)?,
// A tuple pattern `(P0, .., Pn)` can be reparsed as `(T0, .., Tn)`
// assuming `T0` to `Tn` are all syntactically valid as types.
PatKind::Tuple(pats) => {
let mut tys = Vec::with_capacity(pats.len());
// FIXME(#48994) - could just be collected into an Option<Vec>
for pat in pats {
tys.push(pat.to_ty()?);
}
TyKind::Tup(tys)
}
_ => return None,
};
Some(P(Ty { kind, id: self.id, span: self.span, tokens: None }))
}
/// Walk top-down and call `it` in each place where a pattern occurs
/// starting with the root pattern `walk` is called on. If `it` returns
2019-09-04 02:43:49 +02:00
/// false then we will descend no further but siblings will be processed.
pub fn walk(&self, it: &mut impl FnMut(&Pat) -> bool) {
2016-04-24 05:26:10 +02:00
if !it(self) {
return;
2016-04-24 05:26:10 +02:00
}
2019-09-26 17:18:31 +02:00
match &self.kind {
// Walk into the pattern associated with `Ident` (if any).
PatKind::Ident(_, _, Some(p)) => p.walk(it),
// Walk into each field of struct.
PatKind::Struct(_, fields, _) => fields.iter().for_each(|field| field.pat.walk(it)),
// Sequence of patterns.
2019-12-22 23:42:04 +01:00
PatKind::TupleStruct(_, s) | PatKind::Tuple(s) | PatKind::Slice(s) | PatKind::Or(s) => {
s.iter().for_each(|p| p.walk(it))
}
// Trivial wrappers over inner patterns.
2019-12-22 23:42:04 +01:00
PatKind::Box(s) | PatKind::Ref(s, _) | PatKind::Paren(s) => s.walk(it),
// These patterns do not contain subpatterns, skip.
2018-09-23 01:19:44 +02:00
PatKind::Wild
2019-07-07 00:26:55 +02:00
| PatKind::Rest
2018-09-23 01:19:44 +02:00
| PatKind::Lit(_)
| PatKind::Range(..)
| PatKind::Ident(..)
| PatKind::Path(..)
2020-02-29 17:32:20 +01:00
| PatKind::MacCall(_) => {}
2016-04-24 05:26:10 +02:00
}
}
/// Is this a `..` pattern?
pub fn is_rest(&self) -> bool {
2020-12-24 02:55:21 +01:00
matches!(self.kind, PatKind::Rest)
}
2016-04-24 05:26:10 +02:00
}
/// A single field in a struct pattern.
2015-03-16 23:49:27 +01:00
///
/// Patterns like the fields of `Foo { x, ref y, ref mut z }`
/// are treated the same as `x: x, y: ref y, z: ref mut z`,
/// except when `is_shorthand` is true.
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct FieldPat {
/// The identifier for the field.
pub ident: Ident,
/// The pattern the field is destructured to.
pub pat: P<Pat>,
pub is_shorthand: bool,
2019-12-03 16:38:34 +01:00
pub attrs: AttrVec,
2019-08-14 03:22:51 +02:00
pub id: NodeId,
pub span: Span,
pub is_placeholder: bool,
}
2011-07-11 14:13:20 +02:00
#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy)]
pub enum BindingMode {
ByRef(Mutability),
ByValue(Mutability),
}
#[derive(Clone, Encodable, Decodable, Debug)]
pub enum RangeEnd {
Included(RangeSyntax),
Excluded,
}
#[derive(Clone, Encodable, Decodable, Debug)]
pub enum RangeSyntax {
/// `...`
DotDotDot,
/// `..=`
DotDotEq,
}
#[derive(Clone, Encodable, Decodable, Debug)]
2016-02-11 19:16:33 +01:00
pub enum PatKind {
/// Represents a wildcard pattern (`_`).
2016-02-11 19:16:33 +01:00
Wild,
/// A `PatKind::Ident` may either be a new bound variable (`ref mut binding @ OPT_SUBPATTERN`),
/// 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.
2018-03-18 14:47:09 +01:00
Ident(BindingMode, Ident, Option<P<Pat>>),
/// A struct or struct variant pattern (e.g., `Variant {x, y, ..}`).
/// The `bool` is `true` in the presence of a `..`.
Struct(Path, Vec<FieldPat>, /* recovered */ bool),
/// A tuple struct/variant pattern (`Variant(x, y, .., z)`).
TupleStruct(Path, Vec<P<Pat>>),
2018-10-19 16:40:07 +02:00
/// An or-pattern `A | B | C`.
/// Invariant: `pats.len() >= 2`.
2018-10-19 16:40:07 +02:00
Or(Vec<P<Pat>>),
/// A possibly qualified path pattern.
2017-08-11 20:34:14 +02:00
/// 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),
/// A tuple pattern (`(a, b)`).
Tuple(Vec<P<Pat>>),
/// A `box` pattern.
2016-02-11 19:16:33 +01:00
Box(P<Pat>),
/// A reference pattern (e.g., `&mut (a, b)`).
2016-02-11 19:16:33 +01:00
Ref(P<Pat>, Mutability),
/// A literal.
2016-02-11 19:16:33 +01:00
Lit(P<Expr>),
/// A range pattern (e.g., `1...2`, `1..=2` or `1..2`).
Range(Option<P<Expr>>, Option<P<Expr>>, Spanned<RangeEnd>),
/// A slice pattern `[a, b, c]`.
Slice(Vec<P<Pat>>),
2019-07-07 00:26:55 +02:00
/// A rest pattern `..`.
///
/// Syntactically it is valid anywhere.
///
/// Semantically however, it only has meaning immediately inside:
/// - a slice pattern: `[a, .., b]`,
/// - a binding pattern immediately inside a slice pattern: `[a, r @ ..]`,
/// - a tuple pattern: `(a, .., b)`,
/// - a tuple struct/variant pattern: `$path(a, .., b)`.
///
/// In all of these cases, an additional restriction applies,
/// only one rest pattern may occur in the pattern sequences.
Rest,
/// Parentheses in patterns used for grouping (i.e., `(PAT)`).
Paren(P<Pat>),
/// A macro pattern; pre-expansion.
2020-02-29 17:32:20 +01:00
MacCall(MacCall),
2010-11-24 23:42:01 +01:00
}
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Copy)]
#[derive(HashStable_Generic, Encodable, Decodable)]
pub enum Mutability {
Mut,
Not,
}
impl Mutability {
/// Returns `MutMutable` only if both `self` and `other` are mutable.
pub fn and(self, other: Self) -> Self {
match self {
Mutability::Mut => other,
Mutability::Not => Mutability::Not,
}
}
pub fn invert(self) -> Self {
match self {
Mutability::Mut => Mutability::Not,
Mutability::Not => Mutability::Mut,
}
}
pub fn prefix_str(&self) -> &'static str {
match self {
Mutability::Mut => "mut ",
Mutability::Not => "",
}
}
}
/// The kind of borrow in an `AddrOf` expression,
/// e.g., `&place` or `&raw const place`.
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
#[derive(Encodable, Decodable, HashStable_Generic)]
pub enum BorrowKind {
/// A normal borrow, `&$expr` or `&mut $expr`.
/// The resulting type is either `&'a T` or `&'a mut T`
/// where `T = typeof($expr)` and `'a` is some lifetime.
2019-12-02 23:20:35 +01:00
Ref,
/// A raw borrow, `&raw const $expr` or `&raw mut $expr`.
/// The resulting type is either `*const T` or `*mut T`
/// where `T = typeof($expr)`.
Raw,
}
#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy)]
pub enum BinOpKind {
2015-03-16 23:11:23 +01:00
/// The `+` operator (addition)
Add,
2015-03-16 23:11:23 +01:00
/// The `-` operator (subtraction)
Sub,
2015-03-16 23:11:23 +01:00
/// The `*` operator (multiplication)
Mul,
2015-03-16 23:11:23 +01:00
/// The `/` operator (division)
Div,
2015-03-16 23:11:23 +01:00
/// The `%` operator (modulus)
Rem,
2015-03-16 23:11:23 +01:00
/// The `&&` operator (logical and)
And,
2015-03-16 23:11:23 +01:00
/// The `||` operator (logical or)
Or,
2015-03-16 23:11:23 +01:00
/// The `^` operator (bitwise xor)
BitXor,
2015-03-16 23:11:23 +01:00
/// The `&` operator (bitwise and)
BitAnd,
2015-03-16 23:11:23 +01:00
/// The `|` operator (bitwise or)
BitOr,
2015-03-16 23:11:23 +01:00
/// The `<<` operator (shift left)
Shl,
2015-03-16 23:11:23 +01:00
/// The `>>` operator (shift right)
Shr,
2015-03-16 23:11:23 +01:00
/// The `==` operator (equality)
Eq,
2015-03-16 23:11:23 +01:00
/// The `<` operator (less than)
Lt,
2015-03-16 23:11:23 +01:00
/// The `<=` operator (less than or equal to)
Le,
2015-03-16 23:11:23 +01:00
/// The `!=` operator (not equal to)
Ne,
2015-03-16 23:11:23 +01:00
/// The `>=` operator (greater than or equal to)
Ge,
2015-03-16 23:11:23 +01:00
/// The `>` operator (greater than)
Gt,
}
impl BinOpKind {
pub fn to_string(&self) -> &'static str {
2019-02-06 18:33:01 +01:00
use BinOpKind::*;
match *self {
Add => "+",
Sub => "-",
Mul => "*",
Div => "/",
Rem => "%",
And => "&&",
Or => "||",
BitXor => "^",
BitAnd => "&",
BitOr => "|",
Shl => "<<",
Shr => ">>",
Eq => "==",
Lt => "<",
Le => "<=",
Ne => "!=",
Ge => ">=",
Gt => ">",
}
}
pub fn lazy(&self) -> bool {
2020-12-24 02:55:21 +01:00
matches!(self, BinOpKind::And | BinOpKind::Or)
}
pub fn is_comparison(&self) -> bool {
2019-02-06 18:33:01 +01:00
use BinOpKind::*;
// Note for developers: please keep this as is;
// we want compilation to fail if another variant is added.
match *self {
2018-09-23 01:19:44 +02:00
Eq | Lt | Le | Ne | Gt | Ge => true,
And | Or | Add | Sub | Mul | Div | Rem | BitXor | BitAnd | BitOr | Shl | Shr => false,
}
}
}
pub type BinOp = Spanned<BinOpKind>;
/// Unary operator.
///
/// Note that `&data` is not an operator, it's an `AddrOf` expression.
#[derive(Clone, Encodable, Decodable, Debug, Copy)]
pub enum UnOp {
2015-03-16 23:11:23 +01:00
/// The `*` operator for dereferencing
Deref,
2015-03-16 23:11:23 +01:00
/// The `!` operator for logical inversion
Not,
2015-03-16 23:11:23 +01:00
/// The `-` operator for negation
Neg,
}
impl UnOp {
pub fn to_string(op: UnOp) -> &'static str {
match op {
UnOp::Deref => "*",
UnOp::Not => "!",
UnOp::Neg => "-",
}
}
}
2015-03-17 00:02:58 +01:00
/// A statement
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct Stmt {
pub id: NodeId,
2019-09-26 18:34:50 +02:00
pub kind: StmtKind,
pub span: Span,
}
impl Stmt {
pub fn tokens(&self) -> Option<&LazyTokenStream> {
match self.kind {
StmtKind::Local(ref local) => local.tokens.as_ref(),
StmtKind::Item(ref item) => item.tokens.as_ref(),
StmtKind::Expr(ref expr) | StmtKind::Semi(ref expr) => expr.tokens.as_ref(),
StmtKind::Empty => None,
StmtKind::MacCall(ref mac) => mac.tokens.as_ref(),
}
}
pub fn has_trailing_semicolon(&self) -> bool {
match &self.kind {
StmtKind::Semi(_) => true,
StmtKind::MacCall(mac) => matches!(mac.style, MacStmtStyle::Semicolon),
_ => false,
}
}
/// Converts a parsed `Stmt` to a `Stmt` with
/// 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
/// a semicolon in the tokenstream.
pub fn add_trailing_semicolon(mut self) -> Self {
2019-09-26 18:34:50 +02:00
self.kind = match self.kind {
StmtKind::Expr(expr) => StmtKind::Semi(expr),
StmtKind::MacCall(mac) => {
StmtKind::MacCall(mac.map(|MacCallStmt { mac, style: _, attrs, tokens }| {
MacCallStmt { mac, style: MacStmtStyle::Semicolon, attrs, tokens }
}))
}
2019-09-26 18:34:50 +02:00
kind => kind,
};
self
}
2017-07-16 00:17:35 +02:00
pub fn is_item(&self) -> bool {
2020-12-24 02:55:21 +01:00
matches!(self.kind, StmtKind::Item(_))
2017-07-16 00:17:35 +02:00
}
pub fn is_expr(&self) -> bool {
2020-12-24 02:55:21 +01:00
matches!(self.kind, StmtKind::Expr(_))
}
}
#[derive(Clone, Encodable, Decodable, Debug)]
pub enum StmtKind {
2016-06-23 03:04:08 +02:00
/// A local (let) binding.
Local(P<Local>),
2016-06-23 03:04:08 +02:00
/// An item definition.
Item(P<Item>),
/// Expr without trailing semi-colon.
Expr(P<Expr>),
/// Expr with a trailing semi-colon.
Semi(P<Expr>),
/// Just a trailing semi-colon.
Empty,
2017-09-06 03:46:21 +02:00
/// Macro.
MacCall(P<MacCallStmt>),
}
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct MacCallStmt {
pub mac: MacCall,
pub style: MacStmtStyle,
pub attrs: AttrVec,
pub tokens: Option<LazyTokenStream>,
}
#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug)]
pub enum MacStmtStyle {
/// The macro statement had a trailing semicolon (e.g., `foo! { ... };`
/// `foo!(...);`, `foo![...];`).
Semicolon,
/// The macro statement had braces (e.g., `foo! { ... }`).
Braces,
/// The macro statement had parentheses or brackets and no semicolon (e.g.,
/// `foo!(...)`). All of these will end up being converted into macro
/// expressions.
NoBraces,
}
/// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`.
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct Local {
pub id: NodeId,
pub pat: P<Pat>,
2015-01-02 12:55:31 +01:00
pub ty: Option<P<Ty>>,
/// Initializer expression to set the value, if any.
pub init: Option<P<Expr>>,
pub span: Span,
2019-12-03 16:38:34 +01:00
pub attrs: AttrVec,
pub tokens: Option<LazyTokenStream>,
}
/// An arm of a 'match'.
///
/// E.g., `0..=10 => { println!("match!") }` as in
///
/// ```
/// match 123 {
/// 0..=10 => { println!("match!") },
/// _ => { println!("no match!") },
/// }
/// ```
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct Arm {
pub attrs: Vec<Attribute>,
/// Match arm pattern, e.g. `10` in `match foo { 10 => {}, _ => {} }`
pub pat: P<Pat>,
/// Match arm guard, e.g. `n > 10` in `match foo { n if n > 10 => {}, _ => {} }`
2019-06-23 11:32:16 +02:00
pub guard: Option<P<Expr>>,
/// Match arm body.
pub body: P<Expr>,
2019-03-30 23:54:29 +01:00
pub span: Span,
2019-08-14 03:22:51 +02:00
pub id: NodeId,
pub is_placeholder: bool,
}
2010-11-25 00:45:59 +01:00
/// Access of a named (e.g., `obj.foo`) or unnamed (e.g., `obj.0`) struct field.
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct Field {
2019-12-03 16:38:34 +01:00
pub attrs: AttrVec,
pub id: NodeId,
pub span: Span,
2018-03-18 14:47:09 +01:00
pub ident: Ident,
pub expr: P<Expr>,
pub is_shorthand: bool,
pub is_placeholder: bool,
}
#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy)]
pub enum BlockCheckMode {
Default,
Unsafe(UnsafeSource),
}
#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy)]
pub enum UnsafeSource {
CompilerGenerated,
UserProvided,
2013-07-02 21:47:32 +02:00
}
/// A constant (expression) that's not an item or associated item,
/// but needs its own `DefId` for type-checking, const-eval, etc.
/// These are usually found nested inside types (e.g., array lengths)
/// or expressions (e.g., repeat counts), and also used to define
/// explicit discriminant values for enum variants.
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct AnonConst {
pub id: NodeId,
pub value: P<Expr>,
}
/// An expression.
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct Expr {
pub id: NodeId,
pub kind: ExprKind,
pub span: Span,
2019-12-03 16:38:34 +01:00
pub attrs: AttrVec,
Rewrite `collect_tokens` implementations to use a flattened buffer Instead of trying to collect tokens at each depth, we 'flatten' the stream as we go allong, pushing open/close delimiters to our buffer just like regular tokens. One capturing is complete, we reconstruct a nested `TokenTree::Delimited` structure, producing a normal `TokenStream`. The reconstructed `TokenStream` is not created immediately - instead, it is produced on-demand by a closure (wrapped in a new `LazyTokenStream` type). This closure stores a clone of the original `TokenCursor`, plus a record of the number of calls to `next()/next_desugared()`. This is sufficient to reconstruct the tokenstream seen by the callback without storing any additional state. If the tokenstream is never used (e.g. when a captured `macro_rules!` argument is never passed to a proc macro), we never actually create a `TokenStream`. This implementation has a number of advantages over the previous one: * It is significantly simpler, with no edge cases around capturing the start/end of a delimited group. * It can be easily extended to allow replacing tokens an an arbitrary 'depth' by just using `Vec::splice` at the proper position. This is important for PR #76130, which requires us to track information about attributes along with tokens. * The lazy approach to `TokenStream` construction allows us to easily parse an AST struct, and then decide after the fact whether we need a `TokenStream`. This will be useful when we start collecting tokens for `Attribute` - we can discard the `LazyTokenStream` if the parsed attribute doesn't need tokens (e.g. is a builtin attribute). The performance impact seems to be neglibile (see https://github.com/rust-lang/rust/pull/77250#issuecomment-703960604). There is a small slowdown on a few benchmarks, but it only rises above 1% for incremental builds, where it represents a larger fraction of the much smaller instruction count. There a ~1% speedup on a few other incremental benchmarks - my guess is that the speedups and slowdowns will usually cancel out in practice.
2020-09-27 03:56:29 +02:00
pub tokens: Option<LazyTokenStream>,
}
// `Expr` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
rustc_data_structures::static_assert_size!(Expr, 120);
impl Expr {
/// Returns `true` if this expression would be valid somewhere that expects a value;
/// for example, an `if` condition.
pub fn returns(&self) -> bool {
if let ExprKind::Block(ref block, _) = self.kind {
2019-09-26 18:34:50 +02:00
match block.stmts.last().map(|last_stmt| &last_stmt.kind) {
// Implicit return
2020-12-29 01:20:06 +01:00
Some(StmtKind::Expr(_)) => true,
// Last statement is an explicit return?
Some(StmtKind::Semi(expr)) => matches!(expr.kind, ExprKind::Ret(_)),
// This is a block that doesn't end in either an implicit or explicit return.
_ => false,
}
} else {
// This is not a block, it is a value.
true
}
}
/// Is this expr either `N`, or `{ N }`.
///
/// If this is not the case, name resolution does not resolve `N` when using
2020-11-17 10:55:13 +01:00
/// `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
}
} else {
self
};
if let ExprKind::Path(None, ref path) = this.kind {
if path.segments.len() == 1 && path.segments[0].args.is_none() {
return true;
}
}
false
}
pub fn to_bound(&self) -> Option<GenericBound> {
match &self.kind {
2018-09-23 01:19:44 +02:00
ExprKind::Path(None, path) => Some(GenericBound::Trait(
PolyTraitRef::new(Vec::new(), path.clone(), self.span),
2018-09-23 01:19:44 +02:00
TraitBoundModifier::None,
)),
_ => None,
}
}
pub fn peel_parens(&self) -> &Expr {
let mut expr = self;
while let ExprKind::Paren(inner) = &expr.kind {
expr = &inner;
}
expr
}
/// Attempts to reparse as `Ty` (for diagnostic purposes).
pub fn to_ty(&self) -> Option<P<Ty>> {
let kind = match &self.kind {
// Trivial conversions.
ExprKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
2020-02-29 17:32:20 +01:00
ExprKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
ExprKind::Paren(expr) => expr.to_ty().map(TyKind::Paren)?,
2019-12-22 23:42:04 +01:00
ExprKind::AddrOf(BorrowKind::Ref, mutbl, expr) => {
expr.to_ty().map(|ty| TyKind::Rptr(None, MutTy { ty, mutbl: *mutbl }))?
}
2018-09-23 01:19:44 +02:00
ExprKind::Repeat(expr, expr_len) => {
expr.to_ty().map(|ty| TyKind::Array(ty, expr_len.clone()))?
}
2018-09-23 01:19:44 +02:00
ExprKind::Array(exprs) if exprs.len() == 1 => exprs[0].to_ty().map(TyKind::Slice)?,
ExprKind::Tup(exprs) => {
2019-12-22 23:42:04 +01:00
let tys = exprs.iter().map(|expr| expr.to_ty()).collect::<Option<Vec<_>>>()?;
TyKind::Tup(tys)
}
// If binary operator is `Add` and both `lhs` and `rhs` are trait bounds,
// then type of result is trait object.
2020-03-06 12:13:55 +01:00
// Otherwise we don't assume the result type.
2018-09-23 01:19:44 +02:00
ExprKind::Binary(binop, lhs, rhs) if binop.node == BinOpKind::Add => {
if let (Some(lhs), Some(rhs)) = (lhs.to_bound(), rhs.to_bound()) {
TyKind::TraitObject(vec![lhs, rhs], TraitObjectSyntax::None)
} else {
return None;
}
2018-09-23 01:19:44 +02:00
}
// This expression doesn't look like a type syntactically.
_ => return None,
};
Some(P(Ty { kind, id: self.id, span: self.span, tokens: None }))
}
pub fn precedence(&self) -> ExprPrecedence {
match self.kind {
ExprKind::Box(_) => ExprPrecedence::Box,
ExprKind::Array(_) => ExprPrecedence::Array,
2020-09-21 22:55:58 +02:00
ExprKind::ConstBlock(_) => ExprPrecedence::ConstBlock,
ExprKind::Call(..) => ExprPrecedence::Call,
ExprKind::MethodCall(..) => ExprPrecedence::MethodCall,
ExprKind::Tup(_) => ExprPrecedence::Tup,
ExprKind::Binary(op, ..) => ExprPrecedence::Binary(op.node),
ExprKind::Unary(..) => ExprPrecedence::Unary,
ExprKind::Lit(_) => ExprPrecedence::Lit,
ExprKind::Type(..) | ExprKind::Cast(..) => ExprPrecedence::Cast,
ExprKind::Let(..) => ExprPrecedence::Let,
ExprKind::If(..) => ExprPrecedence::If,
ExprKind::While(..) => ExprPrecedence::While,
ExprKind::ForLoop(..) => ExprPrecedence::ForLoop,
ExprKind::Loop(..) => ExprPrecedence::Loop,
ExprKind::Match(..) => ExprPrecedence::Match,
ExprKind::Closure(..) => ExprPrecedence::Closure,
ExprKind::Block(..) => ExprPrecedence::Block,
ExprKind::TryBlock(..) => ExprPrecedence::TryBlock,
2018-06-07 00:50:59 +02:00
ExprKind::Async(..) => ExprPrecedence::Async,
ExprKind::Await(..) => ExprPrecedence::Await,
ExprKind::Assign(..) => ExprPrecedence::Assign,
ExprKind::AssignOp(..) => ExprPrecedence::AssignOp,
ExprKind::Field(..) => ExprPrecedence::Field,
ExprKind::Index(..) => ExprPrecedence::Index,
ExprKind::Range(..) => ExprPrecedence::Range,
ExprKind::Underscore => ExprPrecedence::Path,
ExprKind::Path(..) => ExprPrecedence::Path,
ExprKind::AddrOf(..) => ExprPrecedence::AddrOf,
ExprKind::Break(..) => ExprPrecedence::Break,
ExprKind::Continue(..) => ExprPrecedence::Continue,
ExprKind::Ret(..) => ExprPrecedence::Ret,
2020-01-22 15:20:27 +01:00
ExprKind::InlineAsm(..) | ExprKind::LlvmInlineAsm(..) => ExprPrecedence::InlineAsm,
2020-02-29 17:32:20 +01:00
ExprKind::MacCall(..) => ExprPrecedence::Mac,
ExprKind::Struct(..) => ExprPrecedence::Struct,
ExprKind::Repeat(..) => ExprPrecedence::Repeat,
ExprKind::Paren(..) => ExprPrecedence::Paren,
ExprKind::Try(..) => ExprPrecedence::Try,
ExprKind::Yield(..) => ExprPrecedence::Yield,
ExprKind::Err => ExprPrecedence::Err,
}
}
}
2016-01-13 07:23:31 +01:00
/// Limit types of a range (inclusive or exclusive)
#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug)]
2016-01-13 07:23:31 +01:00
pub enum RangeLimits {
/// Inclusive at the beginning, exclusive at the end
HalfOpen,
/// Inclusive at the beginning and end
Closed,
}
#[derive(Clone, Encodable, Decodable, Debug)]
pub enum StructRest {
/// `..x`.
Base(P<Expr>),
/// `..`.
Rest(Span),
/// No trailing `..` or expression.
None,
}
#[derive(Clone, Encodable, Decodable, Debug)]
pub enum ExprKind {
/// A `box x` expression.
Box(P<Expr>),
2015-03-16 23:11:23 +01:00
/// An array (`[a, b, c, d]`)
Array(Vec<P<Expr>>),
2020-09-21 22:55:58 +02:00
/// Allow anonymous constants from an inline `const` block
ConstBlock(AnonConst),
2015-03-17 13:12:20 +01:00
/// A function call
2015-03-18 20:26:37 +01:00
///
2015-03-17 13:12:20 +01:00
/// The first field resolves to the function itself,
/// and the second field is the list of arguments.
/// 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)`)
2015-03-18 20:26:37 +01:00
///
/// The `PathSegment` represents the method name and its generic arguments
2015-03-18 20:26:37 +01:00
/// (within the angle brackets).
/// The first element of the vector of an `Expr` is the expression that evaluates
2015-03-17 13:12:20 +01:00
/// to the object on which the method is being called on (the receiver),
/// and the remaining elements are the rest of the arguments.
/// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as
/// `ExprKind::MethodCall(PathSegment { foo, [Bar, Baz] }, [x, a, b, c, d])`.
2020-06-10 02:31:12 +02:00
/// 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, Vec<P<Expr>>, Span),
/// A tuple (e.g., `(a, b, c, d)`).
Tup(Vec<P<Expr>>),
/// A binary operation (e.g., `a + b`, `a * b`).
Binary(BinOp, P<Expr>, P<Expr>),
/// A unary operation (e.g., `!x`, `*x`).
Unary(UnOp, P<Expr>),
/// A literal (e.g., `1`, `"foo"`).
Lit(Lit),
/// A cast (e.g., `foo as f64`).
Cast(P<Expr>, P<Ty>),
2019-04-27 12:06:02 +02:00
/// A type ascription (e.g., `42: usize`).
Type(P<Expr>, P<Ty>),
/// A `let pat = expr` expression that is only semantically allowed in the condition
/// of `if` / `while` expressions. (e.g., `if let 0 = x { .. }`).
Let(P<Pat>, P<Expr>),
/// An `if` block, with an optional `else` block.
2015-03-18 20:26:37 +01:00
///
2015-03-16 23:11:23 +01:00
/// `if expr { block } else { expr }`
If(P<Expr>, P<Block>, Option<P<Expr>>),
/// A while loop, with an optional label.
2015-03-18 20:26:37 +01:00
///
2015-03-18 13:36:10 +01:00
/// `'label: while expr { block }`
While(P<Expr>, P<Block>, Option<Label>),
/// A `for` loop, with an optional label.
2015-03-18 20:26:37 +01:00
///
2015-03-18 13:36:10 +01:00
/// `'label: for pat in expr { block }`
2015-03-18 20:26:37 +01:00
///
/// This is desugared to a combination of `loop` and `match` expressions.
ForLoop(P<Pat>, P<Expr>, P<Block>, Option<Label>),
/// Conditionless loop (can be exited with `break`, `continue`, or `return`).
2015-03-18 20:26:37 +01:00
///
2015-03-18 13:36:10 +01:00
/// `'label: loop { block }`
Loop(P<Block>, Option<Label>),
/// 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(CaptureBy, Async, Movability, P<FnDecl>, P<Expr>, Span),
/// A block (`'label: { ... }`).
Block(P<Block>, Option<Label>),
/// An async block (`async move { ... }`).
2018-06-07 00:50:59 +02:00
///
/// The `NodeId` is the `NodeId` for the closure that results from
/// desugaring an async block, just like the NodeId field in the
/// `Async::Yes` variant. This is necessary in order to create a def for the
2018-06-07 00:50:59 +02:00
/// closure which can be used as a parent of any child defs. Defs
/// created during lowering cannot be made the parent of any other
/// preexisting defs.
Async(CaptureBy, NodeId, P<Block>),
/// An await expression (`my_future.await`).
2019-07-02 06:30:21 +02:00
Await(P<Expr>),
/// A try block (`try { ... }`).
TryBlock(P<Block>),
/// An assignment (`a = foo()`).
/// The `Span` argument is the span of the `=` token.
Assign(P<Expr>, P<Expr>, Span),
/// An assignment with an operator.
2015-03-18 20:26:37 +01:00
///
/// E.g., `a += 1`.
AssignOp(BinOp, P<Expr>, P<Expr>),
/// Access of a named (e.g., `obj.foo`) or unnamed (e.g., `obj.0`) struct field.
2018-03-18 14:47:09 +01:00
Field(P<Expr>, Ident),
/// An indexing operation (e.g., `foo[2]`).
Index(P<Expr>, P<Expr>),
/// A range (e.g., `1..2`, `1..`, `..2`, `1..=2`, `..=2`; and `..` in destructuring assingment).
2016-01-13 07:23:31 +01:00
Range(Option<P<Expr>>, Option<P<Expr>>, RangeLimits),
/// An underscore, used in destructuring assignment to ignore a value.
Underscore,
/// Variable reference, possibly containing `::` and/or type
/// parameters (e.g., `foo::bar::<baz>`).
2015-03-18 20:26:37 +01:00
///
/// Optionally "qualified" (e.g., `<Vec<T> as SomeTrait>::SomeType`).
Path(Option<QSelf>, Path),
/// A referencing operation (`&a`, `&mut a`, `&raw const a` or `&raw mut a`).
AddrOf(BorrowKind, Mutability, P<Expr>),
/// A `break`, with an optional label to break, and an optional expression.
Break(Option<Label>, Option<P<Expr>>),
/// A `continue`, with an optional label.
Continue(Option<Label>),
/// A `return`, with an optional value to be returned.
Ret(Option<P<Expr>>),
2020-01-22 15:20:27 +01:00
/// Output of the `asm!()` macro.
2020-05-26 21:07:59 +02:00
InlineAsm(P<InlineAsm>),
/// Output of the `llvm_asm!()` macro.
LlvmInlineAsm(P<LlvmInlineAsm>),
/// A macro invocation; pre-expansion.
2020-02-29 17:32:20 +01:00
MacCall(MacCall),
2014-06-09 22:12:30 +02:00
/// A struct literal expression.
2015-03-18 20:26:37 +01:00
///
/// E.g., `Foo {x: 1, y: 2}`, or `Foo {x: 1, .. rest}`.
Struct(Path, Vec<Field>, StructRest),
/// An array literal constructed from one repeated element.
2015-03-18 20:26:37 +01:00
///
/// E.g., `[1; 5]`. The expression is the element to be
/// repeated; the constant is the number of times to repeat it.
Repeat(P<Expr>, AnonConst),
/// No-op: used solely so we can pretty-print faithfully.
Paren(P<Expr>),
/// A try expression (`expr?`).
Try(P<Expr>),
2016-12-26 14:34:03 +01:00
/// A `yield`, with an optional value to be yielded.
2016-12-26 14:34:03 +01:00
Yield(Option<P<Expr>>),
/// Placeholder for an expression that wasn't syntactically well formed in some way.
Err,
}
/// The explicit `Self` type in a "qualified path". The actual
/// path, including the trait and the associated item, is stored
/// separately. `position` represents the index of the associated
/// item qualified with this `Self` type.
///
/// ```ignore (only-for-syntax-highlight)
2015-11-03 17:34:11 +01:00
/// <Vec<T> as a::b::Trait>::AssociatedItem
/// ^~~~~ ~~~~~~~~~~~~~~^
/// ty position = 3
///
2015-11-03 17:34:11 +01:00
/// <Vec<T>>::AssociatedItem
/// ^~~~~ ^
/// ty position = 0
/// ```
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct QSelf {
pub ty: P<Ty>,
2018-05-22 21:26:35 +02:00
/// The span of `a::b::Trait` in a path like `<Vec<T> as
/// a::b::Trait>::AssociatedItem`; in the case where `position ==
/// 0`, this is an empty span.
pub path_span: Span,
2018-09-23 01:19:44 +02:00
pub position: usize,
}
/// A capture clause used in closures and `async` blocks.
#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
pub enum CaptureBy {
/// `move |x| y + x`.
Value,
/// `move` keyword was not specified.
Ref,
}
/// The movability of a generator / closure literal:
/// whether a generator contains self-references, causing it to be `!Unpin`.
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Encodable, Decodable, Debug, Copy)]
#[derive(HashStable_Generic)]
pub enum Movability {
/// May contain self-references, `!Unpin`.
Static,
/// Must not contain self-references, `Unpin`.
Movable,
}
/// Represents a macro invocation. The `path` indicates which macro
/// is being invoked, and the `args` are arguments passed to it.
#[derive(Clone, Encodable, Decodable, Debug)]
2020-02-29 17:32:20 +01:00
pub struct MacCall {
pub path: Path,
pub args: P<MacArgs>,
pub prior_type_ascription: Option<(Span, bool)>,
2017-02-21 06:05:59 +01:00
}
2020-02-29 17:32:20 +01:00
impl MacCall {
pub fn span(&self) -> Span {
self.path.span.to(self.args.span().unwrap_or(self.path.span))
}
}
/// Arguments passed to an attribute or a function-like macro.
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
pub enum MacArgs {
/// No arguments - `#[attr]`.
Empty,
/// Delimited arguments - `#[attr()/[]/{}]` or `mac!()/[]/{}`.
Delimited(DelimSpan, MacDelimiter, TokenStream),
/// Arguments of a key-value attribute - `#[attr = "value"]`.
2019-12-02 19:56:11 +01:00
Eq(
/// Span of the `=` token.
Span,
/// "value" as a nonterminal token.
Token,
2019-12-02 19:56:11 +01:00
),
}
impl MacArgs {
pub fn delim(&self) -> DelimToken {
match self {
MacArgs::Delimited(_, delim, _) => delim.to_token(),
MacArgs::Empty | MacArgs::Eq(..) => token::NoDelim,
}
}
pub fn span(&self) -> Option<Span> {
match self {
MacArgs::Empty => None,
MacArgs::Delimited(dspan, ..) => Some(dspan.entire()),
MacArgs::Eq(eq_span, token) => Some(eq_span.to(token.span)),
}
}
/// Tokens inside the delimiters or after `=`.
/// 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(.., token) => TokenTree::Token(token.clone()).into(),
}
}
/// Whether a macro with these arguments needs a semicolon
/// when used as a standalone item or statement.
pub fn need_semicolon(&self) -> bool {
2019-12-22 23:42:04 +01:00
!matches!(self, MacArgs::Delimited(_, MacDelimiter::Brace, _))
}
}
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
pub enum MacDelimiter {
Parenthesis,
Bracket,
Brace,
}
impl MacDelimiter {
pub fn to_token(self) -> DelimToken {
match self {
MacDelimiter::Parenthesis => DelimToken::Paren,
MacDelimiter::Bracket => DelimToken::Bracket,
MacDelimiter::Brace => DelimToken::Brace,
}
}
2019-12-02 19:56:11 +01:00
pub fn from_token(delim: DelimToken) -> Option<MacDelimiter> {
match delim {
2019-12-02 19:56:11 +01:00
token::Paren => Some(MacDelimiter::Parenthesis),
token::Bracket => Some(MacDelimiter::Bracket),
token::Brace => Some(MacDelimiter::Brace),
token::NoDelim => None,
}
}
}
/// Represents a macro definition.
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
2017-03-17 22:58:48 +01:00
pub struct MacroDef {
pub body: P<MacArgs>,
/// `true` if macro was defined with `macro_rules`.
pub macro_rules: bool,
2017-03-17 22:58:48 +01:00
}
#[derive(Clone, Encodable, Decodable, Debug, Copy, Hash, Eq, PartialEq)]
#[derive(HashStable_Generic)]
pub enum StrStyle {
/// A regular string, like `"foo"`.
Cooked,
/// A raw string, like `r##"foo"##`.
2015-03-18 20:26:37 +01:00
///
/// The value is the number of `#` symbols used.
2018-09-23 01:19:44 +02:00
Raw(u16),
}
2019-05-11 15:03:27 +02:00
/// An AST literal.
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
2019-05-09 01:00:29 +02:00
pub struct Lit {
2019-05-11 15:03:27 +02:00
/// The original literal token as written in source code.
2019-05-09 01:17:32 +02:00
pub token: token::Lit,
2019-05-11 15:03:27 +02:00
/// 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.
2019-09-26 17:56:53 +02:00
pub kind: LitKind,
2019-05-09 01:00:29 +02:00
pub span: Span,
}
/// Same as `Lit`, but restricted to string literals.
#[derive(Clone, Copy, Encodable, Decodable, Debug)]
pub struct StrLit {
/// The original literal token as written in source code.
pub style: StrStyle,
pub symbol: Symbol,
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 {
let token_kind = match self.style {
StrStyle::Cooked => token::Str,
StrStyle::Raw(n) => token::StrRaw(n),
};
Lit {
token: token::Lit::new(token_kind, self.symbol, self.suffix),
span: self.span,
kind: LitKind::Str(self.symbol_unescaped, self.style),
}
}
}
/// Type of the integer literal based on provided suffix.
#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
#[derive(HashStable_Generic)]
pub enum LitIntType {
/// e.g. `42_i32`.
Signed(IntTy),
/// e.g. `42_u32`.
Unsigned(UintTy),
/// e.g. `42`.
Unsuffixed,
}
/// Type of the float literal based on provided suffix.
#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
#[derive(HashStable_Generic)]
pub enum LitFloatType {
/// A float literal with a suffix (`1f32` or `1E10f32`).
Suffixed(FloatTy),
/// A float literal without a suffix (`1.0 or 1.0E10`).
Unsuffixed,
}
/// Literal kind.
///
/// 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"`).
Str(Symbol, StrStyle),
/// A byte string (`b"foo"`).
ByteStr(Lrc<[u8]>),
/// A byte char (`b'f'`).
Byte(u8),
/// A character literal (`'a'`).
Char(char),
/// An integer literal (`1`).
Int(u128, LitIntType),
/// A float literal (`1f64` or `1E10f64`).
Float(Symbol, LitFloatType),
/// A boolean literal.
Bool(bool),
/// Placeholder for a literal that wasn't well-formed in some way.
Err(Symbol),
}
impl LitKind {
/// Returns `true` if this literal is a string.
pub fn is_str(&self) -> bool {
2020-12-24 02:55:21 +01:00
matches!(self, LitKind::Str(..))
}
/// Returns `true` if this literal is byte literal string.
pub fn is_bytestr(&self) -> bool {
2020-12-24 02:55:21 +01:00
matches!(self, LitKind::ByteStr(_))
}
/// Returns `true` if this is a numeric literal.
pub fn is_numeric(&self) -> bool {
2020-12-24 02:55:21 +01:00
matches!(self, LitKind::Int(..) | LitKind::Float(..))
}
/// Returns `true` if this literal has no suffix.
/// Note: this will return true for literals with prefixes such as raw strings and byte strings.
pub fn is_unsuffixed(&self) -> bool {
!self.is_suffixed()
}
/// Returns `true` if this literal has a suffix.
pub fn is_suffixed(&self) -> bool {
match *self {
// suffixed variants
LitKind::Int(_, LitIntType::Signed(..) | LitIntType::Unsigned(..))
| LitKind::Float(_, LitFloatType::Suffixed(..)) => true,
// unsuffixed variants
2018-09-23 01:19:44 +02:00
LitKind::Str(..)
| LitKind::ByteStr(..)
| LitKind::Byte(..)
| LitKind::Char(..)
| LitKind::Int(_, LitIntType::Unsuffixed)
| LitKind::Float(_, LitFloatType::Unsuffixed)
| LitKind::Bool(..)
| LitKind::Err(..) => false,
}
}
}
// N.B., If you change this, you'll probably want to change the corresponding
// type structure in `middle/ty.rs` as well.
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct MutTy {
pub ty: P<Ty>,
pub mutbl: Mutability,
}
2019-11-07 13:11:59 +01:00
/// Represents a function's signature in a trait declaration,
/// trait implementation, or free function.
#[derive(Clone, Encodable, Decodable, Debug)]
2019-11-07 13:11:59 +01:00
pub struct FnSig {
pub header: FnHeader,
pub decl: P<FnDecl>,
Use smaller def span for functions Currently, the def span of a funtion encompasses the entire function signature and body. However, this is usually unnecessarily verbose - when we are pointing at an entire function in a diagnostic, we almost always want to point at the signature. The actual contents of the body tends to be irrelevant to the diagnostic we are emitting, and just takes up additional screen space. This commit changes the `def_span` of all function items (freestanding functions, `impl`-block methods, and `trait`-block methods) to be the span of the signature. For example, the function ```rust pub fn foo<T>(val: T) -> T { val } ``` now has a `def_span` corresponding to `pub fn foo<T>(val: T) -> T` (everything before the opening curly brace). Trait methods without a body have a `def_span` which includes the trailing semicolon. For example: ```rust trait Foo { fn bar(); }``` the function definition `Foo::bar` has a `def_span` of `fn bar();` This makes our diagnostic output much shorter, and emphasizes information that is relevant to whatever diagnostic we are reporting. We continue to use the full span (including the body) in a few of places: * MIR building uses the full span when building source scopes. * 'Outlives suggestions' use the full span to sort the diagnostics being emitted. * The `#[rustc_on_unimplemented(enclosing_scope="in this scope")]` attribute points the entire scope body. * The 'unconditional recursion' lint uses the full span to show additional context for the recursive call. All of these cases work only with local items, so we don't need to add anything extra to crate metadata.
2020-08-12 23:02:14 +02:00
pub span: Span,
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
#[derive(Encodable, Decodable, HashStable_Generic)]
pub enum FloatTy {
F32,
F64,
}
impl FloatTy {
pub fn name_str(self) -> &'static str {
match self {
FloatTy::F32 => "f32",
FloatTy::F64 => "f64",
}
}
pub fn name(self) -> Symbol {
match self {
FloatTy::F32 => sym::f32,
FloatTy::F64 => sym::f64,
}
}
pub fn bit_width(self) -> u64 {
match self {
FloatTy::F32 => 32,
FloatTy::F64 => 64,
}
}
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
#[derive(Encodable, Decodable, HashStable_Generic)]
pub enum IntTy {
Isize,
I8,
I16,
I32,
I64,
I128,
2013-07-02 21:47:32 +02:00
}
impl IntTy {
pub fn name_str(&self) -> &'static str {
match *self {
IntTy::Isize => "isize",
IntTy::I8 => "i8",
IntTy::I16 => "i16",
IntTy::I32 => "i32",
IntTy::I64 => "i64",
IntTy::I128 => "i128",
}
}
pub fn name(&self) -> Symbol {
2019-05-23 04:22:43 +02:00
match *self {
IntTy::Isize => sym::isize,
IntTy::I8 => sym::i8,
IntTy::I16 => sym::i16,
IntTy::I32 => sym::i32,
IntTy::I64 => sym::i64,
IntTy::I128 => sym::i128,
}
}
pub fn bit_width(&self) -> Option<u64> {
2015-08-15 00:46:51 +02:00
Some(match *self {
IntTy::Isize => return None,
IntTy::I8 => 8,
IntTy::I16 => 16,
IntTy::I32 => 32,
IntTy::I64 => 64,
IntTy::I128 => 128,
2015-08-15 00:46:51 +02:00
})
}
pub fn normalize(&self, target_width: u32) -> Self {
match self {
IntTy::Isize => match target_width {
16 => IntTy::I16,
32 => IntTy::I32,
64 => IntTy::I64,
_ => unreachable!(),
},
_ => *self,
}
}
}
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, Debug)]
#[derive(Encodable, Decodable, HashStable_Generic)]
pub enum UintTy {
Usize,
U8,
U16,
U32,
U64,
U128,
2013-07-02 21:47:32 +02:00
}
impl UintTy {
pub fn name_str(&self) -> &'static str {
match *self {
UintTy::Usize => "usize",
UintTy::U8 => "u8",
UintTy::U16 => "u16",
UintTy::U32 => "u32",
UintTy::U64 => "u64",
UintTy::U128 => "u128",
}
}
pub fn name(&self) -> Symbol {
2019-05-23 04:22:43 +02:00
match *self {
UintTy::Usize => sym::usize,
UintTy::U8 => sym::u8,
UintTy::U16 => sym::u16,
UintTy::U32 => sym::u32,
UintTy::U64 => sym::u64,
UintTy::U128 => sym::u128,
}
}
pub fn bit_width(&self) -> Option<u64> {
2015-08-15 00:46:51 +02:00
Some(match *self {
UintTy::Usize => return None,
UintTy::U8 => 8,
UintTy::U16 => 16,
UintTy::U32 => 32,
UintTy::U64 => 64,
UintTy::U128 => 128,
2015-08-15 00:46:51 +02:00
})
}
pub fn normalize(&self, target_width: u32) -> Self {
match self {
UintTy::Usize => match target_width {
16 => UintTy::U16,
32 => UintTy::U32,
64 => UintTy::U64,
_ => unreachable!(),
},
_ => *self,
}
}
}
/// A constraint on an associated type (e.g., `A = Bar` in `Foo<A = Bar>` or
/// `A: TraitA + TraitB` in `Foo<A: TraitA + TraitB>`).
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct AssocTyConstraint {
pub id: NodeId,
pub ident: Ident,
2020-11-19 18:28:38 +01:00
pub gen_args: Option<GenericArgs>,
pub kind: AssocTyConstraintKind,
pub span: Span,
}
/// The kinds of an `AssocTyConstraint`.
#[derive(Clone, Encodable, Decodable, Debug)]
pub enum AssocTyConstraintKind {
/// E.g., `A = Bar` in `Foo<A = Bar>`.
2019-12-22 23:42:04 +01:00
Equality { ty: P<Ty> },
/// E.g. `A: TraitA + TraitB` in `Foo<A: TraitA + TraitB>`.
2019-12-22 23:42:04 +01:00
Bound { bounds: GenericBounds },
}
2020-09-20 22:19:51 +02:00
#[derive(Encodable, Decodable, Debug)]
pub struct Ty {
pub id: NodeId,
2019-09-26 18:25:31 +02:00
pub kind: TyKind,
pub span: Span,
Rewrite `collect_tokens` implementations to use a flattened buffer Instead of trying to collect tokens at each depth, we 'flatten' the stream as we go allong, pushing open/close delimiters to our buffer just like regular tokens. One capturing is complete, we reconstruct a nested `TokenTree::Delimited` structure, producing a normal `TokenStream`. The reconstructed `TokenStream` is not created immediately - instead, it is produced on-demand by a closure (wrapped in a new `LazyTokenStream` type). This closure stores a clone of the original `TokenCursor`, plus a record of the number of calls to `next()/next_desugared()`. This is sufficient to reconstruct the tokenstream seen by the callback without storing any additional state. If the tokenstream is never used (e.g. when a captured `macro_rules!` argument is never passed to a proc macro), we never actually create a `TokenStream`. This implementation has a number of advantages over the previous one: * It is significantly simpler, with no edge cases around capturing the start/end of a delimited group. * It can be easily extended to allow replacing tokens an an arbitrary 'depth' by just using `Vec::splice` at the proper position. This is important for PR #76130, which requires us to track information about attributes along with tokens. * The lazy approach to `TokenStream` construction allows us to easily parse an AST struct, and then decide after the fact whether we need a `TokenStream`. This will be useful when we start collecting tokens for `Attribute` - we can discard the `LazyTokenStream` if the parsed attribute doesn't need tokens (e.g. is a builtin attribute). The performance impact seems to be neglibile (see https://github.com/rust-lang/rust/pull/77250#issuecomment-703960604). There is a small slowdown on a few benchmarks, but it only rises above 1% for incremental builds, where it represents a larger fraction of the much smaller instruction count. There a ~1% speedup on a few other incremental benchmarks - my guess is that the speedups and slowdowns will usually cancel out in practice.
2020-09-27 03:56:29 +02:00
pub tokens: Option<LazyTokenStream>,
2013-01-15 23:59:39 +01:00
}
2020-09-20 22:19:51 +02:00
impl Clone for Ty {
fn clone(&self) -> Self {
ensure_sufficient_stack(|| Self {
id: self.id,
kind: self.kind.clone(),
span: self.span,
tokens: self.tokens.clone(),
})
}
}
2020-10-10 01:51:54 +02:00
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
}
}
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct BareFnTy {
pub unsafety: Unsafe,
pub ext: Extern,
2018-05-27 21:07:09 +02:00
pub generic_params: Vec<GenericParam>,
2018-09-23 01:19:44 +02:00
pub decl: P<FnDecl>,
}
2019-02-08 14:53:55 +01:00
/// The various kinds of type recognized by the compiler.
#[derive(Clone, Encodable, Decodable, Debug)]
pub enum TyKind {
/// A variable-length slice (`[T]`).
Slice(P<Ty>),
/// A fixed length array (`[T; n]`).
Array(P<Ty>, AnonConst),
/// A raw pointer (`*const T` or `*mut T`).
Ptr(MutTy),
/// A reference (`&'a T` or `&'a mut T`).
Rptr(Option<Lifetime>, MutTy),
/// A bare function (e.g., `fn(usize) -> bool`).
BareFn(P<BareFnTy>),
/// The never type (`!`).
Never,
/// A tuple (`(A, B, C, D,...)`).
2018-09-23 01:19:44 +02:00
Tup(Vec<P<Ty>>),
/// A path (`module::module::...::Type`), optionally
/// "qualified", e.g., `<Vec<T> as SomeTrait>::SomeType`.
2014-11-10 14:41:27 +01:00
///
/// Type parameters are stored in the `Path` itself.
Path(Option<QSelf>, Path),
/// A trait object type `Bound1 + Bound2 + Bound3`
/// where `Bound` is a trait or a lifetime.
TraitObject(GenericBounds, TraitObjectSyntax),
/// An `impl Bound1 + Bound2 + Bound3` type
/// where `Bound` is a trait or a lifetime.
///
/// The `NodeId` exists to prevent lowering from having to
/// generate `NodeId`s on the fly, which would complicate
2019-08-01 01:41:54 +02:00
/// the generation of opaque `type Foo = impl Trait` items significantly.
ImplTrait(NodeId, GenericBounds),
/// No-op; kept solely so that we can pretty-print faithfully.
Paren(P<Ty>),
/// Unused for now.
Typeof(AnonConst),
/// This means the type should be inferred instead of it having been
2014-06-09 22:12:30 +02:00
/// specified. This can appear anywhere in a type.
Infer,
/// Inferred type of a `self` or `&self` argument in a method.
ImplicitSelf,
/// A macro in the type position.
2020-02-29 17:32:20 +01:00
MacCall(MacCall),
/// Placeholder for a kind that has failed to be defined.
Err,
/// Placeholder for a `va_list`.
CVarArgs,
}
2017-10-10 16:33:19 +02:00
impl TyKind {
pub fn is_implicit_self(&self) -> bool {
matches!(self, TyKind::ImplicitSelf)
}
2018-07-06 22:18:38 +02:00
2018-07-21 03:04:02 +02:00
pub fn is_unit(&self) -> bool {
2020-12-29 01:20:06 +01:00
matches!(self, TyKind::Tup(tys) if tys.is_empty())
}
}
2017-10-10 16:33:19 +02:00
/// Syntax used to declare a trait object.
#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug)]
2017-10-10 16:33:19 +02:00
pub enum TraitObjectSyntax {
Dyn,
None,
}
2020-01-22 15:20:27 +01:00
/// Inline assembly operand explicit register or register class.
///
/// E.g., `"eax"` as in `asm!("mov eax, 2", out("eax") result)`.
#[derive(Clone, Copy, Encodable, Decodable, Debug)]
2020-01-22 15:20:27 +01:00
pub enum InlineAsmRegOrRegClass {
Reg(Symbol),
RegClass(Symbol),
}
bitflags::bitflags! {
#[derive(Encodable, Decodable, HashStable_Generic)]
pub struct InlineAsmOptions: u8 {
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;
}
}
2020-10-04 15:52:14 +02:00
#[derive(Clone, PartialEq, PartialOrd, Encodable, Decodable, Debug, Hash, HashStable_Generic)]
pub enum InlineAsmTemplatePiece {
String(String),
Placeholder { operand_idx: usize, modifier: Option<char>, span: Span },
}
impl fmt::Display for InlineAsmTemplatePiece {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::String(s) => {
for c in s.chars() {
match c {
'{' => f.write_str("{{")?,
'}' => f.write_str("}}")?,
_ => c.fmt(f)?,
}
}
Ok(())
}
Self::Placeholder { operand_idx, modifier: Some(modifier), .. } => {
write!(f, "{{{}:{}}}", operand_idx, modifier)
}
Self::Placeholder { operand_idx, modifier: None, .. } => {
write!(f, "{{{}}}", operand_idx)
}
}
}
}
impl InlineAsmTemplatePiece {
/// Rebuilds the asm template string from its pieces.
pub fn to_string(s: &[Self]) -> String {
use fmt::Write;
let mut out = String::new();
for p in s.iter() {
let _ = write!(out, "{}", p);
}
out
}
}
2020-01-22 15:20:27 +01:00
/// Inline assembly operand.
///
/// E.g., `out("eax") result` as in `asm!("mov eax, 2", out("eax") result)`.
#[derive(Clone, Encodable, Decodable, Debug)]
2020-01-22 15:20:27 +01:00
pub enum InlineAsmOperand {
In {
reg: InlineAsmRegOrRegClass,
expr: P<Expr>,
},
Out {
reg: InlineAsmRegOrRegClass,
late: bool,
expr: Option<P<Expr>>,
},
InOut {
reg: InlineAsmRegOrRegClass,
late: bool,
expr: P<Expr>,
},
SplitInOut {
reg: InlineAsmRegOrRegClass,
late: bool,
in_expr: P<Expr>,
out_expr: Option<P<Expr>>,
},
Const {
expr: P<Expr>,
},
Sym {
expr: P<Expr>,
},
}
/// Inline assembly.
///
/// E.g., `asm!("NOP");`.
#[derive(Clone, Encodable, Decodable, Debug)]
2020-01-22 15:20:27 +01:00
pub struct InlineAsm {
pub template: Vec<InlineAsmTemplatePiece>,
pub operands: Vec<(InlineAsmOperand, Span)>,
pub options: InlineAsmOptions,
2020-05-26 21:07:59 +02:00
pub line_spans: Vec<Span>,
2020-01-22 15:20:27 +01:00
}
/// Inline assembly dialect.
///
/// E.g., `"intel"` as in `llvm_asm!("mov eax, 2" : "={eax}"(result) : : : "intel")`.
2020-10-04 15:52:14 +02:00
#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, Hash, HashStable_Generic)]
pub enum LlvmAsmDialect {
Att,
Intel,
}
/// LLVM-style inline assembly.
///
/// E.g., `"={eax}"(result)` as in `llvm_asm!("mov eax, 2" : "={eax}"(result) : : : "intel")`.
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct LlvmInlineAsmOutput {
pub constraint: Symbol,
pub expr: P<Expr>,
pub is_rw: bool,
pub is_indirect: bool,
}
/// LLVM-style inline assembly.
///
/// E.g., `llvm_asm!("NOP");`.
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct LlvmInlineAsm {
pub asm: Symbol,
pub asm_str_style: StrStyle,
pub outputs: Vec<LlvmInlineAsmOutput>,
pub inputs: Vec<(Symbol, P<Expr>)>,
pub clobbers: Vec<Symbol>,
pub volatile: bool,
pub alignstack: bool,
pub dialect: LlvmAsmDialect,
}
/// A parameter in a function header.
///
/// E.g., `bar: usize` as in `fn foo(bar: usize)`.
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct Param {
2019-12-03 16:38:34 +01:00
pub attrs: AttrVec,
pub ty: P<Ty>,
pub pat: P<Pat>,
pub id: NodeId,
2019-07-27 00:52:37 +02:00
pub span: Span,
pub is_placeholder: bool,
}
2016-03-06 13:54:44 +01:00
/// Alternative representation for `Arg`s describing `self` parameter of methods.
///
/// E.g., `&mut self` as in `fn foo(&mut self)`.
#[derive(Clone, Encodable, Decodable, Debug)]
pub enum SelfKind {
/// `self`, `mut self`
2016-03-06 13:54:44 +01:00
Value(Mutability),
/// `&'lt self`, `&'lt mut self`
2016-03-06 13:54:44 +01:00
Region(Option<Lifetime>, Mutability),
/// `self: TYPE`, `mut self: TYPE`
2016-03-06 13:54:44 +01:00
Explicit(P<Ty>, Mutability),
}
pub type ExplicitSelf = Spanned<SelfKind>;
impl Param {
/// Attempts to cast parameter to `ExplicitSelf`.
pub fn to_self(&self) -> Option<ExplicitSelf> {
2019-09-26 17:18:31 +02:00
if let PatKind::Ident(BindingMode::ByValue(mutbl), ident, _) = self.pat.kind {
2019-05-11 16:41:37 +02:00
if ident.name == kw::SelfLower {
2019-09-26 18:25:31 +02:00
return match self.ty.kind {
TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
2019-09-26 18:25:31 +02:00
TyKind::Rptr(lt, MutTy { ref ty, mutbl }) if ty.kind.is_implicit_self() => {
2016-03-06 13:54:44 +01:00
Some(respan(self.pat.span, SelfKind::Region(lt, mutbl)))
}
2018-09-23 01:19:44 +02:00
_ => Some(respan(
self.pat.span.to(self.ty.span),
SelfKind::Explicit(self.ty.clone(), mutbl),
)),
};
}
}
None
}
/// Returns `true` if parameter is `self`.
2016-03-06 13:54:44 +01:00
pub fn is_self(&self) -> bool {
2019-09-26 17:18:31 +02:00
if let PatKind::Ident(_, ident, _) = self.pat.kind {
2019-05-11 16:41:37 +02:00
ident.name == kw::SelfLower
2016-03-06 13:54:44 +01:00
} else {
false
}
}
/// Builds a `Param` object from `ExplicitSelf`.
2019-12-03 16:38:34 +01:00
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 {
attrs,
2016-03-06 13:54:44 +01:00
pat: P(Pat {
id: DUMMY_NODE_ID,
2019-09-26 17:18:31 +02:00
kind: PatKind::Ident(BindingMode::ByValue(mutbl), eself_ident, None),
span,
tokens: None,
2016-03-06 13:54:44 +01:00
}),
2019-07-27 00:52:37 +02:00
span,
ty,
id: DUMMY_NODE_ID,
2019-12-22 23:42:04 +01:00
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,
2018-09-23 01:19:44 +02:00
P(Ty {
id: DUMMY_NODE_ID,
2019-12-22 23:42:04 +01:00
kind: TyKind::Rptr(lt, MutTy { ty: infer_ty, mutbl }),
2018-09-23 01:19:44 +02:00
span,
tokens: None,
2018-09-23 01:19:44 +02:00
}),
),
}
}
}
/// A signature (not the body) of a function declaration.
///
/// E.g., `fn foo(bar: baz)`.
///
/// Please note that it's different from `FnHeader` structure
/// which contains metadata about function safety, asyncness, constness and ABI.
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct FnDecl {
pub inputs: Vec<Param>,
2020-02-15 04:10:59 +01:00
pub output: FnRetTy,
}
2016-03-06 13:54:44 +01:00
impl FnDecl {
pub fn get_self(&self) -> Option<ExplicitSelf> {
self.inputs.get(0).and_then(Param::to_self)
2016-03-06 13:54:44 +01:00
}
pub fn has_self(&self) -> bool {
self.inputs.get(0).map_or(false, Param::is_self)
2016-03-06 13:54:44 +01:00
}
pub fn c_variadic(&self) -> bool {
2020-12-24 02:55:21 +01:00
self.inputs.last().map_or(false, |arg| matches!(arg.ty.kind, TyKind::CVarArgs))
}
2016-03-06 13:54:44 +01:00
}
/// Is the trait definition an auto trait?
#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
pub enum IsAuto {
Yes,
2018-09-23 01:19:44 +02:00
No,
}
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Encodable, Decodable, Debug)]
#[derive(HashStable_Generic)]
pub enum Unsafe {
Yes(Span),
No,
}
#[derive(Copy, Clone, Encodable, Decodable, Debug)]
pub enum Async {
Yes { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
No,
}
impl Async {
pub fn is_async(self) -> bool {
matches!(self, Async::Yes { .. })
2018-06-07 00:50:59 +02:00
}
2020-03-06 12:13:55 +01:00
/// In this case this is an `async` return, the `NodeId` for the generated `impl Trait` item.
pub fn opt_return_id(self) -> Option<NodeId> {
match self {
Async::Yes { return_impl_trait_id, .. } => Some(return_impl_trait_id),
Async::No => None,
}
}
2018-06-07 00:50:59 +02:00
}
#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
#[derive(HashStable_Generic)]
pub enum Const {
Yes(Span),
No,
}
/// Item defaultness.
/// For details see the [RFC #2532](https://github.com/rust-lang/rfcs/pull/2532).
#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
pub enum Defaultness {
Default(Span),
Final,
}
#[derive(Copy, Clone, PartialEq, Encodable, Decodable, HashStable_Generic)]
pub enum ImplPolarity {
2015-03-17 00:36:13 +01:00
/// `impl Trait for Type`
Positive,
2015-03-17 00:36:13 +01:00
/// `impl !Trait for Type`
Negative(Span),
}
std: Rename Show/String to Debug/Display This commit is an implementation of [RFC 565][rfc] which is a stabilization of the `std::fmt` module and the implementations of various formatting traits. Specifically, the following changes were performed: [rfc]: https://github.com/rust-lang/rfcs/blob/master/text/0565-show-string-guidelines.md * The `Show` trait is now deprecated, it was renamed to `Debug` * The `String` trait is now deprecated, it was renamed to `Display` * Many `Debug` and `Display` implementations were audited in accordance with the RFC and audited implementations now have the `#[stable]` attribute * Integers and floats no longer print a suffix * Smart pointers no longer print details that they are a smart pointer * Paths with `Debug` are now quoted and escape characters * The `unwrap` methods on `Result` now require `Display` instead of `Debug` * The `Error` trait no longer has a `detail` method and now requires that `Display` must be implemented. With the loss of `String`, this has moved into libcore. * `impl<E: Error> FromError<E> for Box<Error>` now exists * `derive(Show)` has been renamed to `derive(Debug)`. This is not currently warned about due to warnings being emitted on stage1+ While backwards compatibility is attempted to be maintained with a blanket implementation of `Display` for the old `String` trait (and the same for `Show`/`Debug`) this is still a breaking change due to primitives no longer implementing `String` as well as modifications such as `unwrap` and the `Error` trait. Most code is fairly straightforward to update with a rename or tweaks of method calls. [breaking-change] Closes #21436
2015-01-21 00:45:07 +01:00
impl fmt::Debug for ImplPolarity {
2019-02-06 18:33:01 +01:00
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
ImplPolarity::Positive => "positive".fmt(f),
ImplPolarity::Negative(_) => "negative".fmt(f),
}
}
}
#[derive(Clone, Encodable, Decodable, Debug)]
2020-02-15 04:10:59 +01:00
pub enum FnRetTy {
2019-02-08 14:53:55 +01:00
/// Returns type is not specified.
2015-03-18 20:26:37 +01:00
///
/// Functions default to `()` and closures default to inference.
/// Span points to where return type would be inserted.
Default(Span),
/// Everything else.
Ty(P<Ty>),
}
2020-02-15 04:10:59 +01:00
impl FnRetTy {
pub fn span(&self) -> Span {
match *self {
2020-02-15 04:10:59 +01:00
FnRetTy::Default(span) => span,
FnRetTy::Ty(ref ty) => ty.span,
}
}
}
#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug)]
pub enum Inline {
Yes,
No,
}
/// Module item kind.
2020-08-23 12:42:19 +02:00
#[derive(Clone, Encodable, Decodable, Debug)]
pub enum ModKind {
/// Module with inlined definition `mod foo { ... }`,
/// or with definition outlined to a separate file `mod foo;` and already loaded from it.
/// The inner span is from the first token past `{` to the last token until `}`,
/// or from the first to the last token in the loaded file.
Loaded(Vec<P<Item>>, Inline, Span),
/// Module with definition outlined to a separate file `mod foo;` but not yet loaded from it.
Unloaded,
}
/// Foreign module declaration.
///
2020-08-23 12:42:19 +02:00
/// E.g., `extern { .. }` or `extern "C" { .. }`.
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct ForeignMod {
2020-08-23 12:42:19 +02:00
/// `unsafe` keyword accepted syntactically for macro DSLs, but not
/// semantically by Rust.
pub unsafety: Unsafe,
pub abi: Option<StrLit>,
pub items: Vec<P<ForeignItem>>,
}
/// Global inline assembly.
2017-03-16 03:27:40 +01:00
///
/// Also known as "module-level assembly" or "file-scoped assembly".
#[derive(Clone, Encodable, Decodable, Debug, Copy)]
2017-03-16 03:27:40 +01:00
pub struct GlobalAsm {
pub asm: Symbol,
}
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct EnumDef {
pub variants: Vec<Variant>,
}
/// Enum variant.
#[derive(Clone, Encodable, Decodable, Debug)]
2019-08-14 02:40:21 +02:00
pub struct Variant {
/// Attributes of the variant.
pub attrs: Vec<Attribute>,
/// Id of the variant (not the constructor, see `VariantData::ctor_id()`).
pub id: NodeId,
/// Span
pub span: Span,
/// The visibility of the variant. Syntactically accepted but not semantically.
pub vis: Visibility,
/// Name of the variant.
pub ident: Ident,
/// Fields and constructor id of the variant.
pub data: VariantData,
/// Explicit discriminant, e.g., `Foo = 1`.
pub disr_expr: Option<AnonConst>,
/// Is a macro placeholder
pub is_placeholder: bool,
}
2018-03-12 21:16:09 +01:00
/// Part of `use` item to the right of its prefix.
#[derive(Clone, Encodable, Decodable, Debug)]
pub enum UseTreeKind {
2018-03-12 21:16:09 +01:00
/// `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),
2018-03-12 21:16:09 +01:00
/// `use prefix::{...}`
Nested(Vec<(UseTree, NodeId)>),
2018-03-12 21:16:09 +01:00
/// `use prefix::*`
Glob,
}
2018-03-12 21:16:09 +01:00
/// A tree of paths sharing common prefixes.
/// Used in `use` items both at top-level and inside of braces in import groups.
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct UseTree {
pub prefix: Path,
pub kind: UseTreeKind,
pub span: Span,
}
impl UseTree {
pub fn ident(&self) -> Ident {
match self.kind {
UseTreeKind::Simple(Some(rename), ..) => rename,
2018-09-23 01:19:44 +02:00
UseTreeKind::Simple(None, ..) => {
2019-12-22 23:42:04 +01:00
self.prefix.segments.last().expect("empty prefix in a simple import").ident
2018-09-23 01:19:44 +02:00
}
_ => panic!("`UseTree::ident` can only be used on a simple import"),
}
}
}
/// Distinguishes between `Attribute`s that decorate items and Attributes that
2014-06-09 22:12:30 +02:00
/// are contained as statements within items. These two cases need to be
/// distinguished for pretty-printing.
#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, HashStable_Generic)]
pub enum AttrStyle {
Outer,
Inner,
2013-07-02 21:47:32 +02:00
}
rustc_index::newtype_index! {
pub struct AttrId {
ENCODABLE = custom
DEBUG_FORMAT = "AttrId({})"
}
}
impl<S: Encoder> rustc_serialize::Encodable<S> for AttrId {
fn encode(&self, s: &mut S) -> Result<(), S::Error> {
s.emit_unit()
2019-07-30 19:40:43 +02:00
}
}
impl<D: Decoder> rustc_serialize::Decodable<D> for AttrId {
fn decode(d: &mut D) -> Result<AttrId, D::Error> {
d.read_nil().map(|_| crate::attr::mk_attr_id())
2019-07-30 19:40:43 +02:00
}
}
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
pub struct AttrItem {
pub path: Path,
pub args: MacArgs,
Rewrite `collect_tokens` implementations to use a flattened buffer Instead of trying to collect tokens at each depth, we 'flatten' the stream as we go allong, pushing open/close delimiters to our buffer just like regular tokens. One capturing is complete, we reconstruct a nested `TokenTree::Delimited` structure, producing a normal `TokenStream`. The reconstructed `TokenStream` is not created immediately - instead, it is produced on-demand by a closure (wrapped in a new `LazyTokenStream` type). This closure stores a clone of the original `TokenCursor`, plus a record of the number of calls to `next()/next_desugared()`. This is sufficient to reconstruct the tokenstream seen by the callback without storing any additional state. If the tokenstream is never used (e.g. when a captured `macro_rules!` argument is never passed to a proc macro), we never actually create a `TokenStream`. This implementation has a number of advantages over the previous one: * It is significantly simpler, with no edge cases around capturing the start/end of a delimited group. * It can be easily extended to allow replacing tokens an an arbitrary 'depth' by just using `Vec::splice` at the proper position. This is important for PR #76130, which requires us to track information about attributes along with tokens. * The lazy approach to `TokenStream` construction allows us to easily parse an AST struct, and then decide after the fact whether we need a `TokenStream`. This will be useful when we start collecting tokens for `Attribute` - we can discard the `LazyTokenStream` if the parsed attribute doesn't need tokens (e.g. is a builtin attribute). The performance impact seems to be neglibile (see https://github.com/rust-lang/rust/pull/77250#issuecomment-703960604). There is a small slowdown on a few benchmarks, but it only rises above 1% for incremental builds, where it represents a larger fraction of the much smaller instruction count. There a ~1% speedup on a few other incremental benchmarks - my guess is that the speedups and slowdowns will usually cancel out in practice.
2020-09-27 03:56:29 +02:00
pub tokens: Option<LazyTokenStream>,
}
2019-12-03 16:38:34 +01:00
/// A list of attributes.
pub type AttrVec = ThinVec<Attribute>;
/// Metadata associated with an item.
#[derive(Clone, Encodable, Decodable, Debug)]
2016-11-14 13:00:25 +01:00
pub struct Attribute {
pub kind: AttrKind,
2014-05-20 09:07:24 +02:00
pub id: AttrId,
/// Denotes if the attribute decorates the following construct (outer)
/// or the construct this attribute is contained within (inner).
pub style: AttrStyle,
2016-11-14 13:00:25 +01:00
pub span: Span,
}
#[derive(Clone, Encodable, Decodable, Debug)]
pub enum AttrKind {
/// A normal attribute.
2020-11-05 18:27:48 +01:00
Normal(AttrItem, Option<LazyTokenStream>),
/// A doc comment (e.g. `/// ...`, `//! ...`, `/** ... */`, `/*! ... */`).
/// Doc attributes (e.g. `#[doc="..."]`) are represented with the `Normal`
/// variant (which is much less compact and thus more expensive).
DocComment(CommentKind, Symbol),
}
/// `TraitRef`s appear in impls.
2015-03-18 20:26:37 +01:00
///
2019-02-08 14:53:55 +01:00
/// Resolution maps each `TraitRef`'s `ref_id` to its defining trait; that's all
/// that the `ref_id` is for. The `impl_id` maps to the "self type" of this impl.
/// If this impl is an `ItemKind::Impl`, the `impl_id` is redundant (it could be the
2019-02-08 14:53:55 +01:00
/// same as the impl's `NodeId`).
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct TraitRef {
pub path: Path,
pub ref_id: NodeId,
2014-11-07 12:53:45 +01:00
}
#[derive(Clone, Encodable, Decodable, Debug)]
2014-11-07 12:53:45 +01:00
pub struct PolyTraitRef {
/// The `'a` in `<'a> Foo<&'a T>`.
2018-05-27 21:07:09 +02:00
pub bound_generic_params: Vec<GenericParam>,
2014-11-07 12:53:45 +01:00
/// The `Foo<&'a T>` in `<'a> Foo<&'a T>`.
pub trait_ref: TraitRef,
pub span: Span,
}
2017-03-16 22:47:32 +01:00
impl PolyTraitRef {
pub fn new(generic_params: Vec<GenericParam>, path: Path, span: Span) -> Self {
2017-03-16 22:47:32 +01:00
PolyTraitRef {
bound_generic_params: generic_params,
trait_ref: TraitRef { path, ref_id: DUMMY_NODE_ID },
span,
2017-03-16 22:47:32 +01:00
}
}
}
#[derive(Copy, Clone, Encodable, Decodable, Debug, HashStable_Generic)]
pub enum CrateSugar {
/// Source is `pub(crate)`.
PubCrate,
/// Source is (just) `crate`.
JustCrate,
}
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct Visibility {
pub kind: VisibilityKind,
pub span: Span,
Rewrite `collect_tokens` implementations to use a flattened buffer Instead of trying to collect tokens at each depth, we 'flatten' the stream as we go allong, pushing open/close delimiters to our buffer just like regular tokens. One capturing is complete, we reconstruct a nested `TokenTree::Delimited` structure, producing a normal `TokenStream`. The reconstructed `TokenStream` is not created immediately - instead, it is produced on-demand by a closure (wrapped in a new `LazyTokenStream` type). This closure stores a clone of the original `TokenCursor`, plus a record of the number of calls to `next()/next_desugared()`. This is sufficient to reconstruct the tokenstream seen by the callback without storing any additional state. If the tokenstream is never used (e.g. when a captured `macro_rules!` argument is never passed to a proc macro), we never actually create a `TokenStream`. This implementation has a number of advantages over the previous one: * It is significantly simpler, with no edge cases around capturing the start/end of a delimited group. * It can be easily extended to allow replacing tokens an an arbitrary 'depth' by just using `Vec::splice` at the proper position. This is important for PR #76130, which requires us to track information about attributes along with tokens. * The lazy approach to `TokenStream` construction allows us to easily parse an AST struct, and then decide after the fact whether we need a `TokenStream`. This will be useful when we start collecting tokens for `Attribute` - we can discard the `LazyTokenStream` if the parsed attribute doesn't need tokens (e.g. is a builtin attribute). The performance impact seems to be neglibile (see https://github.com/rust-lang/rust/pull/77250#issuecomment-703960604). There is a small slowdown on a few benchmarks, but it only rises above 1% for incremental builds, where it represents a larger fraction of the much smaller instruction count. There a ~1% speedup on a few other incremental benchmarks - my guess is that the speedups and slowdowns will usually cancel out in practice.
2020-09-27 03:56:29 +02:00
pub tokens: Option<LazyTokenStream>,
}
2018-01-29 06:12:09 +01:00
#[derive(Clone, Encodable, Decodable, Debug)]
2018-01-29 06:12:09 +01:00
pub enum VisibilityKind {
Public,
2018-01-29 06:12:09 +01:00
Crate(CrateSugar),
Restricted { path: P<Path>, id: NodeId },
Inherited,
2013-07-02 21:47:32 +02:00
}
impl VisibilityKind {
2018-07-06 22:18:38 +02:00
pub fn is_pub(&self) -> bool {
matches!(self, VisibilityKind::Public)
}
}
/// Field of a struct.
///
/// E.g., `bar: usize` as in `struct Foo { bar: usize }`.
#[derive(Clone, Encodable, Decodable, Debug)]
2016-04-06 10:19:10 +02:00
pub struct StructField {
pub attrs: Vec<Attribute>,
pub id: NodeId,
2016-04-06 10:19:10 +02:00
pub span: Span,
2016-04-02 15:47:53 +02:00
pub vis: Visibility,
pub ident: Option<Ident>,
pub ty: P<Ty>,
pub is_placeholder: bool,
}
/// Fields and constructor ids of enum variants and structs.
#[derive(Clone, Encodable, Decodable, Debug)]
2015-10-10 02:28:40 +02:00
pub enum VariantData {
/// Struct variant.
///
/// E.g., `Bar { .. }` as in `enum Foo { Bar { .. } }`.
Struct(Vec<StructField>, bool),
/// Tuple variant.
///
/// E.g., `Bar(..)` as in `enum Foo { Bar(..) }`.
2015-10-10 02:28:40 +02:00
Tuple(Vec<StructField>, NodeId),
/// Unit variant.
///
/// E.g., `Bar = ..` as in `enum Foo { Bar = .. }`.
2015-10-10 02:28:40 +02:00
Unit(NodeId),
2015-10-08 22:45:46 +02:00
}
impl VariantData {
/// Return the fields of this variant.
pub fn fields(&self) -> &[StructField] {
2015-10-10 02:28:40 +02:00
match *self {
VariantData::Struct(ref fields, ..) | VariantData::Tuple(ref fields, _) => fields,
_ => &[],
}
2015-10-08 22:45:46 +02:00
}
/// Return the `NodeId` of this variant's constructor, if it has one.
pub fn ctor_id(&self) -> Option<NodeId> {
2015-10-10 02:28:40 +02:00
match *self {
VariantData::Struct(..) => None,
VariantData::Tuple(_, id) | VariantData::Unit(id) => Some(id),
2015-10-10 02:28:40 +02:00
}
}
2013-01-13 22:45:57 +01:00
}
/// An item definition.
#[derive(Clone, Encodable, Decodable, Debug)]
2019-11-30 18:10:59 +01:00
pub struct Item<K = ItemKind> {
pub attrs: Vec<Attribute>,
pub id: NodeId,
pub span: Span,
pub vis: Visibility,
/// The name of the item.
/// It might be a dummy name in case of anonymous items.
pub ident: Ident,
2019-11-30 18:10:59 +01:00
pub kind: K,
/// Original tokens this item was parsed from. This isn't necessarily
/// available for all items, although over time more and more items should
/// have this be `Some`. Right now this is primarily used for procedural
/// macros, notably custom attributes.
///
/// Note that the tokens here do not include the outer attributes, but will
/// include inner attributes.
Rewrite `collect_tokens` implementations to use a flattened buffer Instead of trying to collect tokens at each depth, we 'flatten' the stream as we go allong, pushing open/close delimiters to our buffer just like regular tokens. One capturing is complete, we reconstruct a nested `TokenTree::Delimited` structure, producing a normal `TokenStream`. The reconstructed `TokenStream` is not created immediately - instead, it is produced on-demand by a closure (wrapped in a new `LazyTokenStream` type). This closure stores a clone of the original `TokenCursor`, plus a record of the number of calls to `next()/next_desugared()`. This is sufficient to reconstruct the tokenstream seen by the callback without storing any additional state. If the tokenstream is never used (e.g. when a captured `macro_rules!` argument is never passed to a proc macro), we never actually create a `TokenStream`. This implementation has a number of advantages over the previous one: * It is significantly simpler, with no edge cases around capturing the start/end of a delimited group. * It can be easily extended to allow replacing tokens an an arbitrary 'depth' by just using `Vec::splice` at the proper position. This is important for PR #76130, which requires us to track information about attributes along with tokens. * The lazy approach to `TokenStream` construction allows us to easily parse an AST struct, and then decide after the fact whether we need a `TokenStream`. This will be useful when we start collecting tokens for `Attribute` - we can discard the `LazyTokenStream` if the parsed attribute doesn't need tokens (e.g. is a builtin attribute). The performance impact seems to be neglibile (see https://github.com/rust-lang/rust/pull/77250#issuecomment-703960604). There is a small slowdown on a few benchmarks, but it only rises above 1% for incremental builds, where it represents a larger fraction of the much smaller instruction count. There a ~1% speedup on a few other incremental benchmarks - my guess is that the speedups and slowdowns will usually cancel out in practice.
2020-09-27 03:56:29 +02:00
pub tokens: Option<LazyTokenStream>,
2013-01-13 22:13:41 +01:00
}
impl Item {
/// Return the span that encompasses the attributes.
pub fn span_with_attributes(&self) -> Span {
self.attrs.iter().fold(self.span, |acc, attr| acc.to(attr.span))
}
}
impl<K: Into<ItemKind>> Item<K> {
pub fn into_item(self) -> Item {
let Item { attrs, id, span, vis, ident, kind, tokens } = self;
Item { attrs, id, span, vis, ident, kind: kind.into(), tokens }
}
}
/// `extern` qualifier on a function item or function type.
#[derive(Clone, Copy, Encodable, Decodable, Debug)]
pub enum Extern {
None,
Implicit,
Explicit(StrLit),
}
impl Extern {
pub fn from_abi(abi: Option<StrLit>) -> Extern {
2019-11-16 18:11:05 +01:00
abi.map_or(Extern::Implicit, Extern::Explicit)
}
}
/// A function header.
///
/// All the information between the visibility and the name of the function is
/// included in this struct (e.g., `async unsafe fn` or `const extern "C" fn`).
#[derive(Clone, Copy, Encodable, Decodable, Debug)]
pub struct FnHeader {
pub unsafety: Unsafe,
pub asyncness: Async,
pub constness: Const,
pub ext: Extern,
}
impl FnHeader {
/// Does this function header have any qualifiers or is it empty?
pub fn has_qualifiers(&self) -> bool {
let Self { unsafety, asyncness, constness, ext } = self;
matches!(unsafety, Unsafe::Yes(_))
|| asyncness.is_async()
|| matches!(constness, Const::Yes(_))
|| !matches!(ext, Extern::None)
}
}
impl Default for FnHeader {
fn default() -> FnHeader {
FnHeader {
unsafety: Unsafe::No,
asyncness: Async::No,
constness: Const::No,
ext: Extern::None,
}
}
}
2021-01-29 08:31:08 +01:00
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct TraitKind(
pub IsAuto,
pub Unsafe,
pub Generics,
pub GenericBounds,
pub Vec<P<AssocItem>>,
);
2021-01-29 08:31:08 +01:00
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct TyAliasKind(pub Defaultness, pub Generics, pub GenericBounds, pub Option<P<Ty>>);
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct ImplKind {
pub unsafety: Unsafe,
pub polarity: ImplPolarity,
pub defaultness: Defaultness,
pub constness: Const,
pub generics: Generics,
/// The trait being implemented, if any.
pub of_trait: Option<TraitRef>,
pub self_ty: P<Ty>,
pub items: Vec<P<AssocItem>>,
}
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct FnKind(pub Defaultness, pub FnSig, pub Generics, pub Option<P<Block>>);
#[derive(Clone, Encodable, Decodable, Debug)]
pub enum ItemKind {
/// An `extern crate` item, with the optional *original* crate name if the crate was renamed.
2015-03-18 20:26:37 +01:00
///
/// E.g., `extern crate foo` or `extern crate foo_bar as foo`.
2020-04-19 13:00:18 +02:00
ExternCrate(Option<Symbol>),
/// A use declaration item (`use`).
///
/// E.g., `use foo;`, `use foo::bar;` or `use foo::bar as FooBar;`.
2021-02-20 10:51:26 +01:00
Use(UseTree),
/// A static item (`static`).
///
/// E.g., `static FOO: i32 = 42;` or `static FOO: &'static str = "bar";`.
Static(P<Ty>, Mutability, Option<P<Expr>>),
/// A constant item (`const`).
///
/// E.g., `const FOO: i32 = 42;`.
Const(Defaultness, P<Ty>, Option<P<Expr>>),
/// A function declaration (`fn`).
///
/// E.g., `fn foo(bar: usize) -> usize { .. }`.
2021-01-29 08:31:08 +01:00
Fn(Box<FnKind>),
/// A module declaration (`mod`).
///
/// E.g., `mod foo;` or `mod foo { .. }`.
/// `unsafe` keyword on modules is accepted syntactically for macro DSLs, but not
/// semantically by Rust.
Mod(Unsafe, ModKind),
/// An external module (`extern`).
///
/// E.g., `extern {}` or `extern "C" {}`.
ForeignMod(ForeignMod),
/// Module-level inline assembly (from `global_asm!()`).
2021-02-20 10:51:26 +01:00
GlobalAsm(GlobalAsm),
/// A type alias (`type`).
///
/// E.g., `type Foo = Bar<u8>;`.
2021-01-29 08:31:08 +01:00
TyAlias(Box<TyAliasKind>),
/// An enum definition (`enum`).
///
/// E.g., `enum Foo<A, B> { C<A>, D<B> }`.
Enum(EnumDef, Generics),
/// A struct definition (`struct`).
///
/// E.g., `struct Foo<A> { x: A }`.
Struct(VariantData, Generics),
/// A union definition (`union`).
2016-08-29 07:04:31 +02:00
///
/// E.g., `union Foo<A, B> { x: A, y: B }`.
2016-07-16 23:15:15 +02:00
Union(VariantData, Generics),
/// A trait declaration (`trait`).
///
/// E.g., `trait Foo { .. }`, `trait Foo<T> { .. }` or `auto trait Foo {}`.
2021-01-29 08:31:08 +01:00
Trait(Box<TraitKind>),
2017-10-02 14:27:45 +02:00
/// Trait alias
///
/// E.g., `trait Foo = Bar + Quux;`.
TraitAlias(Generics, GenericBounds),
/// An implementation.
///
/// E.g., `impl<A> Foo<A> { .. }` or `impl<A> Trait for Foo<A> { .. }`.
2021-01-29 08:31:08 +01:00
Impl(Box<ImplKind>),
/// A macro invocation.
///
2019-07-14 21:16:16 +02:00
/// E.g., `foo!(..)`.
2020-02-29 17:32:20 +01:00
MacCall(MacCall),
/// A macro definition.
2017-03-17 22:58:48 +01:00
MacroDef(MacroDef),
2011-05-11 15:10:24 +02:00
}
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
rustc_data_structures::static_assert_size!(ItemKind, 112);
impl ItemKind {
2020-02-23 06:04:37 +01:00
pub fn article(&self) -> &str {
use ItemKind::*;
match self {
Use(..) | Static(..) | Const(..) | Fn(..) | Mod(..) | GlobalAsm(..) | TyAlias(..)
| Struct(..) | Union(..) | Trait(..) | TraitAlias(..) | MacroDef(..) => "a",
2020-02-29 17:32:20 +01:00
ExternCrate(..) | ForeignMod(..) | MacCall(..) | Enum(..) | Impl { .. } => "an",
2020-02-23 06:04:37 +01:00
}
}
pub fn descr(&self) -> &str {
match self {
ItemKind::ExternCrate(..) => "extern crate",
2020-02-23 06:04:37 +01:00
ItemKind::Use(..) => "`use` import",
ItemKind::Static(..) => "static item",
ItemKind::Const(..) => "constant item",
ItemKind::Fn(..) => "function",
ItemKind::Mod(..) => "module",
2020-02-23 06:04:37 +01:00
ItemKind::ForeignMod(..) => "extern block",
ItemKind::GlobalAsm(..) => "global asm item",
ItemKind::TyAlias(..) => "type alias",
ItemKind::Enum(..) => "enum",
ItemKind::Struct(..) => "struct",
2016-08-29 07:04:31 +02:00
ItemKind::Union(..) => "union",
ItemKind::Trait(..) => "trait",
2017-10-02 14:27:45 +02:00
ItemKind::TraitAlias(..) => "trait alias",
2020-02-29 17:32:20 +01:00
ItemKind::MacCall(..) => "item macro invocation",
2020-02-23 06:04:37 +01:00
ItemKind::MacroDef(..) => "macro definition",
ItemKind::Impl { .. } => "implementation",
}
}
pub fn generics(&self) -> Option<&Generics> {
match self {
2021-01-29 08:31:08 +01:00
Self::Fn(box FnKind(_, _, generics, _))
| Self::TyAlias(box TyAliasKind(_, generics, ..))
| Self::Enum(_, generics)
| Self::Struct(_, generics)
| Self::Union(_, generics)
2021-01-29 08:31:08 +01:00
| Self::Trait(box TraitKind(_, _, generics, ..))
| Self::TraitAlias(generics, _)
2021-01-29 08:31:08 +01:00
| Self::Impl(box ImplKind { generics, .. }) => Some(generics),
_ => None,
}
}
}
/// Represents associated items.
/// These include items in `impl` and `trait` definitions.
pub type AssocItem = Item<AssocItemKind>;
/// Represents associated item kinds.
///
/// The term "provided" in the variants below refers to the item having a default
/// definition / body. Meanwhile, a "required" item lacks a definition / body.
/// In an implementation, all items must be provided.
/// The `Option`s below denote the bodies, where `Some(_)`
/// means "provided" and conversely `None` means "required".
#[derive(Clone, Encodable, Decodable, Debug)]
pub enum AssocItemKind {
/// An associated constant, `const $ident: $ty $def?;` where `def ::= "=" $expr? ;`.
/// If `def` is parsed, then the constant is provided, and otherwise required.
Const(Defaultness, P<Ty>, Option<P<Expr>>),
/// An associated function.
2021-01-29 08:31:08 +01:00
Fn(Box<FnKind>),
/// An associated type.
2021-01-29 08:31:08 +01:00
TyAlias(Box<TyAliasKind>),
/// A macro expanding to associated items.
2020-02-29 17:32:20 +01:00
MacCall(MacCall),
}
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
rustc_data_structures::static_assert_size!(AssocItemKind, 72);
impl AssocItemKind {
pub fn defaultness(&self) -> Defaultness {
match *self {
2021-01-29 08:31:08 +01:00
Self::Const(def, ..)
| Self::Fn(box FnKind(def, ..))
| Self::TyAlias(box TyAliasKind(def, ..)) => def,
2020-02-29 17:32:20 +01:00
Self::MacCall(..) => Defaultness::Final,
}
}
}
impl From<AssocItemKind> for ItemKind {
fn from(assoc_item_kind: AssocItemKind) -> ItemKind {
match assoc_item_kind {
AssocItemKind::Const(a, b, c) => ItemKind::Const(a, b, c),
2021-01-29 08:31:08 +01:00
AssocItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
AssocItemKind::TyAlias(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
2020-02-29 17:32:20 +01:00
AssocItemKind::MacCall(a) => ItemKind::MacCall(a),
}
}
}
impl TryFrom<ItemKind> for AssocItemKind {
type Error = ItemKind;
fn try_from(item_kind: ItemKind) -> Result<AssocItemKind, ItemKind> {
Ok(match item_kind {
ItemKind::Const(a, b, c) => AssocItemKind::Const(a, b, c),
2021-01-29 08:31:08 +01:00
ItemKind::Fn(fn_kind) => AssocItemKind::Fn(fn_kind),
ItemKind::TyAlias(ty_alias_kind) => AssocItemKind::TyAlias(ty_alias_kind),
2020-02-29 17:32:20 +01:00
ItemKind::MacCall(a) => AssocItemKind::MacCall(a),
_ => return Err(item_kind),
})
}
}
/// An item in `extern` block.
#[derive(Clone, Encodable, Decodable, Debug)]
pub enum ForeignItemKind {
/// A foreign static item (`static FOO: u8`).
Static(P<Ty>, Mutability, Option<P<Expr>>),
2021-01-29 08:31:08 +01:00
/// An foreign function.
Fn(Box<FnKind>),
/// An foreign type.
TyAlias(Box<TyAliasKind>),
/// A macro expanding to foreign items.
2020-02-29 17:32:20 +01:00
MacCall(MacCall),
}
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
rustc_data_structures::static_assert_size!(ForeignItemKind, 72);
impl From<ForeignItemKind> for ItemKind {
fn from(foreign_item_kind: ForeignItemKind) -> ItemKind {
match foreign_item_kind {
ForeignItemKind::Static(a, b, c) => ItemKind::Static(a, b, c),
2021-01-29 08:31:08 +01:00
ForeignItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
ForeignItemKind::TyAlias(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
2020-02-29 17:32:20 +01:00
ForeignItemKind::MacCall(a) => ItemKind::MacCall(a),
}
}
}
impl TryFrom<ItemKind> for ForeignItemKind {
type Error = ItemKind;
fn try_from(item_kind: ItemKind) -> Result<ForeignItemKind, ItemKind> {
Ok(match item_kind {
ItemKind::Static(a, b, c) => ForeignItemKind::Static(a, b, c),
2021-01-29 08:31:08 +01:00
ItemKind::Fn(fn_kind) => ForeignItemKind::Fn(fn_kind),
ItemKind::TyAlias(ty_alias_kind) => ForeignItemKind::TyAlias(ty_alias_kind),
2020-02-29 17:32:20 +01:00
ItemKind::MacCall(a) => ForeignItemKind::MacCall(a),
_ => return Err(item_kind),
})
}
}
pub type ForeignItem = Item<ForeignItemKind>;