2019-10-24 16:11:43 +03:00
|
|
|
//! 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).
|
|
|
|
//!
|
2020-06-16 18:11:47 -07:00
|
|
|
//! Other module items worth mentioning:
|
2019-10-24 16:11:43 +03:00
|
|
|
//! - [`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.
|
2022-11-23 15:39:42 +11:00
|
|
|
//! - [`MetaItemLit`] and [`LitKind`]: Literal expressions.
|
2023-08-02 09:56:26 +10:00
|
|
|
//! - [`MacroDef`], [`MacStmtStyle`], [`MacCall`]: Macro definition and invocation.
|
2019-10-24 16:11:43 +03:00
|
|
|
//! - [`Attribute`]: Metadata associated with item.
|
2020-05-01 20:25:50 +02:00
|
|
|
//! - [`UnOp`], [`BinOp`], and [`BinOpKind`]: Unary and binary operators.
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2023-01-11 21:41:13 +01:00
|
|
|
use std::borrow::Cow;
|
2023-12-31 20:40:09 +00:00
|
|
|
use std::{cmp, fmt, mem};
|
2019-02-07 02:33:01 +09:00
|
|
|
|
2024-09-22 19:05:04 -04:00
|
|
|
pub use GenericArgs::*;
|
|
|
|
pub use UnsafeSource::*;
|
2024-02-27 18:11:23 +00:00
|
|
|
pub use rustc_ast_ir::{Movability, Mutability};
|
2024-01-17 15:40:30 -08:00
|
|
|
use rustc_data_structures::packed::Pu128;
|
2019-11-10 18:10:15 +01:00
|
|
|
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
2020-09-21 04:19:51 +08:00
|
|
|
use rustc_data_structures::stack::ensure_sufficient_stack;
|
2018-02-27 17:11:14 +01:00
|
|
|
use rustc_data_structures::sync::Lrc;
|
2024-04-29 08:53:45 +10:00
|
|
|
use rustc_macros::{Decodable, Encodable, HashStable_Generic};
|
2023-12-31 20:40:09 +00:00
|
|
|
pub use rustc_span::AttrId;
|
2024-09-22 19:05:04 -04:00
|
|
|
use rustc_span::source_map::{Spanned, respan};
|
|
|
|
use rustc_span::symbol::{Ident, Symbol, kw, sym};
|
|
|
|
use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span};
|
|
|
|
use thin_vec::{ThinVec, thin_vec};
|
2024-07-29 08:13:50 +10:00
|
|
|
|
2023-01-11 21:41:13 +01:00
|
|
|
pub use crate::format::*;
|
2019-02-07 02:33:01 +09:00
|
|
|
use crate::ptr::P;
|
2022-05-22 12:00:59 +03:00
|
|
|
use crate::token::{self, CommentKind, Delimiter};
|
2022-09-09 17:15:53 +10:00
|
|
|
use crate::tokenstream::{DelimSpan, LazyAttrTokenStream, TokenStream};
|
2019-02-07 02:33:01 +09:00
|
|
|
pub use crate::util::parser::ExprPrecedence;
|
2016-08-31 14:00:29 +03:00
|
|
|
|
2019-10-24 16:11:43 +03:00
|
|
|
/// 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.
|
2022-01-25 16:13:07 -08:00
|
|
|
#[derive(Clone, Encodable, Decodable, Copy, HashStable_Generic, Eq, PartialEq)]
|
2018-01-16 01:44:32 +03:00
|
|
|
pub struct Label {
|
|
|
|
pub ident: Ident,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Debug for Label {
|
2019-02-07 02:33:01 +09:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
2018-01-16 01:44:32 +03:00
|
|
|
write!(f, "label({:?})", self.ident)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-24 16:11:43 +03:00
|
|
|
/// A "Lifetime" is an annotation of the scope in which variable
|
|
|
|
/// can be used, e.g. `'a` in `&'a i32`.
|
2024-04-04 10:48:47 -04:00
|
|
|
#[derive(Clone, Encodable, Decodable, Copy, PartialEq, Eq, Hash)]
|
2013-02-11 16:33:31 -08:00
|
|
|
pub struct Lifetime {
|
2014-03-27 15:39:48 -07:00
|
|
|
pub id: NodeId,
|
2017-03-25 21:14:18 +00:00
|
|
|
pub ident: Ident,
|
2013-02-11 16:33:31 -08:00
|
|
|
}
|
|
|
|
|
2015-06-17 09:56:27 +03:00
|
|
|
impl fmt::Debug for Lifetime {
|
2019-02-07 02:33:01 +09:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
2018-09-22 16:19:44 -07:00
|
|
|
write!(f, "lifetime({}: {})", self.id, self)
|
2015-06-17 09:56:27 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-05 15:42:28 -04:00
|
|
|
impl fmt::Display for Lifetime {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
2019-10-22 11:04:25 +11:00
|
|
|
write!(f, "{}", self.ident.name)
|
2019-07-05 15:42:28 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-24 13:14:34 +02:00
|
|
|
/// A "Path" is essentially Rust's notion of a name.
|
|
|
|
///
|
|
|
|
/// It's represented as a sequence of identifiers,
|
2014-06-09 13:12:30 -07:00
|
|
|
/// along with a bunch of supporting information.
|
2016-06-24 13:14:34 +02:00
|
|
|
///
|
2018-11-27 02:59:49 +00:00
|
|
|
/// E.g., `std::cmp::PartialEq`.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2013-03-26 17:00:35 -07:00
|
|
|
pub struct Path {
|
2014-03-27 15:39:48 -07:00
|
|
|
pub span: Span,
|
2013-08-07 09:47:28 -07:00
|
|
|
/// The segments in the path: the things separated by `::`.
|
2019-05-11 17:41:37 +03:00
|
|
|
/// Global paths begin with `kw::PathRoot`.
|
2022-09-08 17:22:52 +10:00
|
|
|
pub segments: ThinVec<PathSegment>,
|
2022-09-09 17:15:53 +10:00
|
|
|
pub tokens: Option<LazyAttrTokenStream>,
|
2013-08-07 09:47:28 -07:00
|
|
|
}
|
|
|
|
|
2019-04-03 02:43:49 +02:00
|
|
|
impl PartialEq<Symbol> for Path {
|
2021-04-11 00:00:00 +00:00
|
|
|
#[inline]
|
2019-04-03 02:43:49 +02:00
|
|
|
fn eq(&self, symbol: &Symbol) -> bool {
|
2019-05-17 09:35:26 +10:00
|
|
|
self.segments.len() == 1 && { self.segments[0].ident.name == *symbol }
|
2019-04-03 02:43:49 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-13 11:23:51 -04:00
|
|
|
impl<CTX: rustc_span::HashStableContext> HashStable<CTX> for Path {
|
2019-11-10 18:10:15 +01:00
|
|
|
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
|
|
|
|
self.segments.len().hash_stable(hcx, hasher);
|
|
|
|
for segment in &self.segments {
|
2022-04-13 11:23:51 -04:00
|
|
|
segment.ident.hash_stable(hcx, hasher);
|
2019-11-10 18:10:15 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-29 12:12:01 +03:00
|
|
|
impl Path {
|
2022-11-27 11:15:06 +00:00
|
|
|
/// Convert a span and an identifier to the corresponding
|
|
|
|
/// one-segment path.
|
2018-03-19 03:54:56 +03:00
|
|
|
pub fn from_ident(ident: Ident) -> Path {
|
2022-09-08 17:22:52 +10:00
|
|
|
Path { segments: thin_vec![PathSegment::from_ident(ident)], span: ident.span, tokens: None }
|
2016-03-29 12:12:01 +03:00
|
|
|
}
|
2016-12-05 03:51:11 +00:00
|
|
|
|
|
|
|
pub fn is_global(&self) -> bool {
|
2019-05-11 17:41:37 +03:00
|
|
|
!self.segments.is_empty() && self.segments[0].ident.name == kw::PathRoot
|
2016-12-05 03:51:11 +00:00
|
|
|
}
|
2023-05-05 21:31:00 +01:00
|
|
|
|
|
|
|
/// If this path is a single identifier with no arguments, does not ensure
|
|
|
|
/// that the path resolves to a const param, the caller should check this.
|
|
|
|
pub fn is_potential_trivial_const_arg(&self) -> bool {
|
|
|
|
self.segments.len() == 1 && self.segments[0].args.is_none()
|
|
|
|
}
|
2016-03-29 12:12:01 +03:00
|
|
|
}
|
|
|
|
|
2016-06-24 13:14:34 +02:00
|
|
|
/// A segment of a path: an identifier, an optional lifetime, and a set of types.
|
|
|
|
///
|
2018-11-27 02:59:49 +00:00
|
|
|
/// E.g., `std`, `String` or `Box<T>`.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2013-08-07 09:47:28 -07:00
|
|
|
pub struct PathSegment {
|
|
|
|
/// The identifier portion of this path segment.
|
2018-03-18 03:53:41 +03:00
|
|
|
pub ident: Ident,
|
2014-11-03 21:52:52 -05:00
|
|
|
|
2018-08-31 12:01:26 +12:00
|
|
|
pub id: NodeId,
|
|
|
|
|
2014-11-03 21:52:52 -05:00
|
|
|
/// Type/lifetime parameters attached to this path. They come in
|
2017-07-23 19:32:36 +03:00
|
|
|
/// 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 17:48:54 +00:00
|
|
|
pub args: Option<P<GenericArgs>>,
|
2016-12-10 06:45:58 +00:00
|
|
|
}
|
|
|
|
|
2016-12-05 03:51:11 +00:00
|
|
|
impl PathSegment {
|
2018-03-19 03:54:56 +03:00
|
|
|
pub fn from_ident(ident: Ident) -> Self {
|
2018-08-31 12:01:26 +12:00
|
|
|
PathSegment { ident, id: DUMMY_NODE_ID, args: None }
|
2017-03-08 20:30:06 +03:00
|
|
|
}
|
2021-03-13 19:14:18 +03:00
|
|
|
|
2018-12-02 15:15:42 +03:00
|
|
|
pub fn path_root(span: Span) -> Self {
|
2019-05-11 17:41:37 +03:00
|
|
|
PathSegment::from_ident(Ident::new(kw::PathRoot, span))
|
2016-12-05 03:51:11 +00:00
|
|
|
}
|
2021-03-13 19:14:18 +03:00
|
|
|
|
|
|
|
pub fn span(&self) -> Span {
|
|
|
|
match &self.args {
|
|
|
|
Some(args) => self.ident.span.to(args.span()),
|
|
|
|
None => self.ident.span,
|
|
|
|
}
|
|
|
|
}
|
2016-12-05 03:51:11 +00:00
|
|
|
}
|
|
|
|
|
2024-05-27 23:53:46 +02:00
|
|
|
/// The generic arguments and associated item constraints of a path segment.
|
2016-06-24 13:14:34 +02:00
|
|
|
///
|
2018-11-27 02:59:49 +00:00
|
|
|
/// E.g., `<A, B>` as in `Foo<A, B>` or `(A, B)` as in `Foo(A, B)`.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2018-02-13 11:32:37 +00:00
|
|
|
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 17:48:54 +00:00
|
|
|
AngleBracketed(AngleBracketedArgs),
|
2019-02-08 14:53:55 +01:00
|
|
|
/// The `(A, B)` and `C` in `Foo(A, B) -> C`.
|
2019-01-21 08:09:56 +01:00
|
|
|
Parenthesized(ParenthesizedArgs),
|
2024-07-05 18:10:05 +03:00
|
|
|
/// `(..)` in return type notation.
|
2024-06-28 11:49:16 -04:00
|
|
|
ParenthesizedElided(Span),
|
2014-11-03 21:52:52 -05:00
|
|
|
}
|
|
|
|
|
2018-02-13 11:32:37 +00:00
|
|
|
impl GenericArgs {
|
2019-01-21 19:42:06 +01:00
|
|
|
pub fn is_angle_bracketed(&self) -> bool {
|
2020-12-24 02:55:21 +01:00
|
|
|
matches!(self, AngleBracketed(..))
|
2019-01-21 19:42:06 +01:00
|
|
|
}
|
|
|
|
|
2017-07-23 20:50:56 +03:00
|
|
|
pub fn span(&self) -> Span {
|
2022-11-16 19:26:38 +00:00
|
|
|
match self {
|
|
|
|
AngleBracketed(data) => data.span,
|
|
|
|
Parenthesized(data) => data.span,
|
2024-06-28 11:49:16 -04:00
|
|
|
ParenthesizedElided(span) => *span,
|
2017-07-20 02:39:34 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-24 16:11:43 +03:00
|
|
|
/// Concrete argument in the sequence of generic args.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2018-05-27 20:07:09 +01:00
|
|
|
pub enum GenericArg {
|
2024-07-05 18:10:05 +03:00
|
|
|
/// `'a` in `Foo<'a>`.
|
2018-02-08 08:58:13 +00:00
|
|
|
Lifetime(Lifetime),
|
2024-07-05 18:10:05 +03:00
|
|
|
/// `Bar` in `Foo<Bar>`.
|
2018-02-08 08:58:13 +00:00
|
|
|
Type(P<Ty>),
|
2024-07-05 18:10:05 +03:00
|
|
|
/// `1` in `Foo<1>`.
|
2019-02-05 16:48:45 +01:00
|
|
|
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,
|
|
|
|
}
|
|
|
|
}
|
2018-02-08 08:58:13 +00:00
|
|
|
}
|
|
|
|
|
2019-02-08 14:53:55 +01:00
|
|
|
/// A path like `Foo<'a, T>`.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug, Default)]
|
2018-02-23 17:48:54 +00:00
|
|
|
pub struct AngleBracketedArgs {
|
2019-02-08 14:53:55 +01:00
|
|
|
/// The overall span.
|
2017-07-23 20:50:56 +03:00
|
|
|
pub span: Span,
|
2020-03-22 04:40:05 +01:00
|
|
|
/// The comma separated parts in the `<...>`.
|
2023-01-30 14:37:06 +11:00
|
|
|
pub args: ThinVec<AngleBracketedArg>,
|
2020-03-22 04:40:05 +01:00
|
|
|
}
|
|
|
|
|
2024-05-27 23:53:46 +02:00
|
|
|
/// Either an argument for a generic parameter or a constraint on an associated item.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2020-03-22 04:40:05 +01:00
|
|
|
pub enum AngleBracketedArg {
|
2024-05-27 23:53:46 +02:00
|
|
|
/// A generic argument for a generic parameter.
|
2020-03-22 04:40:05 +01:00
|
|
|
Arg(GenericArg),
|
2024-05-27 23:53:46 +02:00
|
|
|
/// A constraint on an associated item.
|
|
|
|
Constraint(AssocItemConstraint),
|
2013-01-13 10:48:09 -08:00
|
|
|
}
|
2010-10-04 17:25:52 -07:00
|
|
|
|
2020-10-03 19:30:32 +01:00
|
|
|
impl AngleBracketedArg {
|
|
|
|
pub fn span(&self) -> Span {
|
|
|
|
match self {
|
|
|
|
AngleBracketedArg::Arg(arg) => arg.span(),
|
|
|
|
AngleBracketedArg::Constraint(constraint) => constraint.span,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-16 22:00:08 +00:00
|
|
|
impl Into<P<GenericArgs>> for AngleBracketedArgs {
|
|
|
|
fn into(self) -> P<GenericArgs> {
|
|
|
|
P(GenericArgs::AngleBracketed(self))
|
2014-11-03 21:52:52 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-16 22:00:08 +00:00
|
|
|
impl Into<P<GenericArgs>> for ParenthesizedArgs {
|
|
|
|
fn into(self) -> P<GenericArgs> {
|
|
|
|
P(GenericArgs::Parenthesized(self))
|
2017-07-20 02:39:34 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-08 14:53:55 +01:00
|
|
|
/// A path like `Foo(A, B) -> C`.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2019-01-21 08:09:56 +01:00
|
|
|
pub struct ParenthesizedArgs {
|
2021-01-02 19:45:11 +01:00
|
|
|
/// ```text
|
|
|
|
/// Foo(A, B) -> C
|
|
|
|
/// ^^^^^^^^^^^^^^
|
|
|
|
/// ```
|
2015-01-10 11:54:15 -05:00
|
|
|
pub span: Span,
|
|
|
|
|
2019-02-28 22:43:53 +00:00
|
|
|
/// `(A, B)`
|
2022-11-23 11:55:16 +11:00
|
|
|
pub inputs: ThinVec<P<Ty>>,
|
2014-11-03 21:52:52 -05:00
|
|
|
|
2021-01-02 19:45:11 +01:00
|
|
|
/// ```text
|
|
|
|
/// Foo(A, B) -> C
|
|
|
|
/// ^^^^^^
|
|
|
|
/// ```
|
|
|
|
pub inputs_span: Span,
|
|
|
|
|
2014-11-03 21:52:52 -05:00
|
|
|
/// `C`
|
2020-02-15 12:10:59 +09:00
|
|
|
pub output: FnRetTy,
|
2014-11-03 21:52:52 -05:00
|
|
|
}
|
|
|
|
|
2019-01-21 08:09:56 +01:00
|
|
|
impl ParenthesizedArgs {
|
2019-01-19 18:44:20 -08:00
|
|
|
pub fn as_angle_bracketed_args(&self) -> AngleBracketedArgs {
|
2020-03-22 04:40:05 +01:00
|
|
|
let args = self
|
|
|
|
.inputs
|
|
|
|
.iter()
|
|
|
|
.cloned()
|
|
|
|
.map(|input| AngleBracketedArg::Arg(GenericArg::Type(input)))
|
|
|
|
.collect();
|
2021-05-12 11:36:07 +02:00
|
|
|
AngleBracketedArgs { span: self.inputs_span, args }
|
2019-01-19 18:44:20 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-09-22 19:05:04 -04:00
|
|
|
pub use crate::node_id::{CRATE_NODE_ID, DUMMY_NODE_ID, NodeId};
|
2013-09-06 22:11:55 -04:00
|
|
|
|
2023-12-20 15:22:06 +01:00
|
|
|
/// Modifiers on a trait bound like `~const`, `?` and `!`.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug)]
|
2023-12-20 15:22:06 +01:00
|
|
|
pub struct TraitBoundModifiers {
|
|
|
|
pub constness: BoundConstness,
|
2024-01-26 17:00:28 +00:00
|
|
|
pub asyncness: BoundAsyncness,
|
2023-12-20 15:22:06 +01:00
|
|
|
pub polarity: BoundPolarity,
|
2018-05-28 13:33:28 +01:00
|
|
|
}
|
|
|
|
|
2023-12-20 15:22:06 +01:00
|
|
|
impl TraitBoundModifiers {
|
2024-01-26 17:00:28 +00:00
|
|
|
pub const NONE: Self = Self {
|
|
|
|
constness: BoundConstness::Never,
|
|
|
|
asyncness: BoundAsyncness::Normal,
|
|
|
|
polarity: BoundPolarity::Positive,
|
|
|
|
};
|
2023-07-25 05:58:53 +00:00
|
|
|
}
|
|
|
|
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2018-06-14 12:08:58 +01:00
|
|
|
pub enum GenericBound {
|
2023-12-20 15:22:06 +01:00
|
|
|
Trait(PolyTraitRef, TraitBoundModifiers),
|
2018-09-22 16:19:44 -07:00
|
|
|
Outlives(Lifetime),
|
2024-06-05 16:18:52 -04:00
|
|
|
/// Precise capturing syntax: `impl Sized + use<'a>`
|
|
|
|
Use(ThinVec<PreciseCapturingArg>, Span),
|
2013-01-10 11:16:54 -08:00
|
|
|
}
|
2011-12-28 17:50:12 +01:00
|
|
|
|
2018-06-14 12:08:58 +01:00
|
|
|
impl GenericBound {
|
2018-02-18 19:40:35 +01:00
|
|
|
pub fn span(&self) -> Span {
|
|
|
|
match self {
|
2022-11-16 19:26:38 +00:00
|
|
|
GenericBound::Trait(t, ..) => t.span,
|
|
|
|
GenericBound::Outlives(l) => l.ident.span,
|
2024-06-05 16:18:52 -04:00
|
|
|
GenericBound::Use(_, span) => *span,
|
2018-02-18 19:40:35 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-14 12:08:58 +01:00
|
|
|
pub type GenericBounds = Vec<GenericBound>;
|
2014-08-27 21:46:52 -04:00
|
|
|
|
2019-02-05 16:50:55 +01:00
|
|
|
/// 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.
|
2022-09-08 15:10:49 +02:00
|
|
|
#[derive(Hash, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
2019-02-05 16:50:55 +01:00
|
|
|
pub enum ParamKindOrd {
|
|
|
|
Lifetime,
|
2022-09-08 15:10:49 +02:00
|
|
|
TypeOrConst,
|
2019-02-05 16:50:55 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Display for ParamKindOrd {
|
2019-02-07 10:27:56 +01:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
2019-02-05 16:50:55 +01:00
|
|
|
match self {
|
|
|
|
ParamKindOrd::Lifetime => "lifetime".fmt(f),
|
2022-09-09 14:28:57 +02:00
|
|
|
ParamKindOrd::TypeOrConst => "type and const".fmt(f),
|
2019-02-05 16:50:55 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2018-05-27 20:07:09 +01:00
|
|
|
pub enum GenericParamKind {
|
2018-11-27 02:59:49 +00:00
|
|
|
/// A lifetime definition (e.g., `'a: 'b + 'c + 'd`).
|
2018-05-30 16:49:39 +01:00
|
|
|
Lifetime,
|
2019-02-05 16:48:45 +01:00
|
|
|
Type {
|
|
|
|
default: Option<P<Ty>>,
|
|
|
|
},
|
|
|
|
Const {
|
|
|
|
ty: P<Ty>,
|
2020-06-21 15:49:56 -07:00
|
|
|
/// Span of the `const` keyword.
|
|
|
|
kw_span: Span,
|
2024-07-05 18:10:05 +03:00
|
|
|
/// Optional default value for the const generic param.
|
2020-12-31 01:58:27 +01:00
|
|
|
default: Option<AnonConst>,
|
2019-02-05 16:48:45 +01:00
|
|
|
},
|
2013-02-14 21:50:03 -08:00
|
|
|
}
|
|
|
|
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2018-05-27 20:07:09 +01:00
|
|
|
pub struct GenericParam {
|
2018-05-26 19:16:21 +01:00
|
|
|
pub id: NodeId,
|
2018-05-31 15:52:17 +01:00
|
|
|
pub ident: Ident,
|
2019-12-03 16:38:34 +01:00
|
|
|
pub attrs: AttrVec,
|
2018-06-14 12:08:58 +01:00
|
|
|
pub bounds: GenericBounds,
|
2019-09-09 09:26:25 -03:00
|
|
|
pub is_placeholder: bool,
|
2018-05-27 20:07:09 +01:00
|
|
|
pub kind: GenericParamKind,
|
2022-04-28 21:59:41 +02:00
|
|
|
pub colon_span: Option<Span>,
|
2017-10-16 21:07:26 +02:00
|
|
|
}
|
|
|
|
|
2021-05-15 14:56:28 -07:00
|
|
|
impl GenericParam {
|
|
|
|
pub fn span(&self) -> Span {
|
|
|
|
match &self.kind {
|
|
|
|
GenericParamKind::Lifetime | GenericParamKind::Type { default: None } => {
|
|
|
|
self.ident.span
|
|
|
|
}
|
|
|
|
GenericParamKind::Type { default: Some(ty) } => self.ident.span.to(ty.span),
|
|
|
|
GenericParamKind::Const { kw_span, default: Some(default), .. } => {
|
|
|
|
kw_span.to(default.value.span)
|
|
|
|
}
|
|
|
|
GenericParamKind::Const { kw_span, default: None, ty } => kw_span.to(ty.span),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-10-16 21:07:26 +02:00
|
|
|
/// Represents lifetime, type and const parameters attached to a declaration of
|
|
|
|
/// a function, enum, trait, etc.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2013-02-14 21:50:03 -08:00
|
|
|
pub struct Generics {
|
2022-11-22 09:17:20 +11:00
|
|
|
pub params: ThinVec<GenericParam>,
|
2014-08-11 09:32:26 -07:00
|
|
|
pub where_clause: WhereClause,
|
2016-08-10 19:39:12 +02:00
|
|
|
pub span: Span,
|
2013-02-14 21:50:03 -08:00
|
|
|
}
|
|
|
|
|
2015-11-28 19:02:07 +00:00
|
|
|
impl Default for Generics {
|
2016-09-11 17:00:09 +05:30
|
|
|
/// Creates an instance of `Generics`.
|
2018-09-22 16:19:44 -07:00
|
|
|
fn default() -> Generics {
|
2022-11-22 09:17:20 +11:00
|
|
|
Generics { params: ThinVec::new(), where_clause: Default::default(), span: DUMMY_SP }
|
2015-11-28 19:02:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-08 14:53:55 +01:00
|
|
|
/// A where-clause in a definition.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2014-08-11 09:32:26 -07:00
|
|
|
pub struct WhereClause {
|
2024-02-19 14:25:33 +01:00
|
|
|
/// `true` if we ate a `where` token.
|
|
|
|
///
|
|
|
|
/// This can happen if we parsed no predicates, e.g., `struct Foo where {}`.
|
|
|
|
/// This allows us to pretty-print accurately and provide correct suggestion diagnostics.
|
2020-06-08 21:09:54 -04:00
|
|
|
pub has_where_token: bool,
|
2022-11-22 16:23:25 +11:00
|
|
|
pub predicates: ThinVec<WherePredicate>,
|
2017-07-27 13:37:35 +09:00
|
|
|
pub span: Span,
|
2014-08-11 09:32:26 -07:00
|
|
|
}
|
|
|
|
|
2022-11-14 15:43:10 +11:00
|
|
|
impl Default for WhereClause {
|
|
|
|
fn default() -> WhereClause {
|
2022-11-22 16:23:25 +11:00
|
|
|
WhereClause { has_where_token: false, predicates: ThinVec::new(), span: DUMMY_SP }
|
2022-11-14 15:43:10 +11:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-08 14:53:55 +01:00
|
|
|
/// A single predicate in a where-clause.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2014-11-29 17:08:30 +13:00
|
|
|
pub enum WherePredicate {
|
2024-05-27 23:53:46 +02:00
|
|
|
/// A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`).
|
2014-11-29 17:08:30 +13:00
|
|
|
BoundPredicate(WhereBoundPredicate),
|
2018-11-27 02:59:49 +00:00
|
|
|
/// A lifetime predicate (e.g., `'a: 'b + 'c`).
|
2014-12-20 02:29:19 -08:00
|
|
|
RegionPredicate(WhereRegionPredicate),
|
2018-11-27 02:59:49 +00:00
|
|
|
/// An equality predicate (unsupported).
|
2015-08-07 09:30:19 -04:00
|
|
|
EqPredicate(WhereEqPredicate),
|
2014-11-29 17:08:30 +13:00
|
|
|
}
|
|
|
|
|
2018-02-18 19:40:35 +01:00
|
|
|
impl WherePredicate {
|
|
|
|
pub fn span(&self) -> Span {
|
|
|
|
match self {
|
2021-01-02 20:09:17 +01:00
|
|
|
WherePredicate::BoundPredicate(p) => p.span,
|
|
|
|
WherePredicate::RegionPredicate(p) => p.span,
|
|
|
|
WherePredicate::EqPredicate(p) => p.span,
|
2018-02-18 19:40:35 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-24 13:14:34 +02:00
|
|
|
/// A type bound.
|
|
|
|
///
|
2018-11-27 02:59:49 +00:00
|
|
|
/// E.g., `for<'c> Foo: Send + Clone + 'c`.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2014-11-29 17:08:30 +13:00
|
|
|
pub struct WhereBoundPredicate {
|
2014-08-11 09:32:26 -07:00
|
|
|
pub span: Span,
|
2019-09-06 03:56:45 +01:00
|
|
|
/// Any generics from a `for` binding.
|
2022-11-22 09:17:20 +11:00
|
|
|
pub bound_generic_params: ThinVec<GenericParam>,
|
2019-09-06 03:56:45 +01:00
|
|
|
/// The type being bounded.
|
2014-12-20 02:29:19 -08:00
|
|
|
pub bounded_ty: P<Ty>,
|
2019-09-06 03:56:45 +01:00
|
|
|
/// Trait and lifetime bounds (`Clone + Send + 'static`).
|
2018-06-14 12:08:58 +01:00
|
|
|
pub bounds: GenericBounds,
|
2014-08-11 09:32:26 -07:00
|
|
|
}
|
|
|
|
|
2016-06-24 13:14:34 +02:00
|
|
|
/// A lifetime predicate.
|
|
|
|
///
|
2018-11-27 02:59:49 +00:00
|
|
|
/// E.g., `'a: 'b + 'c`.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2014-12-20 02:29:19 -08:00
|
|
|
pub struct WhereRegionPredicate {
|
|
|
|
pub span: Span,
|
|
|
|
pub lifetime: Lifetime,
|
2018-06-14 12:08:58 +01:00
|
|
|
pub bounds: GenericBounds,
|
2014-12-20 02:29:19 -08:00
|
|
|
}
|
|
|
|
|
2016-06-24 13:14:34 +02:00
|
|
|
/// An equality predicate (unsupported).
|
|
|
|
///
|
2018-11-27 02:59:49 +00:00
|
|
|
/// E.g., `T = int`.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2014-11-29 17:08:30 +13:00
|
|
|
pub struct WhereEqPredicate {
|
|
|
|
pub span: Span,
|
2017-01-16 21:32:13 +03:00
|
|
|
pub lhs_ty: P<Ty>,
|
|
|
|
pub rhs_ty: P<Ty>,
|
2014-11-29 17:08:30 +13:00
|
|
|
}
|
|
|
|
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2013-07-19 07:38:55 +02:00
|
|
|
pub struct Crate {
|
2022-08-17 12:34:33 +10:00
|
|
|
pub attrs: AttrVec,
|
2023-01-30 15:39:22 +11:00
|
|
|
pub items: ThinVec<P<Item>>,
|
2022-03-03 18:45:25 -05:00
|
|
|
pub spans: ModSpans,
|
2022-01-05 16:09:55 +08:00
|
|
|
/// Must be equal to `CRATE_NODE_ID` after the crate root is expanded, but may hold
|
|
|
|
/// expansion placeholders or an unassigned value (`DUMMY_NODE_ID`) before that.
|
|
|
|
pub id: NodeId,
|
|
|
|
pub is_placeholder: bool,
|
2013-01-14 19:06:59 -08:00
|
|
|
}
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2022-11-25 09:53:37 +11:00
|
|
|
/// A semantic representation of a meta item. A meta item is a slightly
|
|
|
|
/// restricted form of an attribute -- it can only contain expressions in
|
|
|
|
/// certain leaf positions, rather than arbitrary token streams -- that is used
|
|
|
|
/// for most built-in attributes.
|
2016-06-24 13:14:34 +02:00
|
|
|
///
|
2018-11-27 02:59:49 +00:00
|
|
|
/// E.g., `#[test]`, `#[derive(..)]`, `#[rustfmt::skip]` or `#[feature = "foo"]`.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
|
2016-11-15 07:37:10 +00:00
|
|
|
pub struct MetaItem {
|
2024-05-21 08:37:05 -05:00
|
|
|
pub unsafety: Safety,
|
2019-03-02 19:15:26 +03:00
|
|
|
pub path: Path,
|
2019-09-26 18:04:05 +01:00
|
|
|
pub kind: MetaItemKind,
|
2016-11-15 07:37:10 +00:00
|
|
|
pub span: Span,
|
|
|
|
}
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2022-11-25 09:53:37 +11:00
|
|
|
/// The meta item kind, containing the data after the initial path.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
|
2016-02-09 12:05:20 +01:00
|
|
|
pub enum MetaItemKind {
|
2016-06-24 13:14:34 +02:00
|
|
|
/// Word meta item.
|
|
|
|
///
|
2022-11-25 09:53:37 +11:00
|
|
|
/// E.g., `#[test]`, which lacks any arguments after `test`.
|
2016-11-15 07:37:10 +00:00
|
|
|
Word,
|
2022-11-25 09:53:37 +11:00
|
|
|
|
2016-06-24 13:14:34 +02:00
|
|
|
/// List meta item.
|
|
|
|
///
|
2022-11-25 09:53:37 +11:00
|
|
|
/// E.g., `#[derive(..)]`, where the field represents the `..`.
|
2022-11-23 11:55:16 +11:00
|
|
|
List(ThinVec<NestedMetaItem>),
|
2022-11-25 09:53:37 +11:00
|
|
|
|
2016-06-24 13:14:34 +02:00
|
|
|
/// Name value meta item.
|
|
|
|
///
|
2022-11-25 09:53:37 +11:00
|
|
|
/// E.g., `#[feature = "foo"]`, where the field represents the `"foo"`.
|
2022-11-23 15:39:42 +11:00
|
|
|
NameValue(MetaItemLit),
|
2013-07-19 21:51:37 +10:00
|
|
|
}
|
|
|
|
|
2022-11-25 09:59:36 +11:00
|
|
|
/// Values inside meta item lists.
|
|
|
|
///
|
|
|
|
/// E.g., each of `Clone`, `Copy` in `#[derive(Clone, Copy)]`.
|
|
|
|
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
|
|
|
|
pub enum NestedMetaItem {
|
|
|
|
/// A full MetaItem, for recursive meta items.
|
|
|
|
MetaItem(MetaItem),
|
|
|
|
|
|
|
|
/// A literal.
|
|
|
|
///
|
|
|
|
/// E.g., `"foo"`, `64`, `true`.
|
|
|
|
Lit(MetaItemLit),
|
|
|
|
}
|
|
|
|
|
2019-09-06 03:56:45 +01:00
|
|
|
/// A block (`{ .. }`).
|
2016-06-24 13:14:34 +02:00
|
|
|
///
|
2018-11-27 02:59:49 +00:00
|
|
|
/// E.g., `{ .. }` as in `fn foo() { .. }`.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2013-07-19 07:38:55 +02:00
|
|
|
pub struct Block {
|
2019-09-06 03:56:45 +01:00
|
|
|
/// The statements in the block.
|
2023-01-30 14:13:27 +11:00
|
|
|
pub stmts: ThinVec<Stmt>,
|
2014-03-27 15:39:48 -07:00
|
|
|
pub id: NodeId,
|
2019-09-06 03:56:45 +01:00
|
|
|
/// Distinguishes between `unsafe { ... }` and `{ ... }`.
|
2014-03-27 15:39:48 -07:00
|
|
|
pub rules: BlockCheckMode,
|
|
|
|
pub span: Span,
|
2022-09-09 17:15:53 +10:00
|
|
|
pub tokens: Option<LazyAttrTokenStream>,
|
2021-09-02 18:34:03 +00:00
|
|
|
/// The following *isn't* a parse error, but will cause multiple errors in following stages.
|
2022-04-15 15:04:34 -07:00
|
|
|
/// ```compile_fail
|
2021-09-02 18:34:03 +00:00
|
|
|
/// let x = {
|
|
|
|
/// foo: var
|
|
|
|
/// };
|
|
|
|
/// ```
|
|
|
|
/// #34255
|
|
|
|
pub could_be_bare_literal: bool,
|
2013-01-14 19:35:08 -08:00
|
|
|
}
|
2010-08-18 09:00:10 -07:00
|
|
|
|
2020-07-02 15:11:03 -07:00
|
|
|
/// A match pattern.
|
|
|
|
///
|
|
|
|
/// Patterns appear in match statements and some other contexts, such as `let` and `if let`.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2013-09-02 03:45:37 +02:00
|
|
|
pub struct Pat {
|
2014-03-27 15:39:48 -07:00
|
|
|
pub id: NodeId,
|
2019-09-26 16:18:31 +01:00
|
|
|
pub kind: PatKind,
|
2014-03-27 15:39:48 -07:00
|
|
|
pub span: Span,
|
2022-09-09 17:15:53 +10:00
|
|
|
pub tokens: Option<LazyAttrTokenStream>,
|
2013-01-14 20:52:28 -08:00
|
|
|
}
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2016-04-24 03:26:10 +00:00
|
|
|
impl Pat {
|
2019-07-09 09:23:51 +02:00
|
|
|
/// Attempt reparsing the pattern as a type.
|
|
|
|
/// This is intended for use by diagnostics.
|
2019-10-15 22:48:13 +02:00
|
|
|
pub fn to_ty(&self) -> Option<P<Ty>> {
|
2019-09-26 17:25:31 +01:00
|
|
|
let kind = match &self.kind {
|
2019-07-09 09:23:51 +02:00
|
|
|
// In a type expression `_` is an inference variable.
|
2017-12-18 23:26:59 +03:00
|
|
|
PatKind::Wild => TyKind::Infer,
|
2019-07-09 09:23:51 +02:00
|
|
|
// An IDENT pattern with no binding mode would be valid as path to a type. E.g. `u32`.
|
2024-04-16 19:23:30 -04:00
|
|
|
PatKind::Ident(BindingMode::NONE, ident, None) => {
|
2018-09-22 16:19:44 -07:00
|
|
|
TyKind::Path(None, Path::from_ident(*ident))
|
|
|
|
}
|
2017-12-18 23:26:59 +03:00
|
|
|
PatKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
|
2020-02-29 19:32:20 +03:00
|
|
|
PatKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
|
2019-07-09 09:23:51 +02:00
|
|
|
// `&mut? P` can be reinterpreted as `&mut? T` where `T` is `P` reparsed as a type.
|
2018-09-22 16:19:44 -07:00
|
|
|
PatKind::Ref(pat, mutbl) => {
|
2022-12-28 18:06:11 +01:00
|
|
|
pat.to_ty().map(|ty| TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }))?
|
2019-12-22 17:42:04 -05:00
|
|
|
}
|
2019-07-09 09:23:51 +02:00
|
|
|
// A slice/array pattern `[P]` can be reparsed as `[T]`, an unsized array,
|
|
|
|
// when `P` can be reparsed as a type `T`.
|
2024-08-07 12:41:49 +02:00
|
|
|
PatKind::Slice(pats) if let [pat] = pats.as_slice() => {
|
|
|
|
pat.to_ty().map(TyKind::Slice)?
|
|
|
|
}
|
2019-07-09 09:23:51 +02:00
|
|
|
// A tuple pattern `(P0, .., Pn)` can be reparsed as `(T0, .., Tn)`
|
|
|
|
// assuming `T0` to `Tn` are all syntactically valid as types.
|
|
|
|
PatKind::Tuple(pats) => {
|
2022-11-23 11:55:16 +11:00
|
|
|
let mut tys = ThinVec::with_capacity(pats.len());
|
2018-08-03 10:19:22 +02:00
|
|
|
// FIXME(#48994) - could just be collected into an Option<Vec>
|
|
|
|
for pat in pats {
|
|
|
|
tys.push(pat.to_ty()?);
|
|
|
|
}
|
2017-12-18 23:26:59 +03:00
|
|
|
TyKind::Tup(tys)
|
|
|
|
}
|
|
|
|
_ => return None,
|
|
|
|
};
|
|
|
|
|
2020-08-21 18:18:04 -04:00
|
|
|
Some(P(Ty { kind, id: self.id, span: self.span, tokens: None }))
|
2017-12-18 23:26:59 +03:00
|
|
|
}
|
|
|
|
|
2019-08-28 07:13:34 +02:00
|
|
|
/// 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.
|
2019-08-28 07:13:34 +02:00
|
|
|
pub fn walk(&self, it: &mut impl FnMut(&Pat) -> bool) {
|
2016-04-24 03:26:10 +00:00
|
|
|
if !it(self) {
|
2019-08-28 07:13:34 +02:00
|
|
|
return;
|
2016-04-24 03:26:10 +00:00
|
|
|
}
|
|
|
|
|
2019-09-26 16:18:31 +01:00
|
|
|
match &self.kind {
|
2019-10-24 16:11:43 +03:00
|
|
|
// Walk into the pattern associated with `Ident` (if any).
|
2019-07-09 09:25:18 +02:00
|
|
|
PatKind::Ident(_, _, Some(p)) => p.walk(it),
|
2019-10-24 16:11:43 +03:00
|
|
|
|
|
|
|
// Walk into each field of struct.
|
2020-12-10 13:20:07 +01:00
|
|
|
PatKind::Struct(_, _, fields, _) => fields.iter().for_each(|field| field.pat.walk(it)),
|
2019-10-24 16:11:43 +03:00
|
|
|
|
|
|
|
// Sequence of patterns.
|
2020-12-10 13:20:07 +01:00
|
|
|
PatKind::TupleStruct(_, _, s)
|
|
|
|
| PatKind::Tuple(s)
|
|
|
|
| PatKind::Slice(s)
|
|
|
|
| PatKind::Or(s) => s.iter().for_each(|p| p.walk(it)),
|
2019-10-24 16:11:43 +03:00
|
|
|
|
|
|
|
// Trivial wrappers over inner patterns.
|
2024-03-20 16:53:50 -04:00
|
|
|
PatKind::Box(s) | PatKind::Deref(s) | PatKind::Ref(s, _) | PatKind::Paren(s) => {
|
|
|
|
s.walk(it)
|
|
|
|
}
|
2019-10-24 16:11:43 +03:00
|
|
|
|
|
|
|
// These patterns do not contain subpatterns, skip.
|
2018-09-22 16:19:44 -07:00
|
|
|
PatKind::Wild
|
2019-07-07 00:26:55 +02:00
|
|
|
| PatKind::Rest
|
2023-11-22 02:30:43 +01:00
|
|
|
| PatKind::Never
|
2018-09-22 16:19:44 -07:00
|
|
|
| PatKind::Lit(_)
|
|
|
|
| PatKind::Range(..)
|
|
|
|
| PatKind::Ident(..)
|
|
|
|
| PatKind::Path(..)
|
2024-01-17 03:14:16 +01:00
|
|
|
| PatKind::MacCall(_)
|
|
|
|
| PatKind::Err(_) => {}
|
2016-04-24 03:26:10 +00:00
|
|
|
}
|
|
|
|
}
|
2019-07-09 09:26:11 +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)
|
2019-07-09 09:26:11 +02:00
|
|
|
}
|
2023-11-27 03:15:56 +01:00
|
|
|
|
2023-11-27 01:53:05 +01:00
|
|
|
/// Whether this could be a never pattern, taking into account that a macro invocation can
|
|
|
|
/// return a never pattern. Used to inform errors during parsing.
|
2023-11-27 03:15:56 +01:00
|
|
|
pub fn could_be_never_pattern(&self) -> bool {
|
|
|
|
let mut could_be_never_pattern = false;
|
|
|
|
self.walk(&mut |pat| match &pat.kind {
|
|
|
|
PatKind::Never | PatKind::MacCall(_) => {
|
|
|
|
could_be_never_pattern = true;
|
|
|
|
false
|
|
|
|
}
|
|
|
|
PatKind::Or(s) => {
|
|
|
|
could_be_never_pattern = s.iter().all(|p| p.could_be_never_pattern());
|
|
|
|
false
|
|
|
|
}
|
|
|
|
_ => true,
|
|
|
|
});
|
|
|
|
could_be_never_pattern
|
|
|
|
}
|
2023-12-12 14:52:05 +01:00
|
|
|
|
|
|
|
/// Whether this contains a `!` pattern. This in particular means that a feature gate error will
|
|
|
|
/// be raised if the feature is off. Used to avoid gating the feature twice.
|
|
|
|
pub fn contains_never_pattern(&self) -> bool {
|
|
|
|
let mut contains_never_pattern = false;
|
|
|
|
self.walk(&mut |pat| {
|
|
|
|
if matches!(pat.kind, PatKind::Never) {
|
|
|
|
contains_never_pattern = true;
|
|
|
|
}
|
|
|
|
true
|
|
|
|
});
|
|
|
|
contains_never_pattern
|
|
|
|
}
|
Detect more cases of `=` to `:` typo
When a `Local` is fully parsed, but not followed by a `;`, keep the `:` span
arround and mention it. If the type could continue being parsed as an
expression, suggest replacing the `:` with a `=`.
```
error: expected one of `!`, `+`, `->`, `::`, `;`, or `=`, found `.`
--> file.rs:2:32
|
2 | let _: std::env::temp_dir().join("foo");
| - ^ expected one of `!`, `+`, `->`, `::`, `;`, or `=`
| |
| while parsing the type for `_`
| help: use `=` if you meant to assign
```
Fix #119665.
2024-02-27 00:48:32 +00:00
|
|
|
|
|
|
|
/// Return a name suitable for diagnostics.
|
|
|
|
pub fn descr(&self) -> Option<String> {
|
|
|
|
match &self.kind {
|
|
|
|
PatKind::Wild => Some("_".to_string()),
|
2024-04-16 19:23:30 -04:00
|
|
|
PatKind::Ident(BindingMode::NONE, ident, None) => Some(format!("{ident}")),
|
Detect more cases of `=` to `:` typo
When a `Local` is fully parsed, but not followed by a `;`, keep the `:` span
arround and mention it. If the type could continue being parsed as an
expression, suggest replacing the `:` with a `=`.
```
error: expected one of `!`, `+`, `->`, `::`, `;`, or `=`, found `.`
--> file.rs:2:32
|
2 | let _: std::env::temp_dir().join("foo");
| - ^ expected one of `!`, `+`, `->`, `::`, `;`, or `=`
| |
| while parsing the type for `_`
| help: use `=` if you meant to assign
```
Fix #119665.
2024-02-27 00:48:32 +00:00
|
|
|
PatKind::Ref(pat, mutbl) => pat.descr().map(|d| format!("&{}{d}", mutbl.prefix_str())),
|
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
2016-04-24 03:26:10 +00:00
|
|
|
}
|
|
|
|
|
2020-12-17 11:39:39 -08:00
|
|
|
/// A single field in a struct pattern.
|
2015-03-17 04:19:27 +05:30
|
|
|
///
|
2020-12-17 11:39:39 -08: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.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2021-03-16 00:36:07 +03:00
|
|
|
pub struct PatField {
|
2020-12-17 11:39:39 -08:00
|
|
|
/// The identifier for the field.
|
2014-03-27 15:39:48 -07:00
|
|
|
pub ident: Ident,
|
2020-12-17 11:39:39 -08:00
|
|
|
/// The pattern the field is destructured to.
|
2014-05-18 01:13:20 +03:00
|
|
|
pub pat: P<Pat>,
|
2014-10-06 13:36:53 +13:00
|
|
|
pub is_shorthand: bool,
|
2019-12-03 16:38:34 +01:00
|
|
|
pub attrs: AttrVec,
|
2019-08-13 22:22:51 -03:00
|
|
|
pub id: NodeId,
|
2019-08-15 02:35:36 +03:00
|
|
|
pub span: Span,
|
2019-09-09 09:26:25 -03:00
|
|
|
pub is_placeholder: bool,
|
2013-01-14 20:52:28 -08:00
|
|
|
}
|
2011-07-11 14:13:20 +02:00
|
|
|
|
2022-08-30 17:34:35 -05:00
|
|
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
|
|
|
#[derive(Encodable, Decodable, HashStable_Generic)]
|
|
|
|
pub enum ByRef {
|
2024-03-23 21:04:45 -04:00
|
|
|
Yes(Mutability),
|
2022-08-30 17:34:35 -05:00
|
|
|
No,
|
|
|
|
}
|
|
|
|
|
2024-04-16 19:05:17 -04:00
|
|
|
impl ByRef {
|
2024-06-26 17:01:04 -04:00
|
|
|
#[must_use]
|
2024-04-16 19:05:17 -04:00
|
|
|
pub fn cap_ref_mutability(mut self, mutbl: Mutability) -> Self {
|
|
|
|
if let ByRef::Yes(old_mutbl) = &mut self {
|
|
|
|
*old_mutbl = cmp::min(*old_mutbl, mutbl);
|
|
|
|
}
|
|
|
|
self
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-16 19:23:30 -04:00
|
|
|
/// The mode of a binding (`mut`, `ref mut`, etc).
|
2024-04-17 09:28:17 -04:00
|
|
|
/// Used for both the explicit binding annotations given in the HIR for a binding
|
|
|
|
/// and the final binding mode that we infer after type inference/match ergonomics.
|
|
|
|
/// `.0` is the by-reference mode (`ref`, `ref mut`, or by value),
|
|
|
|
/// `.1` is the mutability of the binding.
|
2022-08-30 17:34:35 -05:00
|
|
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
|
|
|
#[derive(Encodable, Decodable, HashStable_Generic)]
|
2024-04-16 19:23:30 -04:00
|
|
|
pub struct BindingMode(pub ByRef, pub Mutability);
|
2022-08-30 17:34:35 -05:00
|
|
|
|
2024-04-16 19:23:30 -04:00
|
|
|
impl BindingMode {
|
2022-08-30 17:34:35 -05:00
|
|
|
pub const NONE: Self = Self(ByRef::No, Mutability::Not);
|
2024-03-23 21:04:45 -04:00
|
|
|
pub const REF: Self = Self(ByRef::Yes(Mutability::Not), Mutability::Not);
|
2022-08-30 17:34:35 -05:00
|
|
|
pub const MUT: Self = Self(ByRef::No, Mutability::Mut);
|
2024-03-23 21:04:45 -04:00
|
|
|
pub const REF_MUT: Self = Self(ByRef::Yes(Mutability::Mut), Mutability::Not);
|
|
|
|
pub const MUT_REF: Self = Self(ByRef::Yes(Mutability::Not), Mutability::Mut);
|
|
|
|
pub const MUT_REF_MUT: Self = Self(ByRef::Yes(Mutability::Mut), Mutability::Mut);
|
2022-08-30 17:34:35 -05:00
|
|
|
|
|
|
|
pub fn prefix_str(self) -> &'static str {
|
|
|
|
match self {
|
|
|
|
Self::NONE => "",
|
|
|
|
Self::REF => "ref ",
|
|
|
|
Self::MUT => "mut ",
|
|
|
|
Self::REF_MUT => "ref mut ",
|
2024-03-23 21:04:45 -04:00
|
|
|
Self::MUT_REF => "mut ref ",
|
|
|
|
Self::MUT_REF_MUT => "mut ref mut ",
|
2022-08-30 17:34:35 -05:00
|
|
|
}
|
|
|
|
}
|
2012-07-31 19:25:24 -07:00
|
|
|
}
|
|
|
|
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2017-01-10 22:13:53 +01:00
|
|
|
pub enum RangeEnd {
|
2021-01-06 12:31:34 -08:00
|
|
|
/// `..=` or `...`
|
2017-09-21 12:13:26 +02:00
|
|
|
Included(RangeSyntax),
|
2021-01-06 12:31:34 -08:00
|
|
|
/// `..`
|
2017-01-10 22:13:53 +01:00
|
|
|
Excluded,
|
|
|
|
}
|
|
|
|
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2017-09-21 12:13:26 +02:00
|
|
|
pub enum RangeSyntax {
|
2019-10-24 16:11:43 +03:00
|
|
|
/// `...`
|
2017-09-21 12:13:26 +02:00
|
|
|
DotDotDot,
|
2019-10-24 16:11:43 +03:00
|
|
|
/// `..=`
|
2017-09-21 12:13:26 +02:00
|
|
|
DotDotEq,
|
|
|
|
}
|
|
|
|
|
2021-01-06 12:31:34 -08:00
|
|
|
/// All the different flavors of pattern that Rust recognizes.
|
2023-10-20 09:55:29 +11:00
|
|
|
//
|
|
|
|
// Adding a new variant? Please update `test_pat` in `tests/ui/macros/stringify.rs`.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2016-02-11 21:16:33 +03:00
|
|
|
pub enum PatKind {
|
2018-11-27 02:59:49 +00:00
|
|
|
/// Represents a wildcard pattern (`_`).
|
2016-02-11 21:16:33 +03:00
|
|
|
Wild,
|
2014-08-06 17:04:44 +02:00
|
|
|
|
2016-03-06 15:54:44 +03:00
|
|
|
/// 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.
|
2024-04-16 19:23:30 -04:00
|
|
|
Ident(BindingMode, Ident, Option<P<Pat>>),
|
2014-07-27 15:23:01 -07:00
|
|
|
|
2018-11-27 02:59:49 +00:00
|
|
|
/// A struct or struct variant pattern (e.g., `Variant {x, y, ..}`).
|
2023-12-22 23:29:20 +00:00
|
|
|
Struct(Option<P<QSelf>>, Path, ThinVec<PatField>, PatFieldsRest),
|
2016-02-13 15:51:27 +03:00
|
|
|
|
2018-11-27 02:59:49 +00:00
|
|
|
/// A tuple struct/variant pattern (`Variant(x, y, .., z)`).
|
2022-11-23 11:55:16 +11:00
|
|
|
TupleStruct(Option<P<QSelf>>, Path, ThinVec<P<Pat>>),
|
2016-02-13 15:51:27 +03:00
|
|
|
|
2018-10-19 15:40:07 +01:00
|
|
|
/// An or-pattern `A | B | C`.
|
2019-07-14 01:05:52 +00:00
|
|
|
/// Invariant: `pats.len() >= 2`.
|
2022-11-23 11:55:16 +11:00
|
|
|
Or(ThinVec<P<Pat>>),
|
2018-10-19 15:40:07 +01:00
|
|
|
|
2016-06-11 18:47:47 +03:00
|
|
|
/// 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
|
2016-06-11 18:47:47 +03:00
|
|
|
/// only legally refer to associated constants.
|
2022-09-08 10:52:51 +10:00
|
|
|
Path(Option<P<QSelf>>, Path),
|
2015-03-25 10:53:28 -06:00
|
|
|
|
2018-11-27 02:59:49 +00:00
|
|
|
/// A tuple pattern (`(a, b)`).
|
2022-11-23 11:55:16 +11:00
|
|
|
Tuple(ThinVec<P<Pat>>),
|
2019-02-18 18:34:42 +00:00
|
|
|
|
2018-11-27 02:59:49 +00:00
|
|
|
/// A `box` pattern.
|
2016-02-11 21:16:33 +03:00
|
|
|
Box(P<Pat>),
|
2019-02-18 18:34:42 +00:00
|
|
|
|
2024-03-20 16:53:50 -04:00
|
|
|
/// A `deref` pattern (currently `deref!()` macro-based syntax).
|
|
|
|
Deref(P<Pat>),
|
|
|
|
|
2018-11-27 02:59:49 +00:00
|
|
|
/// A reference pattern (e.g., `&mut (a, b)`).
|
2016-02-11 21:16:33 +03:00
|
|
|
Ref(P<Pat>, Mutability),
|
2019-02-18 18:34:42 +00:00
|
|
|
|
2018-11-27 02:59:49 +00:00
|
|
|
/// A literal.
|
2016-02-11 21:16:33 +03:00
|
|
|
Lit(P<Expr>),
|
2019-02-18 18:34:42 +00:00
|
|
|
|
2021-01-06 12:31:34 -08:00
|
|
|
/// A range pattern (e.g., `1...2`, `1..2`, `1..`, `..2`, `1..=2`, `..=2`).
|
2019-12-11 10:04:34 +01:00
|
|
|
Range(Option<P<Expr>>, Option<P<Expr>>, Spanned<RangeEnd>),
|
2019-02-18 18:34:42 +00:00
|
|
|
|
2019-07-09 09:25:18 +02:00
|
|
|
/// A slice pattern `[a, b, c]`.
|
2022-11-23 11:55:16 +11:00
|
|
|
Slice(ThinVec<P<Pat>>),
|
2019-02-18 18:34:42 +00:00
|
|
|
|
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,
|
|
|
|
|
2024-07-05 18:10:05 +03:00
|
|
|
// A never pattern `!`.
|
2023-11-22 02:30:43 +01:00
|
|
|
Never,
|
|
|
|
|
2018-11-27 02:59:49 +00:00
|
|
|
/// Parentheses in patterns used for grouping (i.e., `(PAT)`).
|
2018-02-24 15:27:06 +03:00
|
|
|
Paren(P<Pat>),
|
2019-02-18 18:34:42 +00:00
|
|
|
|
2018-11-27 02:59:49 +00:00
|
|
|
/// A macro pattern; pre-expansion.
|
2022-08-12 12:20:10 +10:00
|
|
|
MacCall(P<MacCall>),
|
2024-01-17 03:14:16 +01:00
|
|
|
|
|
|
|
/// Placeholder for a pattern that wasn't syntactically well formed in some way.
|
|
|
|
Err(ErrorGuaranteed),
|
2010-11-24 14:42:01 -08:00
|
|
|
}
|
|
|
|
|
2023-12-22 23:29:20 +00:00
|
|
|
/// Whether the `..` is present in a struct fields pattern.
|
|
|
|
#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq)]
|
|
|
|
pub enum PatFieldsRest {
|
|
|
|
/// `module::StructName { field, ..}`
|
|
|
|
Rest,
|
|
|
|
/// `module::StructName { field }`
|
|
|
|
None,
|
|
|
|
}
|
|
|
|
|
2019-11-23 14:15:49 +00:00
|
|
|
/// The kind of borrow in an `AddrOf` expression,
|
|
|
|
/// e.g., `&place` or `&raw const place`.
|
|
|
|
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Encodable, Decodable, HashStable_Generic)]
|
2019-11-23 14:15:49 +00:00
|
|
|
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 22:20:35 +00: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)`.
|
2019-11-23 14:15:49 +00:00
|
|
|
Raw,
|
|
|
|
}
|
|
|
|
|
2023-11-28 09:36:09 +11:00
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
|
2016-02-08 13:16:12 +01:00
|
|
|
pub enum BinOpKind {
|
2015-03-17 03:41:23 +05:30
|
|
|
/// The `+` operator (addition)
|
2016-02-08 13:16:12 +01:00
|
|
|
Add,
|
2015-03-17 03:41:23 +05:30
|
|
|
/// The `-` operator (subtraction)
|
2016-02-08 13:16:12 +01:00
|
|
|
Sub,
|
2015-03-17 03:41:23 +05:30
|
|
|
/// The `*` operator (multiplication)
|
2016-02-08 13:16:12 +01:00
|
|
|
Mul,
|
2015-03-17 03:41:23 +05:30
|
|
|
/// The `/` operator (division)
|
2016-02-08 13:16:12 +01:00
|
|
|
Div,
|
2015-03-17 03:41:23 +05:30
|
|
|
/// The `%` operator (modulus)
|
2016-02-08 13:16:12 +01:00
|
|
|
Rem,
|
2015-03-17 03:41:23 +05:30
|
|
|
/// The `&&` operator (logical and)
|
2016-02-08 13:16:12 +01:00
|
|
|
And,
|
2015-03-17 03:41:23 +05:30
|
|
|
/// The `||` operator (logical or)
|
2016-02-08 13:16:12 +01:00
|
|
|
Or,
|
2015-03-17 03:41:23 +05:30
|
|
|
/// The `^` operator (bitwise xor)
|
2016-02-08 13:16:12 +01:00
|
|
|
BitXor,
|
2015-03-17 03:41:23 +05:30
|
|
|
/// The `&` operator (bitwise and)
|
2016-02-08 13:16:12 +01:00
|
|
|
BitAnd,
|
2015-03-17 03:41:23 +05:30
|
|
|
/// The `|` operator (bitwise or)
|
2016-02-08 13:16:12 +01:00
|
|
|
BitOr,
|
2015-03-17 03:41:23 +05:30
|
|
|
/// The `<<` operator (shift left)
|
2016-02-08 13:16:12 +01:00
|
|
|
Shl,
|
2015-03-17 03:41:23 +05:30
|
|
|
/// The `>>` operator (shift right)
|
2016-02-08 13:16:12 +01:00
|
|
|
Shr,
|
2015-03-17 03:41:23 +05:30
|
|
|
/// The `==` operator (equality)
|
2016-02-08 13:16:12 +01:00
|
|
|
Eq,
|
2015-03-17 03:41:23 +05:30
|
|
|
/// The `<` operator (less than)
|
2016-02-08 13:16:12 +01:00
|
|
|
Lt,
|
2015-03-17 03:41:23 +05:30
|
|
|
/// The `<=` operator (less than or equal to)
|
2016-02-08 13:16:12 +01:00
|
|
|
Le,
|
2015-03-17 03:41:23 +05:30
|
|
|
/// The `!=` operator (not equal to)
|
2016-02-08 13:16:12 +01:00
|
|
|
Ne,
|
2015-03-17 03:41:23 +05:30
|
|
|
/// The `>=` operator (greater than or equal to)
|
2016-02-08 13:16:12 +01:00
|
|
|
Ge,
|
2015-03-17 03:41:23 +05:30
|
|
|
/// The `>` operator (greater than)
|
2016-02-08 13:16:12 +01:00
|
|
|
Gt,
|
2010-09-27 18:25:02 -07:00
|
|
|
}
|
|
|
|
|
2016-02-08 13:16:12 +01:00
|
|
|
impl BinOpKind {
|
2023-11-28 09:11:03 +11:00
|
|
|
pub fn as_str(&self) -> &'static str {
|
2019-02-07 02:33:01 +09:00
|
|
|
use BinOpKind::*;
|
2023-11-28 09:11:03 +11:00
|
|
|
match self {
|
2016-02-08 13:16:12 +01:00
|
|
|
Add => "+",
|
|
|
|
Sub => "-",
|
|
|
|
Mul => "*",
|
|
|
|
Div => "/",
|
|
|
|
Rem => "%",
|
|
|
|
And => "&&",
|
|
|
|
Or => "||",
|
|
|
|
BitXor => "^",
|
|
|
|
BitAnd => "&",
|
|
|
|
BitOr => "|",
|
|
|
|
Shl => "<<",
|
|
|
|
Shr => ">>",
|
|
|
|
Eq => "==",
|
|
|
|
Lt => "<",
|
|
|
|
Le => "<=",
|
|
|
|
Ne => "!=",
|
|
|
|
Ge => ">=",
|
|
|
|
Gt => ">",
|
2015-11-28 19:02:07 +00:00
|
|
|
}
|
|
|
|
}
|
2023-11-28 09:42:25 +11:00
|
|
|
|
|
|
|
pub fn is_lazy(&self) -> bool {
|
2020-12-24 02:55:21 +01:00
|
|
|
matches!(self, BinOpKind::And | BinOpKind::Or)
|
2015-11-28 19:02:07 +00:00
|
|
|
}
|
|
|
|
|
2024-04-10 10:53:24 +00:00
|
|
|
pub fn is_comparison(self) -> bool {
|
|
|
|
crate::util::parser::AssocOp::from_ast_binop(self).is_comparison()
|
2015-11-28 19:02:07 +00:00
|
|
|
}
|
2023-11-28 09:36:09 +11:00
|
|
|
|
|
|
|
/// Returns `true` if the binary operator takes its arguments by value.
|
|
|
|
pub fn is_by_value(self) -> bool {
|
|
|
|
!self.is_comparison()
|
|
|
|
}
|
2015-11-28 19:02:07 +00:00
|
|
|
}
|
|
|
|
|
2016-02-08 13:16:12 +01:00
|
|
|
pub type BinOp = Spanned<BinOpKind>;
|
2015-01-13 14:24:37 +11:00
|
|
|
|
2019-10-24 16:11:43 +03:00
|
|
|
/// Unary operator.
|
|
|
|
///
|
|
|
|
/// Note that `&data` is not an operator, it's an `AddrOf` expression.
|
2023-11-28 09:36:09 +11:00
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
|
2013-09-02 03:45:37 +02:00
|
|
|
pub enum UnOp {
|
2015-03-17 03:41:23 +05:30
|
|
|
/// The `*` operator for dereferencing
|
2016-02-08 13:21:29 +01:00
|
|
|
Deref,
|
2015-03-17 03:41:23 +05:30
|
|
|
/// The `!` operator for logical inversion
|
2016-02-08 13:21:29 +01:00
|
|
|
Not,
|
2015-03-17 03:41:23 +05:30
|
|
|
/// The `-` operator for negation
|
2016-02-08 13:21:29 +01:00
|
|
|
Neg,
|
2012-09-07 18:53:14 -07:00
|
|
|
}
|
|
|
|
|
2015-11-28 19:02:07 +00:00
|
|
|
impl UnOp {
|
2023-11-28 09:11:03 +11:00
|
|
|
pub fn as_str(&self) -> &'static str {
|
|
|
|
match self {
|
2016-02-08 13:21:29 +01:00
|
|
|
UnOp::Deref => "*",
|
|
|
|
UnOp::Not => "!",
|
|
|
|
UnOp::Neg => "-",
|
2015-11-28 19:02:07 +00:00
|
|
|
}
|
|
|
|
}
|
2023-11-28 09:36:09 +11:00
|
|
|
|
|
|
|
/// Returns `true` if the unary operator takes its argument by value.
|
|
|
|
pub fn is_by_value(self) -> bool {
|
|
|
|
matches!(self, Self::Neg | Self::Not)
|
|
|
|
}
|
2015-11-28 19:02:07 +00:00
|
|
|
}
|
|
|
|
|
2024-06-18 21:32:50 +10:00
|
|
|
/// A statement. No `attrs` or `tokens` fields because each `StmtKind` variant
|
|
|
|
/// contains an AST node with those fields. (Except for `StmtKind::Empty`,
|
|
|
|
/// which never has attrs or tokens)
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2016-06-17 02:27:16 +00:00
|
|
|
pub struct Stmt {
|
|
|
|
pub id: NodeId,
|
2019-09-26 17:34:50 +01:00
|
|
|
pub kind: StmtKind,
|
2016-06-17 02:27:16 +00:00
|
|
|
pub span: Span,
|
|
|
|
}
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2016-07-02 09:01:21 +00:00
|
|
|
impl Stmt {
|
2020-10-25 17:14:19 -04:00
|
|
|
pub fn has_trailing_semicolon(&self) -> bool {
|
|
|
|
match &self.kind {
|
|
|
|
StmtKind::Semi(_) => true,
|
|
|
|
StmtKind::MacCall(mac) => matches!(mac.style, MacStmtStyle::Semicolon),
|
|
|
|
_ => false,
|
|
|
|
}
|
|
|
|
}
|
2020-11-17 14:27:44 -05:00
|
|
|
|
|
|
|
/// Converts a parsed `Stmt` to a `Stmt` with
|
|
|
|
/// a trailing semicolon.
|
|
|
|
///
|
|
|
|
/// This only modifies the parsed AST struct, not the attached
|
2022-09-09 17:15:53 +10:00
|
|
|
/// `LazyAttrTokenStream`. The parser is responsible for calling
|
|
|
|
/// `ToAttrTokenStream::add_trailing_semi` when there is actually
|
2020-11-17 14:27:44 -05:00
|
|
|
/// a semicolon in the tokenstream.
|
2016-07-02 09:01:21 +00:00
|
|
|
pub fn add_trailing_semicolon(mut self) -> Self {
|
2019-09-26 17:34:50 +01:00
|
|
|
self.kind = match self.kind {
|
2016-07-02 09:01:21 +00:00
|
|
|
StmtKind::Expr(expr) => StmtKind::Semi(expr),
|
2020-08-30 18:38:32 -04:00
|
|
|
StmtKind::MacCall(mac) => {
|
2020-11-17 14:27:44 -05:00
|
|
|
StmtKind::MacCall(mac.map(|MacCallStmt { mac, style: _, attrs, tokens }| {
|
|
|
|
MacCallStmt { mac, style: MacStmtStyle::Semicolon, attrs, tokens }
|
2020-08-30 18:38:32 -04:00
|
|
|
}))
|
|
|
|
}
|
2019-09-26 17:34:50 +01:00
|
|
|
kind => kind,
|
2016-07-02 09:01:21 +00:00
|
|
|
};
|
2020-11-17 14:27:44 -05:00
|
|
|
|
2016-07-02 09:01:21 +00:00
|
|
|
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
|
|
|
}
|
2018-03-15 23:20:56 -07:00
|
|
|
|
|
|
|
pub fn is_expr(&self) -> bool {
|
2020-12-24 02:55:21 +01:00
|
|
|
matches!(self.kind, StmtKind::Expr(_))
|
2018-03-15 23:20:56 -07:00
|
|
|
}
|
2016-07-02 09:01:21 +00:00
|
|
|
}
|
|
|
|
|
2023-10-20 09:55:29 +11:00
|
|
|
// Adding a new variant? Please update `test_stmt` in `tests/ui/macros/stringify.rs`.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2016-02-08 17:23:13 +01:00
|
|
|
pub enum StmtKind {
|
2016-06-23 01:04:08 +00:00
|
|
|
/// A local (let) binding.
|
2024-03-14 11:25:05 +01:00
|
|
|
Let(P<Local>),
|
2016-06-23 01:04:08 +00:00
|
|
|
/// An item definition.
|
2016-06-17 02:27:16 +00:00
|
|
|
Item(P<Item>),
|
2016-06-26 02:19:34 +00:00
|
|
|
/// Expr without trailing semi-colon.
|
2016-06-17 02:27:16 +00:00
|
|
|
Expr(P<Expr>),
|
2017-09-03 12:27:31 -07:00
|
|
|
/// Expr with a trailing semi-colon.
|
2016-06-17 02:27:16 +00:00
|
|
|
Semi(P<Expr>),
|
2020-02-27 04:10:42 +01:00
|
|
|
/// Just a trailing semi-colon.
|
|
|
|
Empty,
|
2017-09-05 18:46:21 -07:00
|
|
|
/// Macro.
|
2020-08-30 18:38:32 -04:00
|
|
|
MacCall(P<MacCallStmt>),
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
|
|
|
pub struct MacCallStmt {
|
2022-08-12 12:20:10 +10:00
|
|
|
pub mac: P<MacCall>,
|
2020-08-30 18:38:32 -04:00
|
|
|
pub style: MacStmtStyle,
|
|
|
|
pub attrs: AttrVec,
|
2022-09-09 17:15:53 +10:00
|
|
|
pub tokens: Option<LazyAttrTokenStream>,
|
2015-11-03 17:39:51 +01:00
|
|
|
}
|
|
|
|
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug)]
|
2014-11-14 09:18:10 -08:00
|
|
|
pub enum MacStmtStyle {
|
2018-11-27 02:59:49 +00:00
|
|
|
/// The macro statement had a trailing semicolon (e.g., `foo! { ... };`
|
|
|
|
/// `foo!(...);`, `foo![...];`).
|
2016-02-09 11:56:59 +01:00
|
|
|
Semicolon,
|
2018-11-27 02:59:49 +00:00
|
|
|
/// The macro statement had braces (e.g., `foo! { ... }`).
|
2016-02-09 11:56:59 +01:00
|
|
|
Braces,
|
2018-11-27 02:59:49 +00:00
|
|
|
/// The macro statement had parentheses or brackets and no semicolon (e.g.,
|
|
|
|
/// `foo!(...)`). All of these will end up being converted into macro
|
2014-11-14 09:18:10 -08:00
|
|
|
/// expressions.
|
2016-02-09 11:56:59 +01:00
|
|
|
NoBraces,
|
2010-09-09 15:59:29 -07:00
|
|
|
}
|
|
|
|
|
2018-11-27 02:59:49 +00:00
|
|
|
/// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2013-07-19 07:38:55 +02:00
|
|
|
pub struct Local {
|
2019-09-06 03:56:45 +01:00
|
|
|
pub id: NodeId,
|
2014-05-18 01:13:20 +03:00
|
|
|
pub pat: P<Pat>,
|
2015-01-02 20:55:31 +09:00
|
|
|
pub ty: Option<P<Ty>>,
|
2021-06-22 13:00:58 -05:00
|
|
|
pub kind: LocalKind,
|
2014-03-27 15:39:48 -07:00
|
|
|
pub span: Span,
|
Detect more cases of `=` to `:` typo
When a `Local` is fully parsed, but not followed by a `;`, keep the `:` span
arround and mention it. If the type could continue being parsed as an
expression, suggest replacing the `:` with a `=`.
```
error: expected one of `!`, `+`, `->`, `::`, `;`, or `=`, found `.`
--> file.rs:2:32
|
2 | let _: std::env::temp_dir().join("foo");
| - ^ expected one of `!`, `+`, `->`, `::`, `;`, or `=`
| |
| while parsing the type for `_`
| help: use `=` if you meant to assign
```
Fix #119665.
2024-02-27 00:48:32 +00:00
|
|
|
pub colon_sp: Option<Span>,
|
2019-12-03 16:38:34 +01:00
|
|
|
pub attrs: AttrVec,
|
2022-09-09 17:15:53 +10:00
|
|
|
pub tokens: Option<LazyAttrTokenStream>,
|
2015-11-03 17:39:51 +01:00
|
|
|
}
|
|
|
|
|
2021-06-22 13:00:58 -05:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
|
|
|
pub enum LocalKind {
|
|
|
|
/// Local declaration.
|
|
|
|
/// Example: `let x;`
|
|
|
|
Decl,
|
|
|
|
/// Local declaration with an initializer.
|
|
|
|
/// Example: `let x = y;`
|
|
|
|
Init(P<Expr>),
|
|
|
|
/// Local declaration with an initializer and an `else` clause.
|
|
|
|
/// Example: `let Some(x) = y else { return };`
|
|
|
|
InitElse(P<Expr>, P<Block>),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl LocalKind {
|
|
|
|
pub fn init(&self) -> Option<&Expr> {
|
|
|
|
match self {
|
|
|
|
Self::Decl => None,
|
|
|
|
Self::Init(i) | Self::InitElse(i, _) => Some(i),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn init_else_opt(&self) -> Option<(&Expr, Option<&Block>)> {
|
|
|
|
match self {
|
|
|
|
Self::Decl => None,
|
|
|
|
Self::Init(init) => Some((init, None)),
|
|
|
|
Self::InitElse(init, els) => Some((init, Some(els))),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-24 13:14:34 +02:00
|
|
|
/// An arm of a 'match'.
|
|
|
|
///
|
2018-11-27 02:59:49 +00:00
|
|
|
/// E.g., `0..=10 => { println!("match!") }` as in
|
2016-06-24 13:14:34 +02:00
|
|
|
///
|
2017-06-20 15:15:16 +08:00
|
|
|
/// ```
|
|
|
|
/// match 123 {
|
2018-05-28 19:42:11 -07:00
|
|
|
/// 0..=10 => { println!("match!") },
|
2017-06-20 15:15:16 +08:00
|
|
|
/// _ => { println!("no match!") },
|
2016-06-24 13:14:34 +02:00
|
|
|
/// }
|
|
|
|
/// ```
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2013-09-02 03:45:37 +02:00
|
|
|
pub struct Arm {
|
2021-06-17 07:11:13 +09:00
|
|
|
pub attrs: AttrVec,
|
2024-07-05 18:10:05 +03:00
|
|
|
/// Match arm pattern, e.g. `10` in `match foo { 10 => {}, _ => {} }`.
|
2019-08-28 00:57:15 +02:00
|
|
|
pub pat: P<Pat>,
|
2024-07-05 18:10:05 +03:00
|
|
|
/// 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>>,
|
2023-11-27 03:15:56 +01:00
|
|
|
/// Match arm body. Omitted if the pattern is a never pattern.
|
|
|
|
pub body: Option<P<Expr>>,
|
2019-03-30 22:54:29 +00:00
|
|
|
pub span: Span,
|
2019-08-13 22:22:51 -03:00
|
|
|
pub id: NodeId,
|
2019-09-09 09:26:25 -03:00
|
|
|
pub is_placeholder: bool,
|
2013-01-14 20:52:28 -08:00
|
|
|
}
|
2010-11-24 15:45:59 -08:00
|
|
|
|
2021-03-16 00:36:07 +03:00
|
|
|
/// A single field in a struct expression, e.g. `x: value` and `y` in `Foo { x: value, y }`.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2021-03-16 00:36:07 +03:00
|
|
|
pub struct ExprField {
|
2019-12-03 16:38:34 +01:00
|
|
|
pub attrs: AttrVec,
|
2019-11-07 11:26:36 +01:00
|
|
|
pub id: NodeId,
|
|
|
|
pub span: Span,
|
2018-03-18 16:47:09 +03:00
|
|
|
pub ident: Ident,
|
2014-05-18 01:13:20 +03:00
|
|
|
pub expr: P<Expr>,
|
2016-10-27 03:15:13 +03:00
|
|
|
pub is_shorthand: bool,
|
2019-09-09 09:26:25 -03:00
|
|
|
pub is_placeholder: bool,
|
2013-01-14 21:36:27 -08:00
|
|
|
}
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy)]
|
2013-07-27 10:25:59 +02:00
|
|
|
pub enum BlockCheckMode {
|
2016-02-08 12:44:45 +01:00
|
|
|
Default,
|
|
|
|
Unsafe(UnsafeSource),
|
2013-09-05 20:50:10 -07:00
|
|
|
}
|
|
|
|
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy)]
|
2013-09-05 20:50:10 -07:00
|
|
|
pub enum UnsafeSource {
|
|
|
|
CompilerGenerated,
|
|
|
|
UserProvided,
|
2013-07-02 12:47:32 -07:00
|
|
|
}
|
2011-10-06 16:42:27 -07:00
|
|
|
|
2018-05-17 21:28:50 +03:00
|
|
|
/// A constant (expression) that's not an item or associated item,
|
|
|
|
/// but needs its own `DefId` for type-checking, const-eval, etc.
|
2018-11-27 02:59:49 +00:00
|
|
|
/// These are usually found nested inside types (e.g., array lengths)
|
|
|
|
/// or expressions (e.g., repeat counts), and also used to define
|
2018-05-17 21:28:50 +03:00
|
|
|
/// explicit discriminant values for enum variants.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2018-05-17 21:28:50 +03:00
|
|
|
pub struct AnonConst {
|
|
|
|
pub id: NodeId,
|
|
|
|
pub value: P<Expr>,
|
|
|
|
}
|
|
|
|
|
2019-09-06 03:56:45 +01:00
|
|
|
/// An expression.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2013-09-02 03:45:37 +02:00
|
|
|
pub struct Expr {
|
2014-03-27 15:39:48 -07:00
|
|
|
pub id: NodeId,
|
2019-09-26 14:39:48 +01:00
|
|
|
pub kind: ExprKind,
|
2014-03-27 15:39:48 -07:00
|
|
|
pub span: Span,
|
2019-12-03 16:38:34 +01:00
|
|
|
pub attrs: AttrVec,
|
2022-09-09 17:15:53 +10:00
|
|
|
pub tokens: Option<LazyAttrTokenStream>,
|
2015-11-03 17:39:51 +01:00
|
|
|
}
|
|
|
|
|
2017-08-17 16:51:52 -07:00
|
|
|
impl Expr {
|
2020-07-28 15:55:42 +02:00
|
|
|
/// 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.
|
2023-05-05 21:31:00 +01:00
|
|
|
///
|
|
|
|
/// Does not ensure that the path resolves to a const param, the caller should check this.
|
2024-09-15 21:21:31 +01:00
|
|
|
pub fn is_potential_trivial_const_arg(&self, strip_identity_block: bool) -> bool {
|
|
|
|
let this = if strip_identity_block { self.maybe_unwrap_block().1 } else { self };
|
2020-07-28 15:55:42 +02:00
|
|
|
|
2022-11-16 19:26:38 +00:00
|
|
|
if let ExprKind::Path(None, path) = &this.kind
|
2023-05-05 21:31:00 +01:00
|
|
|
&& path.is_potential_trivial_const_arg()
|
2022-11-16 19:26:38 +00:00
|
|
|
{
|
|
|
|
true
|
|
|
|
} else {
|
|
|
|
false
|
2020-07-28 15:55:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-09-15 21:21:31 +01:00
|
|
|
/// Returns an expression with (when possible) *one* outter brace removed
|
|
|
|
pub fn maybe_unwrap_block(&self) -> (bool, &Expr) {
|
Fix anon const def-creation when macros are involved
Ever since #125915, some `ast::AnonConst`s turn into `hir::ConstArgKind::Path`s,
which don't have associated `DefId`s. To deal with the fact that we don't have
resolution information in `DefCollector`, we decided to implement a process
where if the anon const *appeared* to be trivial (i.e., `N` or `{ N }`), we
would avoid creating a def for it in `DefCollector`. If later, in AST lowering,
we realized it turned out to be a unit struct literal, or we were lowering it
to something that didn't use `hir::ConstArg`, we'd create its def there.
However, let's say we have a macro `m!()` that expands to a reference to a free
constant `FOO`. If we use `m!()` in the body of an anon const (e.g., `Foo<{ m!() }>`),
then in def collection, it appears to be a nontrivial anon const and we create
a def. But the macro expands to something that looks like a trivial const arg,
but is not, so in AST lowering we "fix" the mistake we assumed def collection
made and create a def for it. This causes a duplicate definition ICE.
The ideal long-term fix for this is a bit unclear. One option is to delay def
creation for all expression-like nodes until AST lowering (see #128844 for an
incomplete attempt at this). This would avoid issues like this one that are
caused by hacky workarounds. However, this approach has some downsides as well,
and the best approach is yet to be determined.
In the meantime, this PR fixes the bug by delaying def creation for anon consts
whose bodies are macro invocations until after we expand the macro and know
what is inside it. This is accomplished by adding information to create the
anon const's def to the data in `Resolver.invocation_parents`.
2024-08-15 14:36:10 -07:00
|
|
|
if let ExprKind::Block(block, None) = &self.kind
|
|
|
|
&& let [stmt] = block.stmts.as_slice()
|
|
|
|
&& let StmtKind::Expr(expr) = &stmt.kind
|
|
|
|
{
|
2024-09-15 21:21:31 +01:00
|
|
|
(true, expr)
|
Fix anon const def-creation when macros are involved
Ever since #125915, some `ast::AnonConst`s turn into `hir::ConstArgKind::Path`s,
which don't have associated `DefId`s. To deal with the fact that we don't have
resolution information in `DefCollector`, we decided to implement a process
where if the anon const *appeared* to be trivial (i.e., `N` or `{ N }`), we
would avoid creating a def for it in `DefCollector`. If later, in AST lowering,
we realized it turned out to be a unit struct literal, or we were lowering it
to something that didn't use `hir::ConstArg`, we'd create its def there.
However, let's say we have a macro `m!()` that expands to a reference to a free
constant `FOO`. If we use `m!()` in the body of an anon const (e.g., `Foo<{ m!() }>`),
then in def collection, it appears to be a nontrivial anon const and we create
a def. But the macro expands to something that looks like a trivial const arg,
but is not, so in AST lowering we "fix" the mistake we assumed def collection
made and create a def for it. This causes a duplicate definition ICE.
The ideal long-term fix for this is a bit unclear. One option is to delay def
creation for all expression-like nodes until AST lowering (see #128844 for an
incomplete attempt at this). This would avoid issues like this one that are
caused by hacky workarounds. However, this approach has some downsides as well,
and the best approach is yet to be determined.
In the meantime, this PR fixes the bug by delaying def creation for anon consts
whose bodies are macro invocations until after we expand the macro and know
what is inside it. This is accomplished by adding information to create the
anon const's def to the data in `Resolver.invocation_parents`.
2024-08-15 14:36:10 -07:00
|
|
|
} else {
|
2024-09-15 21:21:31 +01:00
|
|
|
(false, self)
|
Fix anon const def-creation when macros are involved
Ever since #125915, some `ast::AnonConst`s turn into `hir::ConstArgKind::Path`s,
which don't have associated `DefId`s. To deal with the fact that we don't have
resolution information in `DefCollector`, we decided to implement a process
where if the anon const *appeared* to be trivial (i.e., `N` or `{ N }`), we
would avoid creating a def for it in `DefCollector`. If later, in AST lowering,
we realized it turned out to be a unit struct literal, or we were lowering it
to something that didn't use `hir::ConstArg`, we'd create its def there.
However, let's say we have a macro `m!()` that expands to a reference to a free
constant `FOO`. If we use `m!()` in the body of an anon const (e.g., `Foo<{ m!() }>`),
then in def collection, it appears to be a nontrivial anon const and we create
a def. But the macro expands to something that looks like a trivial const arg,
but is not, so in AST lowering we "fix" the mistake we assumed def collection
made and create a def for it. This causes a duplicate definition ICE.
The ideal long-term fix for this is a bit unclear. One option is to delay def
creation for all expression-like nodes until AST lowering (see #128844 for an
incomplete attempt at this). This would avoid issues like this one that are
caused by hacky workarounds. However, this approach has some downsides as well,
and the best approach is yet to be determined.
In the meantime, this PR fixes the bug by delaying def creation for anon consts
whose bodies are macro invocations until after we expand the macro and know
what is inside it. This is accomplished by adding information to create the
anon const's def to the data in `Resolver.invocation_parents`.
2024-08-15 14:36:10 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-15 22:48:13 +02:00
|
|
|
pub fn to_bound(&self) -> Option<GenericBound> {
|
2019-09-26 14:39:48 +01:00
|
|
|
match &self.kind {
|
2018-09-22 16:19:44 -07:00
|
|
|
ExprKind::Path(None, path) => Some(GenericBound::Trait(
|
2022-11-22 09:17:20 +11:00
|
|
|
PolyTraitRef::new(ThinVec::new(), path.clone(), self.span),
|
2023-12-20 15:22:06 +01:00
|
|
|
TraitBoundModifiers::NONE,
|
2018-09-22 16:19:44 -07:00
|
|
|
)),
|
2017-12-17 01:53:11 +03:00
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-06 18:29:41 -08:00
|
|
|
pub fn peel_parens(&self) -> &Expr {
|
|
|
|
let mut expr = self;
|
|
|
|
while let ExprKind::Paren(inner) = &expr.kind {
|
2022-11-29 11:01:17 +00:00
|
|
|
expr = inner;
|
2021-03-06 18:29:41 -08:00
|
|
|
}
|
|
|
|
expr
|
|
|
|
}
|
|
|
|
|
2023-01-13 18:00:56 +01:00
|
|
|
pub fn peel_parens_and_refs(&self) -> &Expr {
|
|
|
|
let mut expr = self;
|
|
|
|
while let ExprKind::Paren(inner) | ExprKind::AddrOf(BorrowKind::Ref, _, inner) = &expr.kind
|
|
|
|
{
|
|
|
|
expr = inner;
|
|
|
|
}
|
|
|
|
expr
|
|
|
|
}
|
|
|
|
|
2019-10-24 16:11:43 +03:00
|
|
|
/// Attempts to reparse as `Ty` (for diagnostic purposes).
|
2019-10-15 22:48:13 +02:00
|
|
|
pub fn to_ty(&self) -> Option<P<Ty>> {
|
2019-09-26 14:39:48 +01:00
|
|
|
let kind = match &self.kind {
|
2019-10-24 16:11:43 +03:00
|
|
|
// Trivial conversions.
|
2017-12-17 01:53:11 +03:00
|
|
|
ExprKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
|
2020-02-29 19:32:20 +03:00
|
|
|
ExprKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
|
2019-10-24 16:11:43 +03:00
|
|
|
|
2017-12-17 01:53:11 +03:00
|
|
|
ExprKind::Paren(expr) => expr.to_ty().map(TyKind::Paren)?,
|
2019-10-24 16:11:43 +03:00
|
|
|
|
2019-11-23 14:15:49 +00:00
|
|
|
ExprKind::AddrOf(BorrowKind::Ref, mutbl, expr) => {
|
2022-12-28 18:06:11 +01:00
|
|
|
expr.to_ty().map(|ty| TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }))?
|
2019-12-22 17:42:04 -05:00
|
|
|
}
|
2019-10-24 16:11:43 +03:00
|
|
|
|
2018-09-22 16:19:44 -07:00
|
|
|
ExprKind::Repeat(expr, expr_len) => {
|
|
|
|
expr.to_ty().map(|ty| TyKind::Array(ty, expr_len.clone()))?
|
|
|
|
}
|
2019-10-24 16:11:43 +03:00
|
|
|
|
2024-08-07 12:41:49 +02:00
|
|
|
ExprKind::Array(exprs) if let [expr] = exprs.as_slice() => {
|
|
|
|
expr.to_ty().map(TyKind::Slice)?
|
|
|
|
}
|
2019-10-24 16:11:43 +03:00
|
|
|
|
2017-12-17 01:53:11 +03:00
|
|
|
ExprKind::Tup(exprs) => {
|
2022-11-23 11:55:16 +11:00
|
|
|
let tys = exprs.iter().map(|expr| expr.to_ty()).collect::<Option<ThinVec<_>>>()?;
|
2017-12-17 01:53:11 +03:00
|
|
|
TyKind::Tup(tys)
|
|
|
|
}
|
2019-10-24 16:11:43 +03:00
|
|
|
|
|
|
|
// 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-22 16:19:44 -07:00
|
|
|
ExprKind::Binary(binop, lhs, rhs) if binop.node == BinOpKind::Add => {
|
2017-12-17 01:53:11 +03:00
|
|
|
if let (Some(lhs), Some(rhs)) = (lhs.to_bound(), rhs.to_bound()) {
|
|
|
|
TyKind::TraitObject(vec![lhs, rhs], TraitObjectSyntax::None)
|
|
|
|
} else {
|
|
|
|
return None;
|
|
|
|
}
|
2018-09-22 16:19:44 -07:00
|
|
|
}
|
2019-10-24 16:11:43 +03:00
|
|
|
|
2021-10-01 23:03:28 +02:00
|
|
|
ExprKind::Underscore => TyKind::Infer,
|
|
|
|
|
2019-10-24 16:11:43 +03:00
|
|
|
// This expression doesn't look like a type syntactically.
|
2017-12-17 01:53:11 +03:00
|
|
|
_ => return None,
|
|
|
|
};
|
|
|
|
|
2020-08-21 18:18:04 -04:00
|
|
|
Some(P(Ty { kind, id: self.id, span: self.span, tokens: None }))
|
2017-12-17 01:53:11 +03:00
|
|
|
}
|
2018-01-10 11:40:16 -08:00
|
|
|
|
|
|
|
pub fn precedence(&self) -> ExprPrecedence {
|
2019-09-26 14:39:48 +01:00
|
|
|
match self.kind {
|
2018-01-10 11:40:16 -08:00
|
|
|
ExprKind::Array(_) => ExprPrecedence::Array,
|
2020-09-21 17:55:58 -03:00
|
|
|
ExprKind::ConstBlock(_) => ExprPrecedence::ConstBlock,
|
2018-01-10 11:40:16 -08:00
|
|
|
ExprKind::Call(..) => ExprPrecedence::Call,
|
|
|
|
ExprKind::MethodCall(..) => ExprPrecedence::MethodCall,
|
|
|
|
ExprKind::Tup(_) => ExprPrecedence::Tup,
|
|
|
|
ExprKind::Binary(op, ..) => ExprPrecedence::Binary(op.node),
|
|
|
|
ExprKind::Unary(..) => ExprPrecedence::Unary,
|
2022-10-31 18:30:09 +00:00
|
|
|
ExprKind::Lit(_) | ExprKind::IncludedBytes(..) => ExprPrecedence::Lit,
|
2024-09-13 12:53:25 -04:00
|
|
|
ExprKind::Cast(..) => ExprPrecedence::Cast,
|
2019-05-15 16:04:12 +02:00
|
|
|
ExprKind::Let(..) => ExprPrecedence::Let,
|
2018-01-10 11:40:16 -08:00
|
|
|
ExprKind::If(..) => ExprPrecedence::If,
|
|
|
|
ExprKind::While(..) => ExprPrecedence::While,
|
2023-12-08 14:51:50 -08:00
|
|
|
ExprKind::ForLoop { .. } => ExprPrecedence::ForLoop,
|
2018-01-10 11:40:16 -08:00
|
|
|
ExprKind::Loop(..) => ExprPrecedence::Loop,
|
2024-04-02 19:30:32 -04:00
|
|
|
ExprKind::Match(_, _, MatchKind::Prefix) => ExprPrecedence::Match,
|
|
|
|
ExprKind::Match(_, _, MatchKind::Postfix) => ExprPrecedence::PostfixMatch,
|
2018-01-10 11:40:16 -08:00
|
|
|
ExprKind::Closure(..) => ExprPrecedence::Closure,
|
|
|
|
ExprKind::Block(..) => ExprPrecedence::Block,
|
2018-07-21 18:47:02 -07:00
|
|
|
ExprKind::TryBlock(..) => ExprPrecedence::TryBlock,
|
2023-10-20 21:26:57 +00:00
|
|
|
ExprKind::Gen(..) => ExprPrecedence::Gen,
|
2019-04-18 12:55:23 -07:00
|
|
|
ExprKind::Await(..) => ExprPrecedence::Await,
|
2018-01-10 11:40:16 -08:00
|
|
|
ExprKind::Assign(..) => ExprPrecedence::Assign,
|
|
|
|
ExprKind::AssignOp(..) => ExprPrecedence::AssignOp,
|
|
|
|
ExprKind::Field(..) => ExprPrecedence::Field,
|
|
|
|
ExprKind::Index(..) => ExprPrecedence::Index,
|
|
|
|
ExprKind::Range(..) => ExprPrecedence::Range,
|
2020-11-11 13:15:15 +00:00
|
|
|
ExprKind::Underscore => ExprPrecedence::Path,
|
2018-01-10 11:40:16 -08:00
|
|
|
ExprKind::Path(..) => ExprPrecedence::Path,
|
|
|
|
ExprKind::AddrOf(..) => ExprPrecedence::AddrOf,
|
|
|
|
ExprKind::Break(..) => ExprPrecedence::Break,
|
|
|
|
ExprKind::Continue(..) => ExprPrecedence::Continue,
|
|
|
|
ExprKind::Ret(..) => ExprPrecedence::Ret,
|
|
|
|
ExprKind::Struct(..) => ExprPrecedence::Struct,
|
|
|
|
ExprKind::Repeat(..) => ExprPrecedence::Repeat,
|
|
|
|
ExprKind::Paren(..) => ExprPrecedence::Paren,
|
|
|
|
ExprKind::Try(..) => ExprPrecedence::Try,
|
|
|
|
ExprKind::Yield(..) => ExprPrecedence::Yield,
|
2022-03-25 23:43:54 -07:00
|
|
|
ExprKind::Yeet(..) => ExprPrecedence::Yeet,
|
2022-11-16 18:36:17 +00:00
|
|
|
ExprKind::Become(..) => ExprPrecedence::Become,
|
2024-09-13 12:53:25 -04:00
|
|
|
ExprKind::InlineAsm(..)
|
|
|
|
| ExprKind::Type(..)
|
|
|
|
| ExprKind::OffsetOf(..)
|
|
|
|
| ExprKind::FormatArgs(..)
|
|
|
|
| ExprKind::MacCall(..) => ExprPrecedence::Mac,
|
2024-02-25 22:22:11 +01:00
|
|
|
ExprKind::Err(_) | ExprKind::Dummy => ExprPrecedence::Err,
|
2018-01-10 11:40:16 -08:00
|
|
|
}
|
|
|
|
}
|
2021-11-28 10:46:06 -08:00
|
|
|
|
2022-11-27 11:15:06 +00:00
|
|
|
/// To a first-order approximation, is this a pattern?
|
2022-06-07 20:53:02 -07:00
|
|
|
pub fn is_approximately_pattern(&self) -> bool {
|
2023-04-15 20:49:54 +02:00
|
|
|
matches!(
|
|
|
|
&self.peel_parens().kind,
|
2023-02-27 13:17:29 +00:00
|
|
|
ExprKind::Array(_)
|
2023-04-15 20:49:54 +02:00
|
|
|
| ExprKind::Call(_, _)
|
|
|
|
| ExprKind::Tup(_)
|
|
|
|
| ExprKind::Lit(_)
|
|
|
|
| ExprKind::Range(_, _, _)
|
|
|
|
| ExprKind::Underscore
|
|
|
|
| ExprKind::Path(_, _)
|
|
|
|
| ExprKind::Struct(_)
|
|
|
|
)
|
2022-06-07 20:53:02 -07:00
|
|
|
}
|
2017-08-17 16:51:52 -07:00
|
|
|
}
|
|
|
|
|
2022-09-08 10:52:51 +10:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
|
|
|
pub struct Closure {
|
|
|
|
pub binder: ClosureBinder,
|
|
|
|
pub capture_clause: CaptureBy,
|
2022-12-20 16:15:55 +00:00
|
|
|
pub constness: Const,
|
2023-12-05 21:39:36 +00:00
|
|
|
pub coroutine_kind: Option<CoroutineKind>,
|
2022-09-08 10:52:51 +10:00
|
|
|
pub movability: Movability,
|
|
|
|
pub fn_decl: P<FnDecl>,
|
|
|
|
pub body: P<Expr>,
|
2022-11-09 20:39:28 +05:30
|
|
|
/// The span of the declaration block: 'move |...| -> ...'
|
2022-09-08 10:52:51 +10:00
|
|
|
pub fn_decl_span: Span,
|
2022-11-09 20:39:28 +05:30
|
|
|
/// The span of the argument block `|...|`
|
|
|
|
pub fn_arg_span: Span,
|
2022-09-08 10:52:51 +10:00
|
|
|
}
|
|
|
|
|
2024-07-05 18:10:05 +03:00
|
|
|
/// Limit types of a range (inclusive or exclusive).
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug)]
|
2016-01-13 01:23:31 -05:00
|
|
|
pub enum RangeLimits {
|
2024-07-05 18:10:05 +03:00
|
|
|
/// Inclusive at the beginning, exclusive at the end.
|
2016-01-13 01:23:31 -05:00
|
|
|
HalfOpen,
|
2024-07-05 18:10:05 +03:00
|
|
|
/// Inclusive at the beginning and end.
|
2016-01-13 01:23:31 -05:00
|
|
|
Closed,
|
|
|
|
}
|
|
|
|
|
2022-09-08 10:52:51 +10:00
|
|
|
/// A method call (e.g. `x.foo::<Bar, Baz>(a, b, c)`).
|
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
|
|
|
pub struct MethodCall {
|
|
|
|
/// The method name and its generic arguments, e.g. `foo::<Bar, Baz>`.
|
|
|
|
pub seg: PathSegment,
|
|
|
|
/// The receiver, e.g. `x`.
|
|
|
|
pub receiver: P<Expr>,
|
|
|
|
/// The arguments, e.g. `a, b, c`.
|
2022-11-23 11:55:16 +11:00
|
|
|
pub args: ThinVec<P<Expr>>,
|
2022-09-08 10:52:51 +10:00
|
|
|
/// The span of the function, without the dot and receiver e.g. `foo::<Bar,
|
|
|
|
/// Baz>(a, b, c)`.
|
|
|
|
pub span: Span,
|
|
|
|
}
|
|
|
|
|
2020-11-07 14:28:55 +00:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
|
|
|
pub enum StructRest {
|
|
|
|
/// `..x`.
|
|
|
|
Base(P<Expr>),
|
|
|
|
/// `..`.
|
|
|
|
Rest(Span),
|
|
|
|
/// No trailing `..` or expression.
|
|
|
|
None,
|
|
|
|
}
|
|
|
|
|
2021-03-16 03:15:53 +03:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
|
|
|
pub struct StructExpr {
|
2022-09-08 10:52:51 +10:00
|
|
|
pub qself: Option<P<QSelf>>,
|
2021-03-16 03:15:53 +03:00
|
|
|
pub path: Path,
|
2023-01-30 15:39:22 +11:00
|
|
|
pub fields: ThinVec<ExprField>,
|
2021-03-16 03:15:53 +03:00
|
|
|
pub rest: StructRest,
|
|
|
|
}
|
|
|
|
|
2023-10-20 09:55:29 +11:00
|
|
|
// Adding a new variant? Please update `test_expr` in `tests/ui/macros/stringify.rs`.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2016-02-08 16:05:05 +01:00
|
|
|
pub enum ExprKind {
|
2024-05-03 01:10:22 +02:00
|
|
|
/// An array (e.g, `[a, b, c, d]`).
|
2022-11-23 11:55:16 +11:00
|
|
|
Array(ThinVec<P<Expr>>),
|
2024-07-05 18:10:05 +03:00
|
|
|
/// Allow anonymous constants from an inline `const` block.
|
2024-06-03 09:11:58 +00:00
|
|
|
ConstBlock(AnonConst),
|
2024-07-05 18:10:05 +03:00
|
|
|
/// A function call.
|
2015-03-19 00:56:37 +05:30
|
|
|
///
|
2015-03-17 17:42:20 +05:30
|
|
|
/// The first field resolves to the function itself,
|
2017-10-27 16:27:59 -02:00
|
|
|
/// 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.
|
2022-11-23 11:55:16 +11:00
|
|
|
Call(P<Expr>, ThinVec<P<Expr>>),
|
2024-05-03 01:10:22 +02:00
|
|
|
/// A method call (e.g., `x.foo::<Bar, Baz>(a, b, c)`).
|
2022-09-08 10:52:51 +10:00
|
|
|
MethodCall(Box<MethodCall>),
|
2018-11-27 02:59:49 +00:00
|
|
|
/// A tuple (e.g., `(a, b, c, d)`).
|
2022-11-23 11:55:16 +11:00
|
|
|
Tup(ThinVec<P<Expr>>),
|
2018-11-27 02:59:49 +00:00
|
|
|
/// A binary operation (e.g., `a + b`, `a * b`).
|
2016-02-08 16:05:05 +01:00
|
|
|
Binary(BinOp, P<Expr>, P<Expr>),
|
2018-11-27 02:59:49 +00:00
|
|
|
/// A unary operation (e.g., `!x`, `*x`).
|
2016-02-08 16:05:05 +01:00
|
|
|
Unary(UnOp, P<Expr>),
|
2018-11-27 02:59:49 +00:00
|
|
|
/// A literal (e.g., `1`, `"foo"`).
|
2022-10-10 13:40:56 +11:00
|
|
|
Lit(token::Lit),
|
2018-11-27 02:59:49 +00:00
|
|
|
/// A cast (e.g., `foo as f64`).
|
2016-02-08 16:05:05 +01:00
|
|
|
Cast(P<Expr>, P<Ty>),
|
2024-05-03 01:10:22 +02:00
|
|
|
/// A type ascription (e.g., `builtin # type_ascribe(42, usize)`).
|
|
|
|
///
|
|
|
|
/// Usually not written directly in user code but
|
|
|
|
/// indirectly via the macro `type_ascribe!(...)`.
|
2016-02-08 16:05:05 +01:00
|
|
|
Type(P<Expr>, P<Ty>),
|
2019-08-28 00:57:15 +02:00
|
|
|
/// A `let pat = expr` expression that is only semantically allowed in the condition
|
2019-05-15 16:04:12 +02:00
|
|
|
/// of `if` / `while` expressions. (e.g., `if let 0 = x { .. }`).
|
2021-08-08 11:49:13 -03:00
|
|
|
///
|
|
|
|
/// `Span` represents the whole `let pat = expr` statement.
|
2024-05-09 18:44:40 +10:00
|
|
|
Let(P<Pat>, P<Expr>, Span, Recovered),
|
2018-11-27 02:59:49 +00:00
|
|
|
/// An `if` block, with an optional `else` block.
|
2015-03-19 00:56:37 +05:30
|
|
|
///
|
2015-03-17 03:41:23 +05:30
|
|
|
/// `if expr { block } else { expr }`
|
2016-02-08 16:05:05 +01:00
|
|
|
If(P<Expr>, P<Block>, Option<P<Expr>>),
|
2019-05-15 16:04:12 +02:00
|
|
|
/// A while loop, with an optional label.
|
2015-03-19 00:56:37 +05:30
|
|
|
///
|
2015-03-18 18:06:10 +05:30
|
|
|
/// `'label: while expr { block }`
|
2018-01-16 01:44:32 +03:00
|
|
|
While(P<Expr>, P<Block>, Option<Label>),
|
2018-11-27 02:59:49 +00:00
|
|
|
/// A `for` loop, with an optional label.
|
2015-03-19 00:56:37 +05:30
|
|
|
///
|
2023-12-08 14:51:50 -08:00
|
|
|
/// `'label: for await? pat in iter { block }`
|
2015-03-19 00:56:37 +05:30
|
|
|
///
|
|
|
|
/// This is desugared to a combination of `loop` and `match` expressions.
|
2023-12-08 14:51:50 -08:00
|
|
|
ForLoop { pat: P<Pat>, iter: P<Expr>, body: P<Block>, label: Option<Label>, kind: ForLoopKind },
|
2018-11-27 02:59:49 +00:00
|
|
|
/// Conditionless loop (can be exited with `break`, `continue`, or `return`).
|
2015-03-19 00:56:37 +05:30
|
|
|
///
|
2015-03-18 18:06:10 +05:30
|
|
|
/// `'label: loop { block }`
|
2022-11-02 21:22:24 -07:00
|
|
|
Loop(P<Block>, Option<Label>, Span),
|
2015-09-30 17:18:09 +13:00
|
|
|
/// A `match` block.
|
2024-02-17 12:43:54 -05:00
|
|
|
Match(P<Expr>, ThinVec<Arm>, MatchKind),
|
2018-11-27 02:59:49 +00:00
|
|
|
/// A closure (e.g., `move |a, b, c| a + b + c`).
|
2022-09-08 10:52:51 +10:00
|
|
|
Closure(Box<Closure>),
|
2018-11-27 02:59:49 +00:00
|
|
|
/// A block (`'label: { ... }`).
|
2018-04-16 05:44:39 +02:00
|
|
|
Block(P<Block>, Option<Label>),
|
2023-10-20 21:26:57 +00:00
|
|
|
/// An `async` block (`async move { ... }`),
|
2024-07-05 18:10:05 +03:00
|
|
|
/// or a `gen` block (`gen move { ... }`).
|
2024-06-27 14:56:57 -04:00
|
|
|
///
|
|
|
|
/// The span is the "decl", which is the header before the body `{ }`
|
|
|
|
/// including the `asyng`/`gen` keywords and possibly `move`.
|
|
|
|
Gen(CaptureBy, P<Block>, GenBlockKind, Span),
|
2023-04-25 18:59:16 +00:00
|
|
|
/// An await expression (`my_future.await`). Span is of await keyword.
|
|
|
|
Await(P<Expr>, Span),
|
2019-04-18 12:55:23 -07:00
|
|
|
|
2018-11-27 02:59:49 +00:00
|
|
|
/// A try block (`try { ... }`).
|
2018-07-21 18:47:02 -07:00
|
|
|
TryBlock(P<Block>),
|
2013-09-02 03:45:37 +02:00
|
|
|
|
2018-11-27 02:59:49 +00:00
|
|
|
/// An assignment (`a = foo()`).
|
2019-12-22 23:09:54 +00:00
|
|
|
/// The `Span` argument is the span of the `=` token.
|
2019-12-22 21:08:53 +00:00
|
|
|
Assign(P<Expr>, P<Expr>, Span),
|
2018-11-27 02:59:49 +00:00
|
|
|
/// An assignment with an operator.
|
2015-03-19 00:56:37 +05:30
|
|
|
///
|
2018-11-27 02:59:49 +00:00
|
|
|
/// E.g., `a += 1`.
|
2016-02-08 16:05:05 +01:00
|
|
|
AssignOp(BinOp, P<Expr>, P<Expr>),
|
2018-11-27 02:59:49 +00:00
|
|
|
/// Access of a named (e.g., `obj.foo`) or unnamed (e.g., `obj.0`) struct field.
|
2018-03-18 16:47:09 +03:00
|
|
|
Field(P<Expr>, Ident),
|
2018-11-27 02:59:49 +00:00
|
|
|
/// An indexing operation (e.g., `foo[2]`).
|
2023-08-03 21:43:17 +02:00
|
|
|
/// The span represents the span of the `[2]`, including brackets.
|
|
|
|
Index(P<Expr>, P<Expr>, Span),
|
2021-04-19 15:57:08 +03:00
|
|
|
/// A range (e.g., `1..2`, `1..`, `..2`, `1..=2`, `..=2`; and `..` in destructuring assignment).
|
2016-01-13 01:23:31 -05:00
|
|
|
Range(Option<P<Expr>>, Option<P<Expr>>, RangeLimits),
|
2020-11-11 13:15:15 +00:00
|
|
|
/// An underscore, used in destructuring assignment to ignore a value.
|
|
|
|
Underscore,
|
2013-11-24 18:38:41 -05:00
|
|
|
|
2015-02-17 19:29:13 +02:00
|
|
|
/// Variable reference, possibly containing `::` and/or type
|
2018-11-27 02:59:49 +00:00
|
|
|
/// parameters (e.g., `foo::bar::<baz>`).
|
2015-03-19 00:56:37 +05:30
|
|
|
///
|
2018-11-27 02:59:49 +00:00
|
|
|
/// Optionally "qualified" (e.g., `<Vec<T> as SomeTrait>::SomeType`).
|
2022-09-08 10:52:51 +10:00
|
|
|
Path(Option<P<QSelf>>, Path),
|
2013-05-10 15:15:06 -07:00
|
|
|
|
2019-11-23 14:15:49 +00:00
|
|
|
/// A referencing operation (`&a`, `&mut a`, `&raw const a` or `&raw mut a`).
|
|
|
|
AddrOf(BorrowKind, Mutability, P<Expr>),
|
2018-11-27 02:59:49 +00:00
|
|
|
/// A `break`, with an optional label to break, and an optional expression.
|
2018-01-16 01:44:32 +03:00
|
|
|
Break(Option<Label>, Option<P<Expr>>),
|
2018-11-27 02:59:49 +00:00
|
|
|
/// A `continue`, with an optional label.
|
2018-01-16 01:44:32 +03:00
|
|
|
Continue(Option<Label>),
|
2018-11-27 02:59:49 +00:00
|
|
|
/// A `return`, with an optional value to be returned.
|
2016-02-08 16:05:05 +01:00
|
|
|
Ret(Option<P<Expr>>),
|
2013-08-27 23:12:05 -07:00
|
|
|
|
2020-01-22 14:20:27 +00:00
|
|
|
/// Output of the `asm!()` macro.
|
2020-05-26 20:07:59 +01:00
|
|
|
InlineAsm(P<InlineAsm>),
|
2011-08-19 15:16:48 -07:00
|
|
|
|
2024-05-03 01:10:22 +02:00
|
|
|
/// An `offset_of` expression (e.g., `builtin # offset_of(Struct, field)`).
|
|
|
|
///
|
|
|
|
/// Usually not written directly in user code but
|
|
|
|
/// indirectly via the macro `core::mem::offset_of!(...)`.
|
2023-04-16 14:21:11 -07:00
|
|
|
OffsetOf(P<Ty>, P<[Ident]>),
|
2022-09-11 00:37:49 -07:00
|
|
|
|
2018-11-27 02:59:49 +00:00
|
|
|
/// A macro invocation; pre-expansion.
|
2022-08-12 12:20:10 +10:00
|
|
|
MacCall(P<MacCall>),
|
2012-07-23 16:39:18 -07:00
|
|
|
|
2014-06-09 13:12:30 -07:00
|
|
|
/// A struct literal expression.
|
2015-03-19 00:56:37 +05:30
|
|
|
///
|
2020-11-07 14:28:55 +00:00
|
|
|
/// E.g., `Foo {x: 1, y: 2}`, or `Foo {x: 1, .. rest}`.
|
2021-03-16 03:15:53 +03:00
|
|
|
Struct(P<StructExpr>),
|
2012-08-03 18:01:30 -07:00
|
|
|
|
2015-08-11 17:35:22 +02:00
|
|
|
/// An array literal constructed from one repeated element.
|
2015-03-19 00:56:37 +05:30
|
|
|
///
|
2018-11-27 02:59:49 +00:00
|
|
|
/// E.g., `[1; 5]`. The expression is the element to be
|
2018-05-17 21:28:50 +03:00
|
|
|
/// repeated; the constant is the number of times to repeat it.
|
|
|
|
Repeat(P<Expr>, AnonConst),
|
2012-10-27 17:14:09 -07:00
|
|
|
|
2018-11-27 02:59:49 +00:00
|
|
|
/// No-op: used solely so we can pretty-print faithfully.
|
2016-02-08 16:05:05 +01:00
|
|
|
Paren(P<Expr>),
|
2016-02-28 17:38:48 -05:00
|
|
|
|
2018-11-27 02:59:49 +00:00
|
|
|
/// A try expression (`expr?`).
|
2016-02-28 17:38:48 -05:00
|
|
|
Try(P<Expr>),
|
2016-12-26 14:34:03 +01:00
|
|
|
|
2018-11-27 02:59:49 +00:00
|
|
|
/// A `yield`, with an optional value to be yielded.
|
2016-12-26 14:34:03 +01:00
|
|
|
Yield(Option<P<Expr>>),
|
2018-12-17 04:57:32 +03:00
|
|
|
|
2022-03-25 23:43:54 -07:00
|
|
|
/// A `do yeet` (aka `throw`/`fail`/`bail`/`raise`/whatever),
|
|
|
|
/// with an optional value to be returned.
|
|
|
|
Yeet(Option<P<Expr>>),
|
|
|
|
|
2022-11-16 18:36:17 +00:00
|
|
|
/// A tail call return, with the value to be returned.
|
|
|
|
///
|
|
|
|
/// While `.0` must be a function call, we check this later, after parsing.
|
|
|
|
Become(P<Expr>),
|
|
|
|
|
2022-10-31 18:30:09 +00:00
|
|
|
/// Bytes included via `include_bytes!`
|
|
|
|
/// Added for optimization purposes to avoid the need to escape
|
|
|
|
/// large binary blobs - should always behave like [`ExprKind::Lit`]
|
|
|
|
/// with a `ByteStr` literal.
|
|
|
|
IncludedBytes(Lrc<[u8]>),
|
|
|
|
|
2023-01-11 21:41:13 +01:00
|
|
|
/// A `format_args!()` expression.
|
|
|
|
FormatArgs(P<FormatArgs>),
|
|
|
|
|
2018-12-17 04:57:32 +03:00
|
|
|
/// Placeholder for an expression that wasn't syntactically well formed in some way.
|
2024-02-25 22:22:11 +01:00
|
|
|
Err(ErrorGuaranteed),
|
2024-02-25 22:22:09 +01:00
|
|
|
|
|
|
|
/// Acts as a null expression. Lowering it will always emit a bug.
|
|
|
|
Dummy,
|
2011-07-08 16:35:09 -07:00
|
|
|
}
|
|
|
|
|
2023-12-08 14:51:50 -08:00
|
|
|
/// Used to differentiate between `for` loops and `for await` loops.
|
|
|
|
#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Eq)]
|
|
|
|
pub enum ForLoopKind {
|
|
|
|
For,
|
|
|
|
ForAwait,
|
|
|
|
}
|
|
|
|
|
2023-10-20 21:26:57 +00:00
|
|
|
/// Used to differentiate between `async {}` blocks and `gen {}` blocks.
|
|
|
|
#[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq)]
|
|
|
|
pub enum GenBlockKind {
|
|
|
|
Async,
|
|
|
|
Gen,
|
2023-11-28 18:18:19 +00:00
|
|
|
AsyncGen,
|
2023-10-20 21:26:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Display for GenBlockKind {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
|
self.modifier().fmt(f)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl GenBlockKind {
|
|
|
|
pub fn modifier(&self) -> &'static str {
|
|
|
|
match self {
|
|
|
|
GenBlockKind::Async => "async",
|
|
|
|
GenBlockKind::Gen => "gen",
|
2023-11-28 18:18:19 +00:00
|
|
|
GenBlockKind::AsyncGen => "async gen",
|
2023-10-20 21:26:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-27 02:59:49 +00:00
|
|
|
/// The explicit `Self` type in a "qualified path". The actual
|
2015-02-17 19:29:13 +02:00
|
|
|
/// path, including the trait and the associated item, is stored
|
2015-03-19 00:48:08 -04:00
|
|
|
/// separately. `position` represents the index of the associated
|
2018-11-27 02:59:49 +00:00
|
|
|
/// item qualified with this `Self` type.
|
2014-08-05 19:44:21 -07:00
|
|
|
///
|
2017-06-20 15:15:16 +08:00
|
|
|
/// ```ignore (only-for-syntax-highlight)
|
2015-11-03 16:34:11 +00:00
|
|
|
/// <Vec<T> as a::b::Trait>::AssociatedItem
|
|
|
|
/// ^~~~~ ~~~~~~~~~~~~~~^
|
|
|
|
/// ty position = 3
|
2015-02-17 19:29:13 +02:00
|
|
|
///
|
2015-11-03 16:34:11 +00:00
|
|
|
/// <Vec<T>>::AssociatedItem
|
|
|
|
/// ^~~~~ ^
|
|
|
|
/// ty position = 0
|
|
|
|
/// ```
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2015-02-17 19:29:13 +02:00
|
|
|
pub struct QSelf {
|
|
|
|
pub ty: P<Ty>,
|
2018-05-22 15:26:35 -04: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-22 16:19:44 -07:00
|
|
|
pub position: usize,
|
2014-08-05 19:44:21 -07:00
|
|
|
}
|
|
|
|
|
2019-10-24 16:11:43 +03:00
|
|
|
/// A capture clause used in closures and `async` blocks.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
|
2016-02-08 15:27:08 +01:00
|
|
|
pub enum CaptureBy {
|
2019-10-24 16:11:43 +03:00
|
|
|
/// `move |x| y + x`.
|
2023-11-04 19:39:32 +01:00
|
|
|
Value {
|
|
|
|
/// The span of the `move` keyword.
|
|
|
|
move_kw: Span,
|
|
|
|
},
|
2019-10-24 16:11:43 +03:00
|
|
|
/// `move` keyword was not specified.
|
2016-02-08 15:27:08 +01:00
|
|
|
Ref,
|
2014-07-23 12:43:29 -07:00
|
|
|
}
|
|
|
|
|
2022-06-02 20:15:05 +04:00
|
|
|
/// Closure lifetime binder, `for<'a, 'b>` in `for<'a, 'b> |_: &'a (), _: &'b ()|`.
|
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
|
|
|
pub enum ClosureBinder {
|
|
|
|
/// The binder is not present, all closure lifetimes are inferred.
|
|
|
|
NotPresent,
|
|
|
|
/// The binder is present.
|
|
|
|
For {
|
|
|
|
/// Span of the whole `for<>` clause
|
|
|
|
///
|
|
|
|
/// ```text
|
|
|
|
/// for<'a, 'b> |_: &'a (), _: &'b ()| { ... }
|
|
|
|
/// ^^^^^^^^^^^ -- this
|
|
|
|
/// ```
|
|
|
|
span: Span,
|
|
|
|
|
|
|
|
/// Lifetimes in the `for<>` closure
|
|
|
|
///
|
|
|
|
/// ```text
|
|
|
|
/// for<'a, 'b> |_: &'a (), _: &'b ()| { ... }
|
|
|
|
/// ^^^^^^ -- this
|
|
|
|
/// ```
|
2022-11-22 09:17:20 +11:00
|
|
|
generic_params: ThinVec<GenericParam>,
|
2022-06-02 20:15:05 +04:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2019-12-01 02:25:32 +03:00
|
|
|
/// Represents a macro invocation. The `path` indicates which macro
|
|
|
|
/// is being invoked, and the `args` are arguments passed to it.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2020-02-29 19:32:20 +03:00
|
|
|
pub struct MacCall {
|
2015-09-20 16:15:37 -04:00
|
|
|
pub path: Path,
|
2022-11-18 11:24:21 +11:00
|
|
|
pub args: P<DelimArgs>,
|
2017-02-21 05:05:59 +00:00
|
|
|
}
|
|
|
|
|
2020-02-29 19:32:20 +03:00
|
|
|
impl MacCall {
|
2019-12-01 15:55:32 +03:00
|
|
|
pub fn span(&self) -> Span {
|
2022-11-18 11:24:21 +11:00
|
|
|
self.path.span.to(self.args.dspan.entire())
|
2019-12-01 15:55:32 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-18 11:24:21 +11:00
|
|
|
/// Arguments passed to an attribute macro.
|
Overhaul `MacArgs::Eq`.
The value in `MacArgs::Eq` is currently represented as a `Token`.
Because of `TokenKind::Interpolated`, `Token` can be either a token or
an arbitrary AST fragment. In practice, a `MacArgs::Eq` starts out as a
literal or macro call AST fragment, and then is later lowered to a
literal token. But this is very non-obvious. `Token` is a much more
general type than what is needed.
This commit restricts things, by introducing a new type `MacArgsEqKind`
that is either an AST expression (pre-lowering) or an AST literal
(post-lowering). The downside is that the code is a bit more verbose in
a few places. The benefit is that makes it much clearer what the
possibilities are (though also shorter in some other places). Also, it
removes one use of `TokenKind::Interpolated`, taking us a step closer to
removing that variant, which will let us make `Token` impl `Copy` and
remove many "handle Interpolated" code paths in the parser.
Things to note:
- Error messages have improved. Messages like this:
```
unexpected token: `"bug" + "found"`
```
now say "unexpected expression", which makes more sense. Although
arbitrary expressions can exist within tokens thanks to
`TokenKind::Interpolated`, that's not obvious to anyone who doesn't
know compiler internals.
- In `parse_mac_args_common`, we no longer need to collect tokens for
the value expression.
2022-04-29 06:52:01 +10:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2022-11-18 11:24:21 +11:00
|
|
|
pub enum AttrArgs {
|
|
|
|
/// No arguments: `#[attr]`.
|
2019-12-01 02:25:32 +03:00
|
|
|
Empty,
|
2022-11-18 11:24:21 +11:00
|
|
|
/// Delimited arguments: `#[attr()/[]/{}]`.
|
|
|
|
Delimited(DelimArgs),
|
|
|
|
/// Arguments of a key-value attribute: `#[attr = "value"]`.
|
2019-12-02 21:56:11 +03:00
|
|
|
Eq(
|
|
|
|
/// Span of the `=` token.
|
|
|
|
Span,
|
Overhaul `MacArgs::Eq`.
The value in `MacArgs::Eq` is currently represented as a `Token`.
Because of `TokenKind::Interpolated`, `Token` can be either a token or
an arbitrary AST fragment. In practice, a `MacArgs::Eq` starts out as a
literal or macro call AST fragment, and then is later lowered to a
literal token. But this is very non-obvious. `Token` is a much more
general type than what is needed.
This commit restricts things, by introducing a new type `MacArgsEqKind`
that is either an AST expression (pre-lowering) or an AST literal
(post-lowering). The downside is that the code is a bit more verbose in
a few places. The benefit is that makes it much clearer what the
possibilities are (though also shorter in some other places). Also, it
removes one use of `TokenKind::Interpolated`, taking us a step closer to
removing that variant, which will let us make `Token` impl `Copy` and
remove many "handle Interpolated" code paths in the parser.
Things to note:
- Error messages have improved. Messages like this:
```
unexpected token: `"bug" + "found"`
```
now say "unexpected expression", which makes more sense. Although
arbitrary expressions can exist within tokens thanks to
`TokenKind::Interpolated`, that's not obvious to anyone who doesn't
know compiler internals.
- In `parse_mac_args_common`, we no longer need to collect tokens for
the value expression.
2022-04-29 06:52:01 +10:00
|
|
|
/// The "value".
|
2022-11-18 11:24:21 +11:00
|
|
|
AttrArgsEq,
|
2019-12-02 21:56:11 +03:00
|
|
|
),
|
2019-12-01 02:25:32 +03:00
|
|
|
}
|
|
|
|
|
2022-11-18 11:24:21 +11:00
|
|
|
// The RHS of an `AttrArgs::Eq` starts out as an expression. Once macro
|
2022-11-23 15:39:42 +11:00
|
|
|
// expansion is completed, all cases end up either as a meta item literal,
|
|
|
|
// which is the form used after lowering to HIR, or as an error.
|
Overhaul `MacArgs::Eq`.
The value in `MacArgs::Eq` is currently represented as a `Token`.
Because of `TokenKind::Interpolated`, `Token` can be either a token or
an arbitrary AST fragment. In practice, a `MacArgs::Eq` starts out as a
literal or macro call AST fragment, and then is later lowered to a
literal token. But this is very non-obvious. `Token` is a much more
general type than what is needed.
This commit restricts things, by introducing a new type `MacArgsEqKind`
that is either an AST expression (pre-lowering) or an AST literal
(post-lowering). The downside is that the code is a bit more verbose in
a few places. The benefit is that makes it much clearer what the
possibilities are (though also shorter in some other places). Also, it
removes one use of `TokenKind::Interpolated`, taking us a step closer to
removing that variant, which will let us make `Token` impl `Copy` and
remove many "handle Interpolated" code paths in the parser.
Things to note:
- Error messages have improved. Messages like this:
```
unexpected token: `"bug" + "found"`
```
now say "unexpected expression", which makes more sense. Although
arbitrary expressions can exist within tokens thanks to
`TokenKind::Interpolated`, that's not obvious to anyone who doesn't
know compiler internals.
- In `parse_mac_args_common`, we no longer need to collect tokens for
the value expression.
2022-04-29 06:52:01 +10:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2022-11-18 11:24:21 +11:00
|
|
|
pub enum AttrArgsEq {
|
Overhaul `MacArgs::Eq`.
The value in `MacArgs::Eq` is currently represented as a `Token`.
Because of `TokenKind::Interpolated`, `Token` can be either a token or
an arbitrary AST fragment. In practice, a `MacArgs::Eq` starts out as a
literal or macro call AST fragment, and then is later lowered to a
literal token. But this is very non-obvious. `Token` is a much more
general type than what is needed.
This commit restricts things, by introducing a new type `MacArgsEqKind`
that is either an AST expression (pre-lowering) or an AST literal
(post-lowering). The downside is that the code is a bit more verbose in
a few places. The benefit is that makes it much clearer what the
possibilities are (though also shorter in some other places). Also, it
removes one use of `TokenKind::Interpolated`, taking us a step closer to
removing that variant, which will let us make `Token` impl `Copy` and
remove many "handle Interpolated" code paths in the parser.
Things to note:
- Error messages have improved. Messages like this:
```
unexpected token: `"bug" + "found"`
```
now say "unexpected expression", which makes more sense. Although
arbitrary expressions can exist within tokens thanks to
`TokenKind::Interpolated`, that's not obvious to anyone who doesn't
know compiler internals.
- In `parse_mac_args_common`, we no longer need to collect tokens for
the value expression.
2022-04-29 06:52:01 +10:00
|
|
|
Ast(P<Expr>),
|
2022-11-23 15:39:42 +11:00
|
|
|
Hir(MetaItemLit),
|
Overhaul `MacArgs::Eq`.
The value in `MacArgs::Eq` is currently represented as a `Token`.
Because of `TokenKind::Interpolated`, `Token` can be either a token or
an arbitrary AST fragment. In practice, a `MacArgs::Eq` starts out as a
literal or macro call AST fragment, and then is later lowered to a
literal token. But this is very non-obvious. `Token` is a much more
general type than what is needed.
This commit restricts things, by introducing a new type `MacArgsEqKind`
that is either an AST expression (pre-lowering) or an AST literal
(post-lowering). The downside is that the code is a bit more verbose in
a few places. The benefit is that makes it much clearer what the
possibilities are (though also shorter in some other places). Also, it
removes one use of `TokenKind::Interpolated`, taking us a step closer to
removing that variant, which will let us make `Token` impl `Copy` and
remove many "handle Interpolated" code paths in the parser.
Things to note:
- Error messages have improved. Messages like this:
```
unexpected token: `"bug" + "found"`
```
now say "unexpected expression", which makes more sense. Although
arbitrary expressions can exist within tokens thanks to
`TokenKind::Interpolated`, that's not obvious to anyone who doesn't
know compiler internals.
- In `parse_mac_args_common`, we no longer need to collect tokens for
the value expression.
2022-04-29 06:52:01 +10:00
|
|
|
}
|
|
|
|
|
2022-11-18 11:24:21 +11:00
|
|
|
impl AttrArgs {
|
2019-12-01 15:55:32 +03:00
|
|
|
pub fn span(&self) -> Option<Span> {
|
2020-12-19 23:38:22 +03:00
|
|
|
match self {
|
2022-11-18 11:24:21 +11:00
|
|
|
AttrArgs::Empty => None,
|
|
|
|
AttrArgs::Delimited(args) => Some(args.dspan.entire()),
|
|
|
|
AttrArgs::Eq(eq_span, AttrArgsEq::Ast(expr)) => Some(eq_span.to(expr.span)),
|
|
|
|
AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => {
|
Overhaul `MacArgs::Eq`.
The value in `MacArgs::Eq` is currently represented as a `Token`.
Because of `TokenKind::Interpolated`, `Token` can be either a token or
an arbitrary AST fragment. In practice, a `MacArgs::Eq` starts out as a
literal or macro call AST fragment, and then is later lowered to a
literal token. But this is very non-obvious. `Token` is a much more
general type than what is needed.
This commit restricts things, by introducing a new type `MacArgsEqKind`
that is either an AST expression (pre-lowering) or an AST literal
(post-lowering). The downside is that the code is a bit more verbose in
a few places. The benefit is that makes it much clearer what the
possibilities are (though also shorter in some other places). Also, it
removes one use of `TokenKind::Interpolated`, taking us a step closer to
removing that variant, which will let us make `Token` impl `Copy` and
remove many "handle Interpolated" code paths in the parser.
Things to note:
- Error messages have improved. Messages like this:
```
unexpected token: `"bug" + "found"`
```
now say "unexpected expression", which makes more sense. Although
arbitrary expressions can exist within tokens thanks to
`TokenKind::Interpolated`, that's not obvious to anyone who doesn't
know compiler internals.
- In `parse_mac_args_common`, we no longer need to collect tokens for
the value expression.
2022-04-29 06:52:01 +10:00
|
|
|
unreachable!("in literal form when getting span: {:?}", lit);
|
|
|
|
}
|
2019-12-01 15:55:32 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-01 02:25:32 +03:00
|
|
|
/// Tokens inside the delimiters or after `=`.
|
|
|
|
/// Proc macros see these tokens, for example.
|
|
|
|
pub fn inner_tokens(&self) -> TokenStream {
|
|
|
|
match self {
|
2022-11-18 11:24:21 +11:00
|
|
|
AttrArgs::Empty => TokenStream::default(),
|
|
|
|
AttrArgs::Delimited(args) => args.tokens.clone(),
|
|
|
|
AttrArgs::Eq(_, AttrArgsEq::Ast(expr)) => TokenStream::from_ast(expr),
|
|
|
|
AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => {
|
Overhaul `MacArgs::Eq`.
The value in `MacArgs::Eq` is currently represented as a `Token`.
Because of `TokenKind::Interpolated`, `Token` can be either a token or
an arbitrary AST fragment. In practice, a `MacArgs::Eq` starts out as a
literal or macro call AST fragment, and then is later lowered to a
literal token. But this is very non-obvious. `Token` is a much more
general type than what is needed.
This commit restricts things, by introducing a new type `MacArgsEqKind`
that is either an AST expression (pre-lowering) or an AST literal
(post-lowering). The downside is that the code is a bit more verbose in
a few places. The benefit is that makes it much clearer what the
possibilities are (though also shorter in some other places). Also, it
removes one use of `TokenKind::Interpolated`, taking us a step closer to
removing that variant, which will let us make `Token` impl `Copy` and
remove many "handle Interpolated" code paths in the parser.
Things to note:
- Error messages have improved. Messages like this:
```
unexpected token: `"bug" + "found"`
```
now say "unexpected expression", which makes more sense. Although
arbitrary expressions can exist within tokens thanks to
`TokenKind::Interpolated`, that's not obvious to anyone who doesn't
know compiler internals.
- In `parse_mac_args_common`, we no longer need to collect tokens for
the value expression.
2022-04-29 06:52:01 +10:00
|
|
|
unreachable!("in literal form when getting inner tokens: {:?}", lit)
|
|
|
|
}
|
2019-12-01 02:25:32 +03:00
|
|
|
}
|
|
|
|
}
|
2018-05-22 08:01:21 -07:00
|
|
|
}
|
|
|
|
|
2022-11-18 11:24:21 +11:00
|
|
|
impl<CTX> HashStable<CTX> for AttrArgs
|
Overhaul `MacArgs::Eq`.
The value in `MacArgs::Eq` is currently represented as a `Token`.
Because of `TokenKind::Interpolated`, `Token` can be either a token or
an arbitrary AST fragment. In practice, a `MacArgs::Eq` starts out as a
literal or macro call AST fragment, and then is later lowered to a
literal token. But this is very non-obvious. `Token` is a much more
general type than what is needed.
This commit restricts things, by introducing a new type `MacArgsEqKind`
that is either an AST expression (pre-lowering) or an AST literal
(post-lowering). The downside is that the code is a bit more verbose in
a few places. The benefit is that makes it much clearer what the
possibilities are (though also shorter in some other places). Also, it
removes one use of `TokenKind::Interpolated`, taking us a step closer to
removing that variant, which will let us make `Token` impl `Copy` and
remove many "handle Interpolated" code paths in the parser.
Things to note:
- Error messages have improved. Messages like this:
```
unexpected token: `"bug" + "found"`
```
now say "unexpected expression", which makes more sense. Although
arbitrary expressions can exist within tokens thanks to
`TokenKind::Interpolated`, that's not obvious to anyone who doesn't
know compiler internals.
- In `parse_mac_args_common`, we no longer need to collect tokens for
the value expression.
2022-04-29 06:52:01 +10:00
|
|
|
where
|
|
|
|
CTX: crate::HashStableContext,
|
|
|
|
{
|
|
|
|
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
|
|
|
|
mem::discriminant(self).hash_stable(ctx, hasher);
|
|
|
|
match self {
|
2022-11-18 11:24:21 +11:00
|
|
|
AttrArgs::Empty => {}
|
|
|
|
AttrArgs::Delimited(args) => args.hash_stable(ctx, hasher),
|
|
|
|
AttrArgs::Eq(_eq_span, AttrArgsEq::Ast(expr)) => {
|
Overhaul `MacArgs::Eq`.
The value in `MacArgs::Eq` is currently represented as a `Token`.
Because of `TokenKind::Interpolated`, `Token` can be either a token or
an arbitrary AST fragment. In practice, a `MacArgs::Eq` starts out as a
literal or macro call AST fragment, and then is later lowered to a
literal token. But this is very non-obvious. `Token` is a much more
general type than what is needed.
This commit restricts things, by introducing a new type `MacArgsEqKind`
that is either an AST expression (pre-lowering) or an AST literal
(post-lowering). The downside is that the code is a bit more verbose in
a few places. The benefit is that makes it much clearer what the
possibilities are (though also shorter in some other places). Also, it
removes one use of `TokenKind::Interpolated`, taking us a step closer to
removing that variant, which will let us make `Token` impl `Copy` and
remove many "handle Interpolated" code paths in the parser.
Things to note:
- Error messages have improved. Messages like this:
```
unexpected token: `"bug" + "found"`
```
now say "unexpected expression", which makes more sense. Although
arbitrary expressions can exist within tokens thanks to
`TokenKind::Interpolated`, that's not obvious to anyone who doesn't
know compiler internals.
- In `parse_mac_args_common`, we no longer need to collect tokens for
the value expression.
2022-04-29 06:52:01 +10:00
|
|
|
unreachable!("hash_stable {:?}", expr);
|
|
|
|
}
|
2022-11-18 11:24:21 +11:00
|
|
|
AttrArgs::Eq(eq_span, AttrArgsEq::Hir(lit)) => {
|
Overhaul `MacArgs::Eq`.
The value in `MacArgs::Eq` is currently represented as a `Token`.
Because of `TokenKind::Interpolated`, `Token` can be either a token or
an arbitrary AST fragment. In practice, a `MacArgs::Eq` starts out as a
literal or macro call AST fragment, and then is later lowered to a
literal token. But this is very non-obvious. `Token` is a much more
general type than what is needed.
This commit restricts things, by introducing a new type `MacArgsEqKind`
that is either an AST expression (pre-lowering) or an AST literal
(post-lowering). The downside is that the code is a bit more verbose in
a few places. The benefit is that makes it much clearer what the
possibilities are (though also shorter in some other places). Also, it
removes one use of `TokenKind::Interpolated`, taking us a step closer to
removing that variant, which will let us make `Token` impl `Copy` and
remove many "handle Interpolated" code paths in the parser.
Things to note:
- Error messages have improved. Messages like this:
```
unexpected token: `"bug" + "found"`
```
now say "unexpected expression", which makes more sense. Although
arbitrary expressions can exist within tokens thanks to
`TokenKind::Interpolated`, that's not obvious to anyone who doesn't
know compiler internals.
- In `parse_mac_args_common`, we no longer need to collect tokens for
the value expression.
2022-04-29 06:52:01 +10:00
|
|
|
eq_span.hash_stable(ctx, hasher);
|
|
|
|
lit.hash_stable(ctx, hasher);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-18 11:24:21 +11:00
|
|
|
/// Delimited arguments, as used in `#[attr()/[]/{}]` or `mac!()/[]/{}`.
|
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
|
|
|
pub struct DelimArgs {
|
|
|
|
pub dspan: DelimSpan,
|
2023-08-02 09:56:26 +10:00
|
|
|
pub delim: Delimiter, // Note: `Delimiter::Invisible` never occurs
|
2022-11-18 11:24:21 +11:00
|
|
|
pub tokens: TokenStream,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl DelimArgs {
|
|
|
|
/// Whether a macro with these arguments needs a semicolon
|
|
|
|
/// when used as a standalone item or statement.
|
|
|
|
pub fn need_semicolon(&self) -> bool {
|
2023-08-02 09:56:26 +10:00
|
|
|
!matches!(self, DelimArgs { delim: Delimiter::Brace, .. })
|
2022-11-18 11:24:21 +11:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<CTX> HashStable<CTX> for DelimArgs
|
|
|
|
where
|
|
|
|
CTX: crate::HashStableContext,
|
|
|
|
{
|
|
|
|
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
|
|
|
|
let DelimArgs { dspan, delim, tokens } = self;
|
|
|
|
dspan.hash_stable(ctx, hasher);
|
|
|
|
delim.hash_stable(ctx, hasher);
|
|
|
|
tokens.hash_stable(ctx, hasher);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-24 16:11:43 +03:00
|
|
|
/// Represents a macro definition.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
|
2017-03-17 21:58:48 +00:00
|
|
|
pub struct MacroDef {
|
2022-11-18 11:24:21 +11:00
|
|
|
pub body: P<DelimArgs>,
|
2019-10-24 16:11:43 +03:00
|
|
|
/// `true` if macro was defined with `macro_rules`.
|
2020-03-14 00:52:24 +03:00
|
|
|
pub macro_rules: bool,
|
2017-03-17 21:58:48 +00:00
|
|
|
}
|
|
|
|
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug, Copy, Hash, Eq, PartialEq)]
|
2020-01-11 20:57:38 +13:00
|
|
|
#[derive(HashStable_Generic)]
|
2013-10-08 02:49:10 +02:00
|
|
|
pub enum StrStyle {
|
2018-11-27 02:59:49 +00:00
|
|
|
/// A regular string, like `"foo"`.
|
2016-02-09 18:01:08 +01:00
|
|
|
Cooked,
|
2018-11-27 02:59:49 +00:00
|
|
|
/// A raw string, like `r##"foo"##`.
|
2015-03-19 00:56:37 +05:30
|
|
|
///
|
2018-04-12 19:50:53 +10:00
|
|
|
/// The value is the number of `#` symbols used.
|
2022-03-23 23:07:39 +01:00
|
|
|
Raw(u8),
|
2013-10-08 02:49:10 +02:00
|
|
|
}
|
|
|
|
|
2024-02-17 12:43:54 -05:00
|
|
|
/// The kind of match expression
|
|
|
|
#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq)]
|
|
|
|
pub enum MatchKind {
|
|
|
|
/// match expr { ... }
|
|
|
|
Prefix,
|
|
|
|
/// expr.match { ... }
|
|
|
|
Postfix,
|
|
|
|
}
|
|
|
|
|
2022-11-23 15:39:42 +11:00
|
|
|
/// A literal in a meta item.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
|
2022-11-23 15:39:42 +11:00
|
|
|
pub struct MetaItemLit {
|
2022-11-29 13:36:00 +11:00
|
|
|
/// The original literal as written in the source code.
|
|
|
|
pub symbol: Symbol,
|
|
|
|
/// The original suffix as written in the source code.
|
|
|
|
pub suffix: Option<Symbol>,
|
2019-05-11 16:03:27 +03:00
|
|
|
/// The "semantic" representation of the literal lowered from the original tokens.
|
|
|
|
/// Strings are unescaped, hexadecimal forms are eliminated, etc.
|
2019-09-26 16:56:53 +01:00
|
|
|
pub kind: LitKind,
|
2019-05-09 02:00:29 +03:00
|
|
|
pub span: Span,
|
|
|
|
}
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2022-11-25 08:18:57 +11:00
|
|
|
/// Similar to `MetaItemLit`, but restricted to string literals.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Copy, Encodable, Decodable, Debug)]
|
2019-11-10 00:44:59 +03:00
|
|
|
pub struct StrLit {
|
2022-11-29 13:46:28 +11:00
|
|
|
/// The original literal as written in source code.
|
2019-11-10 00:44:59 +03:00
|
|
|
pub symbol: Symbol,
|
2022-11-29 13:46:28 +11:00
|
|
|
/// The original suffix as written in source code.
|
2019-11-10 00:44:59 +03:00
|
|
|
pub suffix: Option<Symbol>,
|
2022-11-29 13:46:28 +11:00
|
|
|
/// The semantic (unescaped) representation of the literal.
|
2019-11-10 00:44:59 +03:00
|
|
|
pub symbol_unescaped: Symbol,
|
2022-11-29 13:46:28 +11:00
|
|
|
pub style: StrStyle,
|
|
|
|
pub span: Span,
|
2019-11-10 00:44:59 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
impl StrLit {
|
2022-10-10 13:40:56 +11:00
|
|
|
pub fn as_token_lit(&self) -> token::Lit {
|
2019-11-10 00:44:59 +03:00
|
|
|
let token_kind = match self.style {
|
|
|
|
StrStyle::Cooked => token::Str,
|
|
|
|
StrStyle::Raw(n) => token::StrRaw(n),
|
|
|
|
};
|
2022-10-10 13:40:56 +11:00
|
|
|
token::Lit::new(token_kind, self.symbol, self.suffix)
|
2019-11-10 00:44:59 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-24 16:11:43 +03:00
|
|
|
/// Type of the integer literal based on provided suffix.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
|
2020-01-11 20:57:38 +13:00
|
|
|
#[derive(HashStable_Generic)]
|
2014-08-05 09:59:03 +02:00
|
|
|
pub enum LitIntType {
|
2019-10-24 16:11:43 +03:00
|
|
|
/// e.g. `42_i32`.
|
2016-02-08 17:16:23 +01:00
|
|
|
Signed(IntTy),
|
2019-10-24 16:11:43 +03:00
|
|
|
/// e.g. `42_u32`.
|
2016-02-08 17:16:23 +01:00
|
|
|
Unsigned(UintTy),
|
2019-10-24 16:11:43 +03:00
|
|
|
/// e.g. `42`.
|
2016-02-08 17:16:23 +01:00
|
|
|
Unsuffixed,
|
2014-08-05 09:59:03 +02:00
|
|
|
}
|
|
|
|
|
2019-10-28 03:46:22 +01:00
|
|
|
/// Type of the float literal based on provided suffix.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
|
2020-01-11 20:57:38 +13:00
|
|
|
#[derive(HashStable_Generic)]
|
2019-10-28 03:46:22 +01:00
|
|
|
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,
|
|
|
|
}
|
|
|
|
|
2022-11-23 15:39:42 +11:00
|
|
|
/// This type is used within both `ast::MetaItemLit` and `hir::Lit`.
|
|
|
|
///
|
2022-10-10 13:40:56 +11:00
|
|
|
/// Note that the entire literal (including the suffix) is considered when
|
|
|
|
/// deciding the `LitKind`. This means that float literals like `1f32` are
|
|
|
|
/// classified by this type as `Float`. This is different to `token::LitKind`
|
|
|
|
/// which does *not* consider the suffix.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug, Hash, Eq, PartialEq, HashStable_Generic)]
|
2016-02-08 17:06:20 +01:00
|
|
|
pub enum LitKind {
|
2022-08-22 13:38:19 +10:00
|
|
|
/// A string literal (`"foo"`). The symbol is unescaped, and so may differ
|
|
|
|
/// from the original token's symbol.
|
2016-11-16 10:52:37 +00:00
|
|
|
Str(Symbol, StrStyle),
|
2022-11-29 13:35:44 +11:00
|
|
|
/// A byte string (`b"foo"`). Not stored as a symbol because it might be
|
|
|
|
/// non-utf8, and symbols only allow utf8 strings.
|
|
|
|
ByteStr(Lrc<[u8]>, StrStyle),
|
2023-03-06 14:15:02 +00:00
|
|
|
/// A C String (`c"foo"`). Guaranteed to only have `\0` at the end.
|
2023-03-05 15:03:22 +00:00
|
|
|
CStr(Lrc<[u8]>, StrStyle),
|
2018-11-27 02:59:49 +00:00
|
|
|
/// A byte char (`b'f'`).
|
2016-02-08 17:06:20 +01:00
|
|
|
Byte(u8),
|
2018-11-27 02:59:49 +00:00
|
|
|
/// A character literal (`'a'`).
|
2016-02-08 17:06:20 +01:00
|
|
|
Char(char),
|
2018-11-27 02:59:49 +00:00
|
|
|
/// An integer literal (`1`).
|
2024-01-17 15:40:30 -08:00
|
|
|
Int(Pu128, LitIntType),
|
2022-10-10 13:40:56 +11:00
|
|
|
/// A float literal (`1.0`, `1f64` or `1E10f64`). The pre-suffix part is
|
|
|
|
/// stored as a symbol rather than `f64` so that `LitKind` can impl `Eq`
|
|
|
|
/// and `Hash`.
|
2019-10-28 03:46:22 +01:00
|
|
|
Float(Symbol, LitFloatType),
|
2022-10-10 13:40:56 +11:00
|
|
|
/// A boolean literal (`true`, `false`).
|
2016-02-08 17:06:20 +01:00
|
|
|
Bool(bool),
|
2019-06-07 12:53:33 +03:00
|
|
|
/// Placeholder for a literal that wasn't well-formed in some way.
|
2024-02-14 20:12:05 +11:00
|
|
|
Err(ErrorGuaranteed),
|
2010-09-09 15:59:29 -07:00
|
|
|
}
|
|
|
|
|
2016-02-08 17:06:20 +01:00
|
|
|
impl LitKind {
|
2023-02-01 20:26:05 +04:00
|
|
|
pub fn str(&self) -> Option<Symbol> {
|
|
|
|
match *self {
|
|
|
|
LitKind::Str(s, _) => Some(s),
|
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-27 02:59:49 +00:00
|
|
|
/// Returns `true` if this literal is a string.
|
2015-11-28 19:02:07 +00:00
|
|
|
pub fn is_str(&self) -> bool {
|
2020-12-24 02:55:21 +01:00
|
|
|
matches!(self, LitKind::Str(..))
|
2015-11-28 19:02:07 +00:00
|
|
|
}
|
2016-08-19 18:58:14 -07:00
|
|
|
|
2018-11-27 02:59:49 +00:00
|
|
|
/// Returns `true` if this literal is byte literal string.
|
2018-10-09 17:53:59 +08:00
|
|
|
pub fn is_bytestr(&self) -> bool {
|
2022-11-29 13:35:44 +11:00
|
|
|
matches!(self, LitKind::ByteStr(..))
|
2018-10-09 17:53:59 +08:00
|
|
|
}
|
|
|
|
|
2018-11-27 02:59:49 +00:00
|
|
|
/// Returns `true` if this is a numeric literal.
|
2018-06-28 14:58:54 -07:00
|
|
|
pub fn is_numeric(&self) -> bool {
|
2020-12-24 02:55:21 +01:00
|
|
|
matches!(self, LitKind::Int(..) | LitKind::Float(..))
|
2018-06-28 14:58:54 -07:00
|
|
|
}
|
|
|
|
|
2018-11-27 02:59:49 +00:00
|
|
|
/// Returns `true` if this literal has no suffix.
|
|
|
|
/// Note: this will return true for literals with prefixes such as raw strings and byte strings.
|
2016-08-19 18:58:14 -07:00
|
|
|
pub fn is_unsuffixed(&self) -> bool {
|
2019-10-24 16:11:43 +03:00
|
|
|
!self.is_suffixed()
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns `true` if this literal has a suffix.
|
|
|
|
pub fn is_suffixed(&self) -> bool {
|
2016-08-19 18:58:14 -07:00
|
|
|
match *self {
|
2019-10-24 16:11:43 +03:00
|
|
|
// suffixed variants
|
2020-04-16 17:38:52 -07:00
|
|
|
LitKind::Int(_, LitIntType::Signed(..) | LitIntType::Unsigned(..))
|
2019-10-28 03:46:22 +01:00
|
|
|
| LitKind::Float(_, LitFloatType::Suffixed(..)) => true,
|
2016-08-19 18:58:14 -07:00
|
|
|
// unsuffixed variants
|
2018-09-22 16:19:44 -07:00
|
|
|
LitKind::Str(..)
|
|
|
|
| LitKind::ByteStr(..)
|
2023-03-05 15:03:22 +00:00
|
|
|
| LitKind::CStr(..)
|
2018-09-22 16:19:44 -07:00
|
|
|
| LitKind::Byte(..)
|
|
|
|
| LitKind::Char(..)
|
|
|
|
| LitKind::Int(_, LitIntType::Unsuffixed)
|
2019-10-28 03:46:22 +01:00
|
|
|
| LitKind::Float(_, LitFloatType::Unsuffixed)
|
2019-06-07 12:53:33 +03:00
|
|
|
| LitKind::Bool(..)
|
2024-02-14 20:12:05 +11:00
|
|
|
| LitKind::Err(_) => false,
|
2016-08-19 18:58:14 -07:00
|
|
|
}
|
|
|
|
}
|
2015-11-28 19:02:07 +00:00
|
|
|
}
|
|
|
|
|
2018-11-27 02:59:49 +00:00
|
|
|
// N.B., If you change this, you'll probably want to change the corresponding
|
|
|
|
// type structure in `middle/ty.rs` as well.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2014-01-09 15:05:33 +02:00
|
|
|
pub struct MutTy {
|
2014-03-27 15:39:48 -07:00
|
|
|
pub ty: P<Ty>,
|
|
|
|
pub mutbl: Mutability,
|
2013-01-14 21:36:27 -08:00
|
|
|
}
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2019-11-07 13:11:59 +01:00
|
|
|
/// Represents a function's signature in a trait declaration,
|
|
|
|
/// trait implementation, or free function.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2019-11-07 13:11:59 +01:00
|
|
|
pub struct FnSig {
|
2018-05-16 22:55:18 -07:00
|
|
|
pub header: FnHeader,
|
2014-03-27 15:39:48 -07:00
|
|
|
pub decl: P<FnDecl>,
|
2020-08-12 17:02:14 -04:00
|
|
|
pub span: Span,
|
2013-01-15 15:03:49 -08:00
|
|
|
}
|
2011-06-03 15:26:03 -07:00
|
|
|
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
|
|
|
#[derive(Encodable, Decodable, HashStable_Generic)]
|
2019-10-28 03:46:22 +01:00
|
|
|
pub enum FloatTy {
|
2024-03-01 04:02:47 -05:00
|
|
|
F16,
|
2019-10-28 03:46:22 +01:00
|
|
|
F32,
|
|
|
|
F64,
|
2024-03-01 04:02:47 -05:00
|
|
|
F128,
|
2019-10-28 03:46:22 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
impl FloatTy {
|
|
|
|
pub fn name_str(self) -> &'static str {
|
|
|
|
match self {
|
2024-03-01 04:02:47 -05:00
|
|
|
FloatTy::F16 => "f16",
|
2019-10-28 03:46:22 +01:00
|
|
|
FloatTy::F32 => "f32",
|
|
|
|
FloatTy::F64 => "f64",
|
2024-03-01 04:02:47 -05:00
|
|
|
FloatTy::F128 => "f128",
|
2019-10-28 03:46:22 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn name(self) -> Symbol {
|
|
|
|
match self {
|
2024-03-01 04:02:47 -05:00
|
|
|
FloatTy::F16 => sym::f16,
|
2019-10-28 03:46:22 +01:00
|
|
|
FloatTy::F32 => sym::f32,
|
|
|
|
FloatTy::F64 => sym::f64,
|
2024-03-01 04:02:47 -05:00
|
|
|
FloatTy::F128 => sym::f128,
|
2019-10-28 03:46:22 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
|
|
|
#[derive(Encodable, Decodable, HashStable_Generic)]
|
2014-01-09 15:05:33 +02:00
|
|
|
pub enum IntTy {
|
2018-01-04 03:12:04 +02:00
|
|
|
Isize,
|
2016-02-08 16:20:57 +01:00
|
|
|
I8,
|
|
|
|
I16,
|
|
|
|
I32,
|
|
|
|
I64,
|
2016-08-23 03:56:52 +03:00
|
|
|
I128,
|
2013-07-02 12:47:32 -07:00
|
|
|
}
|
2011-12-07 21:06:12 +01:00
|
|
|
|
2014-06-18 10:44:20 -07:00
|
|
|
impl IntTy {
|
2019-10-28 03:46:22 +01:00
|
|
|
pub fn name_str(&self) -> &'static str {
|
2015-11-28 19:02:07 +00:00
|
|
|
match *self {
|
2018-01-04 03:12:04 +02:00
|
|
|
IntTy::Isize => "isize",
|
2016-02-08 16:20:57 +01:00
|
|
|
IntTy::I8 => "i8",
|
|
|
|
IntTy::I16 => "i16",
|
|
|
|
IntTy::I32 => "i32",
|
2016-08-23 03:56:52 +03:00
|
|
|
IntTy::I64 => "i64",
|
|
|
|
IntTy::I128 => "i128",
|
2015-11-28 19:02:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-28 03:46:22 +01:00
|
|
|
pub fn name(&self) -> Symbol {
|
2019-05-23 12:22:43 +10: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,
|
|
|
|
}
|
|
|
|
}
|
2014-06-18 10:44:20 -07:00
|
|
|
}
|
|
|
|
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, Debug)]
|
|
|
|
#[derive(Encodable, Decodable, HashStable_Generic)]
|
2014-01-09 15:05:33 +02:00
|
|
|
pub enum UintTy {
|
2018-01-04 03:12:04 +02:00
|
|
|
Usize,
|
2016-02-08 16:20:57 +01:00
|
|
|
U8,
|
|
|
|
U16,
|
|
|
|
U32,
|
|
|
|
U64,
|
2016-08-23 03:56:52 +03:00
|
|
|
U128,
|
2013-07-02 12:47:32 -07:00
|
|
|
}
|
2011-12-07 21:06:12 +01:00
|
|
|
|
2014-06-18 10:44:20 -07:00
|
|
|
impl UintTy {
|
2019-10-28 03:46:22 +01:00
|
|
|
pub fn name_str(&self) -> &'static str {
|
2015-11-28 19:02:07 +00:00
|
|
|
match *self {
|
2018-01-04 03:12:04 +02:00
|
|
|
UintTy::Usize => "usize",
|
2016-02-08 16:20:57 +01:00
|
|
|
UintTy::U8 => "u8",
|
|
|
|
UintTy::U16 => "u16",
|
|
|
|
UintTy::U32 => "u32",
|
2016-08-23 03:56:52 +03:00
|
|
|
UintTy::U64 => "u64",
|
|
|
|
UintTy::U128 => "u128",
|
2015-11-28 19:02:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-28 03:46:22 +01:00
|
|
|
pub fn name(&self) -> Symbol {
|
2019-05-23 12:22:43 +10: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,
|
|
|
|
}
|
|
|
|
}
|
2014-06-18 10:44:20 -07:00
|
|
|
}
|
|
|
|
|
2024-05-27 23:53:46 +02:00
|
|
|
/// A constraint on an associated item.
|
|
|
|
///
|
|
|
|
/// ### Examples
|
|
|
|
///
|
|
|
|
/// * the `A = Ty` and `B = Ty` in `Trait<A = Ty, B = Ty>`
|
|
|
|
/// * the `G<Ty> = Ty` in `Trait<G<Ty> = Ty>`
|
|
|
|
/// * the `A: Bound` in `Trait<A: Bound>`
|
|
|
|
/// * the `RetTy` in `Trait(ArgTy, ArgTy) -> RetTy`
|
|
|
|
/// * the `C = { Ct }` in `Trait<C = { Ct }>` (feature `associated_const_equality`)
|
2024-06-28 11:49:16 -04:00
|
|
|
/// * the `f(..): Bound` in `Trait<f(..): Bound>` (feature `return_type_notation`)
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2024-05-27 23:53:46 +02:00
|
|
|
pub struct AssocItemConstraint {
|
2014-11-29 17:08:30 +13:00
|
|
|
pub id: NodeId,
|
|
|
|
pub ident: Ident,
|
2020-11-19 18:28:38 +01:00
|
|
|
pub gen_args: Option<GenericArgs>,
|
2024-05-27 23:53:46 +02:00
|
|
|
pub kind: AssocItemConstraintKind,
|
2014-11-29 17:08:30 +13:00
|
|
|
pub span: Span,
|
|
|
|
}
|
|
|
|
|
2022-01-07 03:58:32 +00:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
|
|
|
pub enum Term {
|
|
|
|
Ty(P<Ty>),
|
|
|
|
Const(AnonConst),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<P<Ty>> for Term {
|
|
|
|
fn from(v: P<Ty>) -> Self {
|
|
|
|
Term::Ty(v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<AnonConst> for Term {
|
|
|
|
fn from(v: AnonConst) -> Self {
|
|
|
|
Term::Const(v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-05-27 23:53:46 +02:00
|
|
|
/// The kind of [associated item constraint][AssocItemConstraint].
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2024-05-27 23:53:46 +02:00
|
|
|
pub enum AssocItemConstraintKind {
|
|
|
|
/// An equality constraint for an associated item (e.g., `AssocTy = Ty` in `Trait<AssocTy = Ty>`).
|
|
|
|
///
|
|
|
|
/// Also known as an *associated item binding* (we *bind* an associated item to a term).
|
|
|
|
///
|
|
|
|
/// Furthermore, associated type equality constraints can also be referred to as *associated type
|
|
|
|
/// bindings*. Similarly with associated const equality constraints and *associated const bindings*.
|
2022-01-07 03:58:32 +00:00
|
|
|
Equality { term: Term },
|
2024-05-27 23:53:46 +02:00
|
|
|
/// A bound on an associated type (e.g., `AssocTy: Bound` in `Trait<AssocTy: Bound>`).
|
2019-02-28 22:43:53 +00:00
|
|
|
Bound { bounds: GenericBounds },
|
|
|
|
}
|
|
|
|
|
2020-09-21 04:19:51 +08:00
|
|
|
#[derive(Encodable, Decodable, Debug)]
|
2013-01-29 13:54:06 -08:00
|
|
|
pub struct Ty {
|
2014-03-27 15:39:48 -07:00
|
|
|
pub id: NodeId,
|
2019-09-26 17:25:31 +01:00
|
|
|
pub kind: TyKind,
|
2014-03-27 15:39:48 -07:00
|
|
|
pub span: Span,
|
2022-09-09 17:15:53 +10:00
|
|
|
pub tokens: Option<LazyAttrTokenStream>,
|
2013-01-15 14:59:39 -08:00
|
|
|
}
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2020-09-21 04:19:51 +08: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-09 16:51:54 -07:00
|
|
|
impl Ty {
|
|
|
|
pub fn peel_refs(&self) -> &Self {
|
|
|
|
let mut final_ty = self;
|
2023-01-14 21:20:20 +13:00
|
|
|
while let TyKind::Ref(_, MutTy { ty, .. }) | TyKind::Ptr(MutTy { ty, .. }) = &final_ty.kind
|
|
|
|
{
|
2022-11-29 11:01:17 +00:00
|
|
|
final_ty = ty;
|
2020-10-09 16:51:54 -07:00
|
|
|
}
|
|
|
|
final_ty
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2014-01-09 15:05:33 +02:00
|
|
|
pub struct BareFnTy {
|
2024-05-17 14:17:48 -03:00
|
|
|
pub safety: Safety,
|
2019-11-09 22:05:20 +03:00
|
|
|
pub ext: Extern,
|
2022-11-22 09:17:20 +11:00
|
|
|
pub generic_params: ThinVec<GenericParam>,
|
2018-09-22 16:19:44 -07:00
|
|
|
pub decl: P<FnDecl>,
|
2024-06-17 18:47:09 +10:00
|
|
|
/// Span of the `[unsafe] [extern] fn(...) -> ...` part, i.e. everything
|
|
|
|
/// after the generic params (if there are any, e.g. `for<'a>`).
|
2022-05-10 21:17:21 +02:00
|
|
|
pub decl_span: Span,
|
2012-11-04 20:41:00 -08:00
|
|
|
}
|
|
|
|
|
2019-02-08 14:53:55 +01:00
|
|
|
/// The various kinds of type recognized by the compiler.
|
2023-10-20 09:55:29 +11:00
|
|
|
//
|
|
|
|
// Adding a new variant? Please update `test_ty` in `tests/ui/macros/stringify.rs`.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2016-02-08 16:53:21 +01:00
|
|
|
pub enum TyKind {
|
2018-11-27 02:59:49 +00:00
|
|
|
/// A variable-length slice (`[T]`).
|
2016-09-20 16:54:24 +02:00
|
|
|
Slice(P<Ty>),
|
2018-11-27 02:59:49 +00:00
|
|
|
/// A fixed length array (`[T; n]`).
|
2018-05-17 21:28:50 +03:00
|
|
|
Array(P<Ty>, AnonConst),
|
2018-11-27 02:59:49 +00:00
|
|
|
/// A raw pointer (`*const T` or `*mut T`).
|
2016-02-08 16:53:21 +01:00
|
|
|
Ptr(MutTy),
|
2018-11-27 02:59:49 +00:00
|
|
|
/// A reference (`&'a T` or `&'a mut T`).
|
2022-12-28 18:06:11 +01:00
|
|
|
Ref(Option<Lifetime>, MutTy),
|
2018-11-27 02:59:49 +00:00
|
|
|
/// A bare function (e.g., `fn(usize) -> bool`).
|
2016-02-08 16:53:21 +01:00
|
|
|
BareFn(P<BareFnTy>),
|
2018-11-27 02:59:49 +00:00
|
|
|
/// The never type (`!`).
|
2016-08-02 15:56:20 +08:00
|
|
|
Never,
|
2018-11-27 02:59:49 +00:00
|
|
|
/// A tuple (`(A, B, C, D,...)`).
|
2022-11-23 11:55:16 +11:00
|
|
|
Tup(ThinVec<P<Ty>>),
|
2024-07-05 18:10:05 +03:00
|
|
|
/// An anonymous struct type i.e. `struct { foo: Type }`.
|
2024-01-04 21:53:06 +08:00
|
|
|
AnonStruct(NodeId, ThinVec<FieldDef>),
|
2024-07-05 18:10:05 +03:00
|
|
|
/// An anonymous union type i.e. `union { bar: Type }`.
|
2024-01-04 21:53:06 +08:00
|
|
|
AnonUnion(NodeId, ThinVec<FieldDef>),
|
2015-02-17 19:29:13 +02:00
|
|
|
/// A path (`module::module::...::Type`), optionally
|
2018-11-27 02:59:49 +00:00
|
|
|
/// "qualified", e.g., `<Vec<T> as SomeTrait>::SomeType`.
|
2014-11-10 19:11:27 +05:30
|
|
|
///
|
2018-11-27 02:59:49 +00:00
|
|
|
/// Type parameters are stored in the `Path` itself.
|
2022-09-08 10:52:51 +10:00
|
|
|
Path(Option<P<QSelf>>, Path),
|
2017-01-16 23:33:45 +03:00
|
|
|
/// A trait object type `Bound1 + Bound2 + Bound3`
|
|
|
|
/// where `Bound` is a trait or a lifetime.
|
2018-06-14 12:08:58 +01:00
|
|
|
TraitObject(GenericBounds, TraitObjectSyntax),
|
2017-01-16 23:33:45 +03:00
|
|
|
/// An `impl Bound1 + Bound2 + Bound3` type
|
|
|
|
/// where `Bound` is a trait or a lifetime.
|
2018-06-18 16:23:13 +02:00
|
|
|
///
|
|
|
|
/// The `NodeId` exists to prevent lowering from having to
|
|
|
|
/// generate `NodeId`s on the fly, which would complicate
|
2019-08-01 00:41:54 +01:00
|
|
|
/// the generation of opaque `type Foo = impl Trait` items significantly.
|
2024-06-05 16:18:52 -04:00
|
|
|
ImplTrait(NodeId, GenericBounds),
|
2018-11-27 02:59:49 +00:00
|
|
|
/// No-op; kept solely so that we can pretty-print faithfully.
|
2016-02-08 16:53:21 +01:00
|
|
|
Paren(P<Ty>),
|
2018-11-27 02:59:49 +00:00
|
|
|
/// Unused for now.
|
2018-05-17 21:28:50 +03:00
|
|
|
Typeof(AnonConst),
|
2018-11-27 02:59:49 +00:00
|
|
|
/// This means the type should be inferred instead of it having been
|
2014-06-09 13:12:30 -07:00
|
|
|
/// specified. This can appear anywhere in a type.
|
2016-02-08 16:53:21 +01:00
|
|
|
Infer,
|
2016-03-06 15:54:44 +03:00
|
|
|
/// Inferred type of a `self` or `&self` argument in a method.
|
|
|
|
ImplicitSelf,
|
2018-11-27 02:59:49 +00:00
|
|
|
/// A macro in the type position.
|
2022-08-12 12:20:10 +10:00
|
|
|
MacCall(P<MacCall>),
|
2018-11-30 15:53:44 +00:00
|
|
|
/// Placeholder for a `va_list`.
|
|
|
|
CVarArgs,
|
2024-04-21 21:45:18 +02:00
|
|
|
/// Pattern types like `pattern_type!(u32 is 1..=)`, which is the same as `NonZero<u32>`,
|
2023-01-30 09:50:16 +00:00
|
|
|
/// just as part of the type system.
|
|
|
|
Pat(P<Ty>, P<Pat>),
|
2024-02-14 14:50:49 +11:00
|
|
|
/// Sometimes we need a dummy value when no error has occurred.
|
|
|
|
Dummy,
|
|
|
|
/// Placeholder for a kind that has failed to be defined.
|
|
|
|
Err(ErrorGuaranteed),
|
2010-09-09 15:59:29 -07:00
|
|
|
}
|
2017-10-10 17:33:19 +03:00
|
|
|
|
2018-03-21 01:58:25 +03:00
|
|
|
impl TyKind {
|
|
|
|
pub fn is_implicit_self(&self) -> bool {
|
2020-09-18 19:11:06 +02:00
|
|
|
matches!(self, TyKind::ImplicitSelf)
|
2018-03-21 01:58:25 +03:00
|
|
|
}
|
2018-07-06 23:18:38 +03:00
|
|
|
|
2018-07-20 18:04:02 -07:00
|
|
|
pub fn is_unit(&self) -> bool {
|
2020-12-29 01:20:06 +01:00
|
|
|
matches!(self, TyKind::Tup(tys) if tys.is_empty())
|
2018-03-21 01:58:25 +03:00
|
|
|
}
|
2022-07-01 16:32:20 +10:00
|
|
|
|
|
|
|
pub fn is_simple_path(&self) -> Option<Symbol> {
|
2022-10-18 13:07:20 +11:00
|
|
|
if let TyKind::Path(None, Path { segments, .. }) = &self
|
|
|
|
&& let [segment] = &segments[..]
|
|
|
|
&& segment.args.is_none()
|
|
|
|
{
|
|
|
|
Some(segment.ident.name)
|
2022-07-01 16:32:20 +10:00
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
2024-01-20 12:55:21 +08:00
|
|
|
|
|
|
|
pub fn is_anon_adt(&self) -> bool {
|
|
|
|
matches!(self, TyKind::AnonStruct(..) | TyKind::AnonUnion(..))
|
|
|
|
}
|
2018-03-21 01:58:25 +03:00
|
|
|
}
|
|
|
|
|
2017-10-10 17:33:19 +03:00
|
|
|
/// Syntax used to declare a trait object.
|
2021-03-13 15:44:29 +03:00
|
|
|
#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
|
2017-10-10 17:33:19 +03:00
|
|
|
pub enum TraitObjectSyntax {
|
|
|
|
Dyn,
|
2022-04-07 18:06:53 -07:00
|
|
|
DynStar,
|
2017-10-10 17:33:19 +03:00
|
|
|
None,
|
|
|
|
}
|
2010-09-09 15:59:29 -07:00
|
|
|
|
2024-04-04 20:23:52 -04:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2024-04-03 21:47:02 -04:00
|
|
|
pub enum PreciseCapturingArg {
|
2024-07-05 18:10:05 +03:00
|
|
|
/// Lifetime parameter.
|
2024-04-03 21:47:02 -04:00
|
|
|
Lifetime(Lifetime),
|
2024-07-05 18:10:05 +03:00
|
|
|
/// Type or const parameter.
|
2024-04-04 20:23:52 -04:00
|
|
|
Arg(Path, NodeId),
|
2024-04-03 21:47:02 -04:00
|
|
|
}
|
|
|
|
|
2020-01-22 14:20:27 +00:00
|
|
|
/// Inline assembly operand explicit register or register class.
|
|
|
|
///
|
|
|
|
/// E.g., `"eax"` as in `asm!("mov eax, 2", out("eax") result)`.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Copy, Encodable, Decodable, Debug)]
|
2020-01-22 14:20:27 +00:00
|
|
|
pub enum InlineAsmRegOrRegClass {
|
|
|
|
Reg(Symbol),
|
|
|
|
RegClass(Symbol),
|
|
|
|
}
|
|
|
|
|
2023-12-30 17:09:02 +01:00
|
|
|
#[derive(Clone, Copy, PartialEq, Eq, Hash, Encodable, Decodable, HashStable_Generic)]
|
|
|
|
pub struct InlineAsmOptions(u16);
|
2020-05-06 14:46:01 +01:00
|
|
|
bitflags::bitflags! {
|
2023-12-30 17:09:02 +01:00
|
|
|
impl InlineAsmOptions: u16 {
|
2022-09-16 11:46:47 +08:00
|
|
|
const PURE = 1 << 0;
|
|
|
|
const NOMEM = 1 << 1;
|
|
|
|
const READONLY = 1 << 2;
|
2020-05-06 14:46:01 +01:00
|
|
|
const PRESERVES_FLAGS = 1 << 3;
|
2022-09-16 11:46:47 +08:00
|
|
|
const NORETURN = 1 << 4;
|
|
|
|
const NOSTACK = 1 << 5;
|
|
|
|
const ATT_SYNTAX = 1 << 6;
|
|
|
|
const RAW = 1 << 7;
|
|
|
|
const MAY_UNWIND = 1 << 8;
|
2020-05-06 14:46:01 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-07-24 15:04:43 +02:00
|
|
|
impl InlineAsmOptions {
|
2024-07-25 10:05:31 +02:00
|
|
|
pub const COUNT: usize = Self::all().bits().count_ones() as usize;
|
|
|
|
|
|
|
|
pub const GLOBAL_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
|
|
|
|
pub const NAKED_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW).union(Self::NORETURN);
|
|
|
|
|
2024-07-24 15:04:43 +02:00
|
|
|
pub fn human_readable_names(&self) -> Vec<&'static str> {
|
|
|
|
let mut options = vec![];
|
|
|
|
|
|
|
|
if self.contains(InlineAsmOptions::PURE) {
|
|
|
|
options.push("pure");
|
|
|
|
}
|
|
|
|
if self.contains(InlineAsmOptions::NOMEM) {
|
|
|
|
options.push("nomem");
|
|
|
|
}
|
|
|
|
if self.contains(InlineAsmOptions::READONLY) {
|
|
|
|
options.push("readonly");
|
|
|
|
}
|
|
|
|
if self.contains(InlineAsmOptions::PRESERVES_FLAGS) {
|
|
|
|
options.push("preserves_flags");
|
|
|
|
}
|
|
|
|
if self.contains(InlineAsmOptions::NORETURN) {
|
|
|
|
options.push("noreturn");
|
|
|
|
}
|
|
|
|
if self.contains(InlineAsmOptions::NOSTACK) {
|
|
|
|
options.push("nostack");
|
|
|
|
}
|
|
|
|
if self.contains(InlineAsmOptions::ATT_SYNTAX) {
|
|
|
|
options.push("att_syntax");
|
|
|
|
}
|
|
|
|
if self.contains(InlineAsmOptions::RAW) {
|
|
|
|
options.push("raw");
|
|
|
|
}
|
|
|
|
if self.contains(InlineAsmOptions::MAY_UNWIND) {
|
|
|
|
options.push("may_unwind");
|
|
|
|
}
|
|
|
|
|
|
|
|
options
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-12-30 17:09:02 +01:00
|
|
|
impl std::fmt::Debug for InlineAsmOptions {
|
|
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
|
|
bitflags::parser::to_writer(self, f)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-17 15:14:55 -06:00
|
|
|
#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Hash, HashStable_Generic)]
|
2020-05-06 14:46:01 +01:00
|
|
|
pub enum InlineAsmTemplatePiece {
|
2024-06-24 16:17:59 +01:00
|
|
|
String(Cow<'static, str>),
|
2020-05-06 14:46:01 +01:00
|
|
|
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("}}")?,
|
2020-06-14 23:30:28 -07:00
|
|
|
_ => c.fmt(f)?,
|
2020-05-06 14:46:01 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
Self::Placeholder { operand_idx, modifier: Some(modifier), .. } => {
|
2022-12-19 10:31:55 +01:00
|
|
|
write!(f, "{{{operand_idx}:{modifier}}}")
|
2020-05-06 14:46:01 +01:00
|
|
|
}
|
|
|
|
Self::Placeholder { operand_idx, modifier: None, .. } => {
|
2022-12-19 10:31:55 +01:00
|
|
|
write!(f, "{{{operand_idx}}}")
|
2020-05-06 14:46:01 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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() {
|
2022-12-19 10:31:55 +01:00
|
|
|
let _ = write!(out, "{p}");
|
2020-05-06 14:46:01 +01:00
|
|
|
}
|
|
|
|
out
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-01 00:50:56 +00:00
|
|
|
/// Inline assembly symbol operands get their own AST node that is somewhat
|
|
|
|
/// similar to `AnonConst`.
|
|
|
|
///
|
|
|
|
/// The main difference is that we specifically don't assign it `DefId` in
|
|
|
|
/// `DefCollector`. Instead this is deferred until AST lowering where we
|
|
|
|
/// lower it to an `AnonConst` (for functions) or a `Path` (for statics)
|
|
|
|
/// depending on what the path resolves to.
|
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
|
|
|
pub struct InlineAsmSym {
|
|
|
|
pub id: NodeId,
|
2022-09-08 10:52:51 +10:00
|
|
|
pub qself: Option<P<QSelf>>,
|
2022-03-01 00:50:56 +00:00
|
|
|
pub path: Path,
|
|
|
|
}
|
|
|
|
|
2020-01-22 14:20:27 +00:00
|
|
|
/// Inline assembly operand.
|
|
|
|
///
|
|
|
|
/// E.g., `out("eax") result` as in `asm!("mov eax, 2", out("eax") result)`.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2020-01-22 14:20:27 +00: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 {
|
2021-04-06 05:50:55 +01:00
|
|
|
anon_const: AnonConst,
|
2020-01-22 14:20:27 +00:00
|
|
|
},
|
|
|
|
Sym {
|
2022-03-01 00:50:56 +00:00
|
|
|
sym: InlineAsmSym,
|
2020-01-22 14:20:27 +00:00
|
|
|
},
|
2023-12-25 20:53:01 +00:00
|
|
|
Label {
|
|
|
|
block: P<Block>,
|
|
|
|
},
|
2020-01-22 14:20:27 +00:00
|
|
|
}
|
|
|
|
|
2023-11-28 10:25:22 +00:00
|
|
|
impl InlineAsmOperand {
|
|
|
|
pub fn reg(&self) -> Option<&InlineAsmRegOrRegClass> {
|
|
|
|
match self {
|
|
|
|
Self::In { reg, .. }
|
|
|
|
| Self::Out { reg, .. }
|
|
|
|
| Self::InOut { reg, .. }
|
|
|
|
| Self::SplitInOut { reg, .. } => Some(reg),
|
2023-12-25 20:53:01 +00:00
|
|
|
Self::Const { .. } | Self::Sym { .. } | Self::Label { .. } => None,
|
2023-11-28 10:25:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-09-10 14:42:17 +02:00
|
|
|
#[derive(Clone, Copy, Encodable, Decodable, Debug, HashStable_Generic)]
|
|
|
|
pub enum AsmMacro {
|
|
|
|
/// The `asm!` macro
|
|
|
|
Asm,
|
|
|
|
/// The `global_asm!` macro
|
|
|
|
GlobalAsm,
|
|
|
|
/// The `naked_asm!` macro
|
|
|
|
NakedAsm,
|
|
|
|
}
|
|
|
|
|
2020-01-22 14:20:27 +00:00
|
|
|
/// Inline assembly.
|
|
|
|
///
|
|
|
|
/// E.g., `asm!("NOP");`.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2020-01-22 14:20:27 +00:00
|
|
|
pub struct InlineAsm {
|
2024-09-10 14:42:17 +02:00
|
|
|
pub asm_macro: AsmMacro,
|
2020-01-22 14:20:27 +00:00
|
|
|
pub template: Vec<InlineAsmTemplatePiece>,
|
2021-08-19 16:34:01 -04:00
|
|
|
pub template_strs: Box<[(Symbol, Option<Symbol>, Span)]>,
|
2020-01-22 14:20:27 +00:00
|
|
|
pub operands: Vec<(InlineAsmOperand, Span)>,
|
2021-10-14 03:23:09 -04:00
|
|
|
pub clobber_abis: Vec<(Symbol, Span)>,
|
2020-01-22 14:20:27 +00:00
|
|
|
pub options: InlineAsmOptions,
|
2020-05-26 20:07:59 +01:00
|
|
|
pub line_spans: Vec<Span>,
|
2020-01-22 14:20:27 +00:00
|
|
|
}
|
|
|
|
|
2019-08-27 13:24:32 +02:00
|
|
|
/// A parameter in a function header.
|
2016-06-24 13:14:34 +02:00
|
|
|
///
|
2018-11-27 02:59:49 +00:00
|
|
|
/// E.g., `bar: usize` as in `fn foo(bar: usize)`.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2019-08-27 13:24:32 +02:00
|
|
|
pub struct Param {
|
2019-12-03 16:38:34 +01:00
|
|
|
pub attrs: AttrVec,
|
2014-03-27 15:39:48 -07:00
|
|
|
pub ty: P<Ty>,
|
2014-05-18 01:13:20 +03:00
|
|
|
pub pat: P<Pat>,
|
2014-03-27 15:39:48 -07:00
|
|
|
pub id: NodeId,
|
2019-07-26 19:52:37 -03:00
|
|
|
pub span: Span,
|
2019-09-09 09:26:25 -03:00
|
|
|
pub is_placeholder: bool,
|
2013-01-15 16:05:20 -08:00
|
|
|
}
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2016-03-06 15:54:44 +03:00
|
|
|
/// Alternative representation for `Arg`s describing `self` parameter of methods.
|
2016-06-24 13:14:34 +02:00
|
|
|
///
|
2018-11-27 02:59:49 +00:00
|
|
|
/// E.g., `&mut self` as in `fn foo(&mut self)`.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2016-05-08 21:18:21 +03:00
|
|
|
pub enum SelfKind {
|
|
|
|
/// `self`, `mut self`
|
2016-03-06 15:54:44 +03:00
|
|
|
Value(Mutability),
|
2016-05-08 21:18:21 +03:00
|
|
|
/// `&'lt self`, `&'lt mut self`
|
2016-03-06 15:54:44 +03:00
|
|
|
Region(Option<Lifetime>, Mutability),
|
2016-05-08 21:18:21 +03:00
|
|
|
/// `self: TYPE`, `mut self: TYPE`
|
2016-03-06 15:54:44 +03:00
|
|
|
Explicit(P<Ty>, Mutability),
|
2016-05-08 21:18:21 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
pub type ExplicitSelf = Spanned<SelfKind>;
|
|
|
|
|
2019-08-27 13:24:32 +02:00
|
|
|
impl Param {
|
2019-10-24 16:11:43 +03:00
|
|
|
/// Attempts to cast parameter to `ExplicitSelf`.
|
2016-05-08 21:18:21 +03:00
|
|
|
pub fn to_self(&self) -> Option<ExplicitSelf> {
|
2024-04-16 19:23:30 -04:00
|
|
|
if let PatKind::Ident(BindingMode(ByRef::No, mutbl), ident, _) = self.pat.kind {
|
2019-05-11 17:41:37 +03:00
|
|
|
if ident.name == kw::SelfLower {
|
2019-09-26 17:25:31 +01:00
|
|
|
return match self.ty.kind {
|
2016-03-06 15:54:44 +03:00
|
|
|
TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
|
2022-12-28 18:06:11 +01:00
|
|
|
TyKind::Ref(lt, MutTy { ref ty, mutbl }) if ty.kind.is_implicit_self() => {
|
2016-03-06 15:54:44 +03:00
|
|
|
Some(respan(self.pat.span, SelfKind::Region(lt, mutbl)))
|
2016-05-08 21:18:21 +03:00
|
|
|
}
|
2018-09-22 16:19:44 -07:00
|
|
|
_ => Some(respan(
|
|
|
|
self.pat.span.to(self.ty.span),
|
|
|
|
SelfKind::Explicit(self.ty.clone(), mutbl),
|
|
|
|
)),
|
|
|
|
};
|
2016-05-08 21:18:21 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
None
|
|
|
|
}
|
|
|
|
|
2019-10-24 16:11:43 +03:00
|
|
|
/// Returns `true` if parameter is `self`.
|
2016-03-06 15:54:44 +03:00
|
|
|
pub fn is_self(&self) -> bool {
|
2019-09-26 16:18:31 +01:00
|
|
|
if let PatKind::Ident(_, ident, _) = self.pat.kind {
|
2019-05-11 17:41:37 +03:00
|
|
|
ident.name == kw::SelfLower
|
2016-03-06 15:54:44 +03:00
|
|
|
} else {
|
|
|
|
false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-24 16:11:43 +03:00
|
|
|
/// 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 {
|
2017-03-15 00:22:48 +00:00
|
|
|
let span = eself.span.to(eself_ident.span);
|
2023-06-10 22:36:28 +00:00
|
|
|
let infer_ty = P(Ty {
|
|
|
|
id: DUMMY_NODE_ID,
|
|
|
|
kind: TyKind::ImplicitSelf,
|
|
|
|
span: eself_ident.span,
|
|
|
|
tokens: None,
|
|
|
|
});
|
2022-08-30 17:34:35 -05:00
|
|
|
let (mutbl, ty) = match eself.node {
|
|
|
|
SelfKind::Explicit(ty, mutbl) => (mutbl, ty),
|
|
|
|
SelfKind::Value(mutbl) => (mutbl, infer_ty),
|
|
|
|
SelfKind::Region(lt, mutbl) => (
|
|
|
|
Mutability::Not,
|
|
|
|
P(Ty {
|
|
|
|
id: DUMMY_NODE_ID,
|
2022-12-28 18:06:11 +01:00
|
|
|
kind: TyKind::Ref(lt, MutTy { ty: infer_ty, mutbl }),
|
2022-08-30 17:34:35 -05:00
|
|
|
span,
|
|
|
|
tokens: None,
|
|
|
|
}),
|
|
|
|
),
|
|
|
|
};
|
|
|
|
Param {
|
2019-06-09 07:58:40 -03:00
|
|
|
attrs,
|
2016-03-06 15:54:44 +03:00
|
|
|
pat: P(Pat {
|
|
|
|
id: DUMMY_NODE_ID,
|
2024-04-16 19:23:30 -04:00
|
|
|
kind: PatKind::Ident(BindingMode(ByRef::No, mutbl), eself_ident, None),
|
2017-08-06 22:54:09 -07:00
|
|
|
span,
|
2020-07-27 18:02:29 -04:00
|
|
|
tokens: None,
|
2016-03-06 15:54:44 +03:00
|
|
|
}),
|
2019-07-26 19:52:37 -03:00
|
|
|
span,
|
2017-08-06 22:54:09 -07:00
|
|
|
ty,
|
2016-05-08 21:18:21 +03:00
|
|
|
id: DUMMY_NODE_ID,
|
2019-09-09 09:26:25 -03:00
|
|
|
is_placeholder: false,
|
2016-05-08 21:18:21 +03:00
|
|
|
}
|
|
|
|
}
|
2014-01-27 14:18:36 +02:00
|
|
|
}
|
|
|
|
|
2019-10-24 16:11:43 +03:00
|
|
|
/// A signature (not the body) of a function declaration.
|
2016-06-24 13:14:34 +02:00
|
|
|
///
|
2018-11-27 02:59:49 +00:00
|
|
|
/// E.g., `fn foo(bar: baz)`.
|
2019-10-24 16:11:43 +03:00
|
|
|
///
|
|
|
|
/// Please note that it's different from `FnHeader` structure
|
|
|
|
/// which contains metadata about function safety, asyncness, constness and ABI.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2014-01-09 15:05:33 +02:00
|
|
|
pub struct FnDecl {
|
2022-11-23 11:55:16 +11:00
|
|
|
pub inputs: ThinVec<Param>,
|
2020-02-15 12:10:59 +09:00
|
|
|
pub output: FnRetTy,
|
2013-01-15 16:05:20 -08:00
|
|
|
}
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2016-03-06 15:54:44 +03:00
|
|
|
impl FnDecl {
|
|
|
|
pub fn has_self(&self) -> bool {
|
2023-05-24 14:19:22 +00:00
|
|
|
self.inputs.get(0).is_some_and(Param::is_self)
|
2016-03-06 15:54:44 +03:00
|
|
|
}
|
2019-08-10 13:29:39 +03:00
|
|
|
pub fn c_variadic(&self) -> bool {
|
2023-05-24 14:19:22 +00:00
|
|
|
self.inputs.last().is_some_and(|arg| matches!(arg.ty.kind, TyKind::CVarArgs))
|
2019-08-10 13:29:39 +03:00
|
|
|
}
|
2016-03-06 15:54:44 +03:00
|
|
|
}
|
|
|
|
|
2017-10-12 09:51:31 -03:00
|
|
|
/// Is the trait definition an auto trait?
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
|
2017-10-12 09:51:31 -03:00
|
|
|
pub enum IsAuto {
|
|
|
|
Yes,
|
2018-09-22 16:19:44 -07:00
|
|
|
No,
|
2017-10-12 09:51:31 -03:00
|
|
|
}
|
|
|
|
|
2024-05-17 14:17:48 -03:00
|
|
|
/// Safety of items.
|
2022-01-17 15:14:55 -06:00
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
|
2020-01-30 02:42:33 +01:00
|
|
|
#[derive(HashStable_Generic)]
|
2024-05-17 14:17:48 -03:00
|
|
|
pub enum Safety {
|
|
|
|
/// `unsafe` an item is explicitly marked as `unsafe`.
|
|
|
|
Unsafe(Span),
|
2024-05-23 10:01:05 -03:00
|
|
|
/// `safe` an item is explicitly marked as `safe`.
|
|
|
|
Safe(Span),
|
2024-05-17 14:17:48 -03:00
|
|
|
/// Default means no value was provided, it will take a default value given the context in
|
|
|
|
/// which is used.
|
|
|
|
Default,
|
2019-11-09 18:01:12 +01:00
|
|
|
}
|
|
|
|
|
2023-11-30 14:54:39 -08:00
|
|
|
/// Describes what kind of coroutine markers, if any, a function has.
|
|
|
|
///
|
|
|
|
/// Coroutine markers are things that cause the function to generate a coroutine, such as `async`,
|
|
|
|
/// which makes the function return `impl Future`, or `gen`, which makes the function return `impl
|
|
|
|
/// Iterator`.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Copy, Clone, Encodable, Decodable, Debug)]
|
2023-11-30 14:54:39 -08:00
|
|
|
pub enum CoroutineKind {
|
2024-07-05 18:10:05 +03:00
|
|
|
/// `async`, which returns an `impl Future`.
|
2023-11-30 14:54:39 -08:00
|
|
|
Async { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
|
2024-07-05 18:10:05 +03:00
|
|
|
/// `gen`, which returns an `impl Iterator`.
|
2023-11-30 14:54:39 -08:00
|
|
|
Gen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
|
2024-07-05 18:10:05 +03:00
|
|
|
/// `async gen`, which returns an `impl AsyncIterator`.
|
2023-12-05 21:45:01 +00:00
|
|
|
AsyncGen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
|
2018-05-16 22:55:18 -07:00
|
|
|
}
|
|
|
|
|
2023-11-30 14:54:39 -08:00
|
|
|
impl CoroutineKind {
|
2024-04-03 02:43:54 +02:00
|
|
|
pub fn span(self) -> Span {
|
|
|
|
match self {
|
|
|
|
CoroutineKind::Async { span, .. } => span,
|
|
|
|
CoroutineKind::Gen { span, .. } => span,
|
|
|
|
CoroutineKind::AsyncGen { span, .. } => span,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-09-11 18:22:37 -04:00
|
|
|
pub fn as_str(self) -> &'static str {
|
|
|
|
match self {
|
|
|
|
CoroutineKind::Async { .. } => "async",
|
|
|
|
CoroutineKind::Gen { .. } => "gen",
|
|
|
|
CoroutineKind::AsyncGen { .. } => "async gen",
|
|
|
|
}
|
2018-06-06 15:50:59 -07:00
|
|
|
}
|
2018-11-27 02:59:49 +00:00
|
|
|
|
2023-12-08 21:38:00 +00:00
|
|
|
pub fn closure_id(self) -> NodeId {
|
|
|
|
match self {
|
|
|
|
CoroutineKind::Async { closure_id, .. }
|
|
|
|
| CoroutineKind::Gen { closure_id, .. }
|
|
|
|
| CoroutineKind::AsyncGen { closure_id, .. } => closure_id,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-30 16:39:56 -08:00
|
|
|
/// In this case this is an `async` or `gen` return, the `NodeId` for the generated `impl Trait`
|
|
|
|
/// item.
|
|
|
|
pub fn return_id(self) -> (NodeId, Span) {
|
2018-06-27 11:25:22 +02:00
|
|
|
match self {
|
2023-11-30 14:54:39 -08:00
|
|
|
CoroutineKind::Async { return_impl_trait_id, span, .. }
|
2023-12-05 21:45:01 +00:00
|
|
|
| CoroutineKind::Gen { return_impl_trait_id, span, .. }
|
|
|
|
| CoroutineKind::AsyncGen { return_impl_trait_id, span, .. } => {
|
|
|
|
(return_impl_trait_id, span)
|
|
|
|
}
|
2018-06-27 11:25:22 +02:00
|
|
|
}
|
|
|
|
}
|
2018-06-06 15:50:59 -07:00
|
|
|
}
|
|
|
|
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
|
2020-01-13 20:30:31 -08:00
|
|
|
#[derive(HashStable_Generic)]
|
2020-01-30 02:42:33 +01:00
|
|
|
pub enum Const {
|
|
|
|
Yes(Span),
|
|
|
|
No,
|
2015-02-25 22:05:07 +02:00
|
|
|
}
|
|
|
|
|
2019-10-24 16:11:43 +03:00
|
|
|
/// Item defaultness.
|
|
|
|
/// For details see the [RFC #2532](https://github.com/rust-lang/rfcs/pull/2532).
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
|
2015-12-18 14:38:28 -08:00
|
|
|
pub enum Defaultness {
|
2020-02-22 02:01:53 +01:00
|
|
|
Default(Span),
|
2015-12-18 14:38:28 -08:00
|
|
|
Final,
|
|
|
|
}
|
|
|
|
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Copy, Clone, PartialEq, Encodable, Decodable, HashStable_Generic)]
|
2014-12-28 23:33:18 +01:00
|
|
|
pub enum ImplPolarity {
|
2015-03-17 05:06:13 +05:30
|
|
|
/// `impl Trait for Type`
|
2014-12-28 23:33:18 +01:00
|
|
|
Positive,
|
2015-03-17 05:06:13 +05:30
|
|
|
/// `impl !Trait for Type`
|
2020-03-04 16:15:23 -08:00
|
|
|
Negative(Span),
|
2014-12-28 23:33:18 +01:00
|
|
|
}
|
|
|
|
|
2015-01-20 15:45:07 -08:00
|
|
|
impl fmt::Debug for ImplPolarity {
|
2019-02-07 02:33:01 +09:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
2014-12-28 23:33:18 +01:00
|
|
|
match *self {
|
|
|
|
ImplPolarity::Positive => "positive".fmt(f),
|
2020-03-04 16:15:23 -08:00
|
|
|
ImplPolarity::Negative(_) => "negative".fmt(f),
|
2014-12-28 23:33:18 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-12-20 15:22:06 +01:00
|
|
|
/// The polarity of a trait bound.
|
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug)]
|
|
|
|
#[derive(HashStable_Generic)]
|
2023-04-25 05:15:50 +00:00
|
|
|
pub enum BoundPolarity {
|
|
|
|
/// `Type: Trait`
|
|
|
|
Positive,
|
|
|
|
/// `Type: !Trait`
|
|
|
|
Negative(Span),
|
|
|
|
/// `Type: ?Trait`
|
|
|
|
Maybe(Span),
|
|
|
|
}
|
|
|
|
|
2023-12-20 15:22:06 +01:00
|
|
|
impl BoundPolarity {
|
|
|
|
pub fn as_str(self) -> &'static str {
|
|
|
|
match self {
|
|
|
|
Self::Positive => "",
|
|
|
|
Self::Negative(_) => "!",
|
|
|
|
Self::Maybe(_) => "?",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// The constness of a trait bound.
|
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug)]
|
|
|
|
#[derive(HashStable_Generic)]
|
|
|
|
pub enum BoundConstness {
|
|
|
|
/// `Type: Trait`
|
|
|
|
Never,
|
2023-12-18 17:55:55 +01:00
|
|
|
/// `Type: const Trait`
|
|
|
|
Always(Span),
|
2023-12-20 15:22:06 +01:00
|
|
|
/// `Type: ~const Trait`
|
|
|
|
Maybe(Span),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl BoundConstness {
|
|
|
|
pub fn as_str(self) -> &'static str {
|
|
|
|
match self {
|
|
|
|
Self::Never => "",
|
2023-12-18 17:55:55 +01:00
|
|
|
Self::Always(_) => "const",
|
2023-12-20 15:22:06 +01:00
|
|
|
Self::Maybe(_) => "~const",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-01-26 17:00:28 +00:00
|
|
|
/// The asyncness of a trait bound.
|
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug)]
|
|
|
|
#[derive(HashStable_Generic)]
|
|
|
|
pub enum BoundAsyncness {
|
|
|
|
/// `Type: Trait`
|
|
|
|
Normal,
|
|
|
|
/// `Type: async Trait`
|
|
|
|
Async(Span),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl BoundAsyncness {
|
|
|
|
pub fn as_str(self) -> &'static str {
|
|
|
|
match self {
|
|
|
|
Self::Normal => "",
|
|
|
|
Self::Async(_) => "async",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2020-02-15 12:10:59 +09:00
|
|
|
pub enum FnRetTy {
|
2019-02-08 14:53:55 +01:00
|
|
|
/// Returns type is not specified.
|
2015-03-19 00:56:37 +05:30
|
|
|
///
|
2018-11-27 02:59:49 +00:00
|
|
|
/// Functions default to `()` and closures default to inference.
|
|
|
|
/// Span points to where return type would be inserted.
|
2016-02-08 15:04:11 +01:00
|
|
|
Default(Span),
|
2018-11-27 02:59:49 +00:00
|
|
|
/// Everything else.
|
2016-02-08 15:04:11 +01:00
|
|
|
Ty(P<Ty>),
|
2014-11-09 16:14:15 +01:00
|
|
|
}
|
|
|
|
|
2020-02-15 12:10:59 +09:00
|
|
|
impl FnRetTy {
|
2014-11-09 16:14:15 +01:00
|
|
|
pub fn span(&self) -> Span {
|
2022-11-16 19:26:38 +00:00
|
|
|
match self {
|
|
|
|
&FnRetTy::Default(span) => span,
|
|
|
|
FnRetTy::Ty(ty) => ty.span,
|
2014-11-09 16:14:15 +01:00
|
|
|
}
|
|
|
|
}
|
2011-05-14 19:02:30 -07:00
|
|
|
}
|
|
|
|
|
2021-02-21 16:32:38 +03:00
|
|
|
#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug)]
|
2021-02-17 00:56:07 +03:00
|
|
|
pub enum Inline {
|
|
|
|
Yes,
|
|
|
|
No,
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Module item kind.
|
2020-08-23 03:42:19 -07:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2021-02-17 00:56:07 +03:00
|
|
|
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.
|
2023-01-30 15:39:22 +11:00
|
|
|
Loaded(ThinVec<P<Item>>, Inline, ModSpans),
|
2021-02-17 00:56:07 +03:00
|
|
|
/// Module with definition outlined to a separate file `mod foo;` but not yet loaded from it.
|
|
|
|
Unloaded,
|
2013-01-15 16:05:20 -08:00
|
|
|
}
|
2010-08-18 09:00:10 -07:00
|
|
|
|
2022-12-15 00:06:34 +01:00
|
|
|
#[derive(Copy, Clone, Encodable, Decodable, Debug, Default)]
|
2022-01-20 11:06:45 -05:00
|
|
|
pub struct ModSpans {
|
|
|
|
/// `inner_span` covers the body of the module; for a file module, its the whole file.
|
|
|
|
/// For an inline module, its the span inside the `{ ... }`, not including the curly braces.
|
|
|
|
pub inner_span: Span,
|
2022-01-20 14:07:54 -05:00
|
|
|
pub inject_use_span: Span,
|
2022-01-20 11:06:45 -05:00
|
|
|
}
|
|
|
|
|
2016-06-24 13:14:34 +02:00
|
|
|
/// Foreign module declaration.
|
|
|
|
///
|
2020-08-23 03:42:19 -07:00
|
|
|
/// E.g., `extern { .. }` or `extern "C" { .. }`.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2014-01-09 15:05:33 +02:00
|
|
|
pub struct ForeignMod {
|
2020-08-23 03:42:19 -07:00
|
|
|
/// `unsafe` keyword accepted syntactically for macro DSLs, but not
|
|
|
|
/// semantically by Rust.
|
2024-05-17 14:17:48 -03:00
|
|
|
pub safety: Safety,
|
2019-11-10 00:44:59 +03:00
|
|
|
pub abi: Option<StrLit>,
|
2022-11-22 16:32:08 +11:00
|
|
|
pub items: ThinVec<P<ForeignItem>>,
|
2013-01-15 16:05:20 -08:00
|
|
|
}
|
2011-02-01 13:40:04 -05:00
|
|
|
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2014-01-09 15:05:33 +02:00
|
|
|
pub struct EnumDef {
|
2023-01-30 15:39:22 +11:00
|
|
|
pub variants: ThinVec<Variant>,
|
2013-01-15 16:05:20 -08:00
|
|
|
}
|
2019-10-24 16:11:43 +03:00
|
|
|
/// Enum variant.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2019-08-13 21:40:21 -03:00
|
|
|
pub struct Variant {
|
2019-03-21 23:38:50 +01:00
|
|
|
/// Attributes of the variant.
|
2021-06-17 07:11:13 +09:00
|
|
|
pub attrs: AttrVec,
|
2019-03-21 23:38:50 +01:00
|
|
|
/// Id of the variant (not the constructor, see `VariantData::ctor_id()`).
|
|
|
|
pub id: NodeId,
|
2019-11-07 11:26:36 +01:00
|
|
|
/// Span
|
|
|
|
pub span: Span,
|
|
|
|
/// The visibility of the variant. Syntactically accepted but not semantically.
|
|
|
|
pub vis: Visibility,
|
|
|
|
/// Name of the variant.
|
|
|
|
pub ident: Ident,
|
|
|
|
|
2019-03-21 23:38:50 +01:00
|
|
|
/// Fields and constructor id of the variant.
|
2015-10-25 18:33:51 +03:00
|
|
|
pub data: VariantData,
|
2018-11-27 02:59:49 +00:00
|
|
|
/// Explicit discriminant, e.g., `Foo = 1`.
|
2018-05-17 21:28:50 +03:00
|
|
|
pub disr_expr: Option<AnonConst>,
|
2024-07-05 18:10:05 +03:00
|
|
|
/// Is a macro placeholder.
|
2019-09-09 09:26:25 -03:00
|
|
|
pub is_placeholder: bool,
|
2013-01-15 16:05:20 -08:00
|
|
|
}
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2018-03-12 23:16:09 +03:00
|
|
|
/// Part of `use` item to the right of its prefix.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2017-09-26 23:04:00 +02:00
|
|
|
pub enum UseTreeKind {
|
2018-03-12 23:16:09 +03:00
|
|
|
/// `use prefix` or `use prefix as rename`
|
2022-12-01 18:51:20 +03:00
|
|
|
Simple(Option<Ident>),
|
2018-03-12 23:16:09 +03:00
|
|
|
/// `use prefix::{...}`
|
2024-05-19 10:22:19 +02:00
|
|
|
///
|
|
|
|
/// The span represents the braces of the nested group and all elements within:
|
|
|
|
///
|
|
|
|
/// ```text
|
|
|
|
/// use foo::{bar, baz};
|
|
|
|
/// ^^^^^^^^^^
|
|
|
|
/// ```
|
2024-04-02 00:26:10 +02:00
|
|
|
Nested { items: ThinVec<(UseTree, NodeId)>, span: Span },
|
2018-03-12 23:16:09 +03:00
|
|
|
/// `use prefix::*`
|
2018-03-09 18:58:44 +03:00
|
|
|
Glob,
|
2011-01-01 12:55:18 -05:00
|
|
|
}
|
|
|
|
|
2018-03-12 23:16:09 +03:00
|
|
|
/// A tree of paths sharing common prefixes.
|
|
|
|
/// Used in `use` items both at top-level and inside of braces in import groups.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2017-09-26 23:04:00 +02:00
|
|
|
pub struct UseTree {
|
|
|
|
pub prefix: Path,
|
2018-03-09 18:58:44 +03:00
|
|
|
pub kind: UseTreeKind,
|
2017-09-26 23:04:00 +02:00
|
|
|
pub span: Span,
|
2016-05-22 18:07:28 +03:00
|
|
|
}
|
|
|
|
|
2018-03-09 18:58:44 +03:00
|
|
|
impl UseTree {
|
|
|
|
pub fn ident(&self) -> Ident {
|
|
|
|
match self.kind {
|
2022-12-01 18:51:20 +03:00
|
|
|
UseTreeKind::Simple(Some(rename)) => rename,
|
|
|
|
UseTreeKind::Simple(None) => {
|
2018-09-22 16:19:44 -07:00
|
|
|
self.prefix.segments.last().expect("empty prefix in a simple import").ident
|
|
|
|
}
|
2018-03-09 18:58:44 +03:00
|
|
|
_ => panic!("`UseTree::ident` can only be used on a simple import"),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-27 02:59:49 +00:00
|
|
|
/// Distinguishes between `Attribute`s that decorate items and Attributes that
|
2014-06-09 13:12:30 -07:00
|
|
|
/// are contained as statements within items. These two cases need to be
|
|
|
|
/// distinguished for pretty-printing.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, HashStable_Generic)]
|
2013-07-19 21:51:37 +10:00
|
|
|
pub enum AttrStyle {
|
2015-10-01 18:03:34 +02:00
|
|
|
Outer,
|
|
|
|
Inner,
|
2013-07-02 12:47:32 -07:00
|
|
|
}
|
2011-06-14 16:13:19 -07:00
|
|
|
|
2019-12-03 16:38:34 +01:00
|
|
|
/// A list of attributes.
|
|
|
|
pub type AttrVec = ThinVec<Attribute>;
|
|
|
|
|
2022-11-25 09:53:37 +11:00
|
|
|
/// A syntax-level representation of an attribute.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2016-11-14 12:00:25 +00:00
|
|
|
pub struct Attribute {
|
2019-10-24 06:33:12 +11:00
|
|
|
pub kind: AttrKind,
|
2014-05-20 00:07:24 -07:00
|
|
|
pub id: AttrId,
|
2019-10-24 16:11:43 +03:00
|
|
|
/// Denotes if the attribute decorates the following construct (outer)
|
|
|
|
/// or the construct this attribute is contained within (inner).
|
2014-03-27 15:39:48 -07:00
|
|
|
pub style: AttrStyle,
|
2016-11-14 12:00:25 +00:00
|
|
|
pub span: Span,
|
2013-01-13 16:51:48 -08:00
|
|
|
}
|
2011-06-14 16:13:19 -07:00
|
|
|
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2019-10-24 06:33:12 +11:00
|
|
|
pub enum AttrKind {
|
|
|
|
/// A normal attribute.
|
2022-08-11 21:06:11 +10:00
|
|
|
Normal(P<NormalAttr>),
|
2019-10-24 06:33:12 +11:00
|
|
|
|
|
|
|
/// 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).
|
2020-07-21 22:16:19 +03:00
|
|
|
DocComment(CommentKind, Symbol),
|
2019-10-24 06:33:12 +11:00
|
|
|
}
|
|
|
|
|
2022-11-25 09:59:36 +11:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
|
|
|
pub struct NormalAttr {
|
|
|
|
pub item: AttrItem,
|
2024-04-25 10:14:17 +10:00
|
|
|
// Tokens for the full attribute, e.g. `#[foo]`, `#![bar]`.
|
2022-11-25 09:59:36 +11:00
|
|
|
pub tokens: Option<LazyAttrTokenStream>,
|
|
|
|
}
|
|
|
|
|
2023-06-30 14:01:24 +00:00
|
|
|
impl NormalAttr {
|
|
|
|
pub fn from_ident(ident: Ident) -> Self {
|
|
|
|
Self {
|
2024-04-20 23:54:50 -05:00
|
|
|
item: AttrItem {
|
2024-05-21 08:37:05 -05:00
|
|
|
unsafety: Safety::Default,
|
2024-04-20 23:54:50 -05:00
|
|
|
path: Path::from_ident(ident),
|
|
|
|
args: AttrArgs::Empty,
|
|
|
|
tokens: None,
|
|
|
|
},
|
2023-06-30 14:01:24 +00:00
|
|
|
tokens: None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-25 09:59:36 +11:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
|
|
|
|
pub struct AttrItem {
|
2024-05-21 08:37:05 -05:00
|
|
|
pub unsafety: Safety,
|
2022-11-25 09:59:36 +11:00
|
|
|
pub path: Path,
|
|
|
|
pub args: AttrArgs,
|
2024-04-25 10:14:17 +10:00
|
|
|
// Tokens for the meta item, e.g. just the `foo` within `#[foo]` or `#![foo]`.
|
2022-11-25 09:59:36 +11:00
|
|
|
pub tokens: Option<LazyAttrTokenStream>,
|
|
|
|
}
|
|
|
|
|
2024-08-02 00:28:57 +08:00
|
|
|
impl AttrItem {
|
|
|
|
pub fn is_valid_for_outer_style(&self) -> bool {
|
|
|
|
self.path == sym::cfg_attr
|
|
|
|
|| self.path == sym::cfg
|
|
|
|
|| self.path == sym::forbid
|
|
|
|
|| self.path == sym::warn
|
|
|
|
|| self.path == sym::allow
|
|
|
|
|| self.path == sym::deny
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-27 02:59:49 +00:00
|
|
|
/// `TraitRef`s appear in impls.
|
2015-03-19 00:56:37 +05:30
|
|
|
///
|
2019-02-08 14:53:55 +01:00
|
|
|
/// Resolution maps each `TraitRef`'s `ref_id` to its defining trait; that's all
|
2018-11-27 02:59:49 +00:00
|
|
|
/// 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`).
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2014-01-09 15:05:33 +02:00
|
|
|
pub struct TraitRef {
|
2014-03-27 15:39:48 -07:00
|
|
|
pub path: Path,
|
|
|
|
pub ref_id: NodeId,
|
2014-11-07 06:53:45 -05:00
|
|
|
}
|
|
|
|
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2014-11-07 06:53:45 -05:00
|
|
|
pub struct PolyTraitRef {
|
2022-04-06 23:08:22 -07:00
|
|
|
/// The `'a` in `for<'a> Foo<&'a T>`.
|
2022-11-22 09:17:20 +11:00
|
|
|
pub bound_generic_params: ThinVec<GenericParam>,
|
2014-11-07 06:53:45 -05:00
|
|
|
|
2019-03-26 17:34:32 +00:00
|
|
|
/// The `Foo<&'a T>` in `<'a> Foo<&'a T>`.
|
2014-12-24 19:38:10 +13:00
|
|
|
pub trait_ref: TraitRef,
|
2015-02-05 21:46:01 +13:00
|
|
|
|
|
|
|
pub span: Span,
|
2013-01-15 16:05:20 -08:00
|
|
|
}
|
2012-04-11 16:18:00 -07:00
|
|
|
|
2017-03-17 00:47:32 +03:00
|
|
|
impl PolyTraitRef {
|
2022-11-22 09:17:20 +11:00
|
|
|
pub fn new(generic_params: ThinVec<GenericParam>, path: Path, span: Span) -> Self {
|
2017-03-17 00:47:32 +03:00
|
|
|
PolyTraitRef {
|
2017-10-16 21:07:26 +02:00
|
|
|
bound_generic_params: generic_params,
|
2020-01-13 20:30:29 -08:00
|
|
|
trait_ref: TraitRef { path, ref_id: DUMMY_NODE_ID },
|
2017-08-06 22:54:09 -07:00
|
|
|
span,
|
2017-03-17 00:47:32 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-21 19:11:00 -04:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
|
|
|
pub struct Visibility {
|
|
|
|
pub kind: VisibilityKind,
|
|
|
|
pub span: Span,
|
2022-09-09 17:15:53 +10:00
|
|
|
pub tokens: Option<LazyAttrTokenStream>,
|
2020-08-21 19:11:00 -04:00
|
|
|
}
|
2018-01-29 14:12:09 +09:00
|
|
|
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2018-01-29 14:12:09 +09:00
|
|
|
pub enum VisibilityKind {
|
2014-01-09 15:05:33 +02:00
|
|
|
Public,
|
2022-08-09 23:31:45 -04:00
|
|
|
Restricted { path: P<Path>, id: NodeId, shorthand: bool },
|
2014-01-09 15:05:33 +02:00
|
|
|
Inherited,
|
2013-07-02 12:47:32 -07:00
|
|
|
}
|
2012-05-08 16:06:24 +02:00
|
|
|
|
2018-03-21 01:58:25 +03:00
|
|
|
impl VisibilityKind {
|
2018-07-06 23:18:38 +03:00
|
|
|
pub fn is_pub(&self) -> bool {
|
2020-09-18 19:11:06 +02:00
|
|
|
matches!(self, VisibilityKind::Public)
|
2018-03-21 01:58:25 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-16 00:36:07 +03:00
|
|
|
/// Field definition in a struct, variant or union.
|
2016-06-24 13:14:34 +02:00
|
|
|
///
|
2018-11-27 02:59:49 +00:00
|
|
|
/// E.g., `bar: usize` as in `struct Foo { bar: usize }`.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2021-03-16 00:36:07 +03:00
|
|
|
pub struct FieldDef {
|
2021-06-17 07:11:13 +09:00
|
|
|
pub attrs: AttrVec,
|
2019-11-07 11:26:36 +01:00
|
|
|
pub id: NodeId,
|
2016-04-06 11:19:10 +03:00
|
|
|
pub span: Span,
|
2016-04-02 16:47:53 +03:00
|
|
|
pub vis: Visibility,
|
2019-11-07 11:26:36 +01:00
|
|
|
pub ident: Option<Ident>,
|
|
|
|
|
2014-03-27 15:39:48 -07:00
|
|
|
pub ty: P<Ty>,
|
2019-09-09 09:26:25 -03:00
|
|
|
pub is_placeholder: bool,
|
2013-01-13 15:28:49 -08:00
|
|
|
}
|
2012-08-15 15:53:58 -07:00
|
|
|
|
2024-05-09 18:44:40 +10:00
|
|
|
/// Was parsing recovery performed?
|
|
|
|
#[derive(Copy, Clone, Debug, Encodable, Decodable, HashStable_Generic)]
|
|
|
|
pub enum Recovered {
|
|
|
|
No,
|
|
|
|
Yes(ErrorGuaranteed),
|
|
|
|
}
|
|
|
|
|
2019-03-21 23:38:50 +01:00
|
|
|
/// Fields and constructor ids of enum variants and structs.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2015-10-10 03:28:40 +03:00
|
|
|
pub enum VariantData {
|
2016-06-24 13:14:34 +02:00
|
|
|
/// Struct variant.
|
|
|
|
///
|
2018-11-27 02:59:49 +00:00
|
|
|
/// E.g., `Bar { .. }` as in `enum Foo { Bar { .. } }`.
|
2024-05-09 18:44:40 +10:00
|
|
|
Struct { fields: ThinVec<FieldDef>, recovered: Recovered },
|
2016-06-24 13:14:34 +02:00
|
|
|
/// Tuple variant.
|
|
|
|
///
|
2018-11-27 02:59:49 +00:00
|
|
|
/// E.g., `Bar(..)` as in `enum Foo { Bar(..) }`.
|
2022-11-23 11:55:16 +11:00
|
|
|
Tuple(ThinVec<FieldDef>, NodeId),
|
2016-06-24 13:14:34 +02:00
|
|
|
/// Unit variant.
|
|
|
|
///
|
2018-11-27 02:59:49 +00:00
|
|
|
/// E.g., `Bar = ..` as in `enum Foo { Bar = .. }`.
|
2015-10-10 03:28:40 +03:00
|
|
|
Unit(NodeId),
|
2015-10-08 23:45:46 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
impl VariantData {
|
2019-03-21 23:38:50 +01:00
|
|
|
/// Return the fields of this variant.
|
2021-03-16 00:36:07 +03:00
|
|
|
pub fn fields(&self) -> &[FieldDef] {
|
2022-11-16 19:26:38 +00:00
|
|
|
match self {
|
2023-12-19 22:47:30 +00:00
|
|
|
VariantData::Struct { fields, .. } | VariantData::Tuple(fields, _) => fields,
|
2015-10-25 18:33:51 +03:00
|
|
|
_ => &[],
|
|
|
|
}
|
2015-10-08 23:45:46 +03:00
|
|
|
}
|
2019-03-21 23:38:50 +01:00
|
|
|
|
|
|
|
/// Return the `NodeId` of this variant's constructor, if it has one.
|
2022-10-25 20:15:15 +04:00
|
|
|
pub fn ctor_node_id(&self) -> Option<NodeId> {
|
2015-10-10 03:28:40 +03:00
|
|
|
match *self {
|
2023-12-19 22:47:30 +00:00
|
|
|
VariantData::Struct { .. } => None,
|
2019-03-21 23:38:50 +01:00
|
|
|
VariantData::Tuple(_, id) | VariantData::Unit(id) => Some(id),
|
2015-10-10 03:28:40 +03:00
|
|
|
}
|
|
|
|
}
|
2013-01-13 13:45:57 -08:00
|
|
|
}
|
2012-08-07 15:34:07 -07:00
|
|
|
|
2020-02-22 03:29:17 +01:00
|
|
|
/// An item definition.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2019-11-30 18:10:59 +01:00
|
|
|
pub struct Item<K = ItemKind> {
|
2022-08-17 12:34:33 +10:00
|
|
|
pub attrs: AttrVec,
|
2014-03-27 15:39:48 -07:00
|
|
|
pub id: NodeId,
|
|
|
|
pub span: Span,
|
2019-11-07 11:26:36 +01:00
|
|
|
pub vis: Visibility,
|
2020-02-22 03:29:17 +01:00
|
|
|
/// The name of the item.
|
|
|
|
/// It might be a dummy name in case of anonymous items.
|
2019-11-07 11:26:36 +01:00
|
|
|
pub ident: Ident,
|
|
|
|
|
2019-11-30 18:10:59 +01:00
|
|
|
pub kind: K,
|
2017-07-10 17:44:46 -07:00
|
|
|
|
|
|
|
/// 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.
|
2017-07-12 09:50:05 -07:00
|
|
|
///
|
|
|
|
/// Note that the tokens here do not include the outer attributes, but will
|
|
|
|
/// include inner attributes.
|
2022-09-09 17:15:53 +10:00
|
|
|
pub tokens: Option<LazyAttrTokenStream>,
|
2013-01-13 13:13:41 -08:00
|
|
|
}
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2019-01-29 13:34:40 +01:00
|
|
|
impl Item {
|
|
|
|
/// Return the span that encompasses the attributes.
|
|
|
|
pub fn span_with_attributes(&self) -> Span {
|
2019-03-03 20:56:24 +03:00
|
|
|
self.attrs.iter().fold(self.span, |acc, attr| acc.to(attr.span))
|
2019-01-29 13:34:40 +01:00
|
|
|
}
|
2023-12-09 17:27:18 +00:00
|
|
|
|
|
|
|
pub fn opt_generics(&self) -> Option<&Generics> {
|
|
|
|
match &self.kind {
|
|
|
|
ItemKind::ExternCrate(_)
|
|
|
|
| ItemKind::Use(_)
|
|
|
|
| ItemKind::Mod(_, _)
|
|
|
|
| ItemKind::ForeignMod(_)
|
|
|
|
| ItemKind::GlobalAsm(_)
|
|
|
|
| ItemKind::MacCall(_)
|
2023-11-26 15:57:31 +03:00
|
|
|
| ItemKind::Delegation(_)
|
2024-03-15 14:21:03 +03:00
|
|
|
| ItemKind::DelegationMac(_)
|
2023-12-09 17:27:18 +00:00
|
|
|
| ItemKind::MacroDef(_) => None,
|
|
|
|
ItemKind::Static(_) => None,
|
|
|
|
ItemKind::Const(i) => Some(&i.generics),
|
|
|
|
ItemKind::Fn(i) => Some(&i.generics),
|
|
|
|
ItemKind::TyAlias(i) => Some(&i.generics),
|
|
|
|
ItemKind::TraitAlias(generics, _)
|
|
|
|
| ItemKind::Enum(_, generics)
|
|
|
|
| ItemKind::Struct(_, generics)
|
|
|
|
| ItemKind::Union(_, generics) => Some(&generics),
|
|
|
|
ItemKind::Trait(i) => Some(&i.generics),
|
|
|
|
ItemKind::Impl(i) => Some(&i.generics),
|
|
|
|
}
|
|
|
|
}
|
2019-01-29 13:34:40 +01:00
|
|
|
}
|
|
|
|
|
2019-11-09 22:05:20 +03:00
|
|
|
/// `extern` qualifier on a function item or function type.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Copy, Encodable, Decodable, Debug)]
|
2019-11-09 22:05:20 +03:00
|
|
|
pub enum Extern {
|
2024-07-05 18:10:05 +03:00
|
|
|
/// No explicit extern keyword was used.
|
2023-01-02 14:25:24 -08:00
|
|
|
///
|
2024-07-05 18:10:05 +03:00
|
|
|
/// E.g. `fn foo() {}`.
|
2019-11-09 22:05:20 +03:00
|
|
|
None,
|
2024-07-05 18:10:05 +03:00
|
|
|
/// An explicit extern keyword was used, but with implicit ABI.
|
2023-01-02 14:25:24 -08:00
|
|
|
///
|
2024-07-05 18:10:05 +03:00
|
|
|
/// E.g. `extern fn foo() {}`.
|
2023-01-02 14:25:24 -08:00
|
|
|
///
|
2024-07-05 18:10:05 +03:00
|
|
|
/// This is just `extern "C"` (see `rustc_target::spec::abi::Abi::FALLBACK`).
|
2022-07-02 18:25:55 +01:00
|
|
|
Implicit(Span),
|
2024-07-05 18:10:05 +03:00
|
|
|
/// An explicit extern keyword was used with an explicit ABI.
|
2023-01-02 14:25:24 -08:00
|
|
|
///
|
2024-07-05 18:10:05 +03:00
|
|
|
/// E.g. `extern "C" fn foo() {}`.
|
2022-07-02 18:25:55 +01:00
|
|
|
Explicit(StrLit, Span),
|
2019-10-27 23:14:35 +01:00
|
|
|
}
|
|
|
|
|
2019-11-09 22:05:20 +03:00
|
|
|
impl Extern {
|
2022-07-02 18:25:55 +01:00
|
|
|
pub fn from_abi(abi: Option<StrLit>, span: Span) -> Extern {
|
|
|
|
match abi {
|
|
|
|
Some(name) => Extern::Explicit(name, span),
|
|
|
|
None => Extern::Implicit(span),
|
|
|
|
}
|
2019-10-27 23:14:35 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-27 02:59:49 +00:00
|
|
|
/// A function header.
|
2018-05-16 22:55:18 -07:00
|
|
|
///
|
2018-11-27 02:59:49 +00:00
|
|
|
/// 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`).
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Copy, Encodable, Decodable, Debug)]
|
2018-05-16 22:55:18 -07:00
|
|
|
pub struct FnHeader {
|
2024-07-05 18:10:05 +03:00
|
|
|
/// Whether this is `unsafe`, or has a default safety.
|
2024-05-17 14:17:48 -03:00
|
|
|
pub safety: Safety,
|
2023-11-30 14:54:39 -08:00
|
|
|
/// Whether this is `async`, `gen`, or nothing.
|
2023-12-05 21:39:36 +00:00
|
|
|
pub coroutine_kind: Option<CoroutineKind>,
|
2023-01-02 14:26:43 -08:00
|
|
|
/// The `const` keyword, if any
|
2020-01-30 02:42:33 +01:00
|
|
|
pub constness: Const,
|
2024-07-05 18:10:05 +03:00
|
|
|
/// The `extern` keyword and corresponding ABI string, if any.
|
2019-11-09 22:05:20 +03:00
|
|
|
pub ext: Extern,
|
2018-05-16 22:55:18 -07:00
|
|
|
}
|
|
|
|
|
2020-01-30 00:18:54 +01:00
|
|
|
impl FnHeader {
|
|
|
|
/// Does this function header have any qualifiers or is it empty?
|
|
|
|
pub fn has_qualifiers(&self) -> bool {
|
2024-05-17 14:17:48 -03:00
|
|
|
let Self { safety, coroutine_kind, constness, ext } = self;
|
|
|
|
matches!(safety, Safety::Unsafe(_))
|
2023-12-05 21:39:36 +00:00
|
|
|
|| coroutine_kind.is_some()
|
2020-01-30 02:42:33 +01:00
|
|
|
|| matches!(constness, Const::Yes(_))
|
2020-01-30 00:18:54 +01:00
|
|
|
|| !matches!(ext, Extern::None)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-16 22:55:18 -07:00
|
|
|
impl Default for FnHeader {
|
|
|
|
fn default() -> FnHeader {
|
2023-12-05 21:39:36 +00:00
|
|
|
FnHeader {
|
2024-05-17 14:17:48 -03:00
|
|
|
safety: Safety::Default,
|
2023-12-05 21:39:36 +00:00
|
|
|
coroutine_kind: None,
|
|
|
|
constness: Const::No,
|
|
|
|
ext: Extern::None,
|
|
|
|
}
|
2018-05-16 22:55:18 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-29 08:31:08 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2021-11-07 16:43:49 +08:00
|
|
|
pub struct Trait {
|
2024-05-17 14:17:48 -03:00
|
|
|
pub safety: Safety,
|
2021-11-07 16:43:49 +08:00
|
|
|
pub is_auto: IsAuto,
|
|
|
|
pub generics: Generics,
|
|
|
|
pub bounds: GenericBounds,
|
2022-11-22 16:32:08 +11:00
|
|
|
pub items: ThinVec<P<AssocItem>>,
|
2021-11-07 16:43:49 +08:00
|
|
|
}
|
2021-02-01 09:19:22 +01:00
|
|
|
|
2021-10-19 18:45:48 -04:00
|
|
|
/// The location of a where clause on a `TyAlias` (`Span`) and whether there was
|
|
|
|
/// a `where` keyword (`bool`). This is split out from `WhereClause`, since there
|
|
|
|
/// are two locations for where clause on type aliases, but their predicates
|
|
|
|
/// are concatenated together.
|
2022-02-14 13:00:10 -05:00
|
|
|
///
|
|
|
|
/// Take this example:
|
2022-03-05 19:38:53 -05:00
|
|
|
/// ```ignore (only-for-syntax-highlight)
|
2022-02-14 13:00:10 -05:00
|
|
|
/// trait Foo {
|
|
|
|
/// type Assoc<'a, 'b> where Self: 'a, Self: 'b;
|
|
|
|
/// }
|
|
|
|
/// impl Foo for () {
|
|
|
|
/// type Assoc<'a, 'b> where Self: 'a = () where Self: 'b;
|
|
|
|
/// // ^^^^^^^^^^^^^^ first where clause
|
|
|
|
/// // ^^^^^^^^^^^^^^ second where clause
|
|
|
|
/// }
|
2022-03-05 19:38:53 -05:00
|
|
|
/// ```
|
2022-03-04 23:21:33 -05:00
|
|
|
///
|
|
|
|
/// If there is no where clause, then this is `false` with `DUMMY_SP`.
|
2021-10-19 18:45:48 -04:00
|
|
|
#[derive(Copy, Clone, Encodable, Decodable, Debug, Default)]
|
2024-02-19 14:25:33 +01:00
|
|
|
pub struct TyAliasWhereClause {
|
|
|
|
pub has_where_token: bool,
|
|
|
|
pub span: Span,
|
|
|
|
}
|
|
|
|
|
|
|
|
/// The span information for the two where clauses on a `TyAlias`.
|
|
|
|
#[derive(Copy, Clone, Encodable, Decodable, Debug, Default)]
|
|
|
|
pub struct TyAliasWhereClauses {
|
|
|
|
/// Before the equals sign.
|
|
|
|
pub before: TyAliasWhereClause,
|
|
|
|
/// After the equals sign.
|
|
|
|
pub after: TyAliasWhereClause,
|
|
|
|
/// The index in `TyAlias.generics.where_clause.predicates` that would split
|
|
|
|
/// into predicates from the where clause before the equals sign and the ones
|
|
|
|
/// from the where clause after the equals sign.
|
|
|
|
pub split: usize,
|
|
|
|
}
|
2021-10-19 18:45:48 -04:00
|
|
|
|
2021-01-29 08:31:08 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2021-11-07 16:43:49 +08:00
|
|
|
pub struct TyAlias {
|
|
|
|
pub defaultness: Defaultness,
|
|
|
|
pub generics: Generics,
|
2024-02-19 14:25:33 +01:00
|
|
|
pub where_clauses: TyAliasWhereClauses,
|
2021-11-07 16:43:49 +08:00
|
|
|
pub bounds: GenericBounds,
|
|
|
|
pub ty: Option<P<Ty>>,
|
|
|
|
}
|
2021-01-29 08:31:08 +01:00
|
|
|
|
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2021-11-07 16:43:49 +08:00
|
|
|
pub struct Impl {
|
2021-01-29 08:31:08 +01:00
|
|
|
pub defaultness: Defaultness,
|
2024-05-17 14:17:48 -03:00
|
|
|
pub safety: Safety,
|
2021-01-29 08:31:08 +01:00
|
|
|
pub generics: Generics,
|
2021-11-07 16:43:49 +08:00
|
|
|
pub constness: Const,
|
|
|
|
pub polarity: ImplPolarity,
|
2021-01-29 08:31:08 +01:00
|
|
|
/// The trait being implemented, if any.
|
|
|
|
pub of_trait: Option<TraitRef>,
|
|
|
|
pub self_ty: P<Ty>,
|
2022-11-22 16:32:08 +11:00
|
|
|
pub items: ThinVec<P<AssocItem>>,
|
2021-01-29 08:31:08 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2021-11-07 16:43:49 +08:00
|
|
|
pub struct Fn {
|
|
|
|
pub defaultness: Defaultness,
|
|
|
|
pub generics: Generics,
|
|
|
|
pub sig: FnSig,
|
|
|
|
pub body: Option<P<Block>>,
|
|
|
|
}
|
2021-01-29 08:31:08 +01:00
|
|
|
|
2023-11-26 15:57:31 +03:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
|
|
|
pub struct Delegation {
|
|
|
|
/// Path resolution id.
|
|
|
|
pub id: NodeId,
|
|
|
|
pub qself: Option<P<QSelf>>,
|
|
|
|
pub path: Path,
|
2024-03-15 14:21:03 +03:00
|
|
|
pub rename: Option<Ident>,
|
|
|
|
pub body: Option<P<Block>>,
|
2024-03-15 14:21:03 +03:00
|
|
|
/// The item was expanded from a glob delegation item.
|
|
|
|
pub from_glob: bool,
|
2024-03-15 14:21:03 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
|
|
|
pub struct DelegationMac {
|
|
|
|
pub qself: Option<P<QSelf>>,
|
|
|
|
pub prefix: Path,
|
2024-03-15 14:21:03 +03:00
|
|
|
// Some for list delegation, and None for glob delegation.
|
|
|
|
pub suffixes: Option<ThinVec<(Ident, Option<Ident>)>>,
|
2023-11-26 15:57:31 +03:00
|
|
|
pub body: Option<P<Block>>,
|
|
|
|
}
|
|
|
|
|
2023-03-29 08:37:47 +00:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2023-03-29 14:14:11 +00:00
|
|
|
pub struct StaticItem {
|
2023-03-29 08:50:04 +00:00
|
|
|
pub ty: P<Ty>,
|
2024-05-07 14:43:23 +02:00
|
|
|
pub safety: Safety,
|
2023-03-29 08:50:04 +00:00
|
|
|
pub mutability: Mutability,
|
|
|
|
pub expr: Option<P<Expr>>,
|
|
|
|
}
|
2023-03-29 08:37:47 +00:00
|
|
|
|
2023-03-29 09:20:45 +00:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
|
|
|
pub struct ConstItem {
|
|
|
|
pub defaultness: Defaultness,
|
2023-05-04 16:08:33 +02:00
|
|
|
pub generics: Generics,
|
2023-03-29 09:20:45 +00:00
|
|
|
pub ty: P<Ty>,
|
|
|
|
pub expr: Option<P<Expr>>,
|
|
|
|
}
|
|
|
|
|
2023-10-20 09:55:29 +11:00
|
|
|
// Adding a new variant? Please update `test_item` in `tests/ui/macros/stringify.rs`.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2016-02-09 11:36:51 +01:00
|
|
|
pub enum ItemKind {
|
2019-09-06 03:56:45 +01:00
|
|
|
/// An `extern crate` item, with the optional *original* crate name if the crate was renamed.
|
2015-03-19 00:56:37 +05:30
|
|
|
///
|
2018-11-27 02:59:49 +00:00
|
|
|
/// E.g., `extern crate foo` or `extern crate foo_bar as foo`.
|
2020-04-19 13:00:18 +02:00
|
|
|
ExternCrate(Option<Symbol>),
|
2019-09-06 03:56:45 +01:00
|
|
|
/// A use declaration item (`use`).
|
2016-06-24 13:14:34 +02:00
|
|
|
///
|
2018-11-27 02:59:49 +00:00
|
|
|
/// E.g., `use foo;`, `use foo::bar;` or `use foo::bar as FooBar;`.
|
2021-02-20 10:51:26 +01:00
|
|
|
Use(UseTree),
|
2019-09-06 03:56:45 +01:00
|
|
|
/// A static item (`static`).
|
2016-06-24 13:14:34 +02:00
|
|
|
///
|
2018-11-27 02:59:49 +00:00
|
|
|
/// E.g., `static FOO: i32 = 42;` or `static FOO: &'static str = "bar";`.
|
2023-03-29 14:14:11 +00:00
|
|
|
Static(Box<StaticItem>),
|
2019-09-06 03:56:45 +01:00
|
|
|
/// A constant item (`const`).
|
2016-06-24 13:14:34 +02:00
|
|
|
///
|
2018-11-27 02:59:49 +00:00
|
|
|
/// E.g., `const FOO: i32 = 42;`.
|
2023-03-29 12:34:05 +00:00
|
|
|
Const(Box<ConstItem>),
|
2019-09-06 03:56:45 +01:00
|
|
|
/// A function declaration (`fn`).
|
2016-06-24 13:14:34 +02:00
|
|
|
///
|
2018-11-27 02:59:49 +00:00
|
|
|
/// E.g., `fn foo(bar: usize) -> usize { .. }`.
|
2021-11-07 16:43:49 +08:00
|
|
|
Fn(Box<Fn>),
|
2019-09-06 03:56:45 +01:00
|
|
|
/// A module declaration (`mod`).
|
2016-06-24 13:14:34 +02:00
|
|
|
///
|
2018-11-27 02:59:49 +00:00
|
|
|
/// E.g., `mod foo;` or `mod foo { .. }`.
|
2021-02-17 00:56:07 +03:00
|
|
|
/// `unsafe` keyword on modules is accepted syntactically for macro DSLs, but not
|
|
|
|
/// semantically by Rust.
|
2024-05-17 14:17:48 -03:00
|
|
|
Mod(Safety, ModKind),
|
2019-09-06 03:56:45 +01:00
|
|
|
/// An external module (`extern`).
|
2016-06-24 13:14:34 +02:00
|
|
|
///
|
2018-11-27 02:59:49 +00:00
|
|
|
/// E.g., `extern {}` or `extern "C" {}`.
|
2016-02-09 11:36:51 +01:00
|
|
|
ForeignMod(ForeignMod),
|
2018-11-27 02:59:49 +00:00
|
|
|
/// Module-level inline assembly (from `global_asm!()`).
|
2021-10-14 03:23:09 -04:00
|
|
|
GlobalAsm(Box<InlineAsm>),
|
2019-09-06 03:56:45 +01:00
|
|
|
/// A type alias (`type`).
|
2016-06-24 13:14:34 +02:00
|
|
|
///
|
2018-11-27 02:59:49 +00:00
|
|
|
/// E.g., `type Foo = Bar<u8>;`.
|
2021-11-07 16:43:49 +08:00
|
|
|
TyAlias(Box<TyAlias>),
|
2019-09-06 03:56:45 +01:00
|
|
|
/// An enum definition (`enum`).
|
2016-06-24 13:14:34 +02:00
|
|
|
///
|
2018-11-27 02:59:49 +00:00
|
|
|
/// E.g., `enum Foo<A, B> { C<A>, D<B> }`.
|
2016-02-09 11:36:51 +01:00
|
|
|
Enum(EnumDef, Generics),
|
2019-09-06 03:56:45 +01:00
|
|
|
/// A struct definition (`struct`).
|
2016-06-24 13:14:34 +02:00
|
|
|
///
|
2018-11-27 02:59:49 +00:00
|
|
|
/// E.g., `struct Foo<A> { x: A }`.
|
2016-02-09 11:36:51 +01:00
|
|
|
Struct(VariantData, Generics),
|
2019-09-06 03:56:45 +01:00
|
|
|
/// A union definition (`union`).
|
2016-08-29 05:04:31 +00:00
|
|
|
///
|
2018-11-27 02:59:49 +00:00
|
|
|
/// E.g., `union Foo<A, B> { x: A, y: B }`.
|
2016-07-17 00:15:15 +03:00
|
|
|
Union(VariantData, Generics),
|
2019-09-06 03:56:45 +01:00
|
|
|
/// A trait declaration (`trait`).
|
2016-06-24 13:14:34 +02:00
|
|
|
///
|
2018-11-27 02:59:49 +00:00
|
|
|
/// E.g., `trait Foo { .. }`, `trait Foo<T> { .. }` or `auto trait Foo {}`.
|
2021-11-07 16:43:49 +08:00
|
|
|
Trait(Box<Trait>),
|
2024-07-05 18:10:05 +03:00
|
|
|
/// Trait alias.
|
2017-10-02 12:27:45 +00:00
|
|
|
///
|
2018-11-27 02:59:49 +00:00
|
|
|
/// E.g., `trait Foo = Bar + Quux;`.
|
2018-06-14 12:08:58 +01:00
|
|
|
TraitAlias(Generics, GenericBounds),
|
2016-06-24 13:14:34 +02:00
|
|
|
/// An implementation.
|
|
|
|
///
|
2018-11-27 02:59:49 +00:00
|
|
|
/// E.g., `impl<A> Foo<A> { .. }` or `impl<A> Trait for Foo<A> { .. }`.
|
2021-11-07 16:43:49 +08:00
|
|
|
Impl(Box<Impl>),
|
2017-03-05 05:15:58 +00:00
|
|
|
/// A macro invocation.
|
2016-06-24 13:14:34 +02:00
|
|
|
///
|
2019-07-14 20:16:16 +01:00
|
|
|
/// E.g., `foo!(..)`.
|
2022-08-12 12:20:10 +10:00
|
|
|
MacCall(P<MacCall>),
|
2017-03-05 05:15:58 +00:00
|
|
|
|
|
|
|
/// A macro definition.
|
2017-03-17 21:58:48 +00:00
|
|
|
MacroDef(MacroDef),
|
2023-11-26 15:57:31 +03:00
|
|
|
|
2024-03-15 14:21:03 +03:00
|
|
|
/// A single delegation item (`reuse`).
|
2023-11-26 15:57:31 +03:00
|
|
|
///
|
|
|
|
/// E.g. `reuse <Type as Trait>::name { target_expr_template }`.
|
|
|
|
Delegation(Box<Delegation>),
|
2024-03-15 14:21:03 +03:00
|
|
|
/// A list or glob delegation item (`reuse prefix::{a, b, c}`, `reuse prefix::*`).
|
2024-03-15 14:21:03 +03:00
|
|
|
/// Treated similarly to a macro call and expanded early.
|
|
|
|
DelegationMac(Box<DelegationMac>),
|
2011-05-11 15:10:24 +02:00
|
|
|
}
|
|
|
|
|
2016-02-09 11:36:51 +01:00
|
|
|
impl ItemKind {
|
2024-05-14 12:23:33 +02:00
|
|
|
/// "a" or "an"
|
2023-04-27 01:53:06 +01:00
|
|
|
pub fn article(&self) -> &'static str {
|
2020-02-23 06:04:37 +01:00
|
|
|
use ItemKind::*;
|
|
|
|
match self {
|
|
|
|
Use(..) | Static(..) | Const(..) | Fn(..) | Mod(..) | GlobalAsm(..) | TyAlias(..)
|
2023-11-26 15:57:31 +03:00
|
|
|
| Struct(..) | Union(..) | Trait(..) | TraitAlias(..) | MacroDef(..)
|
2024-03-15 14:21:03 +03:00
|
|
|
| Delegation(..) | DelegationMac(..) => "a",
|
2020-02-29 19:32:20 +03:00
|
|
|
ExternCrate(..) | ForeignMod(..) | MacCall(..) | Enum(..) | Impl { .. } => "an",
|
2020-02-23 06:04:37 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-27 01:53:06 +01:00
|
|
|
pub fn descr(&self) -> &'static str {
|
2020-02-23 06:04:37 +01:00
|
|
|
match self {
|
2016-02-09 11:36:51 +01:00
|
|
|
ItemKind::ExternCrate(..) => "extern crate",
|
2020-02-23 06:04:37 +01:00
|
|
|
ItemKind::Use(..) => "`use` import",
|
2023-03-29 08:50:04 +00:00
|
|
|
ItemKind::Static(..) => "static item",
|
2016-02-09 11:36:51 +01:00
|
|
|
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",
|
2019-08-02 11:02:08 +01:00
|
|
|
ItemKind::TyAlias(..) => "type alias",
|
2016-02-09 11:36:51 +01:00
|
|
|
ItemKind::Enum(..) => "enum",
|
|
|
|
ItemKind::Struct(..) => "struct",
|
2016-08-29 05:04:31 +00:00
|
|
|
ItemKind::Union(..) => "union",
|
2016-02-09 11:36:51 +01:00
|
|
|
ItemKind::Trait(..) => "trait",
|
2017-10-02 12:27:45 +00:00
|
|
|
ItemKind::TraitAlias(..) => "trait alias",
|
2020-02-29 19:32:20 +03:00
|
|
|
ItemKind::MacCall(..) => "item macro invocation",
|
2020-02-23 06:04:37 +01:00
|
|
|
ItemKind::MacroDef(..) => "macro definition",
|
|
|
|
ItemKind::Impl { .. } => "implementation",
|
2023-11-26 15:57:31 +03:00
|
|
|
ItemKind::Delegation(..) => "delegated function",
|
2024-03-15 14:21:03 +03:00
|
|
|
ItemKind::DelegationMac(..) => "delegation",
|
2014-09-20 14:08:10 +02:00
|
|
|
}
|
|
|
|
}
|
2020-01-21 23:01:21 -08:00
|
|
|
|
|
|
|
pub fn generics(&self) -> Option<&Generics> {
|
|
|
|
match self {
|
2021-11-07 16:43:49 +08:00
|
|
|
Self::Fn(box Fn { generics, .. })
|
|
|
|
| Self::TyAlias(box TyAlias { generics, .. })
|
2023-05-04 16:08:33 +02:00
|
|
|
| Self::Const(box ConstItem { generics, .. })
|
2020-01-21 23:01:21 -08:00
|
|
|
| Self::Enum(_, generics)
|
|
|
|
| Self::Struct(_, generics)
|
|
|
|
| Self::Union(_, generics)
|
2021-11-07 16:43:49 +08:00
|
|
|
| Self::Trait(box Trait { generics, .. })
|
2020-01-21 23:01:21 -08:00
|
|
|
| Self::TraitAlias(generics, _)
|
2021-11-07 16:43:49 +08:00
|
|
|
| Self::Impl(box Impl { generics, .. }) => Some(generics),
|
2020-01-21 23:01:21 -08:00
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
2014-09-20 14:08:10 +02:00
|
|
|
}
|
|
|
|
|
2020-02-13 18:05:40 +01:00
|
|
|
/// Represents associated items.
|
|
|
|
/// These include items in `impl` and `trait` definitions.
|
2020-02-22 03:29:17 +01:00
|
|
|
pub type AssocItem = Item<AssocItemKind>;
|
2011-02-02 10:43:57 -05:00
|
|
|
|
2020-02-29 15:51:08 +03:00
|
|
|
/// Represents associated item kinds.
|
2020-02-13 18:05:40 +01:00
|
|
|
///
|
|
|
|
/// 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".
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2020-02-13 18:05:40 +01:00
|
|
|
pub enum AssocItemKind {
|
2020-02-29 15:51:08 +03:00
|
|
|
/// An associated constant, `const $ident: $ty $def?;` where `def ::= "=" $expr? ;`.
|
2020-02-13 18:15:58 +01:00
|
|
|
/// If `def` is parsed, then the constant is provided, and otherwise required.
|
2023-03-29 12:34:05 +00:00
|
|
|
Const(Box<ConstItem>),
|
2020-02-29 15:51:08 +03:00
|
|
|
/// An associated function.
|
2021-11-07 16:43:49 +08:00
|
|
|
Fn(Box<Fn>),
|
2020-02-29 15:51:08 +03:00
|
|
|
/// An associated type.
|
2022-10-10 02:05:24 +00:00
|
|
|
Type(Box<TyAlias>),
|
2020-02-29 15:51:08 +03:00
|
|
|
/// A macro expanding to associated items.
|
2022-08-12 12:20:10 +10:00
|
|
|
MacCall(P<MacCall>),
|
2023-11-26 15:57:31 +03:00
|
|
|
/// An associated delegation item.
|
|
|
|
Delegation(Box<Delegation>),
|
2024-03-15 14:21:03 +03:00
|
|
|
/// An associated list or glob delegation item.
|
2024-03-15 14:21:03 +03:00
|
|
|
DelegationMac(Box<DelegationMac>),
|
2014-09-20 14:08:10 +02:00
|
|
|
}
|
2020-02-23 10:24:30 +01:00
|
|
|
|
|
|
|
impl AssocItemKind {
|
|
|
|
pub fn defaultness(&self) -> Defaultness {
|
|
|
|
match *self {
|
2023-03-29 12:34:05 +00:00
|
|
|
Self::Const(box ConstItem { defaultness, .. })
|
2021-11-07 16:43:49 +08:00
|
|
|
| Self::Fn(box Fn { defaultness, .. })
|
2022-10-10 02:05:24 +00:00
|
|
|
| Self::Type(box TyAlias { defaultness, .. }) => defaultness,
|
2024-03-15 14:21:03 +03:00
|
|
|
Self::MacCall(..) | Self::Delegation(..) | Self::DelegationMac(..) => {
|
|
|
|
Defaultness::Final
|
|
|
|
}
|
2020-02-23 10:24:30 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-02-24 12:06:45 +03:00
|
|
|
|
2020-02-29 15:51:08 +03:00
|
|
|
impl From<AssocItemKind> for ItemKind {
|
|
|
|
fn from(assoc_item_kind: AssocItemKind) -> ItemKind {
|
|
|
|
match assoc_item_kind {
|
2023-03-29 09:20:45 +00:00
|
|
|
AssocItemKind::Const(item) => ItemKind::Const(item),
|
2021-01-29 08:31:08 +01:00
|
|
|
AssocItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
|
2022-10-10 02:05:24 +00:00
|
|
|
AssocItemKind::Type(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
|
2020-02-29 19:32:20 +03:00
|
|
|
AssocItemKind::MacCall(a) => ItemKind::MacCall(a),
|
2023-11-26 15:57:31 +03:00
|
|
|
AssocItemKind::Delegation(delegation) => ItemKind::Delegation(delegation),
|
2024-03-15 14:21:03 +03:00
|
|
|
AssocItemKind::DelegationMac(delegation) => ItemKind::DelegationMac(delegation),
|
2020-02-24 12:06:45 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-02-29 15:51:08 +03:00
|
|
|
|
2020-02-29 18:29:44 +03:00
|
|
|
impl TryFrom<ItemKind> for AssocItemKind {
|
|
|
|
type Error = ItemKind;
|
|
|
|
|
|
|
|
fn try_from(item_kind: ItemKind) -> Result<AssocItemKind, ItemKind> {
|
|
|
|
Ok(match item_kind {
|
2023-03-29 09:20:45 +00:00
|
|
|
ItemKind::Const(item) => AssocItemKind::Const(item),
|
2021-01-29 08:31:08 +01:00
|
|
|
ItemKind::Fn(fn_kind) => AssocItemKind::Fn(fn_kind),
|
2022-10-10 02:05:24 +00:00
|
|
|
ItemKind::TyAlias(ty_kind) => AssocItemKind::Type(ty_kind),
|
2020-02-29 19:32:20 +03:00
|
|
|
ItemKind::MacCall(a) => AssocItemKind::MacCall(a),
|
2023-11-26 15:57:31 +03:00
|
|
|
ItemKind::Delegation(d) => AssocItemKind::Delegation(d),
|
2024-03-15 14:21:03 +03:00
|
|
|
ItemKind::DelegationMac(d) => AssocItemKind::DelegationMac(d),
|
2020-02-29 18:29:44 +03:00
|
|
|
_ => return Err(item_kind),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-29 15:51:08 +03:00
|
|
|
/// An item in `extern` block.
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
2020-02-29 15:51:08 +03:00
|
|
|
pub enum ForeignItemKind {
|
|
|
|
/// A foreign static item (`static FOO: u8`).
|
2024-06-20 19:50:57 -04:00
|
|
|
Static(Box<StaticItem>),
|
2021-01-29 08:31:08 +01:00
|
|
|
/// An foreign function.
|
2021-11-07 16:43:49 +08:00
|
|
|
Fn(Box<Fn>),
|
2021-01-29 08:31:08 +01:00
|
|
|
/// An foreign type.
|
2021-11-07 16:43:49 +08:00
|
|
|
TyAlias(Box<TyAlias>),
|
2020-02-29 15:51:08 +03:00
|
|
|
/// A macro expanding to foreign items.
|
2022-08-12 12:20:10 +10:00
|
|
|
MacCall(P<MacCall>),
|
2020-02-29 15:51:08 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
impl From<ForeignItemKind> for ItemKind {
|
|
|
|
fn from(foreign_item_kind: ForeignItemKind) -> ItemKind {
|
|
|
|
match foreign_item_kind {
|
2024-04-29 11:27:14 -03:00
|
|
|
ForeignItemKind::Static(box static_foreign_item) => {
|
2024-09-11 14:58:08 -04:00
|
|
|
ItemKind::Static(Box::new(static_foreign_item))
|
2023-03-29 08:50:04 +00:00
|
|
|
}
|
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 19:32:20 +03:00
|
|
|
ForeignItemKind::MacCall(a) => ItemKind::MacCall(a),
|
2020-02-29 15:51:08 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-29 18:29:44 +03:00
|
|
|
impl TryFrom<ItemKind> for ForeignItemKind {
|
|
|
|
type Error = ItemKind;
|
|
|
|
|
|
|
|
fn try_from(item_kind: ItemKind) -> Result<ForeignItemKind, ItemKind> {
|
|
|
|
Ok(match item_kind {
|
2024-09-11 14:58:08 -04:00
|
|
|
ItemKind::Static(box static_item) => ForeignItemKind::Static(Box::new(static_item)),
|
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 19:32:20 +03:00
|
|
|
ItemKind::MacCall(a) => ForeignItemKind::MacCall(a),
|
2020-02-29 18:29:44 +03:00
|
|
|
_ => return Err(item_kind),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-29 15:51:08 +03:00
|
|
|
pub type ForeignItem = Item<ForeignItemKind>;
|
2022-07-31 06:57:53 +10:00
|
|
|
|
|
|
|
// Some nodes are used a lot. Make sure they don't unintentionally get bigger.
|
2024-04-16 17:02:20 +10:00
|
|
|
#[cfg(target_pointer_width = "64")]
|
2022-07-31 06:57:53 +10:00
|
|
|
mod size_asserts {
|
2022-08-10 09:47:59 +10:00
|
|
|
use rustc_data_structures::static_assert_size;
|
2024-07-29 08:13:50 +10:00
|
|
|
|
2022-07-31 06:57:53 +10:00
|
|
|
use super::*;
|
2022-10-05 21:46:21 +02:00
|
|
|
// tidy-alphabetical-start
|
2023-03-29 12:34:05 +00:00
|
|
|
static_assert_size!(AssocItem, 88);
|
|
|
|
static_assert_size!(AssocItemKind, 16);
|
2022-08-11 21:06:11 +10:00
|
|
|
static_assert_size!(Attribute, 32);
|
2023-01-30 14:13:27 +11:00
|
|
|
static_assert_size!(Block, 32);
|
2022-09-08 17:22:52 +10:00
|
|
|
static_assert_size!(Expr, 72);
|
|
|
|
static_assert_size!(ExprKind, 40);
|
2023-11-30 14:54:39 -08:00
|
|
|
static_assert_size!(Fn, 160);
|
2024-04-29 11:27:14 -03:00
|
|
|
static_assert_size!(ForeignItem, 88);
|
|
|
|
static_assert_size!(ForeignItemKind, 16);
|
2022-08-26 15:07:40 +10:00
|
|
|
static_assert_size!(GenericArg, 24);
|
2024-01-26 17:00:28 +00:00
|
|
|
static_assert_size!(GenericBound, 88);
|
2022-11-22 16:23:25 +11:00
|
|
|
static_assert_size!(Generics, 40);
|
2022-11-22 16:32:08 +11:00
|
|
|
static_assert_size!(Impl, 136);
|
2023-01-30 15:39:22 +11:00
|
|
|
static_assert_size!(Item, 136);
|
|
|
|
static_assert_size!(ItemKind, 64);
|
2024-01-17 15:40:30 -08:00
|
|
|
static_assert_size!(LitKind, 24);
|
Detect more cases of `=` to `:` typo
When a `Local` is fully parsed, but not followed by a `;`, keep the `:` span
arround and mention it. If the type could continue being parsed as an
expression, suggest replacing the `:` with a `=`.
```
error: expected one of `!`, `+`, `->`, `::`, `;`, or `=`, found `.`
--> file.rs:2:32
|
2 | let _: std::env::temp_dir().join("foo");
| - ^ expected one of `!`, `+`, `->`, `::`, `;`, or `=`
| |
| while parsing the type for `_`
| help: use `=` if you meant to assign
```
Fix #119665.
2024-02-27 00:48:32 +00:00
|
|
|
static_assert_size!(Local, 80);
|
2024-01-17 15:40:30 -08:00
|
|
|
static_assert_size!(MetaItemLit, 40);
|
2022-08-26 15:07:40 +10:00
|
|
|
static_assert_size!(Param, 40);
|
2023-01-30 14:58:23 +11:00
|
|
|
static_assert_size!(Pat, 72);
|
2022-09-08 17:22:52 +10:00
|
|
|
static_assert_size!(Path, 24);
|
2022-08-10 09:47:59 +10:00
|
|
|
static_assert_size!(PathSegment, 24);
|
2023-01-30 14:58:23 +11:00
|
|
|
static_assert_size!(PatKind, 48);
|
2022-08-10 09:47:59 +10:00
|
|
|
static_assert_size!(Stmt, 32);
|
2022-08-16 12:18:34 +10:00
|
|
|
static_assert_size!(StmtKind, 16);
|
2022-09-08 17:22:52 +10:00
|
|
|
static_assert_size!(Ty, 64);
|
|
|
|
static_assert_size!(TyKind, 40);
|
2022-10-05 21:46:21 +02:00
|
|
|
// tidy-alphabetical-end
|
2022-07-31 06:57:53 +10:00
|
|
|
}
|