2020-02-11 18:41:28 +00:00
|
|
|
use crate::def::{DefKind, Namespace, Res};
|
2020-01-02 04:18:45 +00:00
|
|
|
use crate::def_id::DefId;
|
|
|
|
crate use crate::hir_id::HirId;
|
2020-08-04 13:34:24 +00:00
|
|
|
use crate::{itemlikevisit, LangItem};
|
2016-03-29 10:14:01 +00:00
|
|
|
|
2020-02-29 17:37:32 +00:00
|
|
|
use rustc_ast::util::parser::ExprPrecedence;
|
2020-04-27 17:56:11 +00:00
|
|
|
use rustc_ast::{self as ast, CrateSugar, LlvmAsmDialect};
|
|
|
|
use rustc_ast::{AttrVec, Attribute, FloatTy, IntTy, Label, LitKind, StrStyle, UintTy};
|
|
|
|
pub use rustc_ast::{BorrowKind, ImplPolarity, IsAuto};
|
|
|
|
pub use rustc_ast::{CaptureBy, Movability, Mutability};
|
|
|
|
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
|
2019-02-24 21:37:55 +00:00
|
|
|
use rustc_data_structures::sync::{par_for_each_in, Send, Sync};
|
2020-01-02 04:18:45 +00:00
|
|
|
use rustc_macros::HashStable_Generic;
|
2020-06-14 21:35:29 +00:00
|
|
|
use rustc_span::def_id::LocalDefId;
|
2020-08-04 13:18:11 +00:00
|
|
|
use rustc_span::source_map::Spanned;
|
2020-04-19 11:00:18 +00:00
|
|
|
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
2019-12-31 17:15:40 +00:00
|
|
|
use rustc_span::{MultiSpan, Span, DUMMY_SP};
|
2020-05-06 13:46:01 +00:00
|
|
|
use rustc_target::asm::InlineAsmRegOrRegClass;
|
2019-12-22 22:42:04 +00:00
|
|
|
use rustc_target::spec::abi::Abi;
|
2015-12-01 17:38:40 +00:00
|
|
|
|
2020-01-11 14:03:15 +00:00
|
|
|
use smallvec::SmallVec;
|
|
|
|
use std::collections::{BTreeMap, BTreeSet};
|
|
|
|
use std::fmt;
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Copy, Clone, Encodable, HashStable_Generic)]
|
2015-07-31 07:04:06 +00:00
|
|
|
pub struct Lifetime {
|
2019-02-02 14:40:08 +00:00
|
|
|
pub hir_id: HirId,
|
2015-07-31 07:04:06 +00:00
|
|
|
pub span: Span,
|
2017-01-09 15:46:11 +00:00
|
|
|
|
2019-02-08 13:53:55 +00:00
|
|
|
/// Either "`'a`", referring to a named lifetime definition,
|
2019-05-11 14:41:37 +00:00
|
|
|
/// or "``" (i.e., `kw::Invalid`), for elision placeholders.
|
2017-01-09 15:46:11 +00:00
|
|
|
///
|
|
|
|
/// HIR lowering inserts these placeholders in type paths that
|
|
|
|
/// refer to type definitions needing lifetime parameters,
|
|
|
|
/// `&T` and `&mut T`, and trait objects without `... + 'a`.
|
2017-09-19 23:36:54 +00:00
|
|
|
pub name: LifetimeName,
|
|
|
|
}
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, Clone, PartialEq, Eq, Encodable, Hash, Copy)]
|
2020-01-02 04:18:45 +00:00
|
|
|
#[derive(HashStable_Generic)]
|
2018-06-01 22:23:48 +00:00
|
|
|
pub enum ParamName {
|
|
|
|
/// Some user-given name like `T` or `'x`.
|
2018-06-27 21:12:17 +00:00
|
|
|
Plain(Ident),
|
2018-03-21 20:30:09 +00:00
|
|
|
|
2019-02-08 13:53:55 +00:00
|
|
|
/// Synthetic name generated when user elided a lifetime in an impl header.
|
|
|
|
///
|
|
|
|
/// E.g., the lifetimes in cases like these:
|
2018-03-21 21:12:39 +00:00
|
|
|
///
|
|
|
|
/// impl Foo for &u32
|
|
|
|
/// impl Foo<'_> for u32
|
|
|
|
///
|
|
|
|
/// in that case, we rewrite to
|
|
|
|
///
|
|
|
|
/// impl<'f> Foo for &'f u32
|
|
|
|
/// impl<'f> Foo<'f> for u32
|
|
|
|
///
|
|
|
|
/// where `'f` is something like `Fresh(0)`. The indices are
|
|
|
|
/// unique per impl, but not necessarily continuous.
|
|
|
|
Fresh(usize),
|
2018-10-11 19:51:44 +00:00
|
|
|
|
|
|
|
/// Indicates an illegal name was given and an error has been
|
2019-09-09 15:44:11 +00:00
|
|
|
/// reported (so we should squelch other derived errors). Occurs
|
2019-02-08 13:53:55 +00:00
|
|
|
/// when, e.g., `'_` is used in the wrong place.
|
2018-10-11 19:51:44 +00:00
|
|
|
Error,
|
2018-06-01 22:23:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl ParamName {
|
2018-06-27 21:12:17 +00:00
|
|
|
pub fn ident(&self) -> Ident {
|
|
|
|
match *self {
|
|
|
|
ParamName::Plain(ident) => ident,
|
2019-12-22 22:42:04 +00:00
|
|
|
ParamName::Fresh(_) | ParamName::Error => {
|
|
|
|
Ident::with_dummy_span(kw::UnderscoreLifetime)
|
|
|
|
}
|
2018-06-27 21:12:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-13 22:36:46 +00:00
|
|
|
pub fn normalize_to_macros_2_0(&self) -> ParamName {
|
2018-06-01 22:23:48 +00:00
|
|
|
match *self {
|
2020-03-13 22:36:46 +00:00
|
|
|
ParamName::Plain(ident) => ParamName::Plain(ident.normalize_to_macros_2_0()),
|
2018-06-27 21:12:17 +00:00
|
|
|
param_name => param_name,
|
2018-06-01 22:23:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, Clone, PartialEq, Eq, Encodable, Hash, Copy)]
|
2020-01-02 04:18:45 +00:00
|
|
|
#[derive(HashStable_Generic)]
|
2018-06-01 22:23:48 +00:00
|
|
|
pub enum LifetimeName {
|
|
|
|
/// User-given names or fresh (synthetic) names.
|
|
|
|
Param(ParamName),
|
|
|
|
|
2019-02-08 13:53:55 +00:00
|
|
|
/// User wrote nothing (e.g., the lifetime in `&u32`).
|
2018-06-01 22:23:48 +00:00
|
|
|
Implicit,
|
|
|
|
|
2019-08-08 07:36:24 +00:00
|
|
|
/// Implicit lifetime in a context like `dyn Foo`. This is
|
|
|
|
/// distinguished from implicit lifetimes elsewhere because the
|
|
|
|
/// lifetime that they default to must appear elsewhere within the
|
|
|
|
/// enclosing type. This means that, in an `impl Trait` context, we
|
|
|
|
/// don't have to create a parameter for them. That is, `impl
|
|
|
|
/// Trait<Item = &u32>` expands to an opaque type like `type
|
|
|
|
/// Foo<'a> = impl Trait<Item = &'a u32>`, but `impl Trait<item =
|
|
|
|
/// dyn Bar>` expands to `type Foo = impl Trait<Item = dyn Bar +
|
|
|
|
/// 'static>`. The latter uses `ImplicitObjectLifetimeDefault` so
|
|
|
|
/// that surrounding code knows not to create a lifetime
|
|
|
|
/// parameter.
|
|
|
|
ImplicitObjectLifetimeDefault,
|
|
|
|
|
2018-10-11 19:51:44 +00:00
|
|
|
/// Indicates an error during lowering (usually `'_` in wrong place)
|
|
|
|
/// that was already reported.
|
|
|
|
Error,
|
|
|
|
|
2019-02-08 13:53:55 +00:00
|
|
|
/// User wrote specifies `'_`.
|
2018-06-01 22:23:48 +00:00
|
|
|
Underscore,
|
2018-03-21 21:12:39 +00:00
|
|
|
|
2019-02-08 13:53:55 +00:00
|
|
|
/// User wrote `'static`.
|
2017-09-19 23:36:54 +00:00
|
|
|
Static,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl LifetimeName {
|
2018-06-09 20:25:33 +00:00
|
|
|
pub fn ident(&self) -> Ident {
|
2017-09-19 23:36:54 +00:00
|
|
|
match *self {
|
2019-08-08 07:36:24 +00:00
|
|
|
LifetimeName::ImplicitObjectLifetimeDefault
|
2019-12-22 22:42:04 +00:00
|
|
|
| LifetimeName::Implicit
|
|
|
|
| LifetimeName::Error => Ident::invalid(),
|
2019-08-10 23:20:18 +00:00
|
|
|
LifetimeName::Underscore => Ident::with_dummy_span(kw::UnderscoreLifetime),
|
|
|
|
LifetimeName::Static => Ident::with_dummy_span(kw::StaticLifetime),
|
2018-06-27 21:12:17 +00:00
|
|
|
LifetimeName::Param(param_name) => param_name.ident(),
|
2017-09-19 23:36:54 +00:00
|
|
|
}
|
|
|
|
}
|
2018-05-25 23:27:54 +00:00
|
|
|
|
2018-06-22 06:24:51 +00:00
|
|
|
pub fn is_elided(&self) -> bool {
|
2018-05-25 23:27:54 +00:00
|
|
|
match self {
|
2019-08-08 07:36:24 +00:00
|
|
|
LifetimeName::ImplicitObjectLifetimeDefault
|
|
|
|
| LifetimeName::Implicit
|
|
|
|
| LifetimeName::Underscore => true,
|
2018-05-25 23:27:54 +00:00
|
|
|
|
|
|
|
// It might seem surprising that `Fresh(_)` counts as
|
|
|
|
// *not* elided -- but this is because, as far as the code
|
|
|
|
// in the compiler is concerned -- `Fresh(_)` variants act
|
|
|
|
// equivalently to "some fresh name". They correspond to
|
|
|
|
// early-bound regions on an impl, in other words.
|
2018-10-11 19:51:44 +00:00
|
|
|
LifetimeName::Error | LifetimeName::Param(_) | LifetimeName::Static => false,
|
2018-05-25 23:27:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn is_static(&self) -> bool {
|
|
|
|
self == &LifetimeName::Static
|
|
|
|
}
|
2018-06-09 20:25:33 +00:00
|
|
|
|
2020-03-13 22:36:46 +00:00
|
|
|
pub fn normalize_to_macros_2_0(&self) -> LifetimeName {
|
2018-06-09 20:25:33 +00:00
|
|
|
match *self {
|
2020-03-13 22:36:46 +00:00
|
|
|
LifetimeName::Param(param_name) => {
|
|
|
|
LifetimeName::Param(param_name.normalize_to_macros_2_0())
|
|
|
|
}
|
2018-06-09 20:25:33 +00:00
|
|
|
lifetime_name => lifetime_name,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Display for Lifetime {
|
2018-08-30 05:02:42 +00:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
2018-06-09 20:25:33 +00:00
|
|
|
self.name.ident().fmt(f)
|
|
|
|
}
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Debug for Lifetime {
|
2018-08-30 05:02:42 +00:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
2020-03-23 10:32:07 +00:00
|
|
|
write!(f, "lifetime({}: {})", self.hir_id, self.name.ident())
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-09 15:46:11 +00:00
|
|
|
impl Lifetime {
|
|
|
|
pub fn is_elided(&self) -> bool {
|
2018-05-25 23:27:54 +00:00
|
|
|
self.name.is_elided()
|
2017-01-09 15:46:11 +00:00
|
|
|
}
|
2017-03-21 12:35:57 +00:00
|
|
|
|
|
|
|
pub fn is_static(&self) -> bool {
|
2018-05-25 23:27:54 +00:00
|
|
|
self.name.is_static()
|
2017-03-21 12:35:57 +00:00
|
|
|
}
|
2017-01-09 15:46:11 +00:00
|
|
|
}
|
|
|
|
|
2019-02-08 13:53:55 +00:00
|
|
|
/// A `Path` is essentially Rust's notion of a name; for instance,
|
2018-01-04 20:23:14 +00:00
|
|
|
/// `std::cmp::PartialEq`. It's represented as a sequence of identifiers,
|
2015-07-31 07:04:06 +00:00
|
|
|
/// along with a bunch of supporting information.
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2019-11-30 16:46:46 +00:00
|
|
|
pub struct Path<'hir> {
|
2015-07-31 07:04:06 +00:00
|
|
|
pub span: Span,
|
2019-04-20 16:36:05 +00:00
|
|
|
/// The resolution for the path.
|
|
|
|
pub res: Res,
|
2015-07-31 07:04:06 +00:00
|
|
|
/// The segments in the path: the things separated by `::`.
|
2019-11-30 16:46:46 +00:00
|
|
|
pub segments: &'hir [PathSegment<'hir>],
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2019-11-30 16:46:46 +00:00
|
|
|
impl Path<'_> {
|
2016-12-05 03:51:11 +00:00
|
|
|
pub fn is_global(&self) -> bool {
|
2019-05-11 14:41:37 +00:00
|
|
|
!self.segments.is_empty() && self.segments[0].ident.name == kw::PathRoot
|
2016-12-05 03:51:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-31 07:04:06 +00:00
|
|
|
/// A segment of a path: an identifier, an optional lifetime, and a set of
|
|
|
|
/// types.
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2019-11-30 16:46:46 +00:00
|
|
|
pub struct PathSegment<'hir> {
|
2015-07-31 07:04:06 +00:00
|
|
|
/// The identifier portion of this path segment.
|
2018-12-03 00:14:35 +00:00
|
|
|
#[stable_hasher(project(name))]
|
2018-06-10 14:40:45 +00:00
|
|
|
pub ident: Ident,
|
2019-04-20 16:36:05 +00:00
|
|
|
// `id` and `res` are optional. We currently only use these in save-analysis,
|
2018-10-11 08:15:18 +00:00
|
|
|
// any path segments without these will not have save-analysis info and
|
|
|
|
// therefore will not have 'jump to def' in IDEs, but otherwise will not be
|
|
|
|
// affected. (In general, we don't bother to get the defs for synthesized
|
|
|
|
// segments, only for segments which have come from the AST).
|
2019-02-02 14:40:08 +00:00
|
|
|
pub hir_id: Option<HirId>,
|
2019-04-20 16:36:05 +00:00
|
|
|
pub res: Option<Res>,
|
2015-07-31 07:04:06 +00:00
|
|
|
|
|
|
|
/// Type/lifetime parameters attached to this path. They come in
|
|
|
|
/// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`. Note that
|
|
|
|
/// this is more than just simple syntactic sugar; the use of
|
|
|
|
/// parens affects the region binding rules, so we preserve the
|
|
|
|
/// distinction.
|
2019-11-30 16:46:46 +00:00
|
|
|
pub args: Option<&'hir GenericArgs<'hir>>,
|
2017-09-21 20:24:26 +00:00
|
|
|
|
|
|
|
/// Whether to infer remaining type parameters, if any.
|
|
|
|
/// This only applies to expression and pattern paths, and
|
|
|
|
/// out of those only the segments with no type parameters
|
2018-11-27 02:59:49 +00:00
|
|
|
/// to begin with, e.g., `Vec::new` is `<Vec<..>>::new::<..>`.
|
2019-06-07 09:18:03 +00:00
|
|
|
pub infer_args: bool,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2019-11-30 16:46:46 +00:00
|
|
|
impl<'hir> PathSegment<'hir> {
|
2019-02-08 13:53:55 +00:00
|
|
|
/// Converts an identifier to the corresponding segment.
|
2019-11-30 16:46:46 +00:00
|
|
|
pub fn from_ident(ident: Ident) -> PathSegment<'hir> {
|
2019-12-22 22:42:04 +00:00
|
|
|
PathSegment { ident, hir_id: None, res: None, infer_args: true, args: None }
|
2016-11-25 11:21:19 +00:00
|
|
|
}
|
2017-09-21 20:24:26 +00:00
|
|
|
|
2019-11-30 16:46:46 +00:00
|
|
|
pub fn generic_args(&self) -> &GenericArgs<'hir> {
|
2019-06-12 08:42:58 +00:00
|
|
|
if let Some(ref args) = self.args {
|
|
|
|
args
|
2017-09-21 20:24:26 +00:00
|
|
|
} else {
|
2019-11-30 16:46:46 +00:00
|
|
|
const DUMMY: &GenericArgs<'_> = &GenericArgs::none();
|
2019-06-12 08:42:58 +00:00
|
|
|
DUMMY
|
|
|
|
}
|
2017-09-21 20:24:26 +00:00
|
|
|
}
|
2016-11-25 11:21:19 +00:00
|
|
|
}
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Encodable, Debug, HashStable_Generic)]
|
2019-02-15 22:20:46 +00:00
|
|
|
pub struct ConstArg {
|
|
|
|
pub value: AnonConst,
|
|
|
|
pub span: Span,
|
|
|
|
}
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2019-11-30 16:46:46 +00:00
|
|
|
pub enum GenericArg<'hir> {
|
2018-02-08 08:58:13 +00:00
|
|
|
Lifetime(Lifetime),
|
2019-11-30 16:46:46 +00:00
|
|
|
Type(Ty<'hir>),
|
2019-02-15 22:20:46 +00:00
|
|
|
Const(ConstArg),
|
2018-02-08 08:58:13 +00:00
|
|
|
}
|
|
|
|
|
2019-11-30 16:46:46 +00:00
|
|
|
impl GenericArg<'_> {
|
2018-07-07 23:53:52 +00:00
|
|
|
pub fn span(&self) -> Span {
|
|
|
|
match self {
|
|
|
|
GenericArg::Lifetime(l) => l.span,
|
|
|
|
GenericArg::Type(t) => t.span,
|
2019-02-15 22:20:46 +00:00
|
|
|
GenericArg::Const(c) => c.span,
|
2018-07-07 23:53:52 +00:00
|
|
|
}
|
|
|
|
}
|
2018-08-07 23:01:47 +00:00
|
|
|
|
2019-02-18 09:59:17 +00:00
|
|
|
pub fn id(&self) -> HirId {
|
2018-08-07 23:01:47 +00:00
|
|
|
match self {
|
2019-02-18 09:59:17 +00:00
|
|
|
GenericArg::Lifetime(l) => l.hir_id,
|
|
|
|
GenericArg::Type(t) => t.hir_id,
|
2019-02-18 13:53:25 +00:00
|
|
|
GenericArg::Const(c) => c.value.hir_id,
|
2018-08-07 23:01:47 +00:00
|
|
|
}
|
|
|
|
}
|
2019-05-14 20:34:43 +00:00
|
|
|
|
|
|
|
pub fn is_const(&self) -> bool {
|
2020-10-27 01:02:48 +00:00
|
|
|
matches!(self, GenericArg::Const(_))
|
2019-05-14 20:34:43 +00:00
|
|
|
}
|
2020-01-22 01:43:24 +00:00
|
|
|
|
|
|
|
pub fn descr(&self) -> &'static str {
|
|
|
|
match self {
|
|
|
|
GenericArg::Lifetime(_) => "lifetime",
|
|
|
|
GenericArg::Type(_) => "type",
|
|
|
|
GenericArg::Const(_) => "constant",
|
|
|
|
}
|
|
|
|
}
|
2018-07-07 23:53:52 +00:00
|
|
|
}
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2019-11-30 16:46:46 +00:00
|
|
|
pub struct GenericArgs<'hir> {
|
2018-02-23 17:48:54 +00:00
|
|
|
/// The generic arguments for this path segment.
|
2019-12-01 16:10:12 +00:00
|
|
|
pub args: &'hir [GenericArg<'hir>],
|
2015-07-31 07:04:06 +00:00
|
|
|
/// Bindings (equality constraints) on associated types, if present.
|
2018-12-18 00:40:22 +00:00
|
|
|
/// E.g., `Foo<A = Bar>`.
|
2019-11-30 16:46:46 +00:00
|
|
|
pub bindings: &'hir [TypeBinding<'hir>],
|
2018-02-23 17:48:54 +00:00
|
|
|
/// Were arguments written in parenthesized form `Fn(T) -> U`?
|
2017-07-28 22:13:40 +00:00
|
|
|
/// This is required mostly for pretty-printing and diagnostics,
|
|
|
|
/// but also for changing lifetime elision rules to be "function-like".
|
|
|
|
pub parenthesized: bool,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2019-11-30 16:46:46 +00:00
|
|
|
impl GenericArgs<'_> {
|
2019-06-12 08:42:58 +00:00
|
|
|
pub const fn none() -> Self {
|
2019-12-01 16:10:12 +00:00
|
|
|
Self { args: &[], bindings: &[], parenthesized: false }
|
2017-07-28 22:13:40 +00:00
|
|
|
}
|
2015-07-31 07:04:06 +00:00
|
|
|
|
2019-11-30 16:46:46 +00:00
|
|
|
pub fn inputs(&self) -> &[Ty<'_>] {
|
2017-07-28 22:13:40 +00:00
|
|
|
if self.parenthesized {
|
2019-12-01 16:10:12 +00:00
|
|
|
for arg in self.args {
|
2018-05-27 00:43:03 +00:00
|
|
|
match arg {
|
|
|
|
GenericArg::Lifetime(_) => {}
|
|
|
|
GenericArg::Type(ref ty) => {
|
2019-09-26 16:25:31 +00:00
|
|
|
if let TyKind::Tup(ref tys) = ty.kind {
|
2018-05-27 00:43:03 +00:00
|
|
|
return tys;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2019-02-15 22:20:46 +00:00
|
|
|
GenericArg::Const(_) => {}
|
2017-07-28 22:13:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-01-02 04:18:45 +00:00
|
|
|
panic!("GenericArgs::inputs: not a `Fn(T) -> U`");
|
2017-07-28 22:13:40 +00:00
|
|
|
}
|
2018-08-07 16:44:30 +00:00
|
|
|
|
|
|
|
pub fn own_counts(&self) -> GenericParamCount {
|
|
|
|
// We could cache this as a property of `GenericParamCount`, but
|
|
|
|
// the aim is to refactor this away entirely eventually and the
|
|
|
|
// presence of this method will be a constant reminder.
|
|
|
|
let mut own_counts: GenericParamCount = Default::default();
|
|
|
|
|
2019-12-01 16:10:12 +00:00
|
|
|
for arg in self.args {
|
2018-08-07 16:44:30 +00:00
|
|
|
match arg {
|
|
|
|
GenericArg::Lifetime(_) => own_counts.lifetimes += 1,
|
|
|
|
GenericArg::Type(_) => own_counts.types += 1,
|
2019-02-15 22:20:46 +00:00
|
|
|
GenericArg::Const(_) => own_counts.consts += 1,
|
2018-08-07 16:44:30 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
own_counts
|
|
|
|
}
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2018-05-28 12:33:28 +00:00
|
|
|
/// A modifier on a bound, currently this is only used for `?Sized`, where the
|
|
|
|
/// modifier is `Maybe`. Negative bounds should also be handled here.
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Hash, Debug)]
|
2020-01-02 04:18:45 +00:00
|
|
|
#[derive(HashStable_Generic)]
|
2018-05-28 12:33:28 +00:00
|
|
|
pub enum TraitBoundModifier {
|
|
|
|
None,
|
|
|
|
Maybe,
|
2020-01-14 04:30:27 +00:00
|
|
|
MaybeConst,
|
2018-05-28 12:33:28 +00:00
|
|
|
}
|
|
|
|
|
2015-07-31 07:04:06 +00:00
|
|
|
/// The AST represents all type param bounds as types.
|
2018-11-01 19:43:38 +00:00
|
|
|
/// `typeck::collect::compute_bounds` matches these against
|
|
|
|
/// the "special" built-in traits (see `middle::lang_items`) and
|
|
|
|
/// detects `Copy`, `Send` and `Sync`.
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2019-11-30 16:46:46 +00:00
|
|
|
pub enum GenericBound<'hir> {
|
|
|
|
Trait(PolyTraitRef<'hir>, TraitBoundModifier),
|
2020-08-04 13:34:24 +00:00
|
|
|
// FIXME(davidtwco): Introduce `PolyTraitRef::LangItem`
|
|
|
|
LangItemTrait(LangItem, Span, HirId, &'hir GenericArgs<'hir>),
|
2018-05-28 12:33:28 +00:00
|
|
|
Outlives(Lifetime),
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2019-11-30 16:46:46 +00:00
|
|
|
impl GenericBound<'_> {
|
2020-03-23 19:27:59 +00:00
|
|
|
pub fn trait_ref(&self) -> Option<&TraitRef<'_>> {
|
2020-01-15 23:49:54 +00:00
|
|
|
match self {
|
2020-03-23 19:27:59 +00:00
|
|
|
GenericBound::Trait(data, _) => Some(&data.trait_ref),
|
2020-01-15 23:49:54 +00:00
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-10 12:32:11 +00:00
|
|
|
pub fn span(&self) -> Span {
|
|
|
|
match self {
|
2018-06-14 11:08:58 +00:00
|
|
|
&GenericBound::Trait(ref t, ..) => t.span,
|
2020-08-04 13:34:24 +00:00
|
|
|
&GenericBound::LangItemTrait(_, span, ..) => span,
|
2018-06-14 11:08:58 +00:00
|
|
|
&GenericBound::Outlives(ref l) => l.span,
|
2018-03-10 12:32:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-30 16:46:46 +00:00
|
|
|
pub type GenericBounds<'hir> = &'hir [GenericBound<'hir>];
|
2015-07-31 07:04:06 +00:00
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Debug, HashStable_Generic)]
|
2018-09-22 08:45:42 +00:00
|
|
|
pub enum LifetimeParamKind {
|
2018-11-27 02:59:49 +00:00
|
|
|
// Indicates that the lifetime definition was explicitly declared (e.g., in
|
|
|
|
// `fn foo<'a>(x: &'a u8) -> &'a u8 { x }`).
|
2018-09-22 08:45:42 +00:00
|
|
|
Explicit,
|
|
|
|
|
|
|
|
// Indicates that the lifetime definition was synthetically added
|
2018-11-27 02:59:49 +00:00
|
|
|
// as a result of an in-band lifetime usage (e.g., in
|
|
|
|
// `fn foo(x: &'a u8) -> &'a u8 { x }`).
|
2018-09-22 08:45:42 +00:00
|
|
|
InBand,
|
|
|
|
|
2018-11-27 02:59:49 +00:00
|
|
|
// Indication that the lifetime was elided (e.g., in both cases in
|
|
|
|
// `fn foo(x: &u8) -> &'_ u8 { x }`).
|
2018-09-22 08:45:42 +00:00
|
|
|
Elided,
|
2018-10-11 19:51:44 +00:00
|
|
|
|
|
|
|
// Indication that the lifetime name was somehow in error.
|
|
|
|
Error,
|
2018-09-22 08:45:42 +00:00
|
|
|
}
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2019-11-30 16:46:46 +00:00
|
|
|
pub enum GenericParamKind<'hir> {
|
2018-11-27 02:59:49 +00:00
|
|
|
/// A lifetime definition (e.g., `'a: 'b + 'c + 'd`).
|
2018-05-25 23:27:54 +00:00
|
|
|
Lifetime {
|
2018-09-22 08:45:42 +00:00
|
|
|
kind: LifetimeParamKind,
|
2018-05-25 23:27:54 +00:00
|
|
|
},
|
|
|
|
Type {
|
2019-11-30 16:46:46 +00:00
|
|
|
default: Option<&'hir Ty<'hir>>,
|
2018-05-25 23:27:54 +00:00
|
|
|
synthetic: Option<SyntheticTyParamKind>,
|
2019-02-15 22:20:46 +00:00
|
|
|
},
|
|
|
|
Const {
|
2019-11-30 16:46:46 +00:00
|
|
|
ty: &'hir Ty<'hir>,
|
2019-12-22 22:42:04 +00:00
|
|
|
},
|
2018-05-25 23:27:54 +00:00
|
|
|
}
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2019-11-30 16:46:46 +00:00
|
|
|
pub struct GenericParam<'hir> {
|
2019-02-02 14:40:08 +00:00
|
|
|
pub hir_id: HirId,
|
2018-06-01 22:23:48 +00:00
|
|
|
pub name: ParamName,
|
2019-11-30 16:46:46 +00:00
|
|
|
pub attrs: &'hir [Attribute],
|
|
|
|
pub bounds: GenericBounds<'hir>,
|
2018-06-27 21:12:17 +00:00
|
|
|
pub span: Span,
|
2016-10-11 14:06:43 +00:00
|
|
|
pub pure_wrt_drop: bool,
|
2019-11-30 16:46:46 +00:00
|
|
|
pub kind: GenericParamKind<'hir>,
|
2017-10-16 19:07:26 +00:00
|
|
|
}
|
|
|
|
|
2019-12-26 12:43:33 +00:00
|
|
|
impl GenericParam<'hir> {
|
|
|
|
pub fn bounds_span(&self) -> Option<Span> {
|
|
|
|
self.bounds.iter().fold(None, |span, bound| {
|
|
|
|
let span = span.map(|s| s.to(bound.span())).unwrap_or_else(|| bound.span());
|
|
|
|
|
|
|
|
Some(span)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-07 16:44:30 +00:00
|
|
|
#[derive(Default)]
|
2018-05-26 12:11:39 +00:00
|
|
|
pub struct GenericParamCount {
|
|
|
|
pub lifetimes: usize,
|
|
|
|
pub types: usize,
|
2019-02-15 22:20:46 +00:00
|
|
|
pub consts: usize,
|
2018-05-26 12:11:39 +00:00
|
|
|
}
|
|
|
|
|
2015-07-31 07:04:06 +00:00
|
|
|
/// Represents lifetimes and type parameters attached to a declaration
|
|
|
|
/// of a function, enum, trait, etc.
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2019-11-30 16:46:46 +00:00
|
|
|
pub struct Generics<'hir> {
|
2019-12-01 16:10:12 +00:00
|
|
|
pub params: &'hir [GenericParam<'hir>],
|
2019-11-30 16:46:46 +00:00
|
|
|
pub where_clause: WhereClause<'hir>,
|
2016-08-10 17:39:12 +00:00
|
|
|
pub span: Span,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2019-11-30 16:46:46 +00:00
|
|
|
impl Generics<'hir> {
|
|
|
|
pub const fn empty() -> Generics<'hir> {
|
2016-03-29 06:32:58 +00:00
|
|
|
Generics {
|
2019-12-01 16:10:12 +00:00
|
|
|
params: &[],
|
2019-11-30 23:17:43 +00:00
|
|
|
where_clause: WhereClause { predicates: &[], span: DUMMY_SP },
|
2016-08-10 17:39:12 +00:00
|
|
|
span: DUMMY_SP,
|
2016-03-29 06:32:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-30 16:46:46 +00:00
|
|
|
pub fn get_named(&self, name: Symbol) -> Option<&GenericParam<'_>> {
|
2019-12-01 16:10:12 +00:00
|
|
|
for param in self.params {
|
2019-10-18 02:22:50 +00:00
|
|
|
if name == param.name.ident().name {
|
2018-06-28 18:06:30 +00:00
|
|
|
return Some(param);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
None
|
|
|
|
}
|
2019-06-01 17:35:31 +00:00
|
|
|
|
|
|
|
pub fn spans(&self) -> MultiSpan {
|
|
|
|
if self.params.is_empty() {
|
|
|
|
self.span.into()
|
|
|
|
} else {
|
|
|
|
self.params.iter().map(|p| p.span).collect::<Vec<Span>>().into()
|
|
|
|
}
|
|
|
|
}
|
2016-10-12 12:23:38 +00:00
|
|
|
}
|
|
|
|
|
2019-02-08 13:53:55 +00:00
|
|
|
/// Synthetic type parameters are converted to another form during lowering; this allows
|
|
|
|
/// us to track the original form they had, and is useful for error messages.
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
|
2020-01-02 04:18:45 +00:00
|
|
|
#[derive(HashStable_Generic)]
|
2017-09-26 09:43:33 +00:00
|
|
|
pub enum SyntheticTyParamKind {
|
2019-12-22 22:42:04 +00:00
|
|
|
ImplTrait,
|
2020-10-04 23:43:15 +00:00
|
|
|
// Created by the `#[rustc_synthetic]` attribute.
|
2020-10-05 00:01:32 +00:00
|
|
|
FromAttr,
|
2017-09-26 09:43:33 +00:00
|
|
|
}
|
|
|
|
|
2019-02-08 13:53:55 +00:00
|
|
|
/// A where-clause in a definition.
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2019-11-30 16:46:46 +00:00
|
|
|
pub struct WhereClause<'hir> {
|
|
|
|
pub predicates: &'hir [WherePredicate<'hir>],
|
2019-12-26 12:43:33 +00:00
|
|
|
// Only valid if predicates aren't empty.
|
2019-12-22 17:15:02 +00:00
|
|
|
pub span: Span,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2019-11-30 16:46:46 +00:00
|
|
|
impl WhereClause<'_> {
|
2018-05-23 02:27:41 +00:00
|
|
|
pub fn span(&self) -> Option<Span> {
|
2019-12-22 22:42:04 +00:00
|
|
|
if self.predicates.is_empty() { None } else { Some(self.span) }
|
2018-05-23 02:27:41 +00:00
|
|
|
}
|
2019-10-09 22:54:23 +00:00
|
|
|
|
|
|
|
/// The `WhereClause` under normal circumstances points at either the predicates or the empty
|
|
|
|
/// space where the `where` clause should be. Only of use for diagnostic suggestions.
|
|
|
|
pub fn span_for_predicates_or_empty_place(&self) -> Span {
|
|
|
|
self.span
|
|
|
|
}
|
2020-05-29 16:44:41 +00:00
|
|
|
|
|
|
|
/// `Span` where further predicates would be suggested, accounting for trailing commas, like
|
|
|
|
/// in `fn foo<T>(t: T) where T: Foo,` so we don't suggest two trailing commas.
|
|
|
|
pub fn tail_span_for_suggestion(&self) -> Span {
|
|
|
|
let end = self.span_for_predicates_or_empty_place().shrink_to_hi();
|
|
|
|
self.predicates.last().map(|p| p.span()).unwrap_or(end).shrink_to_hi().to(end)
|
|
|
|
}
|
2018-05-23 02:27:41 +00:00
|
|
|
}
|
|
|
|
|
2019-02-08 13:53:55 +00:00
|
|
|
/// A single predicate in a where-clause.
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2019-11-30 16:46:46 +00:00
|
|
|
pub enum WherePredicate<'hir> {
|
2018-11-27 02:59:49 +00:00
|
|
|
/// A type binding (e.g., `for<'c> Foo: Send + Clone + 'c`).
|
2019-11-30 16:46:46 +00:00
|
|
|
BoundPredicate(WhereBoundPredicate<'hir>),
|
2018-11-27 02:59:49 +00:00
|
|
|
/// A lifetime predicate (e.g., `'a: 'b + 'c`).
|
2019-11-30 16:46:46 +00:00
|
|
|
RegionPredicate(WhereRegionPredicate<'hir>),
|
2018-11-27 02:59:49 +00:00
|
|
|
/// An equality predicate (unsupported).
|
2019-11-30 16:46:46 +00:00
|
|
|
EqPredicate(WhereEqPredicate<'hir>),
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2019-11-30 16:46:46 +00:00
|
|
|
impl WherePredicate<'_> {
|
2018-03-10 12:32:11 +00:00
|
|
|
pub fn span(&self) -> Span {
|
|
|
|
match self {
|
|
|
|
&WherePredicate::BoundPredicate(ref p) => p.span,
|
|
|
|
&WherePredicate::RegionPredicate(ref p) => p.span,
|
|
|
|
&WherePredicate::EqPredicate(ref p) => p.span,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-08 13:53:55 +00:00
|
|
|
/// A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`).
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2019-11-30 16:46:46 +00:00
|
|
|
pub struct WhereBoundPredicate<'hir> {
|
2015-07-31 07:04:06 +00:00
|
|
|
pub span: Span,
|
2019-02-08 13:53:55 +00:00
|
|
|
/// Any generics from a `for` binding.
|
2019-11-30 16:46:46 +00:00
|
|
|
pub bound_generic_params: &'hir [GenericParam<'hir>],
|
2019-02-08 13:53:55 +00:00
|
|
|
/// The type being bounded.
|
2019-11-30 16:46:46 +00:00
|
|
|
pub bounded_ty: &'hir Ty<'hir>,
|
2019-02-08 13:53:55 +00:00
|
|
|
/// Trait and lifetime bounds (e.g., `Clone + Send + 'static`).
|
2019-11-30 16:46:46 +00:00
|
|
|
pub bounds: GenericBounds<'hir>,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2019-02-08 13:53:55 +00:00
|
|
|
/// A lifetime predicate (e.g., `'a: 'b + 'c`).
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2019-11-30 16:46:46 +00:00
|
|
|
pub struct WhereRegionPredicate<'hir> {
|
2015-07-31 07:04:06 +00:00
|
|
|
pub span: Span,
|
|
|
|
pub lifetime: Lifetime,
|
2019-11-30 16:46:46 +00:00
|
|
|
pub bounds: GenericBounds<'hir>,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2019-02-08 13:53:55 +00:00
|
|
|
/// An equality predicate (e.g., `T = int`); currently unsupported.
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2019-11-30 16:46:46 +00:00
|
|
|
pub struct WhereEqPredicate<'hir> {
|
2019-02-02 14:40:08 +00:00
|
|
|
pub hir_id: HirId,
|
2015-07-31 07:04:06 +00:00
|
|
|
pub span: Span,
|
2019-11-30 16:46:46 +00:00
|
|
|
pub lhs_ty: &'hir Ty<'hir>,
|
|
|
|
pub rhs_ty: &'hir Ty<'hir>,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Encodable, Debug, HashStable_Generic)]
|
2018-06-06 20:13:52 +00:00
|
|
|
pub struct ModuleItems {
|
|
|
|
// Use BTreeSets here so items are in the same order as in the
|
|
|
|
// list of all items in Crate
|
2019-03-11 08:44:19 +00:00
|
|
|
pub items: BTreeSet<HirId>,
|
2018-06-06 20:13:52 +00:00
|
|
|
pub trait_items: BTreeSet<TraitItemId>,
|
|
|
|
pub impl_items: BTreeSet<ImplItemId>,
|
|
|
|
}
|
|
|
|
|
2020-02-07 15:43:36 +00:00
|
|
|
/// A type representing only the top-level module.
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Encodable, Debug, HashStable_Generic)]
|
2020-02-07 15:43:36 +00:00
|
|
|
pub struct CrateItem<'hir> {
|
|
|
|
pub module: Mod<'hir>,
|
|
|
|
pub attrs: &'hir [Attribute],
|
|
|
|
pub span: Span,
|
|
|
|
}
|
|
|
|
|
2017-08-31 18:33:19 +00:00
|
|
|
/// The top-level data structure that stores the entire contents of
|
|
|
|
/// the crate currently being compiled.
|
|
|
|
///
|
2020-03-05 21:07:42 +00:00
|
|
|
/// For more details, see the [rustc dev guide].
|
2017-12-31 16:08:04 +00:00
|
|
|
///
|
2020-03-09 21:33:04 +00:00
|
|
|
/// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/hir.html
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug)]
|
2019-11-28 10:49:29 +00:00
|
|
|
pub struct Crate<'hir> {
|
2020-02-07 15:43:36 +00:00
|
|
|
pub item: CrateItem<'hir>,
|
2019-11-28 22:50:47 +00:00
|
|
|
pub exported_macros: &'hir [MacroDef<'hir>],
|
2019-06-20 22:55:40 +00:00
|
|
|
// Attributes from non-exported macros, kept only for collecting the library feature list.
|
2019-11-28 10:49:29 +00:00
|
|
|
pub non_exported_macro_attrs: &'hir [Attribute],
|
2015-11-18 09:16:25 +00:00
|
|
|
|
2019-09-06 02:57:44 +00:00
|
|
|
// N.B., we use a `BTreeMap` here so that `visit_all_items` iterates
|
2015-11-18 09:16:25 +00:00
|
|
|
// over the ids in increasing order. In principle it should not
|
|
|
|
// matter what order we visit things in, but in *practice* it
|
|
|
|
// does, because it can affect the order in which errors are
|
|
|
|
// detected, which in turn can make compile-fail tests yield
|
|
|
|
// slightly different results.
|
2019-11-28 18:28:50 +00:00
|
|
|
pub items: BTreeMap<HirId, Item<'hir>>,
|
2016-11-02 22:25:31 +00:00
|
|
|
|
2019-11-28 20:47:10 +00:00
|
|
|
pub trait_items: BTreeMap<TraitItemId, TraitItem<'hir>>,
|
2019-11-28 21:16:44 +00:00
|
|
|
pub impl_items: BTreeMap<ImplItemId, ImplItem<'hir>>,
|
2019-11-29 10:09:23 +00:00
|
|
|
pub bodies: BTreeMap<BodyId, Body<'hir>>,
|
2019-03-10 12:07:16 +00:00
|
|
|
pub trait_impls: BTreeMap<DefId, Vec<HirId>>,
|
2017-02-21 17:23:47 +00:00
|
|
|
|
|
|
|
/// A list of the body ids written out in the order in which they
|
|
|
|
/// appear in the crate. If you're going to process all the bodies
|
|
|
|
/// in the crate, you should iterate over this list rather than the keys
|
|
|
|
/// of bodies.
|
|
|
|
pub body_ids: Vec<BodyId>,
|
2018-06-06 20:13:52 +00:00
|
|
|
|
|
|
|
/// A list of modules written out in the order in which they
|
|
|
|
/// appear in the crate. This includes the main crate module.
|
2019-07-10 10:22:07 +00:00
|
|
|
pub modules: BTreeMap<HirId, ModuleItems>,
|
2020-02-03 23:34:36 +00:00
|
|
|
/// A list of proc macro HirIds, written out in the order in which
|
|
|
|
/// they are declared in the static array generated by proc_macro_harness.
|
|
|
|
pub proc_macros: Vec<HirId>,
|
2020-06-12 17:13:10 +00:00
|
|
|
|
|
|
|
pub trait_map: BTreeMap<HirId, Vec<TraitCandidate>>,
|
2015-11-17 22:32:12 +00:00
|
|
|
}
|
|
|
|
|
2019-11-28 18:28:50 +00:00
|
|
|
impl Crate<'hir> {
|
|
|
|
pub fn item(&self, id: HirId) -> &Item<'hir> {
|
2015-11-17 22:32:12 +00:00
|
|
|
&self.items[&id]
|
|
|
|
}
|
|
|
|
|
2019-11-28 20:47:10 +00:00
|
|
|
pub fn trait_item(&self, id: TraitItemId) -> &TraitItem<'hir> {
|
2016-12-04 02:21:06 +00:00
|
|
|
&self.trait_items[&id]
|
|
|
|
}
|
|
|
|
|
2019-11-28 21:16:44 +00:00
|
|
|
pub fn impl_item(&self, id: ImplItemId) -> &ImplItem<'hir> {
|
2016-11-02 22:25:31 +00:00
|
|
|
&self.impl_items[&id]
|
|
|
|
}
|
|
|
|
|
2019-11-29 10:09:23 +00:00
|
|
|
pub fn body(&self, id: BodyId) -> &Body<'hir> {
|
2019-11-28 18:28:50 +00:00
|
|
|
&self.bodies[&id]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Crate<'_> {
|
2017-08-11 18:34:14 +00:00
|
|
|
/// Visits all items in the crate in some deterministic (but
|
2015-11-17 22:32:12 +00:00
|
|
|
/// unspecified) order. If you just need to process every item,
|
|
|
|
/// but don't care about nesting, this method is the best choice.
|
|
|
|
///
|
|
|
|
/// If you do care about nesting -- usually because your algorithm
|
|
|
|
/// follows lexical scoping rules -- then you want a different
|
|
|
|
/// approach. You should override `visit_nested_item` in your
|
|
|
|
/// visitor and then call `intravisit::walk_crate` instead.
|
2016-11-02 22:22:59 +00:00
|
|
|
pub fn visit_all_item_likes<'hir, V>(&'hir self, visitor: &mut V)
|
2019-12-22 22:42:04 +00:00
|
|
|
where
|
|
|
|
V: itemlikevisit::ItemLikeVisitor<'hir>,
|
2016-03-29 05:50:44 +00:00
|
|
|
{
|
2020-03-01 19:56:30 +00:00
|
|
|
for item in self.items.values() {
|
2015-11-17 22:32:12 +00:00
|
|
|
visitor.visit_item(item);
|
|
|
|
}
|
2016-11-02 22:25:31 +00:00
|
|
|
|
2020-03-01 19:56:30 +00:00
|
|
|
for trait_item in self.trait_items.values() {
|
2016-12-04 02:21:06 +00:00
|
|
|
visitor.visit_trait_item(trait_item);
|
|
|
|
}
|
|
|
|
|
2020-03-01 19:56:30 +00:00
|
|
|
for impl_item in self.impl_items.values() {
|
2016-11-02 22:25:31 +00:00
|
|
|
visitor.visit_impl_item(impl_item);
|
|
|
|
}
|
2015-11-17 22:32:12 +00:00
|
|
|
}
|
2016-10-28 20:58:32 +00:00
|
|
|
|
2019-02-08 13:53:55 +00:00
|
|
|
/// A parallel version of `visit_all_item_likes`.
|
2018-04-25 22:50:33 +00:00
|
|
|
pub fn par_visit_all_item_likes<'hir, V>(&'hir self, visitor: &V)
|
2019-12-22 22:42:04 +00:00
|
|
|
where
|
|
|
|
V: itemlikevisit::ParItemLikeVisitor<'hir> + Sync + Send,
|
2018-04-25 22:50:33 +00:00
|
|
|
{
|
2020-01-02 08:53:15 +00:00
|
|
|
parallel!(
|
2019-12-22 22:42:04 +00:00
|
|
|
{
|
|
|
|
par_for_each_in(&self.items, |(_, item)| {
|
|
|
|
visitor.visit_item(item);
|
|
|
|
});
|
|
|
|
},
|
|
|
|
{
|
|
|
|
par_for_each_in(&self.trait_items, |(_, trait_item)| {
|
|
|
|
visitor.visit_trait_item(trait_item);
|
|
|
|
});
|
|
|
|
},
|
|
|
|
{
|
|
|
|
par_for_each_in(&self.impl_items, |(_, impl_item)| {
|
|
|
|
visitor.visit_impl_item(impl_item);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
);
|
2018-04-25 22:50:33 +00:00
|
|
|
}
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// A macro definition, in this crate or imported from another.
|
|
|
|
///
|
|
|
|
/// Not parsed directly, but created on macro import or `macro_rules!` expansion.
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2019-11-28 22:50:47 +00:00
|
|
|
pub struct MacroDef<'hir> {
|
2020-03-13 21:00:35 +00:00
|
|
|
pub ident: Ident,
|
2019-11-30 16:46:46 +00:00
|
|
|
pub vis: Visibility<'hir>,
|
2019-11-28 22:50:47 +00:00
|
|
|
pub attrs: &'hir [Attribute],
|
2019-02-02 14:40:08 +00:00
|
|
|
pub hir_id: HirId,
|
2015-07-31 07:04:06 +00:00
|
|
|
pub span: Span,
|
2020-03-13 21:00:35 +00:00
|
|
|
pub ast: ast::MacroDef,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2019-03-18 08:02:57 +00:00
|
|
|
/// A block of statements `{ .. }`, which may have a label (in this case the
|
|
|
|
/// `targeted_by_break` field will be `true`) and may be `unsafe` by means of
|
|
|
|
/// the `rules` being anything but `DefaultBlock`.
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2019-11-29 12:43:03 +00:00
|
|
|
pub struct Block<'hir> {
|
2019-02-08 13:53:55 +00:00
|
|
|
/// Statements in a block.
|
2019-11-29 12:43:03 +00:00
|
|
|
pub stmts: &'hir [Stmt<'hir>],
|
2015-07-31 07:04:06 +00:00
|
|
|
/// An expression at the end of the block
|
2019-02-08 13:53:55 +00:00
|
|
|
/// without a semicolon, if any.
|
2019-11-29 12:43:03 +00:00
|
|
|
pub expr: Option<&'hir Expr<'hir>>,
|
2018-12-03 00:14:35 +00:00
|
|
|
#[stable_hasher(ignore)]
|
2017-08-04 07:49:40 +00:00
|
|
|
pub hir_id: HirId,
|
2019-02-08 13:53:55 +00:00
|
|
|
/// Distinguishes between `unsafe { ... }` and `{ ... }`.
|
2015-07-31 07:04:06 +00:00
|
|
|
pub rules: BlockCheckMode,
|
|
|
|
pub span: Span,
|
2017-03-22 15:40:29 +00:00
|
|
|
/// If true, then there may exist `break 'a` values that aim to
|
2018-04-25 17:28:04 +00:00
|
|
|
/// break out of this block early.
|
2019-09-18 15:08:56 +00:00
|
|
|
/// Used by `'label: {}` blocks and by `try {}` blocks.
|
2017-03-22 15:40:29 +00:00
|
|
|
pub targeted_by_break: bool,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2019-11-29 12:43:03 +00:00
|
|
|
pub struct Pat<'hir> {
|
2018-12-03 00:14:35 +00:00
|
|
|
#[stable_hasher(ignore)]
|
2017-08-04 07:49:40 +00:00
|
|
|
pub hir_id: HirId,
|
2019-11-29 12:43:03 +00:00
|
|
|
pub kind: PatKind<'hir>,
|
2015-07-31 07:04:06 +00:00
|
|
|
pub span: Span,
|
2020-11-04 16:32:52 +00:00
|
|
|
// Whether to use default binding modes.
|
|
|
|
// At present, this is false only for destructuring assignment.
|
|
|
|
pub default_binding_modes: bool,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2019-11-29 12:43:03 +00:00
|
|
|
impl Pat<'_> {
|
2016-03-29 06:32:58 +00:00
|
|
|
// FIXME(#19596) this is a workaround, but there should be a better way
|
2019-11-29 12:43:03 +00:00
|
|
|
fn walk_short_(&self, it: &mut impl FnMut(&Pat<'_>) -> bool) -> bool {
|
2016-03-29 06:32:58 +00:00
|
|
|
if !it(self) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2019-09-21 13:49:15 +00:00
|
|
|
use PatKind::*;
|
2019-09-26 15:18:31 +00:00
|
|
|
match &self.kind {
|
2019-09-21 13:49:15 +00:00
|
|
|
Wild | Lit(_) | Range(..) | Binding(.., None) | Path(_) => true,
|
|
|
|
Box(s) | Ref(s, _) | Binding(.., Some(s)) => s.walk_short_(it),
|
|
|
|
Struct(_, fields, _) => fields.iter().all(|field| field.pat.walk_short_(it)),
|
|
|
|
TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().all(|p| p.walk_short_(it)),
|
|
|
|
Slice(before, slice, after) => {
|
2019-12-22 22:42:04 +00:00
|
|
|
before.iter().chain(slice.iter()).chain(after.iter()).all(|p| p.walk_short_(it))
|
2016-03-29 06:32:58 +00:00
|
|
|
}
|
2019-09-21 13:49:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Walk the pattern in left-to-right order,
|
|
|
|
/// short circuiting (with `.all(..)`) if `false` is returned.
|
|
|
|
///
|
|
|
|
/// Note that when visiting e.g. `Tuple(ps)`,
|
|
|
|
/// if visiting `ps[0]` returns `false`,
|
|
|
|
/// then `ps[1]` will not be visited.
|
2019-11-29 12:43:03 +00:00
|
|
|
pub fn walk_short(&self, mut it: impl FnMut(&Pat<'_>) -> bool) -> bool {
|
2019-09-21 13:49:15 +00:00
|
|
|
self.walk_short_(&mut it)
|
|
|
|
}
|
|
|
|
|
|
|
|
// FIXME(#19596) this is a workaround, but there should be a better way
|
2019-11-29 12:43:03 +00:00
|
|
|
fn walk_(&self, it: &mut impl FnMut(&Pat<'_>) -> bool) {
|
2019-09-21 13:49:15 +00:00
|
|
|
if !it(self) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
use PatKind::*;
|
2019-09-26 15:18:31 +00:00
|
|
|
match &self.kind {
|
2019-12-22 22:42:04 +00:00
|
|
|
Wild | Lit(_) | Range(..) | Binding(.., None) | Path(_) => {}
|
2019-09-21 13:49:15 +00:00
|
|
|
Box(s) | Ref(s, _) | Binding(.., Some(s)) => s.walk_(it),
|
|
|
|
Struct(_, fields, _) => fields.iter().for_each(|field| field.pat.walk_(it)),
|
|
|
|
TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().for_each(|p| p.walk_(it)),
|
|
|
|
Slice(before, slice, after) => {
|
2019-12-22 22:42:04 +00:00
|
|
|
before.iter().chain(slice.iter()).chain(after.iter()).for_each(|p| p.walk_(it))
|
2016-03-29 06:32:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-21 13:49:15 +00:00
|
|
|
/// Walk the pattern in left-to-right order.
|
|
|
|
///
|
|
|
|
/// If `it(pat)` returns `false`, the children are not visited.
|
2019-11-29 12:43:03 +00:00
|
|
|
pub fn walk(&self, mut it: impl FnMut(&Pat<'_>) -> bool) {
|
2016-03-29 06:32:58 +00:00
|
|
|
self.walk_(&mut it)
|
|
|
|
}
|
2019-12-14 22:43:21 +00:00
|
|
|
|
|
|
|
/// Walk the pattern in left-to-right order.
|
|
|
|
///
|
|
|
|
/// If you always want to recurse, prefer this method over `walk`.
|
2019-11-29 12:43:03 +00:00
|
|
|
pub fn walk_always(&self, mut it: impl FnMut(&Pat<'_>)) {
|
2019-12-14 22:43:21 +00:00
|
|
|
self.walk(|p| {
|
|
|
|
it(p);
|
|
|
|
true
|
|
|
|
})
|
|
|
|
}
|
2016-03-29 06:32:58 +00:00
|
|
|
}
|
|
|
|
|
2019-02-08 13:53:55 +00:00
|
|
|
/// A single field in a struct pattern.
|
2015-07-31 07:04:06 +00: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`,
|
2019-02-08 13:53:55 +00:00
|
|
|
/// except `is_shorthand` is true.
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2019-11-29 12:43:03 +00:00
|
|
|
pub struct FieldPat<'hir> {
|
2018-12-03 00:14:35 +00:00
|
|
|
#[stable_hasher(ignore)]
|
2019-02-02 14:40:08 +00:00
|
|
|
pub hir_id: HirId,
|
2019-02-08 13:53:55 +00:00
|
|
|
/// The identifier for the field.
|
2018-12-03 00:14:35 +00:00
|
|
|
#[stable_hasher(project(name))]
|
2018-05-25 23:50:15 +00:00
|
|
|
pub ident: Ident,
|
2019-02-08 13:53:55 +00:00
|
|
|
/// The pattern the field is destructured to.
|
2019-11-29 12:43:03 +00:00
|
|
|
pub pat: &'hir Pat<'hir>,
|
2015-07-31 07:04:06 +00:00
|
|
|
pub is_shorthand: bool,
|
2019-08-14 23:35:36 +00:00
|
|
|
pub span: Span,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2017-07-21 23:29:43 +00:00
|
|
|
/// Explicit binding annotations given in the HIR for a binding. Note
|
|
|
|
/// that this is not the final binding *mode* that we infer after type
|
|
|
|
/// inference.
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)]
|
2017-07-21 23:29:43 +00:00
|
|
|
pub enum BindingAnnotation {
|
2018-09-12 10:31:11 +00:00
|
|
|
/// No binding annotation given: this means that the final binding mode
|
|
|
|
/// will depend on whether we have skipped through a `&` reference
|
|
|
|
/// when matching. For example, the `x` in `Some(x)` will have binding
|
|
|
|
/// mode `None`; if you do `let Some(x) = &Some(22)`, it will
|
|
|
|
/// ultimately be inferred to be by-reference.
|
|
|
|
///
|
|
|
|
/// Note that implicit reference skipping is not implemented yet (#42640).
|
|
|
|
Unannotated,
|
2017-07-21 23:29:43 +00:00
|
|
|
|
2018-09-12 10:31:11 +00:00
|
|
|
/// Annotated with `mut x` -- could be either ref or not, similar to `None`.
|
|
|
|
Mutable,
|
2017-07-21 23:29:43 +00:00
|
|
|
|
2018-09-12 10:31:11 +00:00
|
|
|
/// Annotated as `ref`, like `ref x`
|
|
|
|
Ref,
|
2017-07-21 23:29:43 +00:00
|
|
|
|
2018-09-12 10:31:11 +00:00
|
|
|
/// Annotated as `ref mut x`.
|
|
|
|
RefMut,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)]
|
2017-01-10 21:13:53 +00:00
|
|
|
pub enum RangeEnd {
|
|
|
|
Included,
|
|
|
|
Excluded,
|
|
|
|
}
|
|
|
|
|
2019-08-30 00:42:45 +00:00
|
|
|
impl fmt::Display for RangeEnd {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
|
f.write_str(match self {
|
|
|
|
RangeEnd::Included => "..=",
|
|
|
|
RangeEnd::Excluded => "..",
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2019-11-29 12:43:03 +00:00
|
|
|
pub enum PatKind<'hir> {
|
2019-02-08 13:53:55 +00:00
|
|
|
/// Represents a wildcard pattern (i.e., `_`).
|
2016-02-14 12:25:12 +00:00
|
|
|
Wild,
|
2015-07-31 07:04:06 +00:00
|
|
|
|
2016-03-06 12:54:44 +00:00
|
|
|
/// A fresh binding `ref mut binding @ OPT_SUBPATTERN`.
|
2019-03-07 11:18:59 +00:00
|
|
|
/// The `HirId` is the canonical ID for the variable being bound,
|
2019-02-08 13:53:55 +00:00
|
|
|
/// (e.g., in `Ok(x) | Err(x)`, both `x` use the same canonical ID),
|
2017-04-29 11:39:47 +00:00
|
|
|
/// which is the pattern ID of the first `x`.
|
2019-11-29 12:43:03 +00:00
|
|
|
Binding(BindingAnnotation, HirId, Ident, Option<&'hir Pat<'hir>>),
|
2015-07-31 07:04:06 +00:00
|
|
|
|
2019-02-08 13:53:55 +00:00
|
|
|
/// A struct or struct variant pattern (e.g., `Variant {x, y, ..}`).
|
2016-02-15 21:40:38 +00:00
|
|
|
/// The `bool` is `true` in the presence of a `..`.
|
2019-11-30 16:46:46 +00:00
|
|
|
Struct(QPath<'hir>, &'hir [FieldPat<'hir>], bool),
|
2016-02-15 21:40:38 +00:00
|
|
|
|
2016-03-06 12:54:44 +00:00
|
|
|
/// A tuple struct/variant pattern `Variant(x, y, .., z)`.
|
2016-03-06 12:54:44 +00:00
|
|
|
/// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
|
2019-02-08 13:53:55 +00:00
|
|
|
/// `0 <= position <= subpats.len()`
|
2019-11-30 16:46:46 +00:00
|
|
|
TupleStruct(QPath<'hir>, &'hir [&'hir Pat<'hir>], Option<usize>),
|
2016-02-15 21:40:38 +00:00
|
|
|
|
2018-10-19 14:40:07 +00:00
|
|
|
/// An or-pattern `A | B | C`.
|
2019-07-14 01:05:52 +00:00
|
|
|
/// Invariant: `pats.len() >= 2`.
|
2019-11-29 12:43:03 +00:00
|
|
|
Or(&'hir [&'hir Pat<'hir>]),
|
2018-10-19 14:40:07 +00:00
|
|
|
|
2016-10-27 02:17:42 +00:00
|
|
|
/// A path pattern for an unit struct/variant or a (maybe-associated) constant.
|
2019-11-30 16:46:46 +00:00
|
|
|
Path(QPath<'hir>),
|
2015-07-31 07:04:06 +00:00
|
|
|
|
2019-02-08 13:53:55 +00:00
|
|
|
/// A tuple pattern (e.g., `(a, b)`).
|
2016-03-06 12:54:44 +00:00
|
|
|
/// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
|
2019-02-08 13:53:55 +00:00
|
|
|
/// `0 <= position <= subpats.len()`
|
2019-11-29 12:43:03 +00:00
|
|
|
Tuple(&'hir [&'hir Pat<'hir>], Option<usize>),
|
2019-02-18 18:34:42 +00:00
|
|
|
|
2019-02-08 13:53:55 +00:00
|
|
|
/// A `box` pattern.
|
2019-11-29 12:43:03 +00:00
|
|
|
Box(&'hir Pat<'hir>),
|
2019-02-18 18:34:42 +00:00
|
|
|
|
2019-02-08 13:53:55 +00:00
|
|
|
/// A reference pattern (e.g., `&mut (a, b)`).
|
2019-11-29 12:43:03 +00:00
|
|
|
Ref(&'hir Pat<'hir>, Mutability),
|
2019-02-18 18:34:42 +00:00
|
|
|
|
2019-02-08 13:53:55 +00:00
|
|
|
/// A literal.
|
2019-11-29 12:43:03 +00:00
|
|
|
Lit(&'hir Expr<'hir>),
|
2019-02-18 18:34:42 +00:00
|
|
|
|
2019-06-14 17:24:38 +00:00
|
|
|
/// A range pattern (e.g., `1..=2` or `1..2`).
|
2019-12-11 09:04:34 +00:00
|
|
|
Range(Option<&'hir Expr<'hir>>, Option<&'hir Expr<'hir>>, RangeEnd),
|
2019-02-18 18:34:42 +00:00
|
|
|
|
2019-12-15 12:16:29 +00:00
|
|
|
/// A slice pattern, `[before_0, ..., before_n, (slice, after_0, ..., after_n)?]`.
|
|
|
|
///
|
|
|
|
/// Here, `slice` is lowered from the syntax `($binding_mode $ident @)? ..`.
|
|
|
|
/// If `slice` exists, then `after` can be non-empty.
|
|
|
|
///
|
|
|
|
/// The representation for e.g., `[a, b, .., c, d]` is:
|
|
|
|
/// ```
|
|
|
|
/// PatKind::Slice([Binding(a), Binding(b)], Some(Wild), [Binding(c), Binding(d)])
|
|
|
|
/// ```
|
2019-11-29 12:43:03 +00:00
|
|
|
Slice(&'hir [&'hir Pat<'hir>], Option<&'hir Pat<'hir>>, &'hir [&'hir Pat<'hir>]),
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)]
|
2018-07-11 10:44:53 +00:00
|
|
|
pub enum BinOpKind {
|
2019-02-08 13:53:55 +00:00
|
|
|
/// The `+` operator (addition).
|
2018-07-11 10:44:53 +00:00
|
|
|
Add,
|
2019-02-08 13:53:55 +00:00
|
|
|
/// The `-` operator (subtraction).
|
2018-07-11 10:44:53 +00:00
|
|
|
Sub,
|
2019-02-08 13:53:55 +00:00
|
|
|
/// The `*` operator (multiplication).
|
2018-07-11 10:44:53 +00:00
|
|
|
Mul,
|
2019-02-08 13:53:55 +00:00
|
|
|
/// The `/` operator (division).
|
2018-07-11 10:44:53 +00:00
|
|
|
Div,
|
2019-02-08 13:53:55 +00:00
|
|
|
/// The `%` operator (modulus).
|
2018-07-11 10:44:53 +00:00
|
|
|
Rem,
|
2019-02-08 13:53:55 +00:00
|
|
|
/// The `&&` operator (logical and).
|
2018-07-11 10:44:53 +00:00
|
|
|
And,
|
2019-02-08 13:53:55 +00:00
|
|
|
/// The `||` operator (logical or).
|
2018-07-11 10:44:53 +00:00
|
|
|
Or,
|
2019-02-08 13:53:55 +00:00
|
|
|
/// The `^` operator (bitwise xor).
|
2018-07-11 10:44:53 +00:00
|
|
|
BitXor,
|
2019-02-08 13:53:55 +00:00
|
|
|
/// The `&` operator (bitwise and).
|
2018-07-11 10:44:53 +00:00
|
|
|
BitAnd,
|
2019-02-08 13:53:55 +00:00
|
|
|
/// The `|` operator (bitwise or).
|
2018-07-11 10:44:53 +00:00
|
|
|
BitOr,
|
2019-02-08 13:53:55 +00:00
|
|
|
/// The `<<` operator (shift left).
|
2018-07-11 10:44:53 +00:00
|
|
|
Shl,
|
2019-02-08 13:53:55 +00:00
|
|
|
/// The `>>` operator (shift right).
|
2018-07-11 10:44:53 +00:00
|
|
|
Shr,
|
2019-02-08 13:53:55 +00:00
|
|
|
/// The `==` operator (equality).
|
2018-07-11 10:44:53 +00:00
|
|
|
Eq,
|
2019-02-08 13:53:55 +00:00
|
|
|
/// The `<` operator (less than).
|
2018-07-11 10:44:53 +00:00
|
|
|
Lt,
|
2019-02-08 13:53:55 +00:00
|
|
|
/// The `<=` operator (less than or equal to).
|
2018-07-11 10:44:53 +00:00
|
|
|
Le,
|
2019-02-08 13:53:55 +00:00
|
|
|
/// The `!=` operator (not equal to).
|
2018-07-11 10:44:53 +00:00
|
|
|
Ne,
|
2019-02-08 13:53:55 +00:00
|
|
|
/// The `>=` operator (greater than or equal to).
|
2018-07-11 10:44:53 +00:00
|
|
|
Ge,
|
2019-02-08 13:53:55 +00:00
|
|
|
/// The `>` operator (greater than).
|
2018-07-11 10:44:53 +00:00
|
|
|
Gt,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2018-07-11 10:44:53 +00:00
|
|
|
impl BinOpKind {
|
2016-03-29 06:32:58 +00:00
|
|
|
pub fn as_str(self) -> &'static str {
|
|
|
|
match self {
|
2018-07-11 10:44:53 +00:00
|
|
|
BinOpKind::Add => "+",
|
|
|
|
BinOpKind::Sub => "-",
|
|
|
|
BinOpKind::Mul => "*",
|
|
|
|
BinOpKind::Div => "/",
|
|
|
|
BinOpKind::Rem => "%",
|
|
|
|
BinOpKind::And => "&&",
|
|
|
|
BinOpKind::Or => "||",
|
|
|
|
BinOpKind::BitXor => "^",
|
|
|
|
BinOpKind::BitAnd => "&",
|
|
|
|
BinOpKind::BitOr => "|",
|
|
|
|
BinOpKind::Shl => "<<",
|
|
|
|
BinOpKind::Shr => ">>",
|
|
|
|
BinOpKind::Eq => "==",
|
|
|
|
BinOpKind::Lt => "<",
|
|
|
|
BinOpKind::Le => "<=",
|
|
|
|
BinOpKind::Ne => "!=",
|
|
|
|
BinOpKind::Ge => ">=",
|
|
|
|
BinOpKind::Gt => ">",
|
2016-03-29 06:32:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn is_lazy(self) -> bool {
|
2020-10-27 01:02:48 +00:00
|
|
|
matches!(self, BinOpKind::And | BinOpKind::Or)
|
2016-03-29 06:32:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn is_shift(self) -> bool {
|
2020-10-27 01:02:48 +00:00
|
|
|
matches!(self, BinOpKind::Shl | BinOpKind::Shr)
|
2016-03-29 06:32:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn is_comparison(self) -> bool {
|
|
|
|
match self {
|
2019-12-22 22:42:04 +00:00
|
|
|
BinOpKind::Eq
|
|
|
|
| BinOpKind::Lt
|
|
|
|
| BinOpKind::Le
|
|
|
|
| BinOpKind::Ne
|
|
|
|
| BinOpKind::Gt
|
|
|
|
| BinOpKind::Ge => true,
|
|
|
|
BinOpKind::And
|
|
|
|
| BinOpKind::Or
|
|
|
|
| BinOpKind::Add
|
|
|
|
| BinOpKind::Sub
|
|
|
|
| BinOpKind::Mul
|
|
|
|
| BinOpKind::Div
|
|
|
|
| BinOpKind::Rem
|
|
|
|
| BinOpKind::BitXor
|
|
|
|
| BinOpKind::BitAnd
|
|
|
|
| BinOpKind::BitOr
|
|
|
|
| BinOpKind::Shl
|
|
|
|
| BinOpKind::Shr => false,
|
2016-03-29 06:32:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-08 13:53:55 +00:00
|
|
|
/// Returns `true` if the binary operator takes its arguments by value.
|
2016-03-29 06:32:58 +00:00
|
|
|
pub fn is_by_value(self) -> bool {
|
|
|
|
!self.is_comparison()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-11 10:44:53 +00:00
|
|
|
impl Into<ast::BinOpKind> for BinOpKind {
|
2018-01-10 19:40:16 +00:00
|
|
|
fn into(self) -> ast::BinOpKind {
|
|
|
|
match self {
|
2018-07-11 10:44:53 +00:00
|
|
|
BinOpKind::Add => ast::BinOpKind::Add,
|
|
|
|
BinOpKind::Sub => ast::BinOpKind::Sub,
|
|
|
|
BinOpKind::Mul => ast::BinOpKind::Mul,
|
|
|
|
BinOpKind::Div => ast::BinOpKind::Div,
|
|
|
|
BinOpKind::Rem => ast::BinOpKind::Rem,
|
|
|
|
BinOpKind::And => ast::BinOpKind::And,
|
|
|
|
BinOpKind::Or => ast::BinOpKind::Or,
|
|
|
|
BinOpKind::BitXor => ast::BinOpKind::BitXor,
|
|
|
|
BinOpKind::BitAnd => ast::BinOpKind::BitAnd,
|
|
|
|
BinOpKind::BitOr => ast::BinOpKind::BitOr,
|
|
|
|
BinOpKind::Shl => ast::BinOpKind::Shl,
|
|
|
|
BinOpKind::Shr => ast::BinOpKind::Shr,
|
|
|
|
BinOpKind::Eq => ast::BinOpKind::Eq,
|
|
|
|
BinOpKind::Lt => ast::BinOpKind::Lt,
|
|
|
|
BinOpKind::Le => ast::BinOpKind::Le,
|
|
|
|
BinOpKind::Ne => ast::BinOpKind::Ne,
|
|
|
|
BinOpKind::Ge => ast::BinOpKind::Ge,
|
|
|
|
BinOpKind::Gt => ast::BinOpKind::Gt,
|
2018-01-10 19:40:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-11 10:44:53 +00:00
|
|
|
pub type BinOp = Spanned<BinOpKind>;
|
2015-07-31 07:04:06 +00:00
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)]
|
2015-07-31 07:04:06 +00:00
|
|
|
pub enum UnOp {
|
2019-02-08 13:53:55 +00:00
|
|
|
/// The `*` operator (deferencing).
|
2015-07-31 07:04:06 +00:00
|
|
|
UnDeref,
|
2019-02-08 13:53:55 +00:00
|
|
|
/// The `!` operator (logical negation).
|
2015-07-31 07:04:06 +00:00
|
|
|
UnNot,
|
2019-02-08 13:53:55 +00:00
|
|
|
/// The `-` operator (negation).
|
2015-09-27 19:23:31 +00:00
|
|
|
UnNeg,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2016-03-29 06:32:58 +00:00
|
|
|
impl UnOp {
|
|
|
|
pub fn as_str(self) -> &'static str {
|
|
|
|
match self {
|
2020-01-02 02:48:12 +00:00
|
|
|
Self::UnDeref => "*",
|
|
|
|
Self::UnNot => "!",
|
|
|
|
Self::UnNeg => "-",
|
2016-03-29 06:32:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-08 13:53:55 +00:00
|
|
|
/// Returns `true` if the unary operator takes its argument by value.
|
2016-03-29 06:32:58 +00:00
|
|
|
pub fn is_by_value(self) -> bool {
|
2020-10-27 01:02:48 +00:00
|
|
|
matches!(self, Self::UnNeg | Self::UnNot)
|
2016-03-29 06:32:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-08 13:53:55 +00:00
|
|
|
/// A statement.
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2019-11-29 12:43:03 +00:00
|
|
|
pub struct Stmt<'hir> {
|
2019-02-02 14:40:08 +00:00
|
|
|
pub hir_id: HirId,
|
2019-11-29 12:43:03 +00:00
|
|
|
pub kind: StmtKind<'hir>,
|
2019-01-16 22:45:02 +00:00
|
|
|
pub span: Span,
|
|
|
|
}
|
2015-07-31 07:04:06 +00:00
|
|
|
|
2019-03-18 08:02:57 +00:00
|
|
|
/// The contents of a statement.
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2019-11-29 12:43:03 +00:00
|
|
|
pub enum StmtKind<'hir> {
|
2019-02-08 13:53:55 +00:00
|
|
|
/// A local (`let`) binding.
|
2019-11-29 12:43:03 +00:00
|
|
|
Local(&'hir Local<'hir>),
|
2019-02-17 06:23:13 +00:00
|
|
|
|
2019-02-08 13:53:55 +00:00
|
|
|
/// An item binding.
|
2019-02-17 06:23:13 +00:00
|
|
|
Item(ItemId),
|
2015-07-31 07:04:06 +00:00
|
|
|
|
2019-02-08 13:53:55 +00:00
|
|
|
/// An expression without a trailing semi-colon (must have unit type).
|
2019-11-29 12:43:03 +00:00
|
|
|
Expr(&'hir Expr<'hir>),
|
2015-07-31 07:04:06 +00:00
|
|
|
|
2019-02-08 13:53:55 +00:00
|
|
|
/// An expression with a trailing semi-colon (may have any type).
|
2019-11-29 12:43:03 +00:00
|
|
|
Semi(&'hir Expr<'hir>),
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
Fix inconsistencies in handling of inert attributes on statements
When the 'early' and 'late' visitors visit an attribute target, they
activate any lint attributes (e.g. `#[allow]`) that apply to it.
This can affect warnings emitted on sibiling attributes. For example,
the following code does not produce an `unused_attributes` for
`#[inline]`, since the sibiling `#[allow(unused_attributes)]` suppressed
the warning.
```rust
trait Foo {
#[allow(unused_attributes)] #[inline] fn first();
#[inline] #[allow(unused_attributes)] fn second();
}
```
However, we do not do this for statements - instead, the lint attributes
only become active when we visit the struct nested inside `StmtKind`
(e.g. `Item`).
Currently, this is difficult to observe due to another issue - the
`HasAttrs` impl for `StmtKind` ignores attributes for `StmtKind::Item`.
As a result, the `unused_doc_comments` lint will never see attributes on
item statements.
This commit makes two interrelated fixes to the handling of inert
(non-proc-macro) attributes on statements:
* The `HasAttr` impl for `StmtKind` now returns attributes for
`StmtKind::Item`, treating it just like every other `StmtKind`
variant. The only place relying on the old behavior was macro
which has been updated to explicitly ignore attributes on item
statements. This allows the `unused_doc_comments` lint to fire for
item statements.
* The `early` and `late` lint visitors now activate lint attributes when
invoking the callback for `Stmt`. This ensures that a lint
attribute (e.g. `#[allow(unused_doc_comments)]`) can be applied to
sibiling attributes on an item statement.
For now, the `unused_doc_comments` lint is explicitly disabled on item
statements, which preserves the current behavior. The exact locatiosn
where this lint should fire are being discussed in PR #78306
2020-10-23 22:17:00 +00:00
|
|
|
impl<'hir> StmtKind<'hir> {
|
|
|
|
pub fn attrs(&self, get_item: impl FnOnce(ItemId) -> &'hir Item<'hir>) -> &'hir [Attribute] {
|
2016-03-10 02:12:36 +00:00
|
|
|
match *self {
|
2019-01-16 23:39:24 +00:00
|
|
|
StmtKind::Local(ref l) => &l.attrs,
|
Fix inconsistencies in handling of inert attributes on statements
When the 'early' and 'late' visitors visit an attribute target, they
activate any lint attributes (e.g. `#[allow]`) that apply to it.
This can affect warnings emitted on sibiling attributes. For example,
the following code does not produce an `unused_attributes` for
`#[inline]`, since the sibiling `#[allow(unused_attributes)]` suppressed
the warning.
```rust
trait Foo {
#[allow(unused_attributes)] #[inline] fn first();
#[inline] #[allow(unused_attributes)] fn second();
}
```
However, we do not do this for statements - instead, the lint attributes
only become active when we visit the struct nested inside `StmtKind`
(e.g. `Item`).
Currently, this is difficult to observe due to another issue - the
`HasAttrs` impl for `StmtKind` ignores attributes for `StmtKind::Item`.
As a result, the `unused_doc_comments` lint will never see attributes on
item statements.
This commit makes two interrelated fixes to the handling of inert
(non-proc-macro) attributes on statements:
* The `HasAttr` impl for `StmtKind` now returns attributes for
`StmtKind::Item`, treating it just like every other `StmtKind`
variant. The only place relying on the old behavior was macro
which has been updated to explicitly ignore attributes on item
statements. This allows the `unused_doc_comments` lint to fire for
item statements.
* The `early` and `late` lint visitors now activate lint attributes when
invoking the callback for `Stmt`. This ensures that a lint
attribute (e.g. `#[allow(unused_doc_comments)]`) can be applied to
sibiling attributes on an item statement.
For now, the `unused_doc_comments` lint is explicitly disabled on item
statements, which preserves the current behavior. The exact locatiosn
where this lint should fire are being discussed in PR #78306
2020-10-23 22:17:00 +00:00
|
|
|
StmtKind::Item(ref item_id) => &get_item(*item_id).attrs,
|
2019-12-22 22:42:04 +00:00
|
|
|
StmtKind::Expr(ref e) | StmtKind::Semi(ref e) => &e.attrs,
|
2016-03-29 06:32:58 +00:00
|
|
|
}
|
|
|
|
}
|
2016-03-10 02:12:36 +00:00
|
|
|
}
|
|
|
|
|
2019-02-08 13:53:55 +00:00
|
|
|
/// Represents a `let` statement (i.e., `let <pat>:<ty> = <expr>;`).
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2019-11-29 12:43:03 +00:00
|
|
|
pub struct Local<'hir> {
|
|
|
|
pub pat: &'hir Pat<'hir>,
|
2019-03-18 08:02:57 +00:00
|
|
|
/// Type annotation, if any (otherwise the type will be inferred).
|
2019-11-30 16:46:46 +00:00
|
|
|
pub ty: Option<&'hir Ty<'hir>>,
|
2019-02-08 13:53:55 +00:00
|
|
|
/// Initializer expression to set the value, if any.
|
2019-11-29 12:43:03 +00:00
|
|
|
pub init: Option<&'hir Expr<'hir>>,
|
2017-08-07 12:43:43 +00:00
|
|
|
pub hir_id: HirId,
|
2015-07-31 07:04:06 +00:00
|
|
|
pub span: Span,
|
2019-12-03 15:38:34 +00:00
|
|
|
pub attrs: AttrVec,
|
2019-03-18 08:02:57 +00:00
|
|
|
/// Can be `ForLoopDesugar` if the `let` statement is part of a `for` loop
|
|
|
|
/// desugaring. Otherwise will be `Normal`.
|
2017-05-27 18:20:17 +00:00
|
|
|
pub source: LocalSource,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2019-03-18 08:02:57 +00:00
|
|
|
/// Represents a single arm of a `match` expression, e.g.
|
2019-09-07 14:00:09 +00:00
|
|
|
/// `<pat> (if <guard>) => <body>`.
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2019-11-29 12:43:03 +00:00
|
|
|
pub struct Arm<'hir> {
|
2019-03-30 22:54:29 +00:00
|
|
|
#[stable_hasher(ignore)]
|
|
|
|
pub hir_id: HirId,
|
|
|
|
pub span: Span,
|
2019-11-29 12:43:03 +00:00
|
|
|
pub attrs: &'hir [Attribute],
|
2019-09-07 14:00:09 +00:00
|
|
|
/// If this pattern and the optional guard matches, then `body` is evaluated.
|
2019-11-29 12:43:03 +00:00
|
|
|
pub pat: &'hir Pat<'hir>,
|
2019-03-18 08:02:57 +00:00
|
|
|
/// Optional guard clause.
|
2019-11-29 12:43:03 +00:00
|
|
|
pub guard: Option<Guard<'hir>>,
|
2019-03-19 05:10:59 +00:00
|
|
|
/// The expression the arm evaluates to if this arm matches.
|
2019-11-29 12:43:03 +00:00
|
|
|
pub body: &'hir Expr<'hir>,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2019-11-29 12:43:03 +00:00
|
|
|
pub enum Guard<'hir> {
|
|
|
|
If(&'hir Expr<'hir>),
|
2018-08-30 04:18:11 +00:00
|
|
|
}
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2019-11-29 12:43:03 +00:00
|
|
|
pub struct Field<'hir> {
|
2018-12-03 00:14:35 +00:00
|
|
|
#[stable_hasher(ignore)]
|
2019-02-02 14:40:08 +00:00
|
|
|
pub hir_id: HirId,
|
2018-05-25 23:50:15 +00:00
|
|
|
pub ident: Ident,
|
2019-11-29 12:43:03 +00:00
|
|
|
pub expr: &'hir Expr<'hir>,
|
2015-07-31 07:04:06 +00:00
|
|
|
pub span: Span,
|
2016-10-27 00:15:13 +00:00
|
|
|
pub is_shorthand: bool,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)]
|
2015-07-31 07:04:06 +00:00
|
|
|
pub enum BlockCheckMode {
|
|
|
|
DefaultBlock,
|
|
|
|
UnsafeBlock(UnsafeSource),
|
|
|
|
PushUnsafeBlock(UnsafeSource),
|
|
|
|
PopUnsafeBlock(UnsafeSource),
|
|
|
|
}
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)]
|
2015-07-31 07:04:06 +00:00
|
|
|
pub enum UnsafeSource {
|
|
|
|
CompilerGenerated,
|
|
|
|
UserProvided,
|
|
|
|
}
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Encodable, Hash, Debug)]
|
2016-12-21 10:32:59 +00:00
|
|
|
pub struct BodyId {
|
2019-02-04 19:01:14 +00:00
|
|
|
pub hir_id: HirId,
|
2016-12-21 10:32:59 +00:00
|
|
|
}
|
|
|
|
|
2017-08-31 18:33:19 +00:00
|
|
|
/// The body of a function, closure, or constant value. In the case of
|
|
|
|
/// a function, the body contains not only the function body itself
|
|
|
|
/// (which is an expression), but also the argument patterns, since
|
|
|
|
/// those are something that the caller doesn't really care about.
|
|
|
|
///
|
2017-09-15 20:19:44 +00:00
|
|
|
/// # Examples
|
2017-08-31 18:33:19 +00:00
|
|
|
///
|
2017-09-15 20:19:44 +00:00
|
|
|
/// ```
|
2017-08-31 18:33:19 +00:00
|
|
|
/// fn foo((x, y): (u32, u32)) -> u32 {
|
|
|
|
/// x + y
|
|
|
|
/// }
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// Here, the `Body` associated with `foo()` would contain:
|
|
|
|
///
|
2019-08-27 11:24:32 +00:00
|
|
|
/// - an `params` array containing the `(x, y)` pattern
|
2017-08-31 18:33:19 +00:00
|
|
|
/// - a `value` containing the `x + y` expression (maybe wrapped in a block)
|
2019-06-18 21:34:51 +00:00
|
|
|
/// - `generator_kind` would be `None`
|
2017-08-31 18:33:19 +00:00
|
|
|
///
|
|
|
|
/// All bodies have an **owner**, which can be accessed via the HIR
|
|
|
|
/// map using `body_owner_def_id()`.
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug)]
|
2019-11-29 10:09:23 +00:00
|
|
|
pub struct Body<'hir> {
|
2019-11-29 12:43:03 +00:00
|
|
|
pub params: &'hir [Param<'hir>],
|
|
|
|
pub value: Expr<'hir>,
|
2019-06-18 21:34:51 +00:00
|
|
|
pub generator_kind: Option<GeneratorKind>,
|
2016-12-21 10:32:59 +00:00
|
|
|
}
|
2016-10-27 20:04:22 +00:00
|
|
|
|
2019-11-29 10:09:23 +00:00
|
|
|
impl Body<'hir> {
|
2016-12-21 10:32:59 +00:00
|
|
|
pub fn id(&self) -> BodyId {
|
2019-12-22 22:42:04 +00:00
|
|
|
BodyId { hir_id: self.value.hir_id }
|
2016-10-27 20:04:22 +00:00
|
|
|
}
|
2019-10-10 14:20:57 +00:00
|
|
|
|
|
|
|
pub fn generator_kind(&self) -> Option<GeneratorKind> {
|
|
|
|
self.generator_kind
|
|
|
|
}
|
2016-10-27 20:04:22 +00:00
|
|
|
}
|
|
|
|
|
2019-06-18 21:34:51 +00:00
|
|
|
/// The type of source expression that caused this generator to be created.
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Clone, PartialEq, Eq, HashStable_Generic, Encodable, Decodable, Debug, Copy)]
|
2019-06-18 21:34:51 +00:00
|
|
|
pub enum GeneratorKind {
|
2019-09-25 14:26:54 +00:00
|
|
|
/// An explicit `async` block or the body of an async function.
|
|
|
|
Async(AsyncGeneratorKind),
|
|
|
|
|
2019-06-18 21:34:51 +00:00
|
|
|
/// A generator literal created via a `yield` inside a closure.
|
|
|
|
Gen,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Display for GeneratorKind {
|
2019-09-25 14:26:54 +00:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
|
match self {
|
|
|
|
GeneratorKind::Async(k) => fmt::Display::fmt(k, f),
|
|
|
|
GeneratorKind::Gen => f.write_str("generator"),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-02 18:24:43 +00:00
|
|
|
/// In the case of a generator created as part of an async construct,
|
|
|
|
/// which kind of async construct caused it to be created?
|
|
|
|
///
|
|
|
|
/// This helps error messages but is also used to drive coercions in
|
|
|
|
/// type-checking (see #60424).
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Clone, PartialEq, Eq, HashStable_Generic, Encodable, Decodable, Debug, Copy)]
|
2019-09-25 14:26:54 +00:00
|
|
|
pub enum AsyncGeneratorKind {
|
|
|
|
/// An explicit `async` block written by the user.
|
|
|
|
Block,
|
|
|
|
|
|
|
|
/// An explicit `async` block written by the user.
|
|
|
|
Closure,
|
|
|
|
|
|
|
|
/// The `async` block generated as the body of an async function.
|
|
|
|
Fn,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Display for AsyncGeneratorKind {
|
2019-06-18 21:34:51 +00:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
|
f.write_str(match self {
|
2019-09-25 14:26:54 +00:00
|
|
|
AsyncGeneratorKind::Block => "`async` block",
|
|
|
|
AsyncGeneratorKind::Closure => "`async` closure body",
|
2019-10-02 18:39:44 +00:00
|
|
|
AsyncGeneratorKind::Fn => "`async fn` body",
|
2019-06-18 21:34:51 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-10 17:20:35 +00:00
|
|
|
#[derive(Copy, Clone, Debug)]
|
|
|
|
pub enum BodyOwnerKind {
|
|
|
|
/// Functions and methods.
|
|
|
|
Fn,
|
|
|
|
|
2018-12-07 17:25:55 +00:00
|
|
|
/// Closures
|
|
|
|
Closure,
|
|
|
|
|
2017-11-10 17:20:35 +00:00
|
|
|
/// Constants and associated constants.
|
|
|
|
Const,
|
|
|
|
|
|
|
|
/// Initializer of a `static` item.
|
|
|
|
Static(Mutability),
|
|
|
|
}
|
|
|
|
|
2018-12-07 17:25:55 +00:00
|
|
|
impl BodyOwnerKind {
|
|
|
|
pub fn is_fn_or_closure(self) -> bool {
|
|
|
|
match self {
|
|
|
|
BodyOwnerKind::Fn | BodyOwnerKind::Closure => true,
|
|
|
|
BodyOwnerKind::Const | BodyOwnerKind::Static(_) => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-07 17:22:35 +00:00
|
|
|
/// The kind of an item that requires const-checking.
|
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
|
|
|
pub enum ConstContext {
|
|
|
|
/// A `const fn`.
|
|
|
|
ConstFn,
|
|
|
|
|
|
|
|
/// A `static` or `static mut`.
|
|
|
|
Static(Mutability),
|
|
|
|
|
|
|
|
/// A `const`, associated `const`, or other const context.
|
|
|
|
///
|
|
|
|
/// Other contexts include:
|
|
|
|
/// - Array length expressions
|
|
|
|
/// - Enum discriminants
|
|
|
|
/// - Const generics
|
|
|
|
///
|
|
|
|
/// For the most part, other contexts are treated just like a regular `const`, so they are
|
|
|
|
/// lumped into the same category.
|
|
|
|
Const,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ConstContext {
|
|
|
|
/// A description of this const context that can appear between backticks in an error message.
|
|
|
|
///
|
|
|
|
/// E.g. `const` or `static mut`.
|
|
|
|
pub fn keyword_name(self) -> &'static str {
|
|
|
|
match self {
|
|
|
|
Self::Const => "const",
|
|
|
|
Self::Static(Mutability::Not) => "static",
|
|
|
|
Self::Static(Mutability::Mut) => "static mut",
|
|
|
|
Self::ConstFn => "const fn",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// A colloquial, trivially pluralizable description of this const context for use in error
|
|
|
|
/// messages.
|
|
|
|
impl fmt::Display for ConstContext {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
|
match *self {
|
|
|
|
Self::Const => write!(f, "constant"),
|
|
|
|
Self::Static(_) => write!(f, "static"),
|
|
|
|
Self::ConstFn => write!(f, "constant function"),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-09 15:04:24 +00:00
|
|
|
/// A literal.
|
|
|
|
pub type Lit = Spanned<LitKind>;
|
|
|
|
|
2018-05-17 18:28:50 +00: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 18:28:50 +00:00
|
|
|
/// explicit discriminant values for enum variants.
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Debug, HashStable_Generic)]
|
2018-05-17 18:28:50 +00:00
|
|
|
pub struct AnonConst {
|
|
|
|
pub hir_id: HirId,
|
|
|
|
pub body: BodyId,
|
|
|
|
}
|
|
|
|
|
2019-09-06 02:57:44 +00:00
|
|
|
/// An expression.
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug)]
|
2019-11-29 12:43:03 +00:00
|
|
|
pub struct Expr<'hir> {
|
2019-09-06 02:57:44 +00:00
|
|
|
pub hir_id: HirId,
|
2019-11-29 12:43:03 +00:00
|
|
|
pub kind: ExprKind<'hir>,
|
2019-12-03 15:38:34 +00:00
|
|
|
pub attrs: AttrVec,
|
2019-09-06 02:57:44 +00:00
|
|
|
pub span: Span,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2019-02-07 05:03:57 +00:00
|
|
|
// `Expr` is used a lot. Make sure it doesn't unintentionally get bigger.
|
|
|
|
#[cfg(target_arch = "x86_64")]
|
2020-06-09 19:34:23 +00:00
|
|
|
rustc_data_structures::static_assert_size!(Expr<'static>, 72);
|
2019-02-07 05:03:57 +00:00
|
|
|
|
2019-11-29 12:43:03 +00:00
|
|
|
impl Expr<'_> {
|
2018-01-10 19:40:16 +00:00
|
|
|
pub fn precedence(&self) -> ExprPrecedence {
|
2019-09-26 13:39:48 +00:00
|
|
|
match self.kind {
|
2018-07-11 12:05:29 +00:00
|
|
|
ExprKind::Box(_) => ExprPrecedence::Box,
|
2020-10-06 20:51:15 +00:00
|
|
|
ExprKind::ConstBlock(_) => ExprPrecedence::ConstBlock,
|
2018-07-11 12:05:29 +00:00
|
|
|
ExprKind::Array(_) => ExprPrecedence::Array,
|
|
|
|
ExprKind::Call(..) => ExprPrecedence::Call,
|
|
|
|
ExprKind::MethodCall(..) => ExprPrecedence::MethodCall,
|
|
|
|
ExprKind::Tup(_) => ExprPrecedence::Tup,
|
|
|
|
ExprKind::Binary(op, ..) => ExprPrecedence::Binary(op.node.into()),
|
|
|
|
ExprKind::Unary(..) => ExprPrecedence::Unary,
|
|
|
|
ExprKind::Lit(_) => ExprPrecedence::Lit,
|
|
|
|
ExprKind::Type(..) | ExprKind::Cast(..) => ExprPrecedence::Cast,
|
2019-04-30 15:46:59 +00:00
|
|
|
ExprKind::DropTemps(ref expr, ..) => expr.precedence(),
|
2018-07-11 12:05:29 +00:00
|
|
|
ExprKind::Loop(..) => ExprPrecedence::Loop,
|
|
|
|
ExprKind::Match(..) => ExprPrecedence::Match,
|
|
|
|
ExprKind::Closure(..) => ExprPrecedence::Closure,
|
|
|
|
ExprKind::Block(..) => ExprPrecedence::Block,
|
|
|
|
ExprKind::Assign(..) => ExprPrecedence::Assign,
|
|
|
|
ExprKind::AssignOp(..) => ExprPrecedence::AssignOp,
|
|
|
|
ExprKind::Field(..) => ExprPrecedence::Field,
|
|
|
|
ExprKind::Index(..) => ExprPrecedence::Index,
|
|
|
|
ExprKind::Path(..) => ExprPrecedence::Path,
|
|
|
|
ExprKind::AddrOf(..) => ExprPrecedence::AddrOf,
|
|
|
|
ExprKind::Break(..) => ExprPrecedence::Break,
|
|
|
|
ExprKind::Continue(..) => ExprPrecedence::Continue,
|
|
|
|
ExprKind::Ret(..) => ExprPrecedence::Ret,
|
2020-02-12 17:32:41 +00:00
|
|
|
ExprKind::InlineAsm(..) => ExprPrecedence::InlineAsm,
|
2020-01-14 13:40:42 +00:00
|
|
|
ExprKind::LlvmInlineAsm(..) => ExprPrecedence::InlineAsm,
|
2018-07-11 12:05:29 +00:00
|
|
|
ExprKind::Struct(..) => ExprPrecedence::Struct,
|
|
|
|
ExprKind::Repeat(..) => ExprPrecedence::Repeat,
|
|
|
|
ExprKind::Yield(..) => ExprPrecedence::Yield,
|
2018-12-17 01:57:32 +00:00
|
|
|
ExprKind::Err => ExprPrecedence::Err,
|
2018-01-10 19:40:16 +00:00
|
|
|
}
|
|
|
|
}
|
2018-09-20 21:13:41 +00:00
|
|
|
|
2019-11-23 14:15:49 +00:00
|
|
|
// Whether this looks like a place expr, without checking for deref
|
|
|
|
// adjustments.
|
|
|
|
// This will return `true` in some potentially surprising cases such as
|
|
|
|
// `CONSTANT.field`.
|
|
|
|
pub fn is_syntactic_place_expr(&self) -> bool {
|
|
|
|
self.is_place_expr(|_| true)
|
|
|
|
}
|
|
|
|
|
2020-08-04 13:34:24 +00:00
|
|
|
/// Whether this is a place expression.
|
|
|
|
///
|
|
|
|
/// `allow_projections_from` should return `true` if indexing a field or index expression based
|
|
|
|
/// on the given expression should be considered a place expression.
|
2019-11-23 14:15:49 +00:00
|
|
|
pub fn is_place_expr(&self, mut allow_projections_from: impl FnMut(&Self) -> bool) -> bool {
|
|
|
|
match self.kind {
|
2020-10-27 01:02:48 +00:00
|
|
|
ExprKind::Path(QPath::Resolved(_, ref path)) => {
|
|
|
|
matches!(path.res, Res::Local(..) | Res::Def(DefKind::Static, _) | Res::Err)
|
|
|
|
}
|
2018-09-20 21:13:41 +00:00
|
|
|
|
2019-11-23 14:15:49 +00:00
|
|
|
// Type ascription inherits its place expression kind from its
|
|
|
|
// operand. See:
|
|
|
|
// https://github.com/rust-lang/rfcs/blob/master/text/0803-type-ascription.md#type-ascription-and-temporaries
|
2019-12-22 22:42:04 +00:00
|
|
|
ExprKind::Type(ref e, _) => e.is_place_expr(allow_projections_from),
|
2018-09-20 21:13:41 +00:00
|
|
|
|
2020-01-02 02:48:12 +00:00
|
|
|
ExprKind::Unary(UnOp::UnDeref, _) => true,
|
2019-11-23 14:15:49 +00:00
|
|
|
|
2019-12-22 22:42:04 +00:00
|
|
|
ExprKind::Field(ref base, _) | ExprKind::Index(ref base, _) => {
|
|
|
|
allow_projections_from(base) || base.is_place_expr(allow_projections_from)
|
2018-09-20 21:13:41 +00:00
|
|
|
}
|
|
|
|
|
2020-08-04 13:34:24 +00:00
|
|
|
// Lang item paths cannot currently be local variables or statics.
|
|
|
|
ExprKind::Path(QPath::LangItem(..)) => false,
|
|
|
|
|
2018-09-20 21:13:41 +00:00
|
|
|
// Partially qualified paths in expressions can only legally
|
|
|
|
// refer to associated items which are always rvalues.
|
2019-12-22 22:42:04 +00:00
|
|
|
ExprKind::Path(QPath::TypeRelative(..))
|
|
|
|
| ExprKind::Call(..)
|
|
|
|
| ExprKind::MethodCall(..)
|
|
|
|
| ExprKind::Struct(..)
|
|
|
|
| ExprKind::Tup(..)
|
|
|
|
| ExprKind::Match(..)
|
|
|
|
| ExprKind::Closure(..)
|
|
|
|
| ExprKind::Block(..)
|
|
|
|
| ExprKind::Repeat(..)
|
|
|
|
| ExprKind::Array(..)
|
|
|
|
| ExprKind::Break(..)
|
|
|
|
| ExprKind::Continue(..)
|
|
|
|
| ExprKind::Ret(..)
|
|
|
|
| ExprKind::Loop(..)
|
|
|
|
| ExprKind::Assign(..)
|
2020-02-12 17:32:41 +00:00
|
|
|
| ExprKind::InlineAsm(..)
|
2020-01-14 13:40:42 +00:00
|
|
|
| ExprKind::LlvmInlineAsm(..)
|
2019-12-22 22:42:04 +00:00
|
|
|
| ExprKind::AssignOp(..)
|
|
|
|
| ExprKind::Lit(_)
|
2020-10-06 20:51:15 +00:00
|
|
|
| ExprKind::ConstBlock(..)
|
2019-12-22 22:42:04 +00:00
|
|
|
| ExprKind::Unary(..)
|
|
|
|
| ExprKind::Box(..)
|
|
|
|
| ExprKind::AddrOf(..)
|
|
|
|
| ExprKind::Binary(..)
|
|
|
|
| ExprKind::Yield(..)
|
|
|
|
| ExprKind::Cast(..)
|
|
|
|
| ExprKind::DropTemps(..)
|
|
|
|
| ExprKind::Err => false,
|
2018-09-20 21:13:41 +00:00
|
|
|
}
|
|
|
|
}
|
2019-10-08 15:26:42 +00:00
|
|
|
|
|
|
|
/// If `Self.kind` is `ExprKind::DropTemps(expr)`, drill down until we get a non-`DropTemps`
|
|
|
|
/// `Expr`. This is used in suggestions to ignore this `ExprKind` as it is semantically
|
|
|
|
/// silent, only signaling the ownership system. By doing this, suggestions that check the
|
|
|
|
/// `ExprKind` of any given `Expr` for presentation don't have to care about `DropTemps`
|
|
|
|
/// beyond remembering to call this function before doing analysis on it.
|
|
|
|
pub fn peel_drop_temps(&self) -> &Self {
|
2019-10-08 16:46:57 +00:00
|
|
|
let mut expr = self;
|
|
|
|
while let ExprKind::DropTemps(inner) = &expr.kind {
|
|
|
|
expr = inner;
|
2019-10-08 15:26:42 +00:00
|
|
|
}
|
2019-10-08 16:46:57 +00:00
|
|
|
expr
|
2019-10-08 15:26:42 +00:00
|
|
|
}
|
2018-01-10 19:40:16 +00:00
|
|
|
}
|
|
|
|
|
2019-12-22 19:46:14 +00:00
|
|
|
/// Checks if the specified expression is a built-in range literal.
|
|
|
|
/// (See: `LoweringContext::lower_expr()`).
|
2020-08-04 13:18:11 +00:00
|
|
|
pub fn is_range_literal(expr: &Expr<'_>) -> bool {
|
2019-12-22 19:46:14 +00:00
|
|
|
match expr.kind {
|
|
|
|
// All built-in range literals but `..=` and `..` desugar to `Struct`s.
|
2020-08-04 13:18:11 +00:00
|
|
|
ExprKind::Struct(ref qpath, _, _) => matches!(
|
|
|
|
**qpath,
|
|
|
|
QPath::LangItem(
|
|
|
|
LangItem::Range
|
|
|
|
| LangItem::RangeTo
|
|
|
|
| LangItem::RangeFrom
|
|
|
|
| LangItem::RangeFull
|
|
|
|
| LangItem::RangeToInclusive,
|
|
|
|
_,
|
|
|
|
)
|
|
|
|
),
|
2019-12-22 19:46:14 +00:00
|
|
|
|
|
|
|
// `..=` desugars into `::std::ops::RangeInclusive::new(...)`.
|
|
|
|
ExprKind::Call(ref func, _) => {
|
2020-08-04 13:18:11 +00:00
|
|
|
matches!(func.kind, ExprKind::Path(QPath::LangItem(LangItem::RangeInclusiveNew, _)))
|
2019-12-22 19:46:14 +00:00
|
|
|
}
|
|
|
|
|
2020-08-04 13:18:11 +00:00
|
|
|
_ => false,
|
2019-12-22 19:46:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2019-11-29 12:43:03 +00:00
|
|
|
pub enum ExprKind<'hir> {
|
2015-09-24 15:00:08 +00:00
|
|
|
/// A `box x` expression.
|
2019-11-29 12:43:03 +00:00
|
|
|
Box(&'hir Expr<'hir>),
|
2020-10-06 20:51:15 +00:00
|
|
|
/// Allow anonymous constants from an inline `const` block
|
|
|
|
ConstBlock(AnonConst),
|
2019-02-08 13:53:55 +00:00
|
|
|
/// An array (e.g., `[a, b, c, d]`).
|
2019-11-29 12:43:03 +00:00
|
|
|
Array(&'hir [Expr<'hir>]),
|
2019-02-08 13:53:55 +00:00
|
|
|
/// A function call.
|
2015-07-31 07:04:06 +00:00
|
|
|
///
|
2018-07-11 12:05:29 +00:00
|
|
|
/// The first field resolves to the function itself (usually an `ExprKind::Path`),
|
2017-10-27 18:27:59 +00: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.
|
2019-11-29 12:43:03 +00:00
|
|
|
Call(&'hir Expr<'hir>, &'hir [Expr<'hir>]),
|
2019-02-08 13:53:55 +00:00
|
|
|
/// A method call (e.g., `x.foo::<'static, Bar, Baz>(a, b, c, d)`).
|
2015-07-31 07:04:06 +00:00
|
|
|
///
|
2017-07-07 12:57:51 +00:00
|
|
|
/// The `PathSegment`/`Span` represent the method name and its generic arguments
|
2015-07-31 07:04:06 +00:00
|
|
|
/// (within the angle brackets).
|
2017-07-07 12:57:51 +00:00
|
|
|
/// The first element of the vector of `Expr`s is the expression that evaluates
|
|
|
|
/// to the object on which the method is being called on (the receiver),
|
|
|
|
/// and the remaining elements are the rest of the arguments.
|
2015-07-31 07:04:06 +00:00
|
|
|
/// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as
|
2017-07-07 12:57:51 +00:00
|
|
|
/// `ExprKind::MethodCall(PathSegment { foo, [Bar, Baz] }, [x, a, b, c, d])`.
|
2020-06-09 19:34:23 +00:00
|
|
|
/// The final `Span` represents the span of the function and arguments
|
|
|
|
/// (e.g. `foo::<Bar, Baz>(a, b, c, d)` in `x.foo::<Bar, Baz>(a, b, c, d)`
|
2019-11-04 09:16:16 +00:00
|
|
|
///
|
|
|
|
/// To resolve the called method to a `DefId`, call [`type_dependent_def_id`] with
|
|
|
|
/// the `hir_id` of the `MethodCall` node itself.
|
|
|
|
///
|
2020-07-17 08:47:04 +00:00
|
|
|
/// [`type_dependent_def_id`]: ../ty/struct.TypeckResults.html#method.type_dependent_def_id
|
2020-06-09 19:34:23 +00:00
|
|
|
MethodCall(&'hir PathSegment<'hir>, Span, &'hir [Expr<'hir>], Span),
|
2019-09-26 06:01:01 +00:00
|
|
|
/// A tuple (e.g., `(a, b, c, d)`).
|
2019-11-29 12:43:03 +00:00
|
|
|
Tup(&'hir [Expr<'hir>]),
|
2019-02-08 13:53:55 +00:00
|
|
|
/// A binary operation (e.g., `a + b`, `a * b`).
|
2019-11-29 12:43:03 +00:00
|
|
|
Binary(BinOp, &'hir Expr<'hir>, &'hir Expr<'hir>),
|
2019-02-08 13:53:55 +00:00
|
|
|
/// A unary operation (e.g., `!x`, `*x`).
|
2019-11-29 12:43:03 +00:00
|
|
|
Unary(UnOp, &'hir Expr<'hir>),
|
2019-02-08 13:53:55 +00:00
|
|
|
/// A literal (e.g., `1`, `"foo"`).
|
2019-01-16 02:51:24 +00:00
|
|
|
Lit(Lit),
|
2019-02-08 13:53:55 +00:00
|
|
|
/// A cast (e.g., `foo as f64`).
|
2019-11-30 16:46:46 +00:00
|
|
|
Cast(&'hir Expr<'hir>, &'hir Ty<'hir>),
|
2019-02-08 13:53:55 +00:00
|
|
|
/// A type reference (e.g., `Foo`).
|
2019-11-30 16:46:46 +00:00
|
|
|
Type(&'hir Expr<'hir>, &'hir Ty<'hir>),
|
2019-04-30 15:46:59 +00:00
|
|
|
/// Wraps the expression in a terminating scope.
|
|
|
|
/// This makes it semantically equivalent to `{ let _t = expr; _t }`.
|
|
|
|
///
|
|
|
|
/// This construct only exists to tweak the drop order in HIR lowering.
|
|
|
|
/// An example of that is the desugaring of `for` loops.
|
2019-11-29 12:43:03 +00:00
|
|
|
DropTemps(&'hir Expr<'hir>),
|
2019-02-08 13:53:55 +00:00
|
|
|
/// A conditionless loop (can be exited with `break`, `continue`, or `return`).
|
2015-07-31 07:04:06 +00:00
|
|
|
///
|
2019-02-08 13:53:55 +00:00
|
|
|
/// I.e., `'label: loop { <block> }`.
|
2019-11-29 12:43:03 +00:00
|
|
|
Loop(&'hir Block<'hir>, Option<Label>, LoopSource),
|
2015-07-31 07:04:06 +00:00
|
|
|
/// A `match` block, with a source that indicates whether or not it is
|
|
|
|
/// the result of a desugaring, and if so, which kind.
|
2019-11-29 12:43:03 +00:00
|
|
|
Match(&'hir Expr<'hir>, &'hir [Arm<'hir>], MatchSource),
|
2019-02-08 13:53:55 +00:00
|
|
|
/// A closure (e.g., `move |a, b, c| {a + b + c}`).
|
2016-04-20 18:44:07 +00:00
|
|
|
///
|
2019-08-13 23:41:43 +00:00
|
|
|
/// The `Span` is the argument block `|...|`.
|
2017-07-10 20:07:55 +00:00
|
|
|
///
|
2019-06-18 21:34:51 +00:00
|
|
|
/// This may also be a generator literal or an `async block` as indicated by the
|
2019-11-09 17:06:57 +00:00
|
|
|
/// `Option<Movability>`.
|
2019-11-30 16:46:46 +00:00
|
|
|
Closure(CaptureBy, &'hir FnDecl<'hir>, BodyId, Span, Option<Movability>),
|
2019-02-08 13:53:55 +00:00
|
|
|
/// A block (e.g., `'label: { ... }`).
|
2019-11-29 12:43:03 +00:00
|
|
|
Block(&'hir Block<'hir>, Option<Label>),
|
2015-07-31 07:04:06 +00:00
|
|
|
|
2019-02-08 13:53:55 +00:00
|
|
|
/// An assignment (e.g., `a = foo()`).
|
2019-11-29 12:43:03 +00:00
|
|
|
Assign(&'hir Expr<'hir>, &'hir Expr<'hir>, Span),
|
2019-02-08 13:53:55 +00:00
|
|
|
/// An assignment with an operator.
|
2015-07-31 07:04:06 +00:00
|
|
|
///
|
2019-02-08 13:53:55 +00:00
|
|
|
/// E.g., `a += 1`.
|
2019-11-29 12:43:03 +00:00
|
|
|
AssignOp(BinOp, &'hir Expr<'hir>, &'hir Expr<'hir>),
|
2019-02-08 13:53:55 +00:00
|
|
|
/// Access of a named (e.g., `obj.foo`) or unnamed (e.g., `obj.0`) struct or tuple field.
|
2019-11-29 12:43:03 +00:00
|
|
|
Field(&'hir Expr<'hir>, Ident),
|
2019-02-08 13:53:55 +00:00
|
|
|
/// An indexing operation (`foo[2]`).
|
2019-11-29 12:43:03 +00:00
|
|
|
Index(&'hir Expr<'hir>, &'hir Expr<'hir>),
|
2015-07-31 07:04:06 +00:00
|
|
|
|
2016-10-27 02:17:42 +00:00
|
|
|
/// Path to a definition, possibly containing lifetime or type parameters.
|
2019-11-30 16:46:46 +00:00
|
|
|
Path(QPath<'hir>),
|
2015-07-31 07:04:06 +00:00
|
|
|
|
2019-11-29 12:43:03 +00:00
|
|
|
/// A referencing operation (i.e., `&a` or `&mut a`).
|
2019-11-29 13:08:03 +00:00
|
|
|
AddrOf(BorrowKind, Mutability, &'hir Expr<'hir>),
|
2019-02-08 13:53:55 +00:00
|
|
|
/// A `break`, with an optional label to break.
|
2019-11-29 12:43:03 +00:00
|
|
|
Break(Destination, Option<&'hir Expr<'hir>>),
|
2019-02-08 13:53:55 +00:00
|
|
|
/// A `continue`, with an optional label.
|
2018-07-11 12:05:29 +00:00
|
|
|
Continue(Destination),
|
2019-02-08 13:53:55 +00:00
|
|
|
/// A `return`, with an optional value to be returned.
|
2019-11-29 12:43:03 +00:00
|
|
|
Ret(Option<&'hir Expr<'hir>>),
|
2015-07-31 07:04:06 +00:00
|
|
|
|
2020-02-12 17:32:41 +00:00
|
|
|
/// Inline assembly (from `asm!`), with its outputs and inputs.
|
|
|
|
InlineAsm(&'hir InlineAsm<'hir>),
|
2020-01-14 13:40:42 +00:00
|
|
|
/// Inline assembly (from `llvm_asm!`), with its outputs and inputs.
|
|
|
|
LlvmInlineAsm(&'hir LlvmInlineAsm<'hir>),
|
2015-07-31 07:04:06 +00:00
|
|
|
|
2016-06-28 16:07:39 +00:00
|
|
|
/// A struct or struct-like variant literal expression.
|
2015-07-31 07:04:06 +00:00
|
|
|
///
|
2019-02-28 22:43:53 +00:00
|
|
|
/// E.g., `Foo {x: 1, y: 2}`, or `Foo {x: 1, .. base}`,
|
|
|
|
/// where `base` is the `Option<Expr>`.
|
2019-11-30 16:46:46 +00:00
|
|
|
Struct(&'hir QPath<'hir>, &'hir [Field<'hir>], Option<&'hir Expr<'hir>>),
|
2015-07-31 07:04:06 +00:00
|
|
|
|
2016-06-28 10:32:45 +00:00
|
|
|
/// An array literal constructed from one repeated element.
|
2015-07-31 07:04:06 +00:00
|
|
|
///
|
2019-02-28 22:43:53 +00:00
|
|
|
/// E.g., `[1; 5]`. The first expression is the element
|
2015-07-31 07:04:06 +00:00
|
|
|
/// to be repeated; the second is the number of times to repeat it.
|
2019-11-29 12:43:03 +00:00
|
|
|
Repeat(&'hir Expr<'hir>, AnonConst),
|
2016-12-26 13:34:03 +00:00
|
|
|
|
2019-02-08 13:53:55 +00:00
|
|
|
/// A suspension point for generators (i.e., `yield <expr>`).
|
2019-11-29 12:43:03 +00:00
|
|
|
Yield(&'hir Expr<'hir>, YieldSource),
|
2018-12-17 01:57:32 +00:00
|
|
|
|
2019-02-08 13:53:55 +00:00
|
|
|
/// A placeholder for an expression that wasn't syntactically well formed in some way.
|
2018-12-17 01:57:32 +00:00
|
|
|
Err,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2019-02-28 22:43:53 +00:00
|
|
|
/// Represents an optionally `Self`-qualified value/type path or associated extension.
|
2019-11-04 08:50:59 +00:00
|
|
|
///
|
|
|
|
/// To resolve the path to a `DefId`, call [`qpath_res`].
|
|
|
|
///
|
2020-07-17 08:47:04 +00:00
|
|
|
/// [`qpath_res`]: ../rustc_middle/ty/struct.TypeckResults.html#method.qpath_res
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2019-11-30 16:46:46 +00:00
|
|
|
pub enum QPath<'hir> {
|
2016-10-27 02:17:42 +00:00
|
|
|
/// Path to a definition, optionally "fully-qualified" with a `Self`
|
|
|
|
/// type, if the path points to an associated item in a trait.
|
|
|
|
///
|
2019-02-08 13:53:55 +00:00
|
|
|
/// E.g., an unqualified path like `Clone::clone` has `None` for `Self`,
|
2016-10-27 02:17:42 +00:00
|
|
|
/// while `<Vec<T> as Clone>::clone` has `Some(Vec<T>)` for `Self`,
|
|
|
|
/// even though they both have the same two-segment `Clone::clone` `Path`.
|
2019-11-30 16:46:46 +00:00
|
|
|
Resolved(Option<&'hir Ty<'hir>>, &'hir Path<'hir>),
|
2016-10-27 02:17:42 +00:00
|
|
|
|
2019-02-08 13:53:55 +00:00
|
|
|
/// Type-related paths (e.g., `<T>::default` or `<T>::Output`).
|
2016-10-27 02:17:42 +00:00
|
|
|
/// Will be resolved by type-checking to an associated item.
|
|
|
|
///
|
|
|
|
/// UFCS source paths can desugar into this, with `Vec::new` turning into
|
|
|
|
/// `<Vec>::new`, and `T::X::Y::method` into `<<<T>::X>::Y>::method`,
|
2018-07-11 14:41:03 +00:00
|
|
|
/// the `X` and `Y` nodes each being a `TyKind::Path(QPath::TypeRelative(..))`.
|
2019-11-30 16:46:46 +00:00
|
|
|
TypeRelative(&'hir Ty<'hir>, &'hir PathSegment<'hir>),
|
2020-08-04 13:34:24 +00:00
|
|
|
|
|
|
|
/// Reference to a `#[lang = "foo"]` item.
|
|
|
|
LangItem(LangItem, Span),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'hir> QPath<'hir> {
|
|
|
|
/// Returns the span of this `QPath`.
|
|
|
|
pub fn span(&self) -> Span {
|
|
|
|
match *self {
|
|
|
|
QPath::Resolved(_, path) => path.span,
|
|
|
|
QPath::TypeRelative(_, ps) => ps.ident.span,
|
|
|
|
QPath::LangItem(_, span) => span,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns the span of the qself of this `QPath`. For example, `()` in
|
|
|
|
/// `<() as Trait>::method`.
|
|
|
|
pub fn qself_span(&self) -> Span {
|
|
|
|
match *self {
|
|
|
|
QPath::Resolved(_, path) => path.span,
|
|
|
|
QPath::TypeRelative(qself, _) => qself.span,
|
|
|
|
QPath::LangItem(_, span) => span,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns the span of the last segment of this `QPath`. For example, `method` in
|
|
|
|
/// `<() as Trait>::method`.
|
|
|
|
pub fn last_segment_span(&self) -> Span {
|
|
|
|
match *self {
|
|
|
|
QPath::Resolved(_, path) => path.segments.last().unwrap().ident.span,
|
|
|
|
QPath::TypeRelative(_, segment) => segment.ident.span,
|
|
|
|
QPath::LangItem(_, span) => span,
|
|
|
|
}
|
|
|
|
}
|
2016-10-27 02:17:42 +00:00
|
|
|
}
|
|
|
|
|
2019-02-08 13:53:55 +00:00
|
|
|
/// Hints at the original code for a let statement.
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Copy, Clone, Encodable, Debug, HashStable_Generic)]
|
2017-05-27 18:20:17 +00:00
|
|
|
pub enum LocalSource {
|
2019-02-08 13:53:55 +00:00
|
|
|
/// A `match _ { .. }`.
|
2017-05-27 18:20:17 +00:00
|
|
|
Normal,
|
2019-02-08 13:53:55 +00:00
|
|
|
/// A desugared `for _ in _ { .. }` loop.
|
2017-05-27 18:20:17 +00:00
|
|
|
ForLoopDesugar,
|
2019-03-12 15:53:33 +00:00
|
|
|
/// When lowering async functions, we create locals within the `async move` so that
|
2019-08-27 11:24:32 +00:00
|
|
|
/// all parameters are dropped after the future is polled.
|
2019-03-12 15:53:33 +00:00
|
|
|
///
|
|
|
|
/// ```ignore (pseudo-Rust)
|
|
|
|
/// async fn foo(<pattern> @ x: Type) {
|
|
|
|
/// async move {
|
|
|
|
/// let <pattern> = x;
|
|
|
|
/// }
|
|
|
|
/// }
|
|
|
|
/// ```
|
|
|
|
AsyncFn,
|
2019-04-18 19:55:23 +00:00
|
|
|
/// A desugared `<expr>.await`.
|
|
|
|
AwaitDesugar,
|
2020-11-04 16:32:52 +00:00
|
|
|
/// A desugared `expr = expr`, where the LHS is a tuple, struct or array.
|
|
|
|
/// The span is that of the `=` sign.
|
|
|
|
AssignDesugar(Span),
|
2017-05-27 18:20:17 +00:00
|
|
|
}
|
|
|
|
|
2019-02-08 13:53:55 +00:00
|
|
|
/// Hints at the original code for a `match _ { .. }`.
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Hash, Debug)]
|
2020-01-02 04:18:45 +00:00
|
|
|
#[derive(HashStable_Generic)]
|
2015-07-31 07:04:06 +00:00
|
|
|
pub enum MatchSource {
|
2019-02-08 13:53:55 +00:00
|
|
|
/// A `match _ { .. }`.
|
2015-07-31 07:04:06 +00:00
|
|
|
Normal,
|
2019-03-11 15:43:27 +00:00
|
|
|
/// An `if _ { .. }` (optionally with `else { .. }`).
|
2019-12-22 22:42:04 +00:00
|
|
|
IfDesugar { contains_else_clause: bool },
|
2019-02-08 13:53:55 +00:00
|
|
|
/// An `if let _ = _ { .. }` (optionally with `else { .. }`).
|
2019-12-22 22:42:04 +00:00
|
|
|
IfLetDesugar { contains_else_clause: bool },
|
2019-06-19 15:21:28 +00:00
|
|
|
/// A `while _ { .. }` (which was desugared to a `loop { match _ { .. } }`).
|
|
|
|
WhileDesugar,
|
2016-06-28 10:32:45 +00:00
|
|
|
/// A `while let _ = _ { .. }` (which was desugared to a
|
2019-02-08 13:53:55 +00:00
|
|
|
/// `loop { match _ { .. } }`).
|
2015-07-31 07:04:06 +00:00
|
|
|
WhileLetDesugar,
|
2019-02-08 13:53:55 +00:00
|
|
|
/// A desugared `for _ in _ { .. }` loop.
|
2015-07-31 07:04:06 +00:00
|
|
|
ForLoopDesugar,
|
2019-02-08 13:53:55 +00:00
|
|
|
/// A desugared `?` operator.
|
2016-02-28 22:38:48 +00:00
|
|
|
TryDesugar,
|
2019-04-18 19:55:23 +00:00
|
|
|
/// A desugared `<expr>.await`.
|
|
|
|
AwaitDesugar,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2019-11-18 20:58:28 +00:00
|
|
|
impl MatchSource {
|
|
|
|
pub fn name(self) -> &'static str {
|
|
|
|
use MatchSource::*;
|
|
|
|
match self {
|
|
|
|
Normal => "match",
|
|
|
|
IfDesugar { .. } | IfLetDesugar { .. } => "if",
|
|
|
|
WhileDesugar | WhileLetDesugar => "while",
|
|
|
|
ForLoopDesugar => "for",
|
|
|
|
TryDesugar => "?",
|
|
|
|
AwaitDesugar => ".await",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-08 13:53:55 +00:00
|
|
|
/// The loop type that yielded an `ExprKind::Loop`.
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)]
|
Implement the `loop_break_value` feature.
This implements RFC 1624, tracking issue #37339.
- `FnCtxt` (in typeck) gets a stack of `LoopCtxt`s, which store the
currently deduced type of that loop, the desired type, and a list of
break expressions currently seen. `loop` loops get a fresh type
variable as their initial type (this logic is stolen from that for
arrays). `while` loops get `()`.
- `break {expr}` looks up the broken loop, and unifies the type of
`expr` with the type of the loop.
- `break` with no expr unifies the loop's type with `()`.
- When building MIR, `loop` loops no longer construct a `()` value at
termination of the loop; rather, the `break` expression assigns the
result of the loop. `while` loops are unchanged.
- `break` respects contexts in which expressions may not end with braced
blocks. That is, `while break { break-value } { while-body }` is
illegal; this preserves backwards compatibility.
- The RFC did not make it clear, but I chose to make `break ()` inside
of a `while` loop illegal, just in case we wanted to do anything with
that design space in the future.
This is my first time dealing with this part of rustc so I'm sure
there's plenty of problems to pick on here ^_^
2016-10-29 22:15:06 +00:00
|
|
|
pub enum LoopSource {
|
2019-02-08 13:53:55 +00:00
|
|
|
/// A `loop { .. }` loop.
|
Implement the `loop_break_value` feature.
This implements RFC 1624, tracking issue #37339.
- `FnCtxt` (in typeck) gets a stack of `LoopCtxt`s, which store the
currently deduced type of that loop, the desired type, and a list of
break expressions currently seen. `loop` loops get a fresh type
variable as their initial type (this logic is stolen from that for
arrays). `while` loops get `()`.
- `break {expr}` looks up the broken loop, and unifies the type of
`expr` with the type of the loop.
- `break` with no expr unifies the loop's type with `()`.
- When building MIR, `loop` loops no longer construct a `()` value at
termination of the loop; rather, the `break` expression assigns the
result of the loop. `while` loops are unchanged.
- `break` respects contexts in which expressions may not end with braced
blocks. That is, `while break { break-value } { while-body }` is
illegal; this preserves backwards compatibility.
- The RFC did not make it clear, but I chose to make `break ()` inside
of a `while` loop illegal, just in case we wanted to do anything with
that design space in the future.
This is my first time dealing with this part of rustc so I'm sure
there's plenty of problems to pick on here ^_^
2016-10-29 22:15:06 +00:00
|
|
|
Loop,
|
2019-06-19 15:21:28 +00:00
|
|
|
/// A `while _ { .. }` loop.
|
|
|
|
While,
|
2019-02-08 13:53:55 +00:00
|
|
|
/// A `while let _ = _ { .. }` loop.
|
Implement the `loop_break_value` feature.
This implements RFC 1624, tracking issue #37339.
- `FnCtxt` (in typeck) gets a stack of `LoopCtxt`s, which store the
currently deduced type of that loop, the desired type, and a list of
break expressions currently seen. `loop` loops get a fresh type
variable as their initial type (this logic is stolen from that for
arrays). `while` loops get `()`.
- `break {expr}` looks up the broken loop, and unifies the type of
`expr` with the type of the loop.
- `break` with no expr unifies the loop's type with `()`.
- When building MIR, `loop` loops no longer construct a `()` value at
termination of the loop; rather, the `break` expression assigns the
result of the loop. `while` loops are unchanged.
- `break` respects contexts in which expressions may not end with braced
blocks. That is, `while break { break-value } { while-body }` is
illegal; this preserves backwards compatibility.
- The RFC did not make it clear, but I chose to make `break ()` inside
of a `while` loop illegal, just in case we wanted to do anything with
that design space in the future.
This is my first time dealing with this part of rustc so I'm sure
there's plenty of problems to pick on here ^_^
2016-10-29 22:15:06 +00:00
|
|
|
WhileLet,
|
2019-02-08 13:53:55 +00:00
|
|
|
/// A `for _ in _ { .. }` loop.
|
Implement the `loop_break_value` feature.
This implements RFC 1624, tracking issue #37339.
- `FnCtxt` (in typeck) gets a stack of `LoopCtxt`s, which store the
currently deduced type of that loop, the desired type, and a list of
break expressions currently seen. `loop` loops get a fresh type
variable as their initial type (this logic is stolen from that for
arrays). `while` loops get `()`.
- `break {expr}` looks up the broken loop, and unifies the type of
`expr` with the type of the loop.
- `break` with no expr unifies the loop's type with `()`.
- When building MIR, `loop` loops no longer construct a `()` value at
termination of the loop; rather, the `break` expression assigns the
result of the loop. `while` loops are unchanged.
- `break` respects contexts in which expressions may not end with braced
blocks. That is, `while break { break-value } { while-body }` is
illegal; this preserves backwards compatibility.
- The RFC did not make it clear, but I chose to make `break ()` inside
of a `while` loop illegal, just in case we wanted to do anything with
that design space in the future.
This is my first time dealing with this part of rustc so I'm sure
there's plenty of problems to pick on here ^_^
2016-10-29 22:15:06 +00:00
|
|
|
ForLoop,
|
|
|
|
}
|
|
|
|
|
2019-06-19 15:21:28 +00:00
|
|
|
impl LoopSource {
|
|
|
|
pub fn name(self) -> &'static str {
|
|
|
|
match self {
|
|
|
|
LoopSource::Loop => "loop",
|
2019-11-18 20:58:28 +00:00
|
|
|
LoopSource::While | LoopSource::WhileLet => "while",
|
2019-06-19 15:21:28 +00:00
|
|
|
LoopSource::ForLoop => "for",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Copy, Clone, Encodable, Debug, HashStable_Generic)]
|
2017-02-16 07:28:59 +00:00
|
|
|
pub enum LoopIdError {
|
|
|
|
OutsideLoopScope,
|
|
|
|
UnlabeledCfInWhileCondition,
|
|
|
|
UnresolvedLabel,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Display for LoopIdError {
|
2018-08-30 05:02:42 +00:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
2019-06-18 21:34:51 +00:00
|
|
|
f.write_str(match self {
|
2017-02-16 07:28:59 +00:00
|
|
|
LoopIdError::OutsideLoopScope => "not inside loop scope",
|
2019-12-22 22:42:04 +00:00
|
|
|
LoopIdError::UnlabeledCfInWhileCondition => {
|
|
|
|
"unlabeled control flow (break or continue) in while condition"
|
|
|
|
}
|
2017-02-16 07:28:59 +00:00
|
|
|
LoopIdError::UnresolvedLabel => "label not found",
|
2019-06-18 21:34:51 +00:00
|
|
|
})
|
2017-02-16 07:28:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Copy, Clone, Encodable, Debug, HashStable_Generic)]
|
2017-02-18 02:55:28 +00:00
|
|
|
pub struct Destination {
|
2017-02-16 07:28:59 +00:00
|
|
|
// This is `Some(_)` iff there is an explicit user-specified `label
|
2018-01-15 22:44:32 +00:00
|
|
|
pub label: Option<Label>,
|
2017-02-16 07:28:59 +00:00
|
|
|
|
|
|
|
// These errors are caught and then reported during the diagnostics pass in
|
|
|
|
// librustc_passes/loops.rs
|
2019-03-07 11:43:27 +00:00
|
|
|
pub target_id: Result<HirId, LoopIdError>,
|
2016-11-25 11:21:19 +00:00
|
|
|
}
|
|
|
|
|
2019-06-18 21:34:51 +00:00
|
|
|
/// The yield kind that caused an `ExprKind::Yield`.
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, Debug, Encodable, Decodable, HashStable_Generic)]
|
2019-06-18 21:34:51 +00:00
|
|
|
pub enum YieldSource {
|
|
|
|
/// An `<expr>.await`.
|
2020-04-02 01:53:00 +00:00
|
|
|
Await { expr: Option<HirId> },
|
2019-06-18 21:34:51 +00:00
|
|
|
/// A plain `yield`.
|
|
|
|
Yield,
|
|
|
|
}
|
|
|
|
|
2020-04-02 01:53:00 +00:00
|
|
|
impl YieldSource {
|
|
|
|
pub fn is_await(&self) -> bool {
|
|
|
|
match self {
|
|
|
|
YieldSource::Await { .. } => true,
|
|
|
|
YieldSource::Yield => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-18 21:34:51 +00:00
|
|
|
impl fmt::Display for YieldSource {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
|
f.write_str(match self {
|
2020-04-02 01:53:00 +00:00
|
|
|
YieldSource::Await { .. } => "`await`",
|
2019-06-18 21:34:51 +00:00
|
|
|
YieldSource::Yield => "`yield`",
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-21 18:44:12 +00:00
|
|
|
impl From<GeneratorKind> for YieldSource {
|
|
|
|
fn from(kind: GeneratorKind) -> Self {
|
|
|
|
match kind {
|
2019-10-16 16:57:18 +00:00
|
|
|
// Guess based on the kind of the current generator.
|
|
|
|
GeneratorKind::Gen => Self::Yield,
|
2020-04-02 01:53:00 +00:00
|
|
|
GeneratorKind::Async(_) => Self::Await { expr: None },
|
2019-10-16 16:57:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-27 02:59:49 +00:00
|
|
|
// N.B., if you change this, you'll probably want to change the corresponding
|
2015-07-31 07:04:06 +00:00
|
|
|
// type structure in middle/ty.rs as well.
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2019-11-30 16:46:46 +00:00
|
|
|
pub struct MutTy<'hir> {
|
|
|
|
pub ty: &'hir Ty<'hir>,
|
2015-07-31 07:04:06 +00:00
|
|
|
pub mutbl: Mutability,
|
|
|
|
}
|
|
|
|
|
2019-11-07 12:06:52 +00:00
|
|
|
/// Represents a function's signature in a trait declaration,
|
|
|
|
/// trait implementation, or a free function.
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2019-11-30 14:20:35 +00:00
|
|
|
pub struct FnSig<'hir> {
|
2018-05-17 05:55:18 +00:00
|
|
|
pub header: FnHeader,
|
2019-11-30 16:46:46 +00:00
|
|
|
pub decl: &'hir FnDecl<'hir>,
|
2020-08-12 21:02:14 +00:00
|
|
|
pub span: Span,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2016-12-04 02:21:06 +00:00
|
|
|
// The bodies for items are stored "out of line", in a separate
|
|
|
|
// hashmap in the `Crate`. Here we just record the node-id of the item
|
|
|
|
// so it can fetched later.
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Encodable, Debug)]
|
2016-12-04 02:21:06 +00:00
|
|
|
pub struct TraitItemId {
|
2019-03-01 09:28:13 +00:00
|
|
|
pub hir_id: HirId,
|
2016-12-04 02:21:06 +00:00
|
|
|
}
|
|
|
|
|
2015-12-18 22:38:28 +00:00
|
|
|
/// Represents an item declaration within a trait declaration,
|
|
|
|
/// possibly including a default implementation. A trait item is
|
|
|
|
/// either required (meaning it doesn't have an implementation, just a
|
|
|
|
/// signature) or provided (meaning it has a default implementation).
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug)]
|
2019-11-28 20:47:10 +00:00
|
|
|
pub struct TraitItem<'hir> {
|
2018-06-10 19:24:24 +00:00
|
|
|
pub ident: Ident,
|
2017-08-18 18:24:19 +00:00
|
|
|
pub hir_id: HirId,
|
2019-11-28 20:47:10 +00:00
|
|
|
pub attrs: &'hir [Attribute],
|
2019-11-30 16:46:46 +00:00
|
|
|
pub generics: Generics<'hir>,
|
2019-11-28 20:47:10 +00:00
|
|
|
pub kind: TraitItemKind<'hir>,
|
2015-07-31 07:04:06 +00:00
|
|
|
pub span: Span,
|
|
|
|
}
|
|
|
|
|
2019-02-28 22:43:53 +00:00
|
|
|
/// Represents a trait method's body (or just argument names).
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Encodable, Debug, HashStable_Generic)]
|
2020-03-05 15:57:34 +00:00
|
|
|
pub enum TraitFn<'hir> {
|
2016-12-20 20:46:11 +00:00
|
|
|
/// No default body in the trait, just a signature.
|
2019-11-30 14:28:32 +00:00
|
|
|
Required(&'hir [Ident]),
|
2016-12-20 20:46:11 +00:00
|
|
|
|
|
|
|
/// Both signature and body are provided in the trait.
|
|
|
|
Provided(BodyId),
|
|
|
|
}
|
|
|
|
|
2016-06-28 10:32:45 +00:00
|
|
|
/// Represents a trait method or associated constant or type
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2019-11-28 20:47:10 +00:00
|
|
|
pub enum TraitItemKind<'hir> {
|
2019-02-28 22:43:53 +00:00
|
|
|
/// An associated constant with an optional value (otherwise `impl`s must contain a value).
|
2019-11-30 16:46:46 +00:00
|
|
|
Const(&'hir Ty<'hir>, Option<BodyId>),
|
2020-03-03 18:46:22 +00:00
|
|
|
/// An associated function with an optional body.
|
2020-03-05 15:57:34 +00:00
|
|
|
Fn(FnSig<'hir>, TraitFn<'hir>),
|
2016-06-28 10:32:45 +00:00
|
|
|
/// An associated type with (possibly empty) bounds and optional concrete
|
2019-02-28 22:43:53 +00:00
|
|
|
/// type.
|
2019-11-30 16:46:46 +00:00
|
|
|
Type(GenericBounds<'hir>, Option<&'hir Ty<'hir>>),
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2016-11-02 22:25:31 +00:00
|
|
|
// The bodies for items are stored "out of line", in a separate
|
|
|
|
// hashmap in the `Crate`. Here we just record the node-id of the item
|
|
|
|
// so it can fetched later.
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Encodable, Debug)]
|
2016-11-02 22:25:31 +00:00
|
|
|
pub struct ImplItemId {
|
2019-03-01 09:28:13 +00:00
|
|
|
pub hir_id: HirId,
|
2016-11-02 22:25:31 +00:00
|
|
|
}
|
|
|
|
|
2019-07-31 23:41:54 +00:00
|
|
|
/// Represents anything within an `impl` block.
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug)]
|
2019-11-28 21:16:44 +00:00
|
|
|
pub struct ImplItem<'hir> {
|
2018-06-10 19:24:24 +00:00
|
|
|
pub ident: Ident,
|
2017-08-18 18:24:19 +00:00
|
|
|
pub hir_id: HirId,
|
2019-11-30 16:46:46 +00:00
|
|
|
pub vis: Visibility<'hir>,
|
2015-12-18 22:38:28 +00:00
|
|
|
pub defaultness: Defaultness,
|
2019-11-28 21:16:44 +00:00
|
|
|
pub attrs: &'hir [Attribute],
|
2019-11-30 16:46:46 +00:00
|
|
|
pub generics: Generics<'hir>,
|
2019-11-28 21:16:44 +00:00
|
|
|
pub kind: ImplItemKind<'hir>,
|
2015-07-31 07:04:06 +00:00
|
|
|
pub span: Span,
|
|
|
|
}
|
|
|
|
|
2019-05-08 19:57:06 +00:00
|
|
|
/// Represents various kinds of content within an `impl`.
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2019-11-28 21:16:44 +00:00
|
|
|
pub enum ImplItemKind<'hir> {
|
2016-06-28 10:32:45 +00:00
|
|
|
/// An associated constant of the given type, set to the constant result
|
2019-07-31 23:41:54 +00:00
|
|
|
/// of the expression.
|
2019-11-30 16:46:46 +00:00
|
|
|
Const(&'hir Ty<'hir>, BodyId),
|
2020-03-07 00:00:46 +00:00
|
|
|
/// An associated function implementation with the given signature and body.
|
2020-03-05 15:57:34 +00:00
|
|
|
Fn(FnSig<'hir>, BodyId),
|
2019-07-31 23:41:54 +00:00
|
|
|
/// An associated type.
|
2019-11-30 16:46:46 +00:00
|
|
|
TyAlias(&'hir Ty<'hir>),
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2020-02-11 18:41:28 +00:00
|
|
|
impl ImplItemKind<'_> {
|
|
|
|
pub fn namespace(&self) -> Namespace {
|
|
|
|
match self {
|
2020-05-10 11:15:51 +00:00
|
|
|
ImplItemKind::TyAlias(..) => Namespace::TypeNS,
|
2020-03-05 15:57:34 +00:00
|
|
|
ImplItemKind::Const(..) | ImplItemKind::Fn(..) => Namespace::ValueNS,
|
2020-02-11 18:41:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-06 05:48:51 +00:00
|
|
|
// The name of the associated type for `Fn` return types.
|
|
|
|
pub const FN_OUTPUT_NAME: Symbol = sym::Output;
|
|
|
|
|
2019-05-08 19:57:06 +00:00
|
|
|
/// Bind a type to an associated type (i.e., `A = Foo`).
|
|
|
|
///
|
|
|
|
/// Bindings like `A: Debug` are represented as a special type `A =
|
|
|
|
/// $::Debug` that is understood by the astconv code.
|
|
|
|
///
|
2019-05-17 01:20:14 +00:00
|
|
|
/// FIXME(alexreg): why have a separate type for the binding case,
|
|
|
|
/// wouldn't it be better to make the `ty` field an enum like the
|
|
|
|
/// following?
|
2019-05-08 19:57:06 +00:00
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// enum TypeBindingKind {
|
|
|
|
/// Equals(...),
|
|
|
|
/// Binding(...),
|
|
|
|
/// }
|
|
|
|
/// ```
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2019-11-30 16:46:46 +00:00
|
|
|
pub struct TypeBinding<'hir> {
|
2019-02-02 14:40:08 +00:00
|
|
|
pub hir_id: HirId,
|
2018-12-03 00:14:35 +00:00
|
|
|
#[stable_hasher(project(name))]
|
2018-06-10 12:55:48 +00:00
|
|
|
pub ident: Ident,
|
2019-11-30 16:46:46 +00:00
|
|
|
pub kind: TypeBindingKind<'hir>,
|
2015-07-31 07:04:06 +00:00
|
|
|
pub span: Span,
|
|
|
|
}
|
|
|
|
|
2019-05-08 19:57:06 +00:00
|
|
|
// Represents the two kinds of type bindings.
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2019-11-30 16:46:46 +00:00
|
|
|
pub enum TypeBindingKind<'hir> {
|
2019-05-08 19:57:06 +00:00
|
|
|
/// E.g., `Foo<Bar: Send>`.
|
2019-11-30 16:46:46 +00:00
|
|
|
Constraint { bounds: &'hir [GenericBound<'hir>] },
|
2019-05-08 19:57:06 +00:00
|
|
|
/// E.g., `Foo<Bar = ()>`.
|
2019-11-30 16:46:46 +00:00
|
|
|
Equality { ty: &'hir Ty<'hir> },
|
2019-05-08 19:57:06 +00:00
|
|
|
}
|
|
|
|
|
2019-11-30 16:46:46 +00:00
|
|
|
impl TypeBinding<'_> {
|
|
|
|
pub fn ty(&self) -> &Ty<'_> {
|
2019-05-08 19:57:06 +00:00
|
|
|
match self.kind {
|
|
|
|
TypeBindingKind::Equality { ref ty } => ty,
|
2020-01-02 04:18:45 +00:00
|
|
|
_ => panic!("expected equality type binding for parenthesized generic args"),
|
2019-05-08 19:57:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug)]
|
2019-11-30 16:46:46 +00:00
|
|
|
pub struct Ty<'hir> {
|
2019-02-28 22:43:53 +00:00
|
|
|
pub hir_id: HirId,
|
2019-11-30 16:46:46 +00:00
|
|
|
pub kind: TyKind<'hir>,
|
2015-07-31 07:04:06 +00:00
|
|
|
pub span: Span,
|
|
|
|
}
|
|
|
|
|
2019-02-08 13:53:55 +00:00
|
|
|
/// Not represented directly in the AST; referred to by name through a `ty_path`.
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
|
2020-01-02 04:18:45 +00:00
|
|
|
#[derive(HashStable_Generic)]
|
2015-07-31 07:04:06 +00:00
|
|
|
pub enum PrimTy {
|
2018-08-22 00:35:55 +00:00
|
|
|
Int(IntTy),
|
|
|
|
Uint(UintTy),
|
|
|
|
Float(FloatTy),
|
|
|
|
Str,
|
|
|
|
Bool,
|
|
|
|
Char,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2020-09-20 06:18:09 +00:00
|
|
|
impl PrimTy {
|
|
|
|
pub fn name_str(self) -> &'static str {
|
|
|
|
match self {
|
|
|
|
PrimTy::Int(i) => i.name_str(),
|
|
|
|
PrimTy::Uint(u) => u.name_str(),
|
|
|
|
PrimTy::Float(f) => f.name_str(),
|
|
|
|
PrimTy::Str => "str",
|
|
|
|
PrimTy::Bool => "bool",
|
|
|
|
PrimTy::Char => "char",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn name(self) -> Symbol {
|
|
|
|
match self {
|
|
|
|
PrimTy::Int(i) => i.name(),
|
|
|
|
PrimTy::Uint(u) => u.name(),
|
|
|
|
PrimTy::Float(f) => f.name(),
|
|
|
|
PrimTy::Str => sym::str,
|
|
|
|
PrimTy::Bool => sym::bool,
|
|
|
|
PrimTy::Char => sym::char,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2019-11-30 16:46:46 +00:00
|
|
|
pub struct BareFnTy<'hir> {
|
2015-07-31 07:04:06 +00:00
|
|
|
pub unsafety: Unsafety,
|
|
|
|
pub abi: Abi,
|
2019-11-30 16:46:46 +00:00
|
|
|
pub generic_params: &'hir [GenericParam<'hir>],
|
|
|
|
pub decl: &'hir FnDecl<'hir>,
|
|
|
|
pub param_names: &'hir [Ident],
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2019-11-30 16:46:46 +00:00
|
|
|
pub struct OpaqueTy<'hir> {
|
|
|
|
pub generics: Generics<'hir>,
|
|
|
|
pub bounds: GenericBounds<'hir>,
|
2018-05-22 12:31:56 +00:00
|
|
|
pub impl_trait_fn: Option<DefId>,
|
2019-07-31 23:41:54 +00:00
|
|
|
pub origin: OpaqueTyOrigin,
|
2019-03-14 00:42:23 +00:00
|
|
|
}
|
|
|
|
|
2019-08-02 00:14:42 +00:00
|
|
|
/// From whence the opaque type came.
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Copy, Clone, Encodable, Decodable, Debug, HashStable_Generic)]
|
2019-07-31 23:41:54 +00:00
|
|
|
pub enum OpaqueTyOrigin {
|
2019-03-14 00:42:23 +00:00
|
|
|
/// `-> impl Trait`
|
2019-08-01 23:09:38 +00:00
|
|
|
FnReturn,
|
2019-03-14 00:42:23 +00:00
|
|
|
/// `async fn`
|
|
|
|
AsyncFn,
|
2020-05-10 11:18:55 +00:00
|
|
|
/// `let _: impl Trait = ...`
|
|
|
|
Binding,
|
|
|
|
/// Impl trait in type aliases, consts, statics, bounds.
|
2019-12-28 15:39:52 +00:00
|
|
|
Misc,
|
2017-10-15 20:43:06 +00:00
|
|
|
}
|
|
|
|
|
2019-02-08 13:53:55 +00:00
|
|
|
/// The various kinds of types recognized by the compiler.
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2019-11-30 16:46:46 +00:00
|
|
|
pub enum TyKind<'hir> {
|
2019-02-08 13:53:55 +00:00
|
|
|
/// A variable length slice (i.e., `[T]`).
|
2019-11-30 16:46:46 +00:00
|
|
|
Slice(&'hir Ty<'hir>),
|
2019-02-08 13:53:55 +00:00
|
|
|
/// A fixed length array (i.e., `[T; n]`).
|
2019-11-30 16:46:46 +00:00
|
|
|
Array(&'hir Ty<'hir>, AnonConst),
|
2019-02-08 13:53:55 +00:00
|
|
|
/// A raw pointer (i.e., `*const T` or `*mut T`).
|
2019-11-30 16:46:46 +00:00
|
|
|
Ptr(MutTy<'hir>),
|
2019-02-08 13:53:55 +00:00
|
|
|
/// A reference (i.e., `&'a T` or `&'a mut T`).
|
2019-11-30 16:46:46 +00:00
|
|
|
Rptr(Lifetime, MutTy<'hir>),
|
2019-02-08 13:53:55 +00:00
|
|
|
/// A bare function (e.g., `fn(usize) -> bool`).
|
2019-11-30 16:46:46 +00:00
|
|
|
BareFn(&'hir BareFnTy<'hir>),
|
2019-02-08 13:53:55 +00:00
|
|
|
/// The never type (`!`).
|
2018-07-11 14:41:03 +00:00
|
|
|
Never,
|
2019-02-28 22:43:53 +00:00
|
|
|
/// A tuple (`(A, B, C, D, ...)`).
|
2019-11-30 16:46:46 +00:00
|
|
|
Tup(&'hir [Ty<'hir>]),
|
2016-10-27 02:17:42 +00:00
|
|
|
/// A path to a type definition (`module::module::...::Type`), or an
|
2019-02-08 13:53:55 +00:00
|
|
|
/// associated type (e.g., `<Vec<T> as Trait>::Type` or `<T>::Target`).
|
2015-07-31 07:04:06 +00:00
|
|
|
///
|
2016-10-27 02:17:42 +00:00
|
|
|
/// Type parameters may be stored in each `PathSegment`.
|
2019-11-30 16:46:46 +00:00
|
|
|
Path(QPath<'hir>),
|
2020-06-07 17:56:17 +00:00
|
|
|
/// A opaque type definition itself. This is currently only used for the
|
|
|
|
/// `opaque type Foo: Trait` item that `impl Trait` in desugars to.
|
2018-10-02 08:54:34 +00:00
|
|
|
///
|
2020-06-07 17:56:17 +00:00
|
|
|
/// The generic argument list contains the lifetimes (and in the future
|
|
|
|
/// possibly parameters) that are actually bound on the `impl Trait`.
|
|
|
|
OpaqueDef(ItemId, &'hir [GenericArg<'hir>]),
|
2017-01-16 20:33:45 +00:00
|
|
|
/// A trait object type `Bound1 + Bound2 + Bound3`
|
|
|
|
/// where `Bound` is a trait or a lifetime.
|
2019-11-30 16:46:46 +00:00
|
|
|
TraitObject(&'hir [PolyTraitRef<'hir>], Lifetime),
|
2019-02-08 13:53:55 +00:00
|
|
|
/// Unused for now.
|
2018-07-11 14:41:03 +00:00
|
|
|
Typeof(AnonConst),
|
2018-11-27 02:59:49 +00:00
|
|
|
/// `TyKind::Infer` means the type should be inferred instead of it having been
|
2015-07-31 07:04:06 +00:00
|
|
|
/// specified. This can appear anywhere in a type.
|
2018-07-11 14:41:03 +00:00
|
|
|
Infer,
|
2017-03-29 01:56:29 +00:00
|
|
|
/// Placeholder for a type that has failed to be defined.
|
2018-07-11 14:41:03 +00:00
|
|
|
Err,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2020-02-12 17:32:41 +00:00
|
|
|
pub enum InlineAsmOperand<'hir> {
|
|
|
|
In {
|
|
|
|
reg: InlineAsmRegOrRegClass,
|
|
|
|
expr: Expr<'hir>,
|
|
|
|
},
|
|
|
|
Out {
|
|
|
|
reg: InlineAsmRegOrRegClass,
|
|
|
|
late: bool,
|
|
|
|
expr: Option<Expr<'hir>>,
|
|
|
|
},
|
|
|
|
InOut {
|
|
|
|
reg: InlineAsmRegOrRegClass,
|
|
|
|
late: bool,
|
|
|
|
expr: Expr<'hir>,
|
|
|
|
},
|
|
|
|
SplitInOut {
|
|
|
|
reg: InlineAsmRegOrRegClass,
|
|
|
|
late: bool,
|
|
|
|
in_expr: Expr<'hir>,
|
|
|
|
out_expr: Option<Expr<'hir>>,
|
|
|
|
},
|
|
|
|
Const {
|
|
|
|
expr: Expr<'hir>,
|
|
|
|
},
|
|
|
|
Sym {
|
|
|
|
expr: Expr<'hir>,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'hir> InlineAsmOperand<'hir> {
|
|
|
|
pub fn reg(&self) -> Option<InlineAsmRegOrRegClass> {
|
|
|
|
match *self {
|
|
|
|
Self::In { reg, .. }
|
|
|
|
| Self::Out { reg, .. }
|
|
|
|
| Self::InOut { reg, .. }
|
|
|
|
| Self::SplitInOut { reg, .. } => Some(reg),
|
|
|
|
Self::Const { .. } | Self::Sym { .. } => None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2020-02-12 17:32:41 +00:00
|
|
|
pub struct InlineAsm<'hir> {
|
|
|
|
pub template: &'hir [InlineAsmTemplatePiece],
|
|
|
|
pub operands: &'hir [InlineAsmOperand<'hir>],
|
|
|
|
pub options: InlineAsmOptions,
|
2020-05-26 19:07:59 +00:00
|
|
|
pub line_spans: &'hir [Span],
|
2020-02-12 17:32:41 +00:00
|
|
|
}
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Copy, Clone, Encodable, Decodable, Debug, HashStable_Generic, PartialEq)]
|
2020-01-14 13:40:42 +00:00
|
|
|
pub struct LlvmInlineAsmOutput {
|
2016-11-16 10:52:37 +00:00
|
|
|
pub constraint: Symbol,
|
2015-12-05 08:18:24 +00:00
|
|
|
pub is_rw: bool,
|
|
|
|
pub is_indirect: bool,
|
2018-10-09 22:53:37 +00:00
|
|
|
pub span: Span,
|
2015-12-05 08:18:24 +00:00
|
|
|
}
|
|
|
|
|
2019-06-12 06:41:00 +00:00
|
|
|
// NOTE(eddyb) This is used within MIR as well, so unlike the rest of the HIR,
|
2020-06-11 14:49:57 +00:00
|
|
|
// it needs to be `Clone` and `Decodable` and use plain `Vec<T>` instead of
|
|
|
|
// arena-allocated slice.
|
|
|
|
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic, PartialEq)]
|
2020-01-14 13:40:42 +00:00
|
|
|
pub struct LlvmInlineAsmInner {
|
2016-11-16 10:52:37 +00:00
|
|
|
pub asm: Symbol,
|
2015-07-31 07:04:06 +00:00
|
|
|
pub asm_str_style: StrStyle,
|
2020-01-14 13:40:42 +00:00
|
|
|
pub outputs: Vec<LlvmInlineAsmOutput>,
|
2019-06-12 06:41:00 +00:00
|
|
|
pub inputs: Vec<Symbol>,
|
|
|
|
pub clobbers: Vec<Symbol>,
|
2015-07-31 07:04:06 +00:00
|
|
|
pub volatile: bool,
|
|
|
|
pub alignstack: bool,
|
2020-01-14 13:40:42 +00:00
|
|
|
pub dialect: LlvmAsmDialect,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2020-01-14 13:40:42 +00:00
|
|
|
pub struct LlvmInlineAsm<'hir> {
|
|
|
|
pub inner: LlvmInlineAsmInner,
|
2019-11-29 12:43:03 +00:00
|
|
|
pub outputs_exprs: &'hir [Expr<'hir>],
|
|
|
|
pub inputs_exprs: &'hir [Expr<'hir>],
|
2019-11-18 13:43:34 +00:00
|
|
|
}
|
|
|
|
|
2019-08-27 11:24:32 +00:00
|
|
|
/// Represents a parameter in a function header.
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2019-11-29 12:43:03 +00:00
|
|
|
pub struct Param<'hir> {
|
|
|
|
pub attrs: &'hir [Attribute],
|
2017-08-04 07:49:40 +00:00
|
|
|
pub hir_id: HirId,
|
2019-11-29 12:43:03 +00:00
|
|
|
pub pat: &'hir Pat<'hir>,
|
2020-07-11 01:11:40 +00:00
|
|
|
pub ty_span: Span,
|
2019-07-26 22:52:37 +00:00
|
|
|
pub span: Span,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2019-02-08 13:53:55 +00:00
|
|
|
/// Represents the header (not the body) of a function declaration.
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2019-11-30 16:46:46 +00:00
|
|
|
pub struct FnDecl<'hir> {
|
2019-08-27 11:24:32 +00:00
|
|
|
/// The types of the function's parameters.
|
2019-05-02 18:03:33 +00:00
|
|
|
///
|
2020-05-01 15:53:52 +00:00
|
|
|
/// Additional argument data is stored in the function's [body](Body::params).
|
2019-11-30 16:46:46 +00:00
|
|
|
pub inputs: &'hir [Ty<'hir>],
|
2020-02-15 03:10:59 +00:00
|
|
|
pub output: FnRetTy<'hir>,
|
2019-02-08 17:30:42 +00:00
|
|
|
pub c_variadic: bool,
|
2018-10-01 15:46:04 +00:00
|
|
|
/// Does the function have an implicit self?
|
|
|
|
pub implicit_self: ImplicitSelfKind,
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Represents what type of implicit self a function has, if any.
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Copy, Clone, Encodable, Decodable, Debug, HashStable_Generic)]
|
2018-10-01 15:46:04 +00:00
|
|
|
pub enum ImplicitSelfKind {
|
|
|
|
/// Represents a `fn x(self);`.
|
|
|
|
Imm,
|
|
|
|
/// Represents a `fn x(mut self);`.
|
|
|
|
Mut,
|
|
|
|
/// Represents a `fn x(&self);`.
|
|
|
|
ImmRef,
|
|
|
|
/// Represents a `fn x(&mut self);`.
|
|
|
|
MutRef,
|
|
|
|
/// Represents when a function does not have a self argument or
|
|
|
|
/// when a function has a `self: X` argument.
|
2019-12-22 22:42:04 +00:00
|
|
|
None,
|
2018-10-01 15:46:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl ImplicitSelfKind {
|
|
|
|
/// Does this represent an implicit self?
|
|
|
|
pub fn has_implicit_self(&self) -> bool {
|
2020-10-27 01:02:48 +00:00
|
|
|
!matches!(*self, ImplicitSelfKind::None)
|
2018-10-01 15:46:04 +00:00
|
|
|
}
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Encodable, Decodable, Debug)]
|
2020-01-30 01:42:33 +00:00
|
|
|
#[derive(HashStable_Generic)]
|
2018-05-17 05:55:18 +00:00
|
|
|
pub enum IsAsync {
|
|
|
|
Async,
|
|
|
|
NotAsync,
|
|
|
|
}
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Encodable, Decodable, HashStable_Generic)]
|
2015-12-18 22:38:28 +00:00
|
|
|
pub enum Defaultness {
|
2016-11-14 16:00:02 +00:00
|
|
|
Default { has_value: bool },
|
2015-12-18 22:38:28 +00:00
|
|
|
Final,
|
|
|
|
}
|
|
|
|
|
2016-02-16 18:36:47 +00:00
|
|
|
impl Defaultness {
|
2016-11-14 16:00:02 +00:00
|
|
|
pub fn has_value(&self) -> bool {
|
|
|
|
match *self {
|
2020-03-02 23:26:00 +00:00
|
|
|
Defaultness::Default { has_value } => has_value,
|
2016-11-14 16:00:02 +00:00
|
|
|
Defaultness::Final => true,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-16 18:36:47 +00:00
|
|
|
pub fn is_final(&self) -> bool {
|
|
|
|
*self == Defaultness::Final
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn is_default(&self) -> bool {
|
2020-10-27 01:02:48 +00:00
|
|
|
matches!(*self, Defaultness::Default { .. })
|
2016-02-16 18:36:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2020-02-15 03:10:59 +00:00
|
|
|
pub enum FnRetTy<'hir> {
|
2015-07-31 07:04:06 +00:00
|
|
|
/// Return type is not specified.
|
|
|
|
///
|
|
|
|
/// Functions default to `()` and
|
|
|
|
/// closures default to inference. Span points to where return
|
|
|
|
/// type would be inserted.
|
|
|
|
DefaultReturn(Span),
|
2019-02-08 13:53:55 +00:00
|
|
|
/// Everything else.
|
2019-11-30 16:46:46 +00:00
|
|
|
Return(&'hir Ty<'hir>),
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2020-02-15 03:10:59 +00:00
|
|
|
impl FnRetTy<'_> {
|
2015-07-31 07:04:06 +00:00
|
|
|
pub fn span(&self) -> Span {
|
|
|
|
match *self {
|
2020-01-02 02:48:12 +00:00
|
|
|
Self::DefaultReturn(span) => span,
|
|
|
|
Self::Return(ref ty) => ty.span,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Encodable, Debug)]
|
2019-11-29 09:24:47 +00:00
|
|
|
pub struct Mod<'hir> {
|
2015-07-31 07:04:06 +00:00
|
|
|
/// A span from the first token past `{` to the last token until `}`.
|
|
|
|
/// For `mod foo;`, the inner span ranges from the first token
|
|
|
|
/// to the last token in the external file.
|
|
|
|
pub inner: Span,
|
2019-11-29 09:24:47 +00:00
|
|
|
pub item_ids: &'hir [ItemId],
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2019-11-28 19:18:29 +00:00
|
|
|
pub struct ForeignMod<'hir> {
|
2015-07-31 07:04:06 +00:00
|
|
|
pub abi: Abi,
|
2019-11-28 19:18:29 +00:00
|
|
|
pub items: &'hir [ForeignItem<'hir>],
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Encodable, Debug, HashStable_Generic)]
|
2017-03-16 02:27:40 +00:00
|
|
|
pub struct GlobalAsm {
|
|
|
|
pub asm: Symbol,
|
|
|
|
}
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2019-11-29 08:26:18 +00:00
|
|
|
pub struct EnumDef<'hir> {
|
|
|
|
pub variants: &'hir [Variant<'hir>],
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2019-11-29 08:26:18 +00:00
|
|
|
pub struct Variant<'hir> {
|
2019-03-21 22:38:50 +00:00
|
|
|
/// Name of the variant.
|
2019-03-12 23:08:36 +00:00
|
|
|
#[stable_hasher(project(name))]
|
2018-12-01 02:47:08 +00:00
|
|
|
pub ident: Ident,
|
2019-03-21 22:38:50 +00:00
|
|
|
/// Attributes of the variant.
|
2019-11-29 08:26:18 +00:00
|
|
|
pub attrs: &'hir [Attribute],
|
2019-03-21 22:38:50 +00:00
|
|
|
/// Id of the variant (not the constructor, see `VariantData::ctor_hir_id()`).
|
|
|
|
pub id: HirId,
|
|
|
|
/// Fields and constructor id of the variant.
|
2019-11-29 08:26:18 +00:00
|
|
|
pub data: VariantData<'hir>,
|
2019-02-08 13:53:55 +00:00
|
|
|
/// Explicit discriminant (e.g., `Foo = 1`).
|
2018-05-17 18:28:50 +00:00
|
|
|
pub disr_expr: Option<AnonConst>,
|
2019-08-14 00:40:21 +00:00
|
|
|
/// Span
|
2019-12-22 22:42:04 +00:00
|
|
|
pub span: Span,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)]
|
2016-11-24 04:11:31 +00:00
|
|
|
pub enum UseKind {
|
2018-11-27 02:59:49 +00:00
|
|
|
/// One import, e.g., `use foo::bar` or `use foo::bar as baz`.
|
2016-11-24 04:11:31 +00:00
|
|
|
/// Also produced for each element of a list `use`, e.g.
|
2019-03-21 22:38:50 +00:00
|
|
|
/// `use foo::{a, b}` lowers to `use foo::a; use foo::b;`.
|
2016-11-24 04:11:31 +00:00
|
|
|
Single,
|
2015-07-31 07:04:06 +00:00
|
|
|
|
2018-11-27 02:59:49 +00:00
|
|
|
/// Glob import, e.g., `use foo::*`.
|
2016-11-24 04:11:31 +00:00
|
|
|
Glob,
|
2015-07-31 07:04:06 +00:00
|
|
|
|
2018-11-27 02:59:49 +00:00
|
|
|
/// Degenerate list import, e.g., `use foo::{a, b}` produces
|
2016-11-24 04:11:31 +00:00
|
|
|
/// an additional `use foo::{}` for performing checks such as
|
|
|
|
/// unstable feature gating. May be removed in the future.
|
|
|
|
ListStem,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2019-05-20 15:19:34 +00:00
|
|
|
/// References to traits in impls.
|
2015-07-31 07:04:06 +00:00
|
|
|
///
|
2019-03-26 17:34:32 +00:00
|
|
|
/// `resolve` maps each `TraitRef`'s `ref_id` to its defining trait; that's all
|
2019-06-16 15:44:19 +00:00
|
|
|
/// that the `ref_id` is for. Note that `ref_id`'s value is not the `HirId` of the
|
|
|
|
/// trait being referred to but just a unique `HirId` that serves as a key
|
2019-05-04 12:18:58 +00:00
|
|
|
/// within the resolution map.
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2019-11-30 16:46:46 +00:00
|
|
|
pub struct TraitRef<'hir> {
|
|
|
|
pub path: &'hir Path<'hir>,
|
2019-06-17 22:40:24 +00:00
|
|
|
// Don't hash the `ref_id`. It is tracked via the thing it is used to access.
|
2018-12-03 00:14:35 +00:00
|
|
|
#[stable_hasher(ignore)]
|
2018-07-31 16:43:51 +00:00
|
|
|
pub hir_ref_id: HirId,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2019-11-30 16:46:46 +00:00
|
|
|
impl TraitRef<'_> {
|
2019-02-08 13:53:55 +00:00
|
|
|
/// Gets the `DefId` of the referenced trait. It _must_ actually be a trait or trait alias.
|
2020-03-23 19:27:59 +00:00
|
|
|
pub fn trait_def_id(&self) -> Option<DefId> {
|
2019-04-20 16:36:05 +00:00
|
|
|
match self.path.res {
|
2020-03-23 19:27:59 +00:00
|
|
|
Res::Def(DefKind::Trait | DefKind::TraitAlias, did) => Some(did),
|
|
|
|
Res::Err => None,
|
2019-01-08 15:50:24 +00:00
|
|
|
_ => unreachable!(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2019-11-30 16:46:46 +00:00
|
|
|
pub struct PolyTraitRef<'hir> {
|
2020-01-27 19:26:06 +00:00
|
|
|
/// The `'a` in `for<'a> Foo<&'a T>`.
|
2019-11-30 16:46:46 +00:00
|
|
|
pub bound_generic_params: &'hir [GenericParam<'hir>],
|
2015-07-31 07:04:06 +00:00
|
|
|
|
2020-01-27 22:08:59 +00:00
|
|
|
/// The `Foo<&'a T>` in `for<'a> Foo<&'a T>`.
|
2019-11-30 16:46:46 +00:00
|
|
|
pub trait_ref: TraitRef<'hir>,
|
2015-07-31 07:04:06 +00:00
|
|
|
|
|
|
|
pub span: Span,
|
|
|
|
}
|
|
|
|
|
2019-11-30 16:46:46 +00:00
|
|
|
pub type Visibility<'hir> = Spanned<VisibilityKind<'hir>>;
|
2018-07-01 03:34:18 +00:00
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug)]
|
2019-11-30 16:46:46 +00:00
|
|
|
pub enum VisibilityKind<'hir> {
|
2018-07-01 18:05:10 +00:00
|
|
|
Public,
|
|
|
|
Crate(CrateSugar),
|
2019-11-30 16:46:46 +00:00
|
|
|
Restricted { path: &'hir Path<'hir>, hir_id: HirId },
|
2018-07-01 18:05:10 +00:00
|
|
|
Inherited,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2019-11-30 16:46:46 +00:00
|
|
|
impl VisibilityKind<'_> {
|
2018-07-01 03:34:18 +00:00
|
|
|
pub fn is_pub(&self) -> bool {
|
2020-10-27 01:02:48 +00:00
|
|
|
matches!(*self, VisibilityKind::Public)
|
2018-07-01 03:34:18 +00:00
|
|
|
}
|
|
|
|
|
2017-03-18 03:38:32 +00:00
|
|
|
pub fn is_pub_restricted(&self) -> bool {
|
2018-07-01 03:34:18 +00:00
|
|
|
match *self {
|
2019-12-22 22:42:04 +00:00
|
|
|
VisibilityKind::Public | VisibilityKind::Inherited => false,
|
|
|
|
VisibilityKind::Crate(..) | VisibilityKind::Restricted { .. } => true,
|
2017-03-18 03:38:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2019-11-29 08:40:33 +00:00
|
|
|
pub struct StructField<'hir> {
|
2016-02-27 08:34:29 +00:00
|
|
|
pub span: Span,
|
2018-12-03 00:14:35 +00:00
|
|
|
#[stable_hasher(project(name))]
|
2018-05-25 23:50:15 +00:00
|
|
|
pub ident: Ident,
|
2019-11-30 16:46:46 +00:00
|
|
|
pub vis: Visibility<'hir>,
|
2019-02-02 14:40:08 +00:00
|
|
|
pub hir_id: HirId,
|
2019-11-30 16:46:46 +00:00
|
|
|
pub ty: &'hir Ty<'hir>,
|
2019-11-29 08:40:33 +00:00
|
|
|
pub attrs: &'hir [Attribute],
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2019-11-29 08:40:33 +00:00
|
|
|
impl StructField<'_> {
|
2016-02-27 00:05:14 +00:00
|
|
|
// Still necessary in couple of places
|
|
|
|
pub fn is_positional(&self) -> bool {
|
2018-05-26 12:12:38 +00:00
|
|
|
let first = self.ident.as_str().as_bytes()[0];
|
2016-02-27 00:05:14 +00:00
|
|
|
first >= b'0' && first <= b'9'
|
|
|
|
}
|
|
|
|
}
|
2015-07-31 07:04:06 +00:00
|
|
|
|
2019-05-08 19:57:06 +00:00
|
|
|
/// Fields and constructor IDs of enum variants and structs.
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2019-11-29 08:26:18 +00:00
|
|
|
pub enum VariantData<'hir> {
|
2019-05-08 19:57:06 +00:00
|
|
|
/// A struct variant.
|
2019-03-21 22:38:50 +00:00
|
|
|
///
|
2019-05-08 19:57:06 +00:00
|
|
|
/// E.g., `Bar { .. }` as in `enum Foo { Bar { .. } }`.
|
2019-11-29 08:40:33 +00:00
|
|
|
Struct(&'hir [StructField<'hir>], /* recovered */ bool),
|
2019-05-08 19:57:06 +00:00
|
|
|
/// A tuple variant.
|
2019-03-21 22:38:50 +00:00
|
|
|
///
|
|
|
|
/// E.g., `Bar(..)` as in `enum Foo { Bar(..) }`.
|
2019-11-29 08:40:33 +00:00
|
|
|
Tuple(&'hir [StructField<'hir>], HirId),
|
2019-05-08 19:57:06 +00:00
|
|
|
/// A unit variant.
|
2019-03-21 22:38:50 +00:00
|
|
|
///
|
|
|
|
/// E.g., `Bar = ..` as in `enum Foo { Bar = .. }`.
|
2019-03-01 08:52:20 +00:00
|
|
|
Unit(HirId),
|
2015-10-08 20:45:46 +00:00
|
|
|
}
|
|
|
|
|
2019-11-29 08:26:18 +00:00
|
|
|
impl VariantData<'hir> {
|
2019-03-21 22:38:50 +00:00
|
|
|
/// Return the fields of this variant.
|
2019-11-29 08:40:33 +00:00
|
|
|
pub fn fields(&self) -> &'hir [StructField<'hir>] {
|
2015-10-10 00:28:40 +00:00
|
|
|
match *self {
|
2019-02-02 14:40:08 +00:00
|
|
|
VariantData::Struct(ref fields, ..) | VariantData::Tuple(ref fields, ..) => fields,
|
2015-10-25 15:33:51 +00:00
|
|
|
_ => &[],
|
|
|
|
}
|
2015-10-08 20:45:46 +00:00
|
|
|
}
|
2019-03-21 22:38:50 +00:00
|
|
|
|
|
|
|
/// Return the `HirId` of this variant's constructor, if it has one.
|
|
|
|
pub fn ctor_hir_id(&self) -> Option<HirId> {
|
2019-02-02 14:40:08 +00:00
|
|
|
match *self {
|
2019-03-21 22:38:50 +00:00
|
|
|
VariantData::Struct(_, _) => None,
|
|
|
|
VariantData::Tuple(_, hir_id) | VariantData::Unit(hir_id) => Some(hir_id),
|
2015-10-10 00:28:40 +00:00
|
|
|
}
|
|
|
|
}
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2015-11-17 22:32:12 +00:00
|
|
|
// The bodies for items are stored "out of line", in a separate
|
|
|
|
// hashmap in the `Crate`. Here we just record the node-id of the item
|
|
|
|
// so it can fetched later.
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Copy, Clone, Encodable, Debug)]
|
2015-11-17 22:32:12 +00:00
|
|
|
pub struct ItemId {
|
2019-03-11 08:44:19 +00:00
|
|
|
pub id: HirId,
|
2015-11-17 22:32:12 +00:00
|
|
|
}
|
2015-11-05 21:17:59 +00:00
|
|
|
|
2015-07-31 07:04:06 +00:00
|
|
|
/// An item
|
|
|
|
///
|
|
|
|
/// The name might be a dummy name in case of anonymous items
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug)]
|
2019-11-28 18:28:50 +00:00
|
|
|
pub struct Item<'hir> {
|
2018-12-01 02:47:08 +00:00
|
|
|
pub ident: Ident,
|
2017-08-18 18:24:19 +00:00
|
|
|
pub hir_id: HirId,
|
2019-11-28 22:50:47 +00:00
|
|
|
pub attrs: &'hir [Attribute],
|
2019-11-28 18:28:50 +00:00
|
|
|
pub kind: ItemKind<'hir>,
|
2019-11-30 16:46:46 +00:00
|
|
|
pub vis: Visibility<'hir>,
|
2015-07-31 07:04:06 +00:00
|
|
|
pub span: Span,
|
|
|
|
}
|
|
|
|
|
2020-01-30 01:42:33 +00:00
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Encodable, Decodable, HashStable_Generic)]
|
2020-01-30 01:42:33 +00:00
|
|
|
pub enum Unsafety {
|
|
|
|
Unsafe,
|
|
|
|
Normal,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Unsafety {
|
|
|
|
pub fn prefix_str(&self) -> &'static str {
|
|
|
|
match self {
|
|
|
|
Self::Unsafe => "unsafe ",
|
|
|
|
Self::Normal => "",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Display for Unsafety {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
|
f.write_str(match *self {
|
|
|
|
Self::Unsafe => "unsafe",
|
|
|
|
Self::Normal => "normal",
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Encodable, Decodable, HashStable_Generic)]
|
2020-01-30 01:42:33 +00:00
|
|
|
pub enum Constness {
|
|
|
|
Const,
|
|
|
|
NotConst,
|
|
|
|
}
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Copy, Clone, Encodable, Debug, HashStable_Generic)]
|
2018-05-17 05:55:18 +00:00
|
|
|
pub struct FnHeader {
|
|
|
|
pub unsafety: Unsafety,
|
|
|
|
pub constness: Constness,
|
|
|
|
pub asyncness: IsAsync,
|
|
|
|
pub abi: Abi,
|
|
|
|
}
|
|
|
|
|
2019-04-30 00:14:31 +00:00
|
|
|
impl FnHeader {
|
|
|
|
pub fn is_const(&self) -> bool {
|
2020-10-27 01:02:48 +00:00
|
|
|
matches!(&self.constness, Constness::Const)
|
2019-04-30 00:14:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2019-11-28 18:28:50 +00:00
|
|
|
pub enum ItemKind<'hir> {
|
2018-03-09 15:51:48 +00:00
|
|
|
/// An `extern crate` item, with optional *original* crate name if the crate was renamed.
|
2015-07-31 07:04:06 +00:00
|
|
|
///
|
2019-02-08 13:53:55 +00:00
|
|
|
/// E.g., `extern crate foo` or `extern crate foo_bar as foo`.
|
2020-04-19 11:00:18 +00:00
|
|
|
ExternCrate(Option<Symbol>),
|
2016-11-24 04:11:31 +00:00
|
|
|
|
|
|
|
/// `use foo::bar::*;` or `use foo::bar::baz as quux;`
|
|
|
|
///
|
|
|
|
/// or just
|
|
|
|
///
|
2019-09-06 02:57:44 +00:00
|
|
|
/// `use foo::bar::baz;` (with `as baz` implicitly on the right).
|
2019-11-30 16:46:46 +00:00
|
|
|
Use(&'hir Path<'hir>, UseKind),
|
2015-07-31 07:04:06 +00:00
|
|
|
|
2019-09-06 02:57:44 +00:00
|
|
|
/// A `static` item.
|
2019-11-30 16:46:46 +00:00
|
|
|
Static(&'hir Ty<'hir>, Mutability, BodyId),
|
2019-09-06 02:57:44 +00:00
|
|
|
/// A `const` item.
|
2019-11-30 16:46:46 +00:00
|
|
|
Const(&'hir Ty<'hir>, BodyId),
|
2019-09-06 02:57:44 +00:00
|
|
|
/// A function declaration.
|
2019-11-30 16:46:46 +00:00
|
|
|
Fn(FnSig<'hir>, Generics<'hir>, BodyId),
|
2019-09-06 02:57:44 +00:00
|
|
|
/// A module.
|
2019-11-29 09:24:47 +00:00
|
|
|
Mod(Mod<'hir>),
|
2019-10-11 01:36:01 +00:00
|
|
|
/// An external module, e.g. `extern { .. }`.
|
2019-11-28 19:18:29 +00:00
|
|
|
ForeignMod(ForeignMod<'hir>),
|
2019-09-06 02:57:44 +00:00
|
|
|
/// Module-level inline assembly (from `global_asm!`).
|
2019-11-28 18:28:50 +00:00
|
|
|
GlobalAsm(&'hir GlobalAsm),
|
2019-09-06 02:57:44 +00:00
|
|
|
/// A type alias, e.g., `type Foo = Bar<u8>`.
|
2019-11-30 16:46:46 +00:00
|
|
|
TyAlias(&'hir Ty<'hir>, Generics<'hir>),
|
2019-09-06 02:57:44 +00:00
|
|
|
/// An opaque `impl Trait` type alias, e.g., `type Foo = impl Bar;`.
|
2019-11-30 16:46:46 +00:00
|
|
|
OpaqueTy(OpaqueTy<'hir>),
|
2019-09-06 02:57:44 +00:00
|
|
|
/// An enum definition, e.g., `enum Foo<A, B> {C<A>, D<B>}`.
|
2019-11-30 16:46:46 +00:00
|
|
|
Enum(EnumDef<'hir>, Generics<'hir>),
|
2019-09-06 02:57:44 +00:00
|
|
|
/// A struct definition, e.g., `struct Foo<A> {x: A}`.
|
2019-11-30 16:46:46 +00:00
|
|
|
Struct(VariantData<'hir>, Generics<'hir>),
|
2019-09-06 02:57:44 +00:00
|
|
|
/// A union definition, e.g., `union Foo<A, B> {x: A, y: B}`.
|
2019-11-30 16:46:46 +00:00
|
|
|
Union(VariantData<'hir>, Generics<'hir>),
|
2019-09-06 02:57:44 +00:00
|
|
|
/// A trait definition.
|
2019-11-30 16:46:46 +00:00
|
|
|
Trait(IsAuto, Unsafety, Generics<'hir>, GenericBounds<'hir>, &'hir [TraitItemRef]),
|
2019-09-06 02:57:44 +00:00
|
|
|
/// A trait alias.
|
2019-11-30 16:46:46 +00:00
|
|
|
TraitAlias(Generics<'hir>, GenericBounds<'hir>),
|
2015-07-31 07:04:06 +00:00
|
|
|
|
2019-09-06 02:57:44 +00:00
|
|
|
/// An implementation, e.g., `impl<A> Trait for Foo { .. }`.
|
2020-01-18 00:14:29 +00:00
|
|
|
Impl {
|
|
|
|
unsafety: Unsafety,
|
|
|
|
polarity: ImplPolarity,
|
|
|
|
defaultness: Defaultness,
|
2020-03-02 23:26:00 +00:00
|
|
|
// We do not put a `Span` in `Defaultness` because it breaks foreign crate metadata
|
|
|
|
// decoding as `Span`s cannot be decoded when a `Session` is not available.
|
|
|
|
defaultness_span: Option<Span>,
|
2020-01-14 04:30:24 +00:00
|
|
|
constness: Constness,
|
2020-01-18 00:14:29 +00:00
|
|
|
generics: Generics<'hir>,
|
|
|
|
|
|
|
|
/// The trait being implemented, if any.
|
|
|
|
of_trait: Option<TraitRef<'hir>>,
|
|
|
|
|
|
|
|
self_ty: &'hir Ty<'hir>,
|
|
|
|
items: &'hir [ImplItemRef<'hir>],
|
|
|
|
},
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2019-11-28 18:28:50 +00:00
|
|
|
impl ItemKind<'_> {
|
2019-11-30 16:46:46 +00:00
|
|
|
pub fn generics(&self) -> Option<&Generics<'_>> {
|
2017-10-28 21:19:07 +00:00
|
|
|
Some(match *self {
|
2019-12-22 22:42:04 +00:00
|
|
|
ItemKind::Fn(_, ref generics, _)
|
|
|
|
| ItemKind::TyAlias(_, ref generics)
|
|
|
|
| ItemKind::OpaqueTy(OpaqueTy { ref generics, impl_trait_fn: None, .. })
|
|
|
|
| ItemKind::Enum(_, ref generics)
|
|
|
|
| ItemKind::Struct(_, ref generics)
|
|
|
|
| ItemKind::Union(_, ref generics)
|
|
|
|
| ItemKind::Trait(_, _, ref generics, _, _)
|
2020-01-18 00:14:29 +00:00
|
|
|
| ItemKind::Impl { ref generics, .. } => generics,
|
2019-12-22 22:42:04 +00:00
|
|
|
_ => return None,
|
2017-10-28 21:19:07 +00:00
|
|
|
})
|
|
|
|
}
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2016-12-04 02:21:06 +00:00
|
|
|
/// A reference from an trait to one of its associated items. This
|
|
|
|
/// contains the item's id, naturally, but also the item's name and
|
|
|
|
/// some other high-level details (like whether it is an associated
|
|
|
|
/// type or method, and whether it is public). This allows other
|
2019-02-08 13:53:55 +00:00
|
|
|
/// passes to find the impl they want without loading the ID (which
|
2016-12-04 02:21:06 +00:00
|
|
|
/// means fewer edges in the incremental compilation graph).
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Encodable, Debug, HashStable_Generic)]
|
2016-12-04 02:21:06 +00:00
|
|
|
pub struct TraitItemRef {
|
|
|
|
pub id: TraitItemId,
|
2018-12-03 00:14:35 +00:00
|
|
|
#[stable_hasher(project(name))]
|
2018-06-10 19:24:24 +00:00
|
|
|
pub ident: Ident,
|
2019-05-19 08:26:08 +00:00
|
|
|
pub kind: AssocItemKind,
|
2016-12-04 02:21:06 +00:00
|
|
|
pub span: Span,
|
|
|
|
pub defaultness: Defaultness,
|
|
|
|
}
|
|
|
|
|
2016-11-10 14:47:00 +00:00
|
|
|
/// A reference from an impl to one of its associated items. This
|
2019-02-08 13:53:55 +00:00
|
|
|
/// contains the item's ID, naturally, but also the item's name and
|
2016-11-10 14:47:00 +00:00
|
|
|
/// some other high-level details (like whether it is an associated
|
|
|
|
/// type or method, and whether it is public). This allows other
|
2019-02-08 13:53:55 +00:00
|
|
|
/// passes to find the impl they want without loading the ID (which
|
2016-11-10 14:47:00 +00:00
|
|
|
/// means fewer edges in the incremental compilation graph).
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2019-11-30 16:46:46 +00:00
|
|
|
pub struct ImplItemRef<'hir> {
|
2016-11-10 14:47:00 +00:00
|
|
|
pub id: ImplItemId,
|
2018-12-03 00:14:35 +00:00
|
|
|
#[stable_hasher(project(name))]
|
2018-06-10 19:24:24 +00:00
|
|
|
pub ident: Ident,
|
2019-05-19 08:26:08 +00:00
|
|
|
pub kind: AssocItemKind,
|
2016-11-10 14:47:00 +00:00
|
|
|
pub span: Span,
|
2019-11-30 16:46:46 +00:00
|
|
|
pub vis: Visibility<'hir>,
|
2016-11-10 14:47:00 +00:00
|
|
|
pub defaultness: Defaultness,
|
|
|
|
}
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)]
|
2019-05-19 08:26:08 +00:00
|
|
|
pub enum AssocItemKind {
|
2016-11-10 14:47:00 +00:00
|
|
|
Const,
|
2020-04-01 02:09:50 +00:00
|
|
|
Fn { has_self: bool },
|
2016-11-10 14:47:00 +00:00
|
|
|
Type,
|
|
|
|
}
|
|
|
|
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2019-11-28 19:18:29 +00:00
|
|
|
pub struct ForeignItem<'hir> {
|
2019-03-12 23:08:36 +00:00
|
|
|
#[stable_hasher(project(name))]
|
2018-12-01 02:47:08 +00:00
|
|
|
pub ident: Ident,
|
2019-11-28 19:18:29 +00:00
|
|
|
pub attrs: &'hir [Attribute],
|
|
|
|
pub kind: ForeignItemKind<'hir>,
|
2019-02-02 14:40:08 +00:00
|
|
|
pub hir_id: HirId,
|
2015-07-31 07:04:06 +00:00
|
|
|
pub span: Span,
|
2019-11-30 16:46:46 +00:00
|
|
|
pub vis: Visibility<'hir>,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2019-02-08 13:53:55 +00:00
|
|
|
/// An item within an `extern` block.
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, HashStable_Generic)]
|
2019-11-28 19:18:29 +00:00
|
|
|
pub enum ForeignItemKind<'hir> {
|
2019-02-08 13:53:55 +00:00
|
|
|
/// A foreign function.
|
2019-11-30 16:46:46 +00:00
|
|
|
Fn(&'hir FnDecl<'hir>, &'hir [Ident], Generics<'hir>),
|
2019-04-21 12:29:58 +00:00
|
|
|
/// A foreign static item (`static ext: u8`).
|
2019-11-30 16:46:46 +00:00
|
|
|
Static(&'hir Ty<'hir>, Mutability),
|
2019-02-08 13:53:55 +00:00
|
|
|
/// A foreign type.
|
2018-07-11 14:56:44 +00:00
|
|
|
Type,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2019-05-04 00:57:46 +00:00
|
|
|
/// A variable captured by a closure.
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Debug, Copy, Clone, Encodable, HashStable_Generic)]
|
2019-05-14 16:42:57 +00:00
|
|
|
pub struct Upvar {
|
2016-03-29 10:14:01 +00:00
|
|
|
// First span where it is accessed (there can be multiple).
|
2019-12-22 22:42:04 +00:00
|
|
|
pub span: Span,
|
2016-03-29 10:14:01 +00:00
|
|
|
}
|
|
|
|
|
2019-12-22 22:42:04 +00:00
|
|
|
// The TraitCandidate's import_ids is empty if the trait is defined in the same module, and
|
|
|
|
// has length > 0 if the trait is found through an chain of imports, starting with the
|
|
|
|
// import/use statement in the scope where the trait is used.
|
2020-06-11 14:49:57 +00:00
|
|
|
#[derive(Encodable, Decodable, Clone, Debug)]
|
2020-06-14 21:35:29 +00:00
|
|
|
pub struct TraitCandidate {
|
2016-04-19 13:43:10 +00:00
|
|
|
pub def_id: DefId,
|
2020-06-14 21:35:29 +00:00
|
|
|
pub import_ids: SmallVec<[LocalDefId; 1]>,
|
2020-02-13 15:47:51 +00:00
|
|
|
}
|
|
|
|
|
2020-02-07 10:14:47 +00:00
|
|
|
#[derive(Copy, Clone, Debug, HashStable_Generic)]
|
2018-08-25 14:56:16 +00:00
|
|
|
pub enum Node<'hir> {
|
2019-11-29 12:43:03 +00:00
|
|
|
Param(&'hir Param<'hir>),
|
2019-11-28 18:28:50 +00:00
|
|
|
Item(&'hir Item<'hir>),
|
2019-11-28 19:18:29 +00:00
|
|
|
ForeignItem(&'hir ForeignItem<'hir>),
|
2019-11-28 20:47:10 +00:00
|
|
|
TraitItem(&'hir TraitItem<'hir>),
|
2019-11-28 21:16:44 +00:00
|
|
|
ImplItem(&'hir ImplItem<'hir>),
|
2019-11-29 08:26:18 +00:00
|
|
|
Variant(&'hir Variant<'hir>),
|
2019-11-29 08:40:33 +00:00
|
|
|
Field(&'hir StructField<'hir>),
|
2018-08-25 14:56:16 +00:00
|
|
|
AnonConst(&'hir AnonConst),
|
2019-11-29 12:43:03 +00:00
|
|
|
Expr(&'hir Expr<'hir>),
|
|
|
|
Stmt(&'hir Stmt<'hir>),
|
2019-11-30 16:46:46 +00:00
|
|
|
PathSegment(&'hir PathSegment<'hir>),
|
|
|
|
Ty(&'hir Ty<'hir>),
|
|
|
|
TraitRef(&'hir TraitRef<'hir>),
|
2019-11-29 12:43:03 +00:00
|
|
|
Binding(&'hir Pat<'hir>),
|
|
|
|
Pat(&'hir Pat<'hir>),
|
|
|
|
Arm(&'hir Arm<'hir>),
|
|
|
|
Block(&'hir Block<'hir>),
|
|
|
|
Local(&'hir Local<'hir>),
|
2019-11-28 22:50:47 +00:00
|
|
|
MacroDef(&'hir MacroDef<'hir>),
|
2018-08-25 14:56:16 +00:00
|
|
|
|
2019-03-21 22:38:50 +00:00
|
|
|
/// `Ctor` refers to the constructor of an enum variant or struct. Only tuple or unit variants
|
|
|
|
/// with synthesized constructors.
|
2019-11-29 08:26:18 +00:00
|
|
|
Ctor(&'hir VariantData<'hir>),
|
2018-08-25 14:56:16 +00:00
|
|
|
|
|
|
|
Lifetime(&'hir Lifetime),
|
2019-11-30 16:46:46 +00:00
|
|
|
GenericParam(&'hir GenericParam<'hir>),
|
|
|
|
Visibility(&'hir Visibility<'hir>),
|
2018-08-25 14:56:16 +00:00
|
|
|
|
2020-02-07 15:43:36 +00:00
|
|
|
Crate(&'hir CrateItem<'hir>),
|
2018-08-25 14:56:16 +00:00
|
|
|
}
|
2019-09-04 17:17:59 +00:00
|
|
|
|
2020-07-09 20:18:22 +00:00
|
|
|
impl<'hir> Node<'hir> {
|
2019-09-04 17:17:59 +00:00
|
|
|
pub fn ident(&self) -> Option<Ident> {
|
|
|
|
match self {
|
2019-12-22 22:42:04 +00:00
|
|
|
Node::TraitItem(TraitItem { ident, .. })
|
|
|
|
| Node::ImplItem(ImplItem { ident, .. })
|
|
|
|
| Node::ForeignItem(ForeignItem { ident, .. })
|
2020-10-22 02:00:32 +00:00
|
|
|
| Node::Field(StructField { ident, .. })
|
|
|
|
| Node::Variant(Variant { ident, .. })
|
|
|
|
| Node::MacroDef(MacroDef { ident, .. })
|
2019-12-22 22:42:04 +00:00
|
|
|
| Node::Item(Item { ident, .. }) => Some(*ident),
|
2019-09-04 17:17:59 +00:00
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
2020-02-01 02:48:35 +00:00
|
|
|
|
2020-07-09 20:18:22 +00:00
|
|
|
pub fn fn_decl(&self) -> Option<&FnDecl<'hir>> {
|
2020-02-01 02:48:35 +00:00
|
|
|
match self {
|
2020-03-03 18:46:22 +00:00
|
|
|
Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. })
|
2020-03-05 15:57:34 +00:00
|
|
|
| Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. })
|
2020-02-01 02:48:35 +00:00
|
|
|
| Node::Item(Item { kind: ItemKind::Fn(fn_sig, _, _), .. }) => Some(fn_sig.decl),
|
|
|
|
Node::ForeignItem(ForeignItem { kind: ForeignItemKind::Fn(fn_decl, _, _), .. }) => {
|
|
|
|
Some(fn_decl)
|
|
|
|
}
|
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-19 23:52:15 +00:00
|
|
|
pub fn body_id(&self) -> Option<BodyId> {
|
|
|
|
match self {
|
|
|
|
Node::TraitItem(TraitItem {
|
|
|
|
kind: TraitItemKind::Fn(_, TraitFn::Provided(body_id)),
|
|
|
|
..
|
|
|
|
})
|
|
|
|
| Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(_, body_id), .. })
|
|
|
|
| Node::Item(Item { kind: ItemKind::Fn(.., body_id), .. }) => Some(*body_id),
|
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-09 20:18:22 +00:00
|
|
|
pub fn generics(&self) -> Option<&'hir Generics<'hir>> {
|
2020-02-01 02:48:35 +00:00
|
|
|
match self {
|
|
|
|
Node::TraitItem(TraitItem { generics, .. })
|
2020-06-12 00:41:16 +00:00
|
|
|
| Node::ImplItem(ImplItem { generics, .. }) => Some(generics),
|
|
|
|
Node::Item(item) => item.kind.generics(),
|
2020-02-01 02:48:35 +00:00
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
2020-09-24 02:43:32 +00:00
|
|
|
|
|
|
|
pub fn hir_id(&self) -> Option<HirId> {
|
|
|
|
match self {
|
|
|
|
Node::Item(Item { hir_id, .. })
|
|
|
|
| Node::ForeignItem(ForeignItem { hir_id, .. })
|
|
|
|
| Node::TraitItem(TraitItem { hir_id, .. })
|
|
|
|
| Node::ImplItem(ImplItem { hir_id, .. })
|
|
|
|
| Node::Field(StructField { hir_id, .. })
|
|
|
|
| Node::AnonConst(AnonConst { hir_id, .. })
|
|
|
|
| Node::Expr(Expr { hir_id, .. })
|
|
|
|
| Node::Stmt(Stmt { hir_id, .. })
|
|
|
|
| Node::Ty(Ty { hir_id, .. })
|
|
|
|
| Node::Binding(Pat { hir_id, .. })
|
|
|
|
| Node::Pat(Pat { hir_id, .. })
|
|
|
|
| Node::Arm(Arm { hir_id, .. })
|
|
|
|
| Node::Block(Block { hir_id, .. })
|
|
|
|
| Node::Local(Local { hir_id, .. })
|
|
|
|
| Node::MacroDef(MacroDef { hir_id, .. })
|
|
|
|
| Node::Lifetime(Lifetime { hir_id, .. })
|
|
|
|
| Node::Param(Param { hir_id, .. })
|
|
|
|
| Node::GenericParam(GenericParam { hir_id, .. }) => Some(*hir_id),
|
|
|
|
Node::TraitRef(TraitRef { hir_ref_id, .. }) => Some(*hir_ref_id),
|
|
|
|
Node::PathSegment(PathSegment { hir_id, .. }) => *hir_id,
|
|
|
|
Node::Variant(Variant { id, .. }) => Some(*id),
|
|
|
|
Node::Ctor(variant) => variant.ctor_hir_id(),
|
|
|
|
Node::Crate(_) | Node::Visibility(_) => None,
|
|
|
|
}
|
|
|
|
}
|
2019-09-04 17:17:59 +00:00
|
|
|
}
|