rust/compiler/rustc_hir/src/hir.rs

3085 lines
98 KiB
Rust
Raw Normal View History

2021-02-18 17:17:43 +01:00
// ignore-tidy-filelength
use crate::def::{CtorKind, DefKind, Namespace, Res};
use crate::def_id::DefId;
crate use crate::hir_id::HirId;
2021-01-24 17:14:17 +01:00
use crate::{itemlikevisit, LangItem};
2016-03-29 12:14:01 +02:00
use rustc_ast::util::parser::ExprPrecedence;
2020-04-27 19:56:11 +02:00
use rustc_ast::{self as ast, CrateSugar, LlvmAsmDialect};
2020-11-27 17:41:05 +01:00
use rustc_ast::{Attribute, FloatTy, IntTy, Label, LitKind, StrStyle, UintTy};
2020-04-27 19:56:11 +02:00
pub use rustc_ast::{BorrowKind, ImplPolarity, IsAuto};
pub use rustc_ast::{CaptureBy, Movability, Mutability};
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_data_structures::sync::{par_for_each_in, Send, Sync};
use rustc_macros::HashStable_Generic;
use rustc_span::source_map::{SourceMap, Spanned};
2020-04-19 13:00:18 +02:00
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{def_id::LocalDefId, BytePos};
use rustc_span::{MultiSpan, Span, DUMMY_SP};
use rustc_target::asm::InlineAsmRegOrRegClass;
2019-12-22 23:42:04 +01:00
use rustc_target::spec::abi::Abi;
use smallvec::SmallVec;
use std::collections::{BTreeMap, BTreeSet};
use std::fmt;
#[derive(Copy, Clone, Encodable, HashStable_Generic)]
2015-07-31 09:04:06 +02:00
pub struct Lifetime {
2019-02-02 15:40:08 +01:00
pub hir_id: HirId,
2015-07-31 09:04:06 +02:00
pub span: Span,
2019-02-08 14:53:55 +01:00
/// Either "`'a`", referring to a named lifetime definition,
/// or "``" (i.e., `kw::Empty`), for elision placeholders.
///
/// 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-20 01:36:54 +02:00
pub name: LifetimeName,
}
#[derive(Debug, Clone, PartialEq, Eq, Encodable, Hash, Copy)]
#[derive(HashStable_Generic)]
pub enum ParamName {
/// Some user-given name like `T` or `'x`.
2018-06-27 23:12:17 +02:00
Plain(Ident),
2019-02-08 14:53:55 +01:00
/// Synthetic name generated when user elided a lifetime in an impl header.
///
/// E.g., the lifetimes in cases like these:
///
/// 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),
/// Indicates an illegal name was given and an error has been
2019-09-09 17:44:11 +02:00
/// reported (so we should squelch other derived errors). Occurs
2019-02-08 14:53:55 +01:00
/// when, e.g., `'_` is used in the wrong place.
Error,
}
impl ParamName {
2018-06-27 23:12:17 +02:00
pub fn ident(&self) -> Ident {
match *self {
ParamName::Plain(ident) => ident,
2019-12-22 23:42:04 +01:00
ParamName::Fresh(_) | ParamName::Error => {
Ident::with_dummy_span(kw::UnderscoreLifetime)
}
2018-06-27 23:12:17 +02:00
}
}
pub fn normalize_to_macros_2_0(&self) -> ParamName {
match *self {
ParamName::Plain(ident) => ParamName::Plain(ident.normalize_to_macros_2_0()),
2018-06-27 23:12:17 +02:00
param_name => param_name,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Encodable, Hash, Copy)]
#[derive(HashStable_Generic)]
pub enum LifetimeName {
/// User-given names or fresh (synthetic) names.
Param(ParamName),
2019-02-08 14:53:55 +01:00
/// User wrote nothing (e.g., the lifetime in `&u32`).
Implicit,
/// 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,
/// Indicates an error during lowering (usually `'_` in wrong place)
/// that was already reported.
Error,
2019-02-08 14:53:55 +01:00
/// User wrote specifies `'_`.
Underscore,
2019-02-08 14:53:55 +01:00
/// User wrote `'static`.
2017-09-20 01:36:54 +02:00
Static,
}
impl LifetimeName {
2018-06-09 22:25:33 +02:00
pub fn ident(&self) -> Ident {
2017-09-20 01:36:54 +02:00
match *self {
LifetimeName::ImplicitObjectLifetimeDefault
2019-12-22 23:42:04 +01:00
| LifetimeName::Implicit
| LifetimeName::Error => Ident::invalid(),
LifetimeName::Underscore => Ident::with_dummy_span(kw::UnderscoreLifetime),
LifetimeName::Static => Ident::with_dummy_span(kw::StaticLifetime),
2018-06-27 23:12:17 +02:00
LifetimeName::Param(param_name) => param_name.ident(),
2017-09-20 01:36:54 +02:00
}
}
2018-05-26 01:27:54 +02:00
2018-06-22 08:24:51 +02:00
pub fn is_elided(&self) -> bool {
2018-05-26 01:27:54 +02:00
match self {
LifetimeName::ImplicitObjectLifetimeDefault
| LifetimeName::Implicit
| LifetimeName::Underscore => true,
2018-05-26 01:27:54 +02: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.
LifetimeName::Error | LifetimeName::Param(_) | LifetimeName::Static => false,
2018-05-26 01:27:54 +02:00
}
}
fn is_static(&self) -> bool {
self == &LifetimeName::Static
}
2018-06-09 22:25:33 +02:00
pub fn normalize_to_macros_2_0(&self) -> LifetimeName {
2018-06-09 22:25:33 +02:00
match *self {
LifetimeName::Param(param_name) => {
LifetimeName::Param(param_name.normalize_to_macros_2_0())
}
2018-06-09 22:25:33 +02:00
lifetime_name => lifetime_name,
}
}
}
impl fmt::Display for Lifetime {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2018-06-09 22:25:33 +02:00
self.name.ident().fmt(f)
}
2015-07-31 09:04:06 +02:00
}
impl fmt::Debug for Lifetime {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2020-03-23 11:32:07 +01:00
write!(f, "lifetime({}: {})", self.hir_id, self.name.ident())
2015-07-31 09:04:06 +02:00
}
}
impl Lifetime {
pub fn is_elided(&self) -> bool {
2018-05-26 01:27:54 +02:00
self.name.is_elided()
}
pub fn is_static(&self) -> bool {
2018-05-26 01:27:54 +02:00
self.name.is_static()
}
}
2019-02-08 14:53:55 +01:00
/// A `Path` is essentially Rust's notion of a name; for instance,
/// `std::cmp::PartialEq`. It's represented as a sequence of identifiers,
2015-07-31 09:04:06 +02:00
/// along with a bunch of supporting information.
#[derive(Debug, HashStable_Generic)]
2019-11-30 17:46:46 +01:00
pub struct Path<'hir> {
2015-07-31 09:04:06 +02:00
pub span: Span,
/// The resolution for the path.
pub res: Res,
2015-07-31 09:04:06 +02:00
/// The segments in the path: the things separated by `::`.
2019-11-30 17:46:46 +01:00
pub segments: &'hir [PathSegment<'hir>],
2015-07-31 09:04:06 +02:00
}
2019-11-30 17:46:46 +01:00
impl Path<'_> {
pub fn is_global(&self) -> bool {
2019-05-11 16:41:37 +02:00
!self.segments.is_empty() && self.segments[0].ident.name == kw::PathRoot
}
}
2015-07-31 09:04:06 +02:00
/// A segment of a path: an identifier, an optional lifetime, and a set of
/// types.
#[derive(Debug, HashStable_Generic)]
2019-11-30 17:46:46 +01:00
pub struct PathSegment<'hir> {
2015-07-31 09:04:06 +02:00
/// The identifier portion of this path segment.
2018-12-03 01:14:35 +01:00
#[stable_hasher(project(name))]
2018-06-10 16:40:45 +02:00
pub ident: Ident,
// `id` and `res` are optional. We currently only use these in save-analysis,
// 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 15:40:08 +01:00
pub hir_id: Option<HirId>,
pub res: Option<Res>,
2015-07-31 09:04:06 +02: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 17:46:46 +01:00
pub args: Option<&'hir GenericArgs<'hir>>,
/// 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
/// to begin with, e.g., `Vec::new` is `<Vec<..>>::new::<..>`.
2019-06-07 11:18:03 +02:00
pub infer_args: bool,
2015-07-31 09:04:06 +02:00
}
2019-11-30 17:46:46 +01:00
impl<'hir> PathSegment<'hir> {
2019-02-08 14:53:55 +01:00
/// Converts an identifier to the corresponding segment.
2019-11-30 17:46:46 +01:00
pub fn from_ident(ident: Ident) -> PathSegment<'hir> {
2019-12-22 23:42:04 +01:00
PathSegment { ident, hir_id: None, res: None, infer_args: true, args: None }
}
pub fn invalid() -> Self {
Self::from_ident(Ident::invalid())
}
pub fn args(&self) -> &GenericArgs<'hir> {
if let Some(ref args) = self.args {
args
} else {
2019-11-30 17:46:46 +01:00
const DUMMY: &GenericArgs<'_> = &GenericArgs::none();
DUMMY
}
}
}
#[derive(Encodable, Debug, HashStable_Generic)]
pub struct ConstArg {
pub value: AnonConst,
pub span: Span,
}
#[derive(Debug, HashStable_Generic)]
2019-11-30 17:46:46 +01:00
pub enum GenericArg<'hir> {
Lifetime(Lifetime),
2019-11-30 17:46:46 +01:00
Type(Ty<'hir>),
Const(ConstArg),
}
2019-11-30 17:46:46 +01:00
impl GenericArg<'_> {
pub fn span(&self) -> Span {
match self {
GenericArg::Lifetime(l) => l.span,
GenericArg::Type(t) => t.span,
GenericArg::Const(c) => c.span,
}
}
pub fn id(&self) -> HirId {
match self {
GenericArg::Lifetime(l) => l.hir_id,
GenericArg::Type(t) => t.hir_id,
2019-02-18 14:53:25 +01:00
GenericArg::Const(c) => c.value.hir_id,
}
}
pub fn is_const(&self) -> bool {
2020-10-27 02:02:48 +01:00
matches!(self, GenericArg::Const(_))
}
pub fn is_synthetic(&self) -> bool {
matches!(self, GenericArg::Lifetime(lifetime) if lifetime.name.ident() == Ident::invalid())
}
pub fn descr(&self) -> &'static str {
match self {
GenericArg::Lifetime(_) => "lifetime",
GenericArg::Type(_) => "type",
GenericArg::Const(_) => "constant",
}
}
pub fn to_ord(&self, feats: &rustc_feature::Features) -> ast::ParamKindOrd {
match self {
GenericArg::Lifetime(_) => ast::ParamKindOrd::Lifetime,
GenericArg::Type(_) => ast::ParamKindOrd::Type,
GenericArg::Const(_) => ast::ParamKindOrd::Const { unordered: feats.const_generics },
}
}
}
#[derive(Debug, HashStable_Generic)]
2019-11-30 17:46:46 +01:00
pub struct GenericArgs<'hir> {
2018-02-23 18:48:54 +01:00
/// The generic arguments for this path segment.
2019-12-01 17:10:12 +01:00
pub args: &'hir [GenericArg<'hir>],
2015-07-31 09:04:06 +02:00
/// Bindings (equality constraints) on associated types, if present.
/// E.g., `Foo<A = Bar>`.
2019-11-30 17:46:46 +01:00
pub bindings: &'hir [TypeBinding<'hir>],
2018-02-23 18:48:54 +01:00
/// Were arguments written in parenthesized form `Fn(T) -> U`?
/// 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 09:04:06 +02:00
}
2019-11-30 17:46:46 +01:00
impl GenericArgs<'_> {
pub const fn none() -> Self {
2019-12-01 17:10:12 +01:00
Self { args: &[], bindings: &[], parenthesized: false }
}
2015-07-31 09:04:06 +02:00
2019-11-30 17:46:46 +01:00
pub fn inputs(&self) -> &[Ty<'_>] {
if self.parenthesized {
2019-12-01 17:10:12 +01:00
for arg in self.args {
match arg {
GenericArg::Lifetime(_) => {}
GenericArg::Type(ref ty) => {
2019-09-26 18:25:31 +02:00
if let TyKind::Tup(ref tys) = ty.kind {
return tys;
}
break;
}
GenericArg::Const(_) => {}
}
}
}
panic!("GenericArgs::inputs: not a `Fn(T) -> U`");
}
2018-08-07 18:44:30 +02: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 17:10:12 +01:00
for arg in self.args {
2018-08-07 18:44:30 +02:00
match arg {
GenericArg::Lifetime(_) => own_counts.lifetimes += 1,
GenericArg::Type(_) => own_counts.types += 1,
GenericArg::Const(_) => own_counts.consts += 1,
2018-08-07 18:44:30 +02:00
};
}
own_counts
}
pub fn span(&self) -> Option<Span> {
self.args
.iter()
.filter(|arg| !arg.is_synthetic())
.map(|arg| arg.span())
2020-12-07 21:23:29 +01:00
.reduce(|span1, span2| span1.to(span2))
}
/// Returns span encompassing arguments and their surrounding `<>` or `()`
pub fn span_ext(&self, sm: &SourceMap) -> Option<Span> {
let mut span = self.span()?;
let (o, c) = if self.parenthesized { ('(', ')') } else { ('<', '>') };
if let Ok(snippet) = sm.span_to_snippet(span) {
let snippet = snippet.as_bytes();
if snippet[0] != (o as u8) || snippet[snippet.len() - 1] != (c as u8) {
span = sm.span_extend_to_prev_char(span, o, true);
span = span.with_lo(span.lo() - BytePos(1));
span = sm.span_extend_to_next_char(span, c, true);
span = span.with_hi(span.hi() + BytePos(1));
}
}
Some(span)
}
pub fn is_empty(&self) -> bool {
self.args.is_empty()
}
2015-07-31 09:04:06 +02:00
}
2018-05-28 14:33:28 +02: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.
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Hash, Debug)]
#[derive(HashStable_Generic)]
2018-05-28 14:33:28 +02:00
pub enum TraitBoundModifier {
None,
Maybe,
MaybeConst,
2018-05-28 14:33:28 +02:00
}
2015-07-31 09:04:06 +02:00
/// The AST represents all type param bounds as types.
/// `typeck::collect::compute_bounds` matches these against
/// the "special" built-in traits (see `middle::lang_items`) and
/// detects `Copy`, `Send` and `Sync`.
#[derive(Debug, HashStable_Generic)]
2019-11-30 17:46:46 +01:00
pub enum GenericBound<'hir> {
Trait(PolyTraitRef<'hir>, TraitBoundModifier),
// FIXME(davidtwco): Introduce `PolyTraitRef::LangItem`
LangItemTrait(LangItem, Span, HirId, &'hir GenericArgs<'hir>),
2018-05-28 14:33:28 +02:00
Outlives(Lifetime),
2015-07-31 09:04:06 +02:00
}
2019-11-30 17:46:46 +01:00
impl GenericBound<'_> {
2020-03-23 20:27:59 +01:00
pub fn trait_ref(&self) -> Option<&TraitRef<'_>> {
match self {
2020-03-23 20:27:59 +01:00
GenericBound::Trait(data, _) => Some(&data.trait_ref),
_ => None,
}
}
pub fn span(&self) -> Span {
match self {
GenericBound::Trait(t, ..) => t.span,
GenericBound::LangItemTrait(_, span, ..) => *span,
GenericBound::Outlives(l) => l.span,
}
}
}
2019-11-30 17:46:46 +01:00
pub type GenericBounds<'hir> = &'hir [GenericBound<'hir>];
2015-07-31 09:04:06 +02:00
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Debug, HashStable_Generic)]
pub enum LifetimeParamKind {
// Indicates that the lifetime definition was explicitly declared (e.g., in
// `fn foo<'a>(x: &'a u8) -> &'a u8 { x }`).
Explicit,
// Indicates that the lifetime definition was synthetically added
// as a result of an in-band lifetime usage (e.g., in
// `fn foo(x: &'a u8) -> &'a u8 { x }`).
InBand,
// Indication that the lifetime was elided (e.g., in both cases in
// `fn foo(x: &u8) -> &'_ u8 { x }`).
Elided,
// Indication that the lifetime name was somehow in error.
Error,
}
#[derive(Debug, HashStable_Generic)]
2019-11-30 17:46:46 +01:00
pub enum GenericParamKind<'hir> {
/// A lifetime definition (e.g., `'a: 'b + 'c + 'd`).
2018-05-26 01:27:54 +02:00
Lifetime {
kind: LifetimeParamKind,
2018-05-26 01:27:54 +02:00
},
Type {
2019-11-30 17:46:46 +01:00
default: Option<&'hir Ty<'hir>>,
2018-05-26 01:27:54 +02:00
synthetic: Option<SyntheticTyParamKind>,
},
Const {
2019-11-30 17:46:46 +01:00
ty: &'hir Ty<'hir>,
/// Optional default value for the const generic param
default: Option<AnonConst>,
2019-12-22 23:42:04 +01:00
},
2018-05-26 01:27:54 +02:00
}
#[derive(Debug, HashStable_Generic)]
2019-11-30 17:46:46 +01:00
pub struct GenericParam<'hir> {
2019-02-02 15:40:08 +01:00
pub hir_id: HirId,
pub name: ParamName,
2019-11-30 17:46:46 +01:00
pub bounds: GenericBounds<'hir>,
2018-06-27 23:12:17 +02:00
pub span: Span,
pub pure_wrt_drop: bool,
2019-11-30 17:46:46 +01:00
pub kind: GenericParamKind<'hir>,
}
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 18:44:30 +02:00
#[derive(Default)]
pub struct GenericParamCount {
pub lifetimes: usize,
pub types: usize,
pub consts: usize,
}
2015-07-31 09:04:06 +02:00
/// Represents lifetimes and type parameters attached to a declaration
/// of a function, enum, trait, etc.
#[derive(Debug, HashStable_Generic)]
2019-11-30 17:46:46 +01:00
pub struct Generics<'hir> {
2019-12-01 17:10:12 +01:00
pub params: &'hir [GenericParam<'hir>],
2019-11-30 17:46:46 +01:00
pub where_clause: WhereClause<'hir>,
2016-08-10 19:39:12 +02:00
pub span: Span,
2015-07-31 09:04:06 +02:00
}
2019-11-30 17:46:46 +01:00
impl Generics<'hir> {
pub const fn empty() -> Generics<'hir> {
Generics {
2019-12-01 17:10:12 +01:00
params: &[],
2019-12-01 00:17:43 +01:00
where_clause: WhereClause { predicates: &[], span: DUMMY_SP },
2016-08-10 19:39:12 +02:00
span: DUMMY_SP,
}
}
2019-11-30 17:46:46 +01:00
pub fn get_named(&self, name: Symbol) -> Option<&GenericParam<'_>> {
2019-12-01 17:10:12 +01:00
for param in self.params {
if name == param.name.ident().name {
2018-06-28 20:06:30 +02:00
return Some(param);
}
}
None
}
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()
}
}
}
2019-02-08 14:53:55 +01: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.
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
#[derive(HashStable_Generic)]
pub enum SyntheticTyParamKind {
2019-12-22 23:42:04 +01:00
ImplTrait,
2020-10-05 01:43:15 +02:00
// Created by the `#[rustc_synthetic]` attribute.
2020-10-05 02:01:32 +02:00
FromAttr,
}
2019-02-08 14:53:55 +01:00
/// A where-clause in a definition.
#[derive(Debug, HashStable_Generic)]
2019-11-30 17:46:46 +01:00
pub struct WhereClause<'hir> {
pub predicates: &'hir [WherePredicate<'hir>],
// Only valid if predicates aren't empty.
pub span: Span,
2015-07-31 09:04:06 +02:00
}
2019-11-30 17:46:46 +01:00
impl WhereClause<'_> {
pub fn span(&self) -> Option<Span> {
2019-12-22 23:42:04 +01:00
if self.predicates.is_empty() { None } else { Some(self.span) }
}
/// 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 18:44:41 +02: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_or(end, |p| p.span()).shrink_to_hi().to(end)
2020-05-29 18:44:41 +02:00
}
}
2019-02-08 14:53:55 +01:00
/// A single predicate in a where-clause.
#[derive(Debug, HashStable_Generic)]
2019-11-30 17:46:46 +01:00
pub enum WherePredicate<'hir> {
/// A type binding (e.g., `for<'c> Foo: Send + Clone + 'c`).
2019-11-30 17:46:46 +01:00
BoundPredicate(WhereBoundPredicate<'hir>),
/// A lifetime predicate (e.g., `'a: 'b + 'c`).
2019-11-30 17:46:46 +01:00
RegionPredicate(WhereRegionPredicate<'hir>),
/// An equality predicate (unsupported).
2019-11-30 17:46:46 +01:00
EqPredicate(WhereEqPredicate<'hir>),
2015-07-31 09:04:06 +02:00
}
2019-11-30 17:46:46 +01:00
impl WherePredicate<'_> {
pub fn span(&self) -> Span {
match self {
WherePredicate::BoundPredicate(p) => p.span,
WherePredicate::RegionPredicate(p) => p.span,
WherePredicate::EqPredicate(p) => p.span,
}
}
}
2019-02-08 14:53:55 +01:00
/// A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`).
#[derive(Debug, HashStable_Generic)]
2019-11-30 17:46:46 +01:00
pub struct WhereBoundPredicate<'hir> {
2015-07-31 09:04:06 +02:00
pub span: Span,
2019-02-08 14:53:55 +01:00
/// Any generics from a `for` binding.
2019-11-30 17:46:46 +01:00
pub bound_generic_params: &'hir [GenericParam<'hir>],
2019-02-08 14:53:55 +01:00
/// The type being bounded.
2019-11-30 17:46:46 +01:00
pub bounded_ty: &'hir Ty<'hir>,
2019-02-08 14:53:55 +01:00
/// Trait and lifetime bounds (e.g., `Clone + Send + 'static`).
2019-11-30 17:46:46 +01:00
pub bounds: GenericBounds<'hir>,
2015-07-31 09:04:06 +02:00
}
2019-02-08 14:53:55 +01:00
/// A lifetime predicate (e.g., `'a: 'b + 'c`).
#[derive(Debug, HashStable_Generic)]
2019-11-30 17:46:46 +01:00
pub struct WhereRegionPredicate<'hir> {
2015-07-31 09:04:06 +02:00
pub span: Span,
pub lifetime: Lifetime,
2019-11-30 17:46:46 +01:00
pub bounds: GenericBounds<'hir>,
2015-07-31 09:04:06 +02:00
}
2019-02-08 14:53:55 +01:00
/// An equality predicate (e.g., `T = int`); currently unsupported.
#[derive(Debug, HashStable_Generic)]
2019-11-30 17:46:46 +01:00
pub struct WhereEqPredicate<'hir> {
2019-02-02 15:40:08 +01:00
pub hir_id: HirId,
2015-07-31 09:04:06 +02:00
pub span: Span,
2019-11-30 17:46:46 +01:00
pub lhs_ty: &'hir Ty<'hir>,
pub rhs_ty: &'hir Ty<'hir>,
2015-07-31 09:04:06 +02:00
}
#[derive(Default, Encodable, Debug, HashStable_Generic)]
2018-06-06 22:13:52 +02:00
pub struct ModuleItems {
// Use BTreeSets here so items are in the same order as in the
// list of all items in Crate
2021-01-30 12:06:04 +01:00
pub items: BTreeSet<ItemId>,
2018-06-06 22:13:52 +02:00
pub trait_items: BTreeSet<TraitItemId>,
pub impl_items: BTreeSet<ImplItemId>,
2020-11-11 21:57:54 +01:00
pub foreign_items: BTreeSet<ForeignItemId>,
2018-06-06 22:13:52 +02:00
}
2020-02-07 16:43:36 +01:00
/// A type representing only the top-level module.
#[derive(Encodable, Debug, HashStable_Generic)]
2020-02-07 16:43:36 +01:00
pub struct CrateItem<'hir> {
pub module: Mod<'hir>,
pub span: Span,
}
/// The top-level data structure that stores the entire contents of
/// the crate currently being compiled.
///
2020-03-05 22:07:42 +01:00
/// For more details, see the [rustc dev guide].
2017-12-31 17:08:04 +01:00
///
/// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/hir.html
#[derive(Debug)]
2019-11-28 11:49:29 +01:00
pub struct Crate<'hir> {
2020-02-07 16:43:36 +01:00
pub item: CrateItem<'hir>,
2019-11-28 23:50:47 +01:00
pub exported_macros: &'hir [MacroDef<'hir>],
// Attributes from non-exported macros, kept only for collecting the library feature list.
2019-11-28 11:49:29 +01:00
pub non_exported_macro_attrs: &'hir [Attribute],
// N.B., we use a `BTreeMap` here so that `visit_all_items` iterates
// 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
2020-12-28 18:15:16 +01:00
// detected, which in turn can make UI tests yield
// slightly different results.
2021-01-30 12:06:04 +01:00
pub items: BTreeMap<ItemId, Item<'hir>>,
2019-11-28 21:47:10 +01:00
pub trait_items: BTreeMap<TraitItemId, TraitItem<'hir>>,
2019-11-28 22:16:44 +01:00
pub impl_items: BTreeMap<ImplItemId, ImplItem<'hir>>,
2020-11-11 21:57:54 +01:00
pub foreign_items: BTreeMap<ForeignItemId, ForeignItem<'hir>>,
2019-11-29 11:09:23 +01:00
pub bodies: BTreeMap<BodyId, Body<'hir>>,
pub trait_impls: BTreeMap<DefId, Vec<LocalDefId>>,
2017-02-21 18:23:47 +01: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 22:13:52 +02:00
/// A list of modules written out in the order in which they
/// appear in the crate. This includes the main crate module.
2021-01-31 17:58:57 +01:00
pub modules: BTreeMap<LocalDefId, ModuleItems>,
/// 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 19:13:10 +02:00
pub trait_map: BTreeMap<HirId, Vec<TraitCandidate>>,
/// Collected attributes from HIR nodes.
2021-01-24 17:14:17 +01:00
pub attrs: BTreeMap<HirId, &'hir [Attribute]>,
}
2019-11-28 19:28:50 +01:00
impl Crate<'hir> {
2021-01-30 12:06:04 +01:00
pub fn item(&self, id: ItemId) -> &Item<'hir> {
&self.items[&id]
}
2019-11-28 21:47:10 +01:00
pub fn trait_item(&self, id: TraitItemId) -> &TraitItem<'hir> {
&self.trait_items[&id]
}
2019-11-28 22:16:44 +01:00
pub fn impl_item(&self, id: ImplItemId) -> &ImplItem<'hir> {
&self.impl_items[&id]
}
2020-11-11 21:57:54 +01:00
pub fn foreign_item(&self, id: ForeignItemId) -> &ForeignItem<'hir> {
&self.foreign_items[&id]
}
2019-11-29 11:09:23 +01:00
pub fn body(&self, id: BodyId) -> &Body<'hir> {
2019-11-28 19:28:50 +01:00
&self.bodies[&id]
}
}
impl Crate<'_> {
2017-08-11 20:34:14 +02:00
/// Visits all items in the crate in some deterministic (but
/// 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.
pub fn visit_all_item_likes<'hir, V>(&'hir self, visitor: &mut V)
2019-12-22 23:42:04 +01:00
where
V: itemlikevisit::ItemLikeVisitor<'hir>,
2016-03-29 07:50:44 +02:00
{
for item in self.items.values() {
visitor.visit_item(item);
}
for trait_item in self.trait_items.values() {
visitor.visit_trait_item(trait_item);
}
for impl_item in self.impl_items.values() {
visitor.visit_impl_item(impl_item);
}
2020-11-11 21:57:54 +01:00
for foreign_item in self.foreign_items.values() {
visitor.visit_foreign_item(foreign_item);
}
}
2016-10-28 22:58:32 +02:00
2019-02-08 14:53:55 +01:00
/// A parallel version of `visit_all_item_likes`.
2018-04-26 00:50:33 +02:00
pub fn par_visit_all_item_likes<'hir, V>(&'hir self, visitor: &V)
2019-12-22 23:42:04 +01:00
where
V: itemlikevisit::ParItemLikeVisitor<'hir> + Sync + Send,
2018-04-26 00:50:33 +02:00
{
2020-01-02 09:53:15 +01:00
parallel!(
2019-12-22 23:42:04 +01: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);
});
2020-11-11 21:57:54 +01:00
},
{
par_for_each_in(&self.foreign_items, |(_, foreign_item)| {
visitor.visit_foreign_item(foreign_item);
});
2019-12-22 23:42:04 +01:00
}
);
2018-04-26 00:50:33 +02:00
}
2015-07-31 09:04:06 +02:00
}
/// A macro definition, in this crate or imported from another.
///
/// Not parsed directly, but created on macro import or `macro_rules!` expansion.
#[derive(Debug)]
2019-11-28 23:50:47 +01:00
pub struct MacroDef<'hir> {
pub ident: Ident,
2019-11-30 17:46:46 +01:00
pub vis: Visibility<'hir>,
pub def_id: LocalDefId,
2015-07-31 09:04:06 +02:00
pub span: Span,
pub ast: ast::MacroDef,
2015-07-31 09:04:06 +02:00
}
impl MacroDef<'_> {
#[inline]
pub fn hir_id(&self) -> HirId {
HirId::make_owner(self.def_id)
}
}
2019-03-18 09:02:57 +01: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`.
#[derive(Debug, HashStable_Generic)]
2019-11-29 13:43:03 +01:00
pub struct Block<'hir> {
2019-02-08 14:53:55 +01:00
/// Statements in a block.
2019-11-29 13:43:03 +01:00
pub stmts: &'hir [Stmt<'hir>],
2015-07-31 09:04:06 +02:00
/// An expression at the end of the block
2019-02-08 14:53:55 +01:00
/// without a semicolon, if any.
2019-11-29 13:43:03 +01:00
pub expr: Option<&'hir Expr<'hir>>,
2018-12-03 01:14:35 +01:00
#[stable_hasher(ignore)]
pub hir_id: HirId,
2019-02-08 14:53:55 +01:00
/// Distinguishes between `unsafe { ... }` and `{ ... }`.
2015-07-31 09:04:06 +02:00
pub rules: BlockCheckMode,
pub span: Span,
/// If true, then there may exist `break 'a` values that aim to
/// break out of this block early.
/// Used by `'label: {}` blocks and by `try {}` blocks.
pub targeted_by_break: bool,
2015-07-31 09:04:06 +02:00
}
#[derive(Debug, HashStable_Generic)]
2019-11-29 13:43:03 +01:00
pub struct Pat<'hir> {
2018-12-03 01:14:35 +01:00
#[stable_hasher(ignore)]
pub hir_id: HirId,
2019-11-29 13:43:03 +01:00
pub kind: PatKind<'hir>,
2015-07-31 09:04:06 +02:00
pub span: Span,
// Whether to use default binding modes.
// At present, this is false only for destructuring assignment.
pub default_binding_modes: bool,
2015-07-31 09:04:06 +02:00
}
impl<'hir> Pat<'hir> {
// FIXME(#19596) this is a workaround, but there should be a better way
fn walk_short_(&self, it: &mut impl FnMut(&Pat<'hir>) -> bool) -> bool {
if !it(self) {
return false;
}
use PatKind::*;
2019-09-26 17:18:31 +02:00
match &self.kind {
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 23:42:04 +01:00
before.iter().chain(slice.iter()).chain(after.iter()).all(|p| p.walk_short_(it))
}
}
}
/// 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.
pub fn walk_short(&self, mut it: impl FnMut(&Pat<'hir>) -> bool) -> bool {
self.walk_short_(&mut it)
}
// FIXME(#19596) this is a workaround, but there should be a better way
fn walk_(&self, it: &mut impl FnMut(&Pat<'hir>) -> bool) {
if !it(self) {
return;
}
use PatKind::*;
2019-09-26 17:18:31 +02:00
match &self.kind {
2019-12-22 23:42:04 +01:00
Wild | Lit(_) | Range(..) | Binding(.., None) | Path(_) => {}
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 23:42:04 +01:00
before.iter().chain(slice.iter()).chain(after.iter()).for_each(|p| p.walk_(it))
}
}
}
/// Walk the pattern in left-to-right order.
///
/// If `it(pat)` returns `false`, the children are not visited.
pub fn walk(&self, mut it: impl FnMut(&Pat<'hir>) -> bool) {
self.walk_(&mut it)
}
2019-12-14 23:43:21 +01:00
/// Walk the pattern in left-to-right order.
///
/// If you always want to recurse, prefer this method over `walk`.
2019-11-29 13:43:03 +01:00
pub fn walk_always(&self, mut it: impl FnMut(&Pat<'_>)) {
2019-12-14 23:43:21 +01:00
self.walk(|p| {
it(p);
true
})
}
}
2019-02-08 14:53:55 +01:00
/// A single field in a struct pattern.
2015-07-31 09:04:06 +02: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 14:53:55 +01:00
/// except `is_shorthand` is true.
#[derive(Debug, HashStable_Generic)]
pub struct PatField<'hir> {
2018-12-03 01:14:35 +01:00
#[stable_hasher(ignore)]
2019-02-02 15:40:08 +01:00
pub hir_id: HirId,
2019-02-08 14:53:55 +01:00
/// The identifier for the field.
2018-12-03 01:14:35 +01:00
#[stable_hasher(project(name))]
2018-05-26 01:50:15 +02:00
pub ident: Ident,
2019-02-08 14:53:55 +01:00
/// The pattern the field is destructured to.
2019-11-29 13:43:03 +01:00
pub pat: &'hir Pat<'hir>,
2015-07-31 09:04:06 +02:00
pub is_shorthand: bool,
pub span: Span,
2015-07-31 09:04:06 +02: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.
#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)]
pub enum BindingAnnotation {
2018-09-12 12:31:11 +02: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,
2018-09-12 12:31:11 +02:00
/// Annotated with `mut x` -- could be either ref or not, similar to `None`.
Mutable,
2018-09-12 12:31:11 +02:00
/// Annotated as `ref`, like `ref x`
Ref,
2018-09-12 12:31:11 +02:00
/// Annotated as `ref mut x`.
RefMut,
2015-07-31 09:04:06 +02:00
}
#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)]
pub enum RangeEnd {
Included,
Excluded,
}
impl fmt::Display for RangeEnd {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(match self {
RangeEnd::Included => "..=",
RangeEnd::Excluded => "..",
})
}
}
#[derive(Debug, HashStable_Generic)]
2019-11-29 13:43:03 +01:00
pub enum PatKind<'hir> {
2019-02-08 14:53:55 +01:00
/// Represents a wildcard pattern (i.e., `_`).
2016-02-14 13:25:12 +01:00
Wild,
2015-07-31 09:04:06 +02:00
/// A fresh binding `ref mut binding @ OPT_SUBPATTERN`.
2019-03-07 12:18:59 +01:00
/// The `HirId` is the canonical ID for the variable being bound,
2019-02-08 14:53:55 +01:00
/// (e.g., in `Ok(x) | Err(x)`, both `x` use the same canonical ID),
/// which is the pattern ID of the first `x`.
2019-11-29 13:43:03 +01:00
Binding(BindingAnnotation, HirId, Ident, Option<&'hir Pat<'hir>>),
2015-07-31 09:04:06 +02:00
2019-02-08 14:53:55 +01:00
/// A struct or struct variant pattern (e.g., `Variant {x, y, ..}`).
/// The `bool` is `true` in the presence of a `..`.
Struct(QPath<'hir>, &'hir [PatField<'hir>], bool),
/// A tuple struct/variant pattern `Variant(x, y, .., z)`.
2016-03-06 13:54:44 +01:00
/// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
2019-02-08 14:53:55 +01:00
/// `0 <= position <= subpats.len()`
2019-11-30 17:46:46 +01:00
TupleStruct(QPath<'hir>, &'hir [&'hir Pat<'hir>], Option<usize>),
2018-10-19 16:40:07 +02:00
/// An or-pattern `A | B | C`.
/// Invariant: `pats.len() >= 2`.
2019-11-29 13:43:03 +01:00
Or(&'hir [&'hir Pat<'hir>]),
2018-10-19 16:40:07 +02:00
/// A path pattern for an unit struct/variant or a (maybe-associated) constant.
2019-11-30 17:46:46 +01:00
Path(QPath<'hir>),
2015-07-31 09:04:06 +02:00
2019-02-08 14:53:55 +01:00
/// A tuple pattern (e.g., `(a, b)`).
2016-03-06 13:54:44 +01:00
/// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
2019-02-08 14:53:55 +01:00
/// `0 <= position <= subpats.len()`
2019-11-29 13:43:03 +01:00
Tuple(&'hir [&'hir Pat<'hir>], Option<usize>),
2019-02-08 14:53:55 +01:00
/// A `box` pattern.
2019-11-29 13:43:03 +01:00
Box(&'hir Pat<'hir>),
2019-02-08 14:53:55 +01:00
/// A reference pattern (e.g., `&mut (a, b)`).
2019-11-29 13:43:03 +01:00
Ref(&'hir Pat<'hir>, Mutability),
2019-02-08 14:53:55 +01:00
/// A literal.
2019-11-29 13:43:03 +01:00
Lit(&'hir Expr<'hir>),
2019-06-14 19:24:38 +02:00
/// A range pattern (e.g., `1..=2` or `1..2`).
Range(Option<&'hir Expr<'hir>>, Option<&'hir Expr<'hir>>, RangeEnd),
2019-12-15 13:16:29 +01: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 13:43:03 +01:00
Slice(&'hir [&'hir Pat<'hir>], Option<&'hir Pat<'hir>>, &'hir [&'hir Pat<'hir>]),
2015-07-31 09:04:06 +02:00
}
#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)]
2018-07-11 12:44:53 +02:00
pub enum BinOpKind {
2019-02-08 14:53:55 +01:00
/// The `+` operator (addition).
2018-07-11 12:44:53 +02:00
Add,
2019-02-08 14:53:55 +01:00
/// The `-` operator (subtraction).
2018-07-11 12:44:53 +02:00
Sub,
2019-02-08 14:53:55 +01:00
/// The `*` operator (multiplication).
2018-07-11 12:44:53 +02:00
Mul,
2019-02-08 14:53:55 +01:00
/// The `/` operator (division).
2018-07-11 12:44:53 +02:00
Div,
2019-02-08 14:53:55 +01:00
/// The `%` operator (modulus).
2018-07-11 12:44:53 +02:00
Rem,
2019-02-08 14:53:55 +01:00
/// The `&&` operator (logical and).
2018-07-11 12:44:53 +02:00
And,
2019-02-08 14:53:55 +01:00
/// The `||` operator (logical or).
2018-07-11 12:44:53 +02:00
Or,
2019-02-08 14:53:55 +01:00
/// The `^` operator (bitwise xor).
2018-07-11 12:44:53 +02:00
BitXor,
2019-02-08 14:53:55 +01:00
/// The `&` operator (bitwise and).
2018-07-11 12:44:53 +02:00
BitAnd,
2019-02-08 14:53:55 +01:00
/// The `|` operator (bitwise or).
2018-07-11 12:44:53 +02:00
BitOr,
2019-02-08 14:53:55 +01:00
/// The `<<` operator (shift left).
2018-07-11 12:44:53 +02:00
Shl,
2019-02-08 14:53:55 +01:00
/// The `>>` operator (shift right).
2018-07-11 12:44:53 +02:00
Shr,
2019-02-08 14:53:55 +01:00
/// The `==` operator (equality).
2018-07-11 12:44:53 +02:00
Eq,
2019-02-08 14:53:55 +01:00
/// The `<` operator (less than).
2018-07-11 12:44:53 +02:00
Lt,
2019-02-08 14:53:55 +01:00
/// The `<=` operator (less than or equal to).
2018-07-11 12:44:53 +02:00
Le,
2019-02-08 14:53:55 +01:00
/// The `!=` operator (not equal to).
2018-07-11 12:44:53 +02:00
Ne,
2019-02-08 14:53:55 +01:00
/// The `>=` operator (greater than or equal to).
2018-07-11 12:44:53 +02:00
Ge,
2019-02-08 14:53:55 +01:00
/// The `>` operator (greater than).
2018-07-11 12:44:53 +02:00
Gt,
2015-07-31 09:04:06 +02:00
}
2018-07-11 12:44:53 +02:00
impl BinOpKind {
pub fn as_str(self) -> &'static str {
match self {
2018-07-11 12:44:53 +02: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 => ">",
}
}
pub fn is_lazy(self) -> bool {
2020-10-27 02:02:48 +01:00
matches!(self, BinOpKind::And | BinOpKind::Or)
}
pub fn is_shift(self) -> bool {
2020-10-27 02:02:48 +01:00
matches!(self, BinOpKind::Shl | BinOpKind::Shr)
}
pub fn is_comparison(self) -> bool {
match self {
2019-12-22 23:42:04 +01: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,
}
}
2019-02-08 14:53:55 +01:00
/// Returns `true` if the binary operator takes its arguments by value.
pub fn is_by_value(self) -> bool {
!self.is_comparison()
}
}
2018-07-11 12:44:53 +02:00
impl Into<ast::BinOpKind> for BinOpKind {
fn into(self) -> ast::BinOpKind {
match self {
2018-07-11 12:44:53 +02: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-07-11 12:44:53 +02:00
pub type BinOp = Spanned<BinOpKind>;
2015-07-31 09:04:06 +02:00
#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)]
2015-07-31 09:04:06 +02:00
pub enum UnOp {
2019-02-08 14:53:55 +01:00
/// The `*` operator (deferencing).
Deref,
2019-02-08 14:53:55 +01:00
/// The `!` operator (logical negation).
Not,
2019-02-08 14:53:55 +01:00
/// The `-` operator (negation).
Neg,
2015-07-31 09:04:06 +02:00
}
impl UnOp {
pub fn as_str(self) -> &'static str {
match self {
Self::Deref => "*",
Self::Not => "!",
Self::Neg => "-",
}
}
2019-02-08 14:53:55 +01:00
/// Returns `true` if the unary operator takes its argument by value.
pub fn is_by_value(self) -> bool {
matches!(self, Self::Neg | Self::Not)
}
}
2019-02-08 14:53:55 +01:00
/// A statement.
#[derive(Debug, HashStable_Generic)]
2019-11-29 13:43:03 +01:00
pub struct Stmt<'hir> {
2019-02-02 15:40:08 +01:00
pub hir_id: HirId,
2019-11-29 13:43:03 +01:00
pub kind: StmtKind<'hir>,
pub span: Span,
}
2015-07-31 09:04:06 +02:00
2019-03-18 09:02:57 +01:00
/// The contents of a statement.
#[derive(Debug, HashStable_Generic)]
2019-11-29 13:43:03 +01:00
pub enum StmtKind<'hir> {
2019-02-08 14:53:55 +01:00
/// A local (`let`) binding.
2019-11-29 13:43:03 +01:00
Local(&'hir Local<'hir>),
2019-02-08 14:53:55 +01:00
/// An item binding.
Item(ItemId),
2015-07-31 09:04:06 +02:00
2019-02-08 14:53:55 +01:00
/// An expression without a trailing semi-colon (must have unit type).
2019-11-29 13:43:03 +01:00
Expr(&'hir Expr<'hir>),
2015-07-31 09:04:06 +02:00
2019-02-08 14:53:55 +01:00
/// An expression with a trailing semi-colon (may have any type).
2019-11-29 13:43:03 +01:00
Semi(&'hir Expr<'hir>),
2015-07-31 09:04:06 +02:00
}
2019-02-08 14:53:55 +01:00
/// Represents a `let` statement (i.e., `let <pat>:<ty> = <expr>;`).
#[derive(Debug, HashStable_Generic)]
2019-11-29 13:43:03 +01:00
pub struct Local<'hir> {
pub pat: &'hir Pat<'hir>,
2019-03-18 09:02:57 +01:00
/// Type annotation, if any (otherwise the type will be inferred).
2019-11-30 17:46:46 +01:00
pub ty: Option<&'hir Ty<'hir>>,
2019-02-08 14:53:55 +01:00
/// Initializer expression to set the value, if any.
2019-11-29 13:43:03 +01:00
pub init: Option<&'hir Expr<'hir>>,
pub hir_id: HirId,
2015-07-31 09:04:06 +02:00
pub span: Span,
2019-03-18 09:02:57 +01:00
/// Can be `ForLoopDesugar` if the `let` statement is part of a `for` loop
/// desugaring. Otherwise will be `Normal`.
pub source: LocalSource,
2015-07-31 09:04:06 +02:00
}
2019-03-18 09:02:57 +01:00
/// Represents a single arm of a `match` expression, e.g.
/// `<pat> (if <guard>) => <body>`.
#[derive(Debug, HashStable_Generic)]
2019-11-29 13:43:03 +01:00
pub struct Arm<'hir> {
2019-03-30 23:54:29 +01:00
#[stable_hasher(ignore)]
pub hir_id: HirId,
pub span: Span,
/// If this pattern and the optional guard matches, then `body` is evaluated.
2019-11-29 13:43:03 +01:00
pub pat: &'hir Pat<'hir>,
2019-03-18 09:02:57 +01:00
/// Optional guard clause.
2019-11-29 13:43:03 +01:00
pub guard: Option<Guard<'hir>>,
/// The expression the arm evaluates to if this arm matches.
2019-11-29 13:43:03 +01:00
pub body: &'hir Expr<'hir>,
2015-07-31 09:04:06 +02:00
}
#[derive(Debug, HashStable_Generic)]
2019-11-29 13:43:03 +01:00
pub enum Guard<'hir> {
If(&'hir Expr<'hir>),
2020-10-24 21:13:54 +02:00
IfLet(&'hir Pat<'hir>, &'hir Expr<'hir>),
2018-08-30 06:18:11 +02:00
}
#[derive(Debug, HashStable_Generic)]
pub struct ExprField<'hir> {
2018-12-03 01:14:35 +01:00
#[stable_hasher(ignore)]
2019-02-02 15:40:08 +01:00
pub hir_id: HirId,
2018-05-26 01:50:15 +02:00
pub ident: Ident,
2019-11-29 13:43:03 +01:00
pub expr: &'hir Expr<'hir>,
2015-07-31 09:04:06 +02:00
pub span: Span,
pub is_shorthand: bool,
2015-07-31 09:04:06 +02:00
}
#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)]
2015-07-31 09:04:06 +02:00
pub enum BlockCheckMode {
DefaultBlock,
UnsafeBlock(UnsafeSource),
PushUnsafeBlock(UnsafeSource),
PopUnsafeBlock(UnsafeSource),
}
#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)]
2015-07-31 09:04:06 +02:00
pub enum UnsafeSource {
CompilerGenerated,
UserProvided,
}
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Encodable, Hash, Debug)]
pub struct BodyId {
2019-02-04 20:01:14 +01:00
pub hir_id: HirId,
}
/// 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 22:19:44 +02:00
/// # Examples
///
2017-09-15 22:19:44 +02:00
/// ```
/// fn foo((x, y): (u32, u32)) -> u32 {
/// x + y
/// }
/// ```
///
/// Here, the `Body` associated with `foo()` would contain:
///
/// - an `params` array containing the `(x, y)` pattern
/// - a `value` containing the `x + y` expression (maybe wrapped in a block)
/// - `generator_kind` would be `None`
///
/// All bodies have an **owner**, which can be accessed via the HIR
/// map using `body_owner_def_id()`.
#[derive(Debug)]
2019-11-29 11:09:23 +01:00
pub struct Body<'hir> {
2019-11-29 13:43:03 +01:00
pub params: &'hir [Param<'hir>],
pub value: Expr<'hir>,
pub generator_kind: Option<GeneratorKind>,
}
2019-11-29 11:09:23 +01:00
impl Body<'hir> {
pub fn id(&self) -> BodyId {
2019-12-22 23:42:04 +01:00
BodyId { hir_id: self.value.hir_id }
}
pub fn generator_kind(&self) -> Option<GeneratorKind> {
self.generator_kind
}
}
/// The type of source expression that caused this generator to be created.
2020-10-04 15:52:14 +02:00
#[derive(
Clone,
PartialEq,
PartialOrd,
Eq,
Hash,
HashStable_Generic,
Encodable,
Decodable,
Debug,
Copy
)]
pub enum GeneratorKind {
/// An explicit `async` block or the body of an async function.
Async(AsyncGeneratorKind),
/// A generator literal created via a `yield` inside a closure.
Gen,
}
impl fmt::Display for GeneratorKind {
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"),
}
}
}
impl GeneratorKind {
pub fn descr(&self) -> &'static str {
match self {
GeneratorKind::Async(ask) => ask.descr(),
GeneratorKind::Gen => "generator",
}
}
}
/// 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-10-04 15:52:14 +02:00
#[derive(
Clone,
PartialEq,
PartialOrd,
Eq,
Hash,
HashStable_Generic,
Encodable,
Decodable,
Debug,
Copy
)]
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 {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(match self {
AsyncGeneratorKind::Block => "`async` block",
AsyncGeneratorKind::Closure => "`async` closure body",
2019-10-02 20:39:44 +02:00
AsyncGeneratorKind::Fn => "`async fn` body",
})
}
}
impl AsyncGeneratorKind {
pub fn descr(&self) -> &'static str {
match self {
AsyncGeneratorKind::Block => "`async` block",
AsyncGeneratorKind::Closure => "`async` closure body",
AsyncGeneratorKind::Fn => "`async fn` body",
}
}
}
#[derive(Copy, Clone, Debug)]
pub enum BodyOwnerKind {
/// Functions and methods.
Fn,
/// Closures
Closure,
/// Constants and associated constants.
Const,
/// Initializer of a `static` item.
Static(Mutability),
}
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 19:22:35 +02: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"),
}
}
}
/// A literal.
pub type Lit = Spanned<LitKind>;
/// A constant (expression) that's not an item or associated item,
/// but needs its own `DefId` for type-checking, const-eval, etc.
/// These are usually found nested inside types (e.g., array lengths)
/// or expressions (e.g., repeat counts), and also used to define
/// explicit discriminant values for enum variants.
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Debug, HashStable_Generic)]
pub struct AnonConst {
pub hir_id: HirId,
pub body: BodyId,
}
/// An expression.
#[derive(Debug)]
2019-11-29 13:43:03 +01:00
pub struct Expr<'hir> {
pub hir_id: HirId,
2019-11-29 13:43:03 +01:00
pub kind: ExprKind<'hir>,
pub span: Span,
2015-07-31 09:04:06 +02:00
}
2019-11-29 13:43:03 +01:00
impl Expr<'_> {
pub fn precedence(&self) -> ExprPrecedence {
match self.kind {
2018-07-11 14:05:29 +02:00
ExprKind::Box(_) => ExprPrecedence::Box,
2020-10-06 22:51:15 +02:00
ExprKind::ConstBlock(_) => ExprPrecedence::ConstBlock,
2018-07-11 14:05:29 +02: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,
ExprKind::DropTemps(ref expr, ..) => expr.precedence(),
2021-01-01 19:38:11 +01:00
ExprKind::If(..) => ExprPrecedence::If,
2018-07-11 14:05:29 +02: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 18:32:41 +01:00
ExprKind::InlineAsm(..) => ExprPrecedence::InlineAsm,
ExprKind::LlvmInlineAsm(..) => ExprPrecedence::InlineAsm,
2018-07-11 14:05:29 +02:00
ExprKind::Struct(..) => ExprPrecedence::Struct,
ExprKind::Repeat(..) => ExprPrecedence::Repeat,
ExprKind::Yield(..) => ExprPrecedence::Yield,
ExprKind::Err => ExprPrecedence::Err,
}
}
// 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)
}
/// 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.
pub fn is_place_expr(&self, mut allow_projections_from: impl FnMut(&Self) -> bool) -> bool {
match self.kind {
2020-10-27 02:02:48 +01:00
ExprKind::Path(QPath::Resolved(_, ref path)) => {
matches!(path.res, Res::Local(..) | Res::Def(DefKind::Static, _) | Res::Err)
}
// 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 23:42:04 +01:00
ExprKind::Type(ref e, _) => e.is_place_expr(allow_projections_from),
ExprKind::Unary(UnOp::Deref, _) => true,
2019-12-22 23:42:04 +01:00
ExprKind::Field(ref base, _) | ExprKind::Index(ref base, _) => {
allow_projections_from(base) || base.is_place_expr(allow_projections_from)
}
// Lang item paths cannot currently be local variables or statics.
ExprKind::Path(QPath::LangItem(..)) => false,
// Partially qualified paths in expressions can only legally
// refer to associated items which are always rvalues.
2019-12-22 23:42:04 +01:00
ExprKind::Path(QPath::TypeRelative(..))
| ExprKind::Call(..)
| ExprKind::MethodCall(..)
| ExprKind::Struct(..)
| ExprKind::Tup(..)
2021-01-01 19:38:11 +01:00
| ExprKind::If(..)
2019-12-22 23:42:04 +01:00
| ExprKind::Match(..)
| ExprKind::Closure(..)
| ExprKind::Block(..)
| ExprKind::Repeat(..)
| ExprKind::Array(..)
| ExprKind::Break(..)
| ExprKind::Continue(..)
| ExprKind::Ret(..)
| ExprKind::Loop(..)
| ExprKind::Assign(..)
2020-02-12 18:32:41 +01:00
| ExprKind::InlineAsm(..)
| ExprKind::LlvmInlineAsm(..)
2019-12-22 23:42:04 +01:00
| ExprKind::AssignOp(..)
| ExprKind::Lit(_)
2020-10-06 22:51:15 +02:00
| ExprKind::ConstBlock(..)
2019-12-22 23:42:04 +01:00
| ExprKind::Unary(..)
| ExprKind::Box(..)
| ExprKind::AddrOf(..)
| ExprKind::Binary(..)
| ExprKind::Yield(..)
| ExprKind::Cast(..)
| ExprKind::DropTemps(..)
| ExprKind::Err => false,
}
}
/// 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 18:46:57 +02:00
let mut expr = self;
while let ExprKind::DropTemps(inner) = &expr.kind {
expr = inner;
}
2019-10-08 18:46:57 +02:00
expr
}
Improve error msgs when found type is deref of expected This improves help messages in two cases: - When expected type is `T` and found type is `&T`, we now look through blocks and suggest dereferencing the expression of the block, rather than the whole block. - In the above case, if the expression is an `&`, we not suggest removing the `&` instead of adding `*`. Both of these are demonstrated in the regression test. Before this patch the first error in the test would be: error[E0308]: `if` and `else` have incompatible types --> test.rs:8:9 | 5 | / if true { 6 | | a | | - expected because of this 7 | | } else { 8 | | b | | ^ expected `usize`, found `&usize` 9 | | }; | |_____- `if` and `else` have incompatible types | help: consider dereferencing the borrow | 7 | } else *{ 8 | b 9 | }; | Now: error[E0308]: `if` and `else` have incompatible types --> test.rs:8:9 | 5 | / if true { 6 | | a | | - expected because of this 7 | | } else { 8 | | b | | ^ | | | | | expected `usize`, found `&usize` | | help: consider dereferencing the borrow: `*b` 9 | | }; | |_____- `if` and `else` have incompatible types The second error: error[E0308]: `if` and `else` have incompatible types --> test.rs:14:9 | 11 | / if true { 12 | | 1 | | - expected because of this 13 | | } else { 14 | | &1 | | ^^ expected integer, found `&{integer}` 15 | | }; | |_____- `if` and `else` have incompatible types | help: consider dereferencing the borrow | 13 | } else *{ 14 | &1 15 | }; | now: error[E0308]: `if` and `else` have incompatible types --> test.rs:14:9 | 11 | / if true { 12 | | 1 | | - expected because of this 13 | | } else { 14 | | &1 | | ^- | | || | | |help: consider removing the `&`: `1` | | expected integer, found `&{integer}` 15 | | }; | |_____- `if` and `else` have incompatible types Fixes #82361
2021-02-21 11:29:43 +01:00
pub fn peel_blocks(&self) -> &Self {
let mut expr = self;
while let ExprKind::Block(Block { expr: Some(inner), .. }, _) = &expr.kind {
expr = inner;
}
expr
}
pub fn can_have_side_effects(&self) -> bool {
match self.peel_drop_temps().kind {
ExprKind::Path(_) | ExprKind::Lit(_) => false,
ExprKind::Type(base, _)
| ExprKind::Unary(_, base)
| ExprKind::Field(base, _)
2021-02-22 01:54:42 +01:00
| ExprKind::Index(base, _)
| ExprKind::AddrOf(.., base)
| ExprKind::Cast(base, _) => {
// This isn't exactly true for `Index` and all `Unnary`, but we are using this
// method exclusively for diagnostics and there's a *cultural* pressure against
// them being used only for its side-effects.
base.can_have_side_effects()
}
ExprKind::Struct(_, fields, init) => fields
.iter()
.map(|field| field.expr)
.chain(init.into_iter())
.all(|e| e.can_have_side_effects()),
ExprKind::Array(args)
| ExprKind::Tup(args)
| ExprKind::Call(
Expr {
kind:
ExprKind::Path(QPath::Resolved(
None,
Path { res: Res::Def(DefKind::Ctor(_, CtorKind::Fn), _), .. },
)),
..
},
args,
) => args.iter().all(|arg| arg.can_have_side_effects()),
ExprKind::If(..)
| ExprKind::Match(..)
| ExprKind::MethodCall(..)
| ExprKind::Call(..)
| ExprKind::Closure(..)
| ExprKind::Block(..)
| ExprKind::Repeat(..)
| ExprKind::Break(..)
| ExprKind::Continue(..)
| ExprKind::Ret(..)
| ExprKind::Loop(..)
| ExprKind::Assign(..)
| ExprKind::InlineAsm(..)
| ExprKind::LlvmInlineAsm(..)
| ExprKind::AssignOp(..)
| ExprKind::ConstBlock(..)
| ExprKind::Box(..)
| ExprKind::Binary(..)
| ExprKind::Yield(..)
| ExprKind::DropTemps(..)
| ExprKind::Err => true,
}
}
}
/// Checks if the specified expression is a built-in range literal.
/// (See: `LoweringContext::lower_expr()`).
pub fn is_range_literal(expr: &Expr<'_>) -> bool {
match expr.kind {
// All built-in range literals but `..=` and `..` desugar to `Struct`s.
ExprKind::Struct(ref qpath, _, _) => matches!(
**qpath,
QPath::LangItem(
LangItem::Range
| LangItem::RangeTo
| LangItem::RangeFrom
| LangItem::RangeFull
| LangItem::RangeToInclusive,
_,
)
),
// `..=` desugars into `::std::ops::RangeInclusive::new(...)`.
ExprKind::Call(ref func, _) => {
matches!(func.kind, ExprKind::Path(QPath::LangItem(LangItem::RangeInclusiveNew, _)))
}
_ => false,
}
}
#[derive(Debug, HashStable_Generic)]
2019-11-29 13:43:03 +01:00
pub enum ExprKind<'hir> {
/// A `box x` expression.
2019-11-29 13:43:03 +01:00
Box(&'hir Expr<'hir>),
2020-10-06 22:51:15 +02:00
/// Allow anonymous constants from an inline `const` block
ConstBlock(AnonConst),
2019-02-08 14:53:55 +01:00
/// An array (e.g., `[a, b, c, d]`).
2019-11-29 13:43:03 +01:00
Array(&'hir [Expr<'hir>]),
2019-02-08 14:53:55 +01:00
/// A function call.
2015-07-31 09:04:06 +02:00
///
2018-07-11 14:05:29 +02:00
/// The first field resolves to the function itself (usually an `ExprKind::Path`),
/// 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 13:43:03 +01:00
Call(&'hir Expr<'hir>, &'hir [Expr<'hir>]),
2019-02-08 14:53:55 +01:00
/// A method call (e.g., `x.foo::<'static, Bar, Baz>(a, b, c, d)`).
2015-07-31 09:04:06 +02:00
///
/// The `PathSegment`/`Span` represent the method name and its generic arguments
2015-07-31 09:04:06 +02:00
/// (within the angle brackets).
/// 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 09:04:06 +02:00
/// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as
/// `ExprKind::MethodCall(PathSegment { foo, [Bar, Baz] }, [x, a, b, c, d])`.
/// 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 10:16:16 +01: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 10:47:04 +02:00
/// [`type_dependent_def_id`]: ../ty/struct.TypeckResults.html#method.type_dependent_def_id
MethodCall(&'hir PathSegment<'hir>, Span, &'hir [Expr<'hir>], Span),
/// A tuple (e.g., `(a, b, c, d)`).
2019-11-29 13:43:03 +01:00
Tup(&'hir [Expr<'hir>]),
2019-02-08 14:53:55 +01:00
/// A binary operation (e.g., `a + b`, `a * b`).
2019-11-29 13:43:03 +01:00
Binary(BinOp, &'hir Expr<'hir>, &'hir Expr<'hir>),
2019-02-08 14:53:55 +01:00
/// A unary operation (e.g., `!x`, `*x`).
2019-11-29 13:43:03 +01:00
Unary(UnOp, &'hir Expr<'hir>),
2019-02-08 14:53:55 +01:00
/// A literal (e.g., `1`, `"foo"`).
Lit(Lit),
2019-02-08 14:53:55 +01:00
/// A cast (e.g., `foo as f64`).
2019-11-30 17:46:46 +01:00
Cast(&'hir Expr<'hir>, &'hir Ty<'hir>),
2019-02-08 14:53:55 +01:00
/// A type reference (e.g., `Foo`).
2019-11-30 17:46:46 +01:00
Type(&'hir Expr<'hir>, &'hir Ty<'hir>),
/// 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 13:43:03 +01:00
DropTemps(&'hir Expr<'hir>),
2021-01-01 19:38:11 +01:00
/// An `if` block, with an optional else block.
///
/// I.e., `if <expr> { <expr> } else { <expr> }`.
If(&'hir Expr<'hir>, &'hir Expr<'hir>, Option<&'hir Expr<'hir>>),
2019-02-08 14:53:55 +01:00
/// A conditionless loop (can be exited with `break`, `continue`, or `return`).
2015-07-31 09:04:06 +02:00
///
2019-02-08 14:53:55 +01:00
/// I.e., `'label: loop { <block> }`.
2021-01-21 02:15:08 +01:00
///
/// The `Span` is the loop header (`for x in y`/`while let pat = expr`).
Loop(&'hir Block<'hir>, Option<Label>, LoopSource, Span),
2015-07-31 09:04:06 +02: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 13:43:03 +01:00
Match(&'hir Expr<'hir>, &'hir [Arm<'hir>], MatchSource),
2019-02-08 14:53:55 +01:00
/// A closure (e.g., `move |a, b, c| {a + b + c}`).
///
/// The `Span` is the argument block `|...|`.
2017-07-10 22:07:55 +02:00
///
/// This may also be a generator literal or an `async block` as indicated by the
/// `Option<Movability>`.
2019-11-30 17:46:46 +01:00
Closure(CaptureBy, &'hir FnDecl<'hir>, BodyId, Span, Option<Movability>),
2019-02-08 14:53:55 +01:00
/// A block (e.g., `'label: { ... }`).
2019-11-29 13:43:03 +01:00
Block(&'hir Block<'hir>, Option<Label>),
2015-07-31 09:04:06 +02:00
2019-02-08 14:53:55 +01:00
/// An assignment (e.g., `a = foo()`).
2019-11-29 13:43:03 +01:00
Assign(&'hir Expr<'hir>, &'hir Expr<'hir>, Span),
2019-02-08 14:53:55 +01:00
/// An assignment with an operator.
2015-07-31 09:04:06 +02:00
///
2019-02-08 14:53:55 +01:00
/// E.g., `a += 1`.
2019-11-29 13:43:03 +01:00
AssignOp(BinOp, &'hir Expr<'hir>, &'hir Expr<'hir>),
2019-02-08 14:53:55 +01:00
/// Access of a named (e.g., `obj.foo`) or unnamed (e.g., `obj.0`) struct or tuple field.
2019-11-29 13:43:03 +01:00
Field(&'hir Expr<'hir>, Ident),
2019-02-08 14:53:55 +01:00
/// An indexing operation (`foo[2]`).
2019-11-29 13:43:03 +01:00
Index(&'hir Expr<'hir>, &'hir Expr<'hir>),
2015-07-31 09:04:06 +02:00
/// Path to a definition, possibly containing lifetime or type parameters.
2019-11-30 17:46:46 +01:00
Path(QPath<'hir>),
2015-07-31 09:04:06 +02:00
2019-11-29 13:43:03 +01:00
/// A referencing operation (i.e., `&a` or `&mut a`).
2019-11-29 14:08:03 +01:00
AddrOf(BorrowKind, Mutability, &'hir Expr<'hir>),
2019-02-08 14:53:55 +01:00
/// A `break`, with an optional label to break.
2019-11-29 13:43:03 +01:00
Break(Destination, Option<&'hir Expr<'hir>>),
2019-02-08 14:53:55 +01:00
/// A `continue`, with an optional label.
2018-07-11 14:05:29 +02:00
Continue(Destination),
2019-02-08 14:53:55 +01:00
/// A `return`, with an optional value to be returned.
2019-11-29 13:43:03 +01:00
Ret(Option<&'hir Expr<'hir>>),
2015-07-31 09:04:06 +02:00
2020-02-12 18:32:41 +01:00
/// Inline assembly (from `asm!`), with its outputs and inputs.
InlineAsm(&'hir InlineAsm<'hir>),
/// Inline assembly (from `llvm_asm!`), with its outputs and inputs.
LlvmInlineAsm(&'hir LlvmInlineAsm<'hir>),
2015-07-31 09:04:06 +02:00
2016-06-28 18:07:39 +02:00
/// A struct or struct-like variant literal expression.
2015-07-31 09:04:06 +02:00
///
/// E.g., `Foo {x: 1, y: 2}`, or `Foo {x: 1, .. base}`,
/// where `base` is the `Option<Expr>`.
Struct(&'hir QPath<'hir>, &'hir [ExprField<'hir>], Option<&'hir Expr<'hir>>),
2015-07-31 09:04:06 +02:00
2016-06-28 12:32:45 +02:00
/// An array literal constructed from one repeated element.
2015-07-31 09:04:06 +02:00
///
/// E.g., `[1; 5]`. The first expression is the element
2015-07-31 09:04:06 +02:00
/// to be repeated; the second is the number of times to repeat it.
2019-11-29 13:43:03 +01:00
Repeat(&'hir Expr<'hir>, AnonConst),
2016-12-26 14:34:03 +01:00
2019-02-08 14:53:55 +01:00
/// A suspension point for generators (i.e., `yield <expr>`).
2019-11-29 13:43:03 +01:00
Yield(&'hir Expr<'hir>, YieldSource),
2019-02-08 14:53:55 +01:00
/// A placeholder for an expression that wasn't syntactically well formed in some way.
Err,
2015-07-31 09:04:06 +02:00
}
/// Represents an optionally `Self`-qualified value/type path or associated extension.
///
/// To resolve the path to a `DefId`, call [`qpath_res`].
///
2020-07-17 10:47:04 +02:00
/// [`qpath_res`]: ../rustc_middle/ty/struct.TypeckResults.html#method.qpath_res
#[derive(Debug, HashStable_Generic)]
2019-11-30 17:46:46 +01:00
pub enum QPath<'hir> {
/// 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 14:53:55 +01:00
/// E.g., an unqualified path like `Clone::clone` has `None` for `Self`,
/// 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 17:46:46 +01:00
Resolved(Option<&'hir Ty<'hir>>, &'hir Path<'hir>),
2019-02-08 14:53:55 +01:00
/// Type-related paths (e.g., `<T>::default` or `<T>::Output`).
/// 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 16:41:03 +02:00
/// the `X` and `Y` nodes each being a `TyKind::Path(QPath::TypeRelative(..))`.
2019-11-30 17:46:46 +01:00
TypeRelative(&'hir Ty<'hir>, &'hir PathSegment<'hir>),
/// 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,
}
}
}
2019-02-08 14:53:55 +01:00
/// Hints at the original code for a let statement.
#[derive(Copy, Clone, Encodable, Debug, HashStable_Generic)]
pub enum LocalSource {
2019-02-08 14:53:55 +01:00
/// A `match _ { .. }`.
Normal,
2019-02-08 14:53:55 +01:00
/// A desugared `for _ in _ { .. }` loop.
ForLoopDesugar,
/// When lowering async functions, we create locals within the `async move` so that
/// all parameters are dropped after the future is polled.
///
/// ```ignore (pseudo-Rust)
/// async fn foo(<pattern> @ x: Type) {
/// async move {
/// let <pattern> = x;
/// }
/// }
/// ```
AsyncFn,
/// A desugared `<expr>.await`.
AwaitDesugar,
/// A desugared `expr = expr`, where the LHS is a tuple, struct or array.
/// The span is that of the `=` sign.
AssignDesugar(Span),
}
2019-02-08 14:53:55 +01:00
/// Hints at the original code for a `match _ { .. }`.
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Hash, Debug)]
#[derive(HashStable_Generic)]
2015-07-31 09:04:06 +02:00
pub enum MatchSource {
2019-02-08 14:53:55 +01:00
/// A `match _ { .. }`.
2015-07-31 09:04:06 +02:00
Normal,
2019-02-08 14:53:55 +01:00
/// An `if let _ = _ { .. }` (optionally with `else { .. }`).
2019-12-22 23:42:04 +01:00
IfLetDesugar { contains_else_clause: bool },
/// An `if let _ = _ => { .. }` match guard.
IfLetGuardDesugar,
2019-06-19 17:21:28 +02:00
/// A `while _ { .. }` (which was desugared to a `loop { match _ { .. } }`).
WhileDesugar,
2016-06-28 12:32:45 +02:00
/// A `while let _ = _ { .. }` (which was desugared to a
2019-02-08 14:53:55 +01:00
/// `loop { match _ { .. } }`).
2015-07-31 09:04:06 +02:00
WhileLetDesugar,
2019-02-08 14:53:55 +01:00
/// A desugared `for _ in _ { .. }` loop.
2015-07-31 09:04:06 +02:00
ForLoopDesugar,
2019-02-08 14:53:55 +01:00
/// A desugared `?` operator.
TryDesugar,
/// A desugared `<expr>.await`.
AwaitDesugar,
2015-07-31 09:04:06 +02:00
}
2019-11-18 21:58:28 +01:00
impl MatchSource {
pub fn name(self) -> &'static str {
use MatchSource::*;
match self {
Normal => "match",
2021-01-01 19:38:11 +01:00
IfLetDesugar { .. } | IfLetGuardDesugar => "if",
2019-11-18 21:58:28 +01:00
WhileDesugar | WhileLetDesugar => "while",
ForLoopDesugar => "for",
TryDesugar => "?",
AwaitDesugar => ".await",
}
}
}
2019-02-08 14:53:55 +01:00
/// The loop type that yielded an `ExprKind::Loop`.
#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)]
pub enum LoopSource {
2019-02-08 14:53:55 +01:00
/// A `loop { .. }` loop.
Loop,
2019-06-19 17:21:28 +02:00
/// A `while _ { .. }` loop.
While,
2019-02-08 14:53:55 +01:00
/// A `while let _ = _ { .. }` loop.
WhileLet,
2019-02-08 14:53:55 +01:00
/// A `for _ in _ { .. }` loop.
ForLoop,
}
2019-06-19 17:21:28 +02:00
impl LoopSource {
pub fn name(self) -> &'static str {
match self {
LoopSource::Loop => "loop",
2019-11-18 21:58:28 +01:00
LoopSource::While | LoopSource::WhileLet => "while",
2019-06-19 17:21:28 +02:00
LoopSource::ForLoop => "for",
}
}
}
#[derive(Copy, Clone, Encodable, Debug, HashStable_Generic)]
pub enum LoopIdError {
OutsideLoopScope,
UnlabeledCfInWhileCondition,
UnresolvedLabel,
}
impl fmt::Display for LoopIdError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(match self {
LoopIdError::OutsideLoopScope => "not inside loop scope",
2019-12-22 23:42:04 +01:00
LoopIdError::UnlabeledCfInWhileCondition => {
"unlabeled control flow (break or continue) in while condition"
}
LoopIdError::UnresolvedLabel => "label not found",
})
}
}
#[derive(Copy, Clone, Encodable, Debug, HashStable_Generic)]
2017-02-18 03:55:28 +01:00
pub struct Destination {
// This is `Some(_)` iff there is an explicit user-specified `label
pub label: Option<Label>,
// These errors are caught and then reported during the diagnostics pass in
// librustc_passes/loops.rs
pub target_id: Result<HirId, LoopIdError>,
}
/// The yield kind that caused an `ExprKind::Yield`.
#[derive(Copy, Clone, PartialEq, Eq, Debug, Encodable, Decodable, HashStable_Generic)]
pub enum YieldSource {
/// An `<expr>.await`.
Await { expr: Option<HirId> },
/// A plain `yield`.
Yield,
}
impl YieldSource {
pub fn is_await(&self) -> bool {
match self {
YieldSource::Await { .. } => true,
YieldSource::Yield => false,
}
}
}
impl fmt::Display for YieldSource {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(match self {
YieldSource::Await { .. } => "`await`",
YieldSource::Yield => "`yield`",
})
}
}
impl From<GeneratorKind> for YieldSource {
fn from(kind: GeneratorKind) -> Self {
match kind {
2019-10-16 18:57:18 +02:00
// Guess based on the kind of the current generator.
GeneratorKind::Gen => Self::Yield,
GeneratorKind::Async(_) => Self::Await { expr: None },
2019-10-16 18:57:18 +02:00
}
}
}
// N.B., if you change this, you'll probably want to change the corresponding
2015-07-31 09:04:06 +02:00
// type structure in middle/ty.rs as well.
#[derive(Debug, HashStable_Generic)]
2019-11-30 17:46:46 +01:00
pub struct MutTy<'hir> {
pub ty: &'hir Ty<'hir>,
2015-07-31 09:04:06 +02:00
pub mutbl: Mutability,
}
2019-11-07 13:06:52 +01:00
/// Represents a function's signature in a trait declaration,
/// trait implementation, or a free function.
#[derive(Debug, HashStable_Generic)]
2019-11-30 15:20:35 +01:00
pub struct FnSig<'hir> {
pub header: FnHeader,
2019-11-30 17:46:46 +01:00
pub decl: &'hir FnDecl<'hir>,
Use smaller def span for functions Currently, the def span of a funtion encompasses the entire function signature and body. However, this is usually unnecessarily verbose - when we are pointing at an entire function in a diagnostic, we almost always want to point at the signature. The actual contents of the body tends to be irrelevant to the diagnostic we are emitting, and just takes up additional screen space. This commit changes the `def_span` of all function items (freestanding functions, `impl`-block methods, and `trait`-block methods) to be the span of the signature. For example, the function ```rust pub fn foo<T>(val: T) -> T { val } ``` now has a `def_span` corresponding to `pub fn foo<T>(val: T) -> T` (everything before the opening curly brace). Trait methods without a body have a `def_span` which includes the trailing semicolon. For example: ```rust trait Foo { fn bar(); }``` the function definition `Foo::bar` has a `def_span` of `fn bar();` This makes our diagnostic output much shorter, and emphasizes information that is relevant to whatever diagnostic we are reporting. We continue to use the full span (including the body) in a few of places: * MIR building uses the full span when building source scopes. * 'Outlives suggestions' use the full span to sort the diagnostics being emitted. * The `#[rustc_on_unimplemented(enclosing_scope="in this scope")]` attribute points the entire scope body. * The 'unconditional recursion' lint uses the full span to show additional context for the recursive call. All of these cases work only with local items, so we don't need to add anything extra to crate metadata.
2020-08-12 23:02:14 +02:00
pub span: Span,
2015-07-31 09:04:06 +02:00
}
// The bodies for items are stored "out of line", in a separate
2020-11-26 19:11:43 +01:00
// hashmap in the `Crate`. Here we just record the hir-id of the item
// so it can fetched later.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Encodable, Debug)]
pub struct TraitItemId {
pub def_id: LocalDefId,
}
impl TraitItemId {
#[inline]
pub fn hir_id(&self) -> HirId {
// Items are always HIR owners.
HirId::make_owner(self.def_id)
}
}
/// 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).
#[derive(Debug)]
2019-11-28 21:47:10 +01:00
pub struct TraitItem<'hir> {
pub ident: Ident,
pub def_id: LocalDefId,
2019-11-30 17:46:46 +01:00
pub generics: Generics<'hir>,
2019-11-28 21:47:10 +01:00
pub kind: TraitItemKind<'hir>,
2015-07-31 09:04:06 +02:00
pub span: Span,
}
impl TraitItem<'_> {
#[inline]
pub fn hir_id(&self) -> HirId {
// Items are always HIR owners.
HirId::make_owner(self.def_id)
}
pub fn trait_item_id(&self) -> TraitItemId {
TraitItemId { def_id: self.def_id }
}
}
/// Represents a trait method's body (or just argument names).
#[derive(Encodable, Debug, HashStable_Generic)]
2020-03-05 16:57:34 +01:00
pub enum TraitFn<'hir> {
/// No default body in the trait, just a signature.
2019-11-30 15:28:32 +01:00
Required(&'hir [Ident]),
/// Both signature and body are provided in the trait.
Provided(BodyId),
}
2016-06-28 12:32:45 +02:00
/// Represents a trait method or associated constant or type
#[derive(Debug, HashStable_Generic)]
2019-11-28 21:47:10 +01:00
pub enum TraitItemKind<'hir> {
/// An associated constant with an optional value (otherwise `impl`s must contain a value).
2019-11-30 17:46:46 +01:00
Const(&'hir Ty<'hir>, Option<BodyId>),
2020-03-03 19:46:22 +01:00
/// An associated function with an optional body.
2020-03-05 16:57:34 +01:00
Fn(FnSig<'hir>, TraitFn<'hir>),
2016-06-28 12:32:45 +02:00
/// An associated type with (possibly empty) bounds and optional concrete
/// type.
2019-11-30 17:46:46 +01:00
Type(GenericBounds<'hir>, Option<&'hir Ty<'hir>>),
2015-07-31 09:04:06 +02:00
}
// The bodies for items are stored "out of line", in a separate
2020-11-26 19:11:43 +01:00
// hashmap in the `Crate`. Here we just record the hir-id of the item
// so it can fetched later.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Encodable, Debug)]
pub struct ImplItemId {
pub def_id: LocalDefId,
}
impl ImplItemId {
#[inline]
pub fn hir_id(&self) -> HirId {
// Items are always HIR owners.
HirId::make_owner(self.def_id)
}
}
2019-08-01 01:41:54 +02:00
/// Represents anything within an `impl` block.
#[derive(Debug)]
2019-11-28 22:16:44 +01:00
pub struct ImplItem<'hir> {
pub ident: Ident,
pub def_id: LocalDefId,
2019-11-30 17:46:46 +01:00
pub vis: Visibility<'hir>,
pub defaultness: Defaultness,
2019-11-30 17:46:46 +01:00
pub generics: Generics<'hir>,
2019-11-28 22:16:44 +01:00
pub kind: ImplItemKind<'hir>,
2015-07-31 09:04:06 +02:00
pub span: Span,
}
impl ImplItem<'_> {
#[inline]
pub fn hir_id(&self) -> HirId {
// Items are always HIR owners.
HirId::make_owner(self.def_id)
}
pub fn impl_item_id(&self) -> ImplItemId {
ImplItemId { def_id: self.def_id }
}
}
2019-05-08 21:57:06 +02:00
/// Represents various kinds of content within an `impl`.
#[derive(Debug, HashStable_Generic)]
2019-11-28 22:16:44 +01:00
pub enum ImplItemKind<'hir> {
2016-06-28 12:32:45 +02:00
/// An associated constant of the given type, set to the constant result
2019-08-01 01:41:54 +02:00
/// of the expression.
2019-11-30 17:46:46 +01:00
Const(&'hir Ty<'hir>, BodyId),
2020-03-07 01:00:46 +01:00
/// An associated function implementation with the given signature and body.
2020-03-05 16:57:34 +01:00
Fn(FnSig<'hir>, BodyId),
2019-08-01 01:41:54 +02:00
/// An associated type.
2019-11-30 17:46:46 +01:00
TyAlias(&'hir Ty<'hir>),
2015-07-31 09:04:06 +02:00
}
impl ImplItemKind<'_> {
pub fn namespace(&self) -> Namespace {
match self {
ImplItemKind::TyAlias(..) => Namespace::TypeNS,
2020-03-05 16:57:34 +01:00
ImplItemKind::Const(..) | ImplItemKind::Fn(..) => Namespace::ValueNS,
}
}
}
// The name of the associated type for `Fn` return types.
pub const FN_OUTPUT_NAME: Symbol = sym::Output;
2019-05-08 21:57:06 +02: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.
///
/// 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 21:57:06 +02:00
///
/// ```
/// enum TypeBindingKind {
/// Equals(...),
/// Binding(...),
/// }
/// ```
#[derive(Debug, HashStable_Generic)]
2019-11-30 17:46:46 +01:00
pub struct TypeBinding<'hir> {
2019-02-02 15:40:08 +01:00
pub hir_id: HirId,
2018-12-03 01:14:35 +01:00
#[stable_hasher(project(name))]
pub ident: Ident,
2020-11-30 09:23:00 +01:00
pub gen_args: &'hir GenericArgs<'hir>,
2019-11-30 17:46:46 +01:00
pub kind: TypeBindingKind<'hir>,
2015-07-31 09:04:06 +02:00
pub span: Span,
}
2019-05-08 21:57:06 +02:00
// Represents the two kinds of type bindings.
#[derive(Debug, HashStable_Generic)]
2019-11-30 17:46:46 +01:00
pub enum TypeBindingKind<'hir> {
2019-05-08 21:57:06 +02:00
/// E.g., `Foo<Bar: Send>`.
2019-11-30 17:46:46 +01:00
Constraint { bounds: &'hir [GenericBound<'hir>] },
2019-05-08 21:57:06 +02:00
/// E.g., `Foo<Bar = ()>`.
2019-11-30 17:46:46 +01:00
Equality { ty: &'hir Ty<'hir> },
2019-05-08 21:57:06 +02:00
}
2019-11-30 17:46:46 +01:00
impl TypeBinding<'_> {
pub fn ty(&self) -> &Ty<'_> {
2019-05-08 21:57:06 +02:00
match self.kind {
TypeBindingKind::Equality { ref ty } => ty,
_ => panic!("expected equality type binding for parenthesized generic args"),
2019-05-08 21:57:06 +02:00
}
}
}
#[derive(Debug)]
2019-11-30 17:46:46 +01:00
pub struct Ty<'hir> {
pub hir_id: HirId,
2019-11-30 17:46:46 +01:00
pub kind: TyKind<'hir>,
2015-07-31 09:04:06 +02:00
pub span: Span,
}
2019-02-08 14:53:55 +01:00
/// Not represented directly in the AST; referred to by name through a `ty_path`.
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
#[derive(HashStable_Generic)]
2015-07-31 09:04:06 +02:00
pub enum PrimTy {
Int(IntTy),
Uint(UintTy),
Float(FloatTy),
Str,
Bool,
Char,
2015-07-31 09:04:06 +02:00
}
impl PrimTy {
2021-02-02 19:16:35 +01:00
/// All of the primitive types
pub const ALL: [Self; 17] = [
// any changes here should also be reflected in `PrimTy::from_name`
Self::Int(IntTy::I8),
Self::Int(IntTy::I16),
Self::Int(IntTy::I32),
Self::Int(IntTy::I64),
Self::Int(IntTy::I128),
Self::Int(IntTy::Isize),
Self::Uint(UintTy::U8),
Self::Uint(UintTy::U16),
Self::Uint(UintTy::U32),
Self::Uint(UintTy::U64),
Self::Uint(UintTy::U128),
Self::Uint(UintTy::Usize),
Self::Float(FloatTy::F32),
Self::Float(FloatTy::F64),
Self::Bool,
Self::Char,
Self::Str,
];
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,
}
}
2021-02-02 19:16:35 +01:00
/// Returns the matching `PrimTy` for a `Symbol` such as "str" or "i32".
/// Returns `None` if no matching type is found.
pub fn from_name(name: Symbol) -> Option<Self> {
let ty = match name {
// any changes here should also be reflected in `PrimTy::ALL`
sym::i8 => Self::Int(IntTy::I8),
sym::i16 => Self::Int(IntTy::I16),
sym::i32 => Self::Int(IntTy::I32),
sym::i64 => Self::Int(IntTy::I64),
sym::i128 => Self::Int(IntTy::I128),
sym::isize => Self::Int(IntTy::Isize),
sym::u8 => Self::Uint(UintTy::U8),
sym::u16 => Self::Uint(UintTy::U16),
sym::u32 => Self::Uint(UintTy::U32),
sym::u64 => Self::Uint(UintTy::U64),
sym::u128 => Self::Uint(UintTy::U128),
sym::usize => Self::Uint(UintTy::Usize),
sym::f32 => Self::Float(FloatTy::F32),
sym::f64 => Self::Float(FloatTy::F64),
sym::bool => Self::Bool,
sym::char => Self::Char,
sym::str => Self::Str,
_ => return None,
};
Some(ty)
}
}
#[derive(Debug, HashStable_Generic)]
2019-11-30 17:46:46 +01:00
pub struct BareFnTy<'hir> {
2015-07-31 09:04:06 +02:00
pub unsafety: Unsafety,
pub abi: Abi,
2019-11-30 17:46:46 +01:00
pub generic_params: &'hir [GenericParam<'hir>],
pub decl: &'hir FnDecl<'hir>,
pub param_names: &'hir [Ident],
2015-07-31 09:04:06 +02:00
}
#[derive(Debug, HashStable_Generic)]
2019-11-30 17:46:46 +01:00
pub struct OpaqueTy<'hir> {
pub generics: Generics<'hir>,
pub bounds: GenericBounds<'hir>,
2018-05-22 14:31:56 +02:00
pub impl_trait_fn: Option<DefId>,
2019-08-01 01:41:54 +02:00
pub origin: OpaqueTyOrigin,
}
2019-08-02 02:14:42 +02:00
/// From whence the opaque type came.
#[derive(Copy, Clone, Encodable, Decodable, Debug, HashStable_Generic)]
2019-08-01 01:41:54 +02:00
pub enum OpaqueTyOrigin {
/// `-> impl Trait`
2019-08-02 01:09:38 +02:00
FnReturn,
/// `async fn`
AsyncFn,
/// `let _: impl Trait = ...`
Binding,
/// type aliases: `type Foo = impl Trait;`
TyAlias,
/// Impl trait consts, statics, bounds.
2019-12-28 16:39:52 +01:00
Misc,
}
2019-02-08 14:53:55 +01:00
/// The various kinds of types recognized by the compiler.
#[derive(Debug, HashStable_Generic)]
2019-11-30 17:46:46 +01:00
pub enum TyKind<'hir> {
2019-02-08 14:53:55 +01:00
/// A variable length slice (i.e., `[T]`).
2019-11-30 17:46:46 +01:00
Slice(&'hir Ty<'hir>),
2019-02-08 14:53:55 +01:00
/// A fixed length array (i.e., `[T; n]`).
2019-11-30 17:46:46 +01:00
Array(&'hir Ty<'hir>, AnonConst),
2019-02-08 14:53:55 +01:00
/// A raw pointer (i.e., `*const T` or `*mut T`).
2019-11-30 17:46:46 +01:00
Ptr(MutTy<'hir>),
2019-02-08 14:53:55 +01:00
/// A reference (i.e., `&'a T` or `&'a mut T`).
2019-11-30 17:46:46 +01:00
Rptr(Lifetime, MutTy<'hir>),
2019-02-08 14:53:55 +01:00
/// A bare function (e.g., `fn(usize) -> bool`).
2019-11-30 17:46:46 +01:00
BareFn(&'hir BareFnTy<'hir>),
2019-02-08 14:53:55 +01:00
/// The never type (`!`).
2018-07-11 16:41:03 +02:00
Never,
/// A tuple (`(A, B, C, D, ...)`).
2019-11-30 17:46:46 +01:00
Tup(&'hir [Ty<'hir>]),
/// A path to a type definition (`module::module::...::Type`), or an
2019-02-08 14:53:55 +01:00
/// associated type (e.g., `<Vec<T> as Trait>::Type` or `<T>::Target`).
2015-07-31 09:04:06 +02:00
///
/// Type parameters may be stored in each `PathSegment`.
2019-11-30 17:46:46 +01:00
Path(QPath<'hir>),
2020-06-07 19:56:17 +02:00
/// A opaque type definition itself. This is currently only used for the
/// `opaque type Foo: Trait` item that `impl Trait` in desugars to.
///
2020-06-07 19:56:17 +02: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>]),
/// A trait object type `Bound1 + Bound2 + Bound3`
/// where `Bound` is a trait or a lifetime.
2019-11-30 17:46:46 +01:00
TraitObject(&'hir [PolyTraitRef<'hir>], Lifetime),
2019-02-08 14:53:55 +01:00
/// Unused for now.
2018-07-11 16:41:03 +02:00
Typeof(AnonConst),
/// `TyKind::Infer` means the type should be inferred instead of it having been
2015-07-31 09:04:06 +02:00
/// specified. This can appear anywhere in a type.
2018-07-11 16:41:03 +02:00
Infer,
/// Placeholder for a type that has failed to be defined.
2018-07-11 16:41:03 +02:00
Err,
2015-07-31 09:04:06 +02:00
}
#[derive(Debug, HashStable_Generic)]
2020-02-12 18:32:41 +01: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,
}
}
}
#[derive(Debug, HashStable_Generic)]
2020-02-12 18:32:41 +01:00
pub struct InlineAsm<'hir> {
pub template: &'hir [InlineAsmTemplatePiece],
pub operands: &'hir [(InlineAsmOperand<'hir>, Span)],
2020-02-12 18:32:41 +01:00
pub options: InlineAsmOptions,
2020-05-26 21:07:59 +02:00
pub line_spans: &'hir [Span],
2020-02-12 18:32:41 +01:00
}
2020-10-04 15:52:14 +02:00
#[derive(Copy, Clone, Encodable, Decodable, Debug, Hash, HashStable_Generic, PartialEq)]
pub struct LlvmInlineAsmOutput {
pub constraint: Symbol,
pub is_rw: bool,
pub is_indirect: bool,
pub span: Span,
}
// NOTE(eddyb) This is used within MIR as well, so unlike the rest of the HIR,
// it needs to be `Clone` and `Decodable` and use plain `Vec<T>` instead of
// arena-allocated slice.
2020-10-04 15:52:14 +02:00
#[derive(Clone, Encodable, Decodable, Debug, Hash, HashStable_Generic, PartialEq)]
pub struct LlvmInlineAsmInner {
pub asm: Symbol,
2015-07-31 09:04:06 +02:00
pub asm_str_style: StrStyle,
pub outputs: Vec<LlvmInlineAsmOutput>,
pub inputs: Vec<Symbol>,
pub clobbers: Vec<Symbol>,
2015-07-31 09:04:06 +02:00
pub volatile: bool,
pub alignstack: bool,
pub dialect: LlvmAsmDialect,
2015-07-31 09:04:06 +02:00
}
#[derive(Debug, HashStable_Generic)]
pub struct LlvmInlineAsm<'hir> {
pub inner: LlvmInlineAsmInner,
2019-11-29 13:43:03 +01:00
pub outputs_exprs: &'hir [Expr<'hir>],
pub inputs_exprs: &'hir [Expr<'hir>],
2019-11-18 14:43:34 +01:00
}
/// Represents a parameter in a function header.
#[derive(Debug, HashStable_Generic)]
2019-11-29 13:43:03 +01:00
pub struct Param<'hir> {
pub hir_id: HirId,
2019-11-29 13:43:03 +01:00
pub pat: &'hir Pat<'hir>,
pub ty_span: Span,
2019-07-27 00:52:37 +02:00
pub span: Span,
2015-07-31 09:04:06 +02:00
}
2019-02-08 14:53:55 +01:00
/// Represents the header (not the body) of a function declaration.
#[derive(Debug, HashStable_Generic)]
2019-11-30 17:46:46 +01:00
pub struct FnDecl<'hir> {
/// The types of the function's parameters.
///
/// Additional argument data is stored in the function's [body](Body::params).
2019-11-30 17:46:46 +01:00
pub inputs: &'hir [Ty<'hir>],
2020-02-15 04:10:59 +01:00
pub output: FnRetTy<'hir>,
pub c_variadic: bool,
/// Does the function have an implicit self?
pub implicit_self: ImplicitSelfKind,
}
/// Represents what type of implicit self a function has, if any.
#[derive(Copy, Clone, Encodable, Decodable, Debug, HashStable_Generic)]
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 23:42:04 +01:00
None,
}
impl ImplicitSelfKind {
/// Does this represent an implicit self?
pub fn has_implicit_self(&self) -> bool {
2020-10-27 02:02:48 +01:00
!matches!(*self, ImplicitSelfKind::None)
}
2015-07-31 09:04:06 +02:00
}
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Encodable, Decodable, Debug)]
#[derive(HashStable_Generic)]
pub enum IsAsync {
Async,
NotAsync,
}
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Encodable, Decodable, HashStable_Generic)]
pub enum Defaultness {
Default { has_value: bool },
Final,
}
impl Defaultness {
pub fn has_value(&self) -> bool {
match *self {
Defaultness::Default { has_value } => has_value,
Defaultness::Final => true,
}
}
pub fn is_final(&self) -> bool {
*self == Defaultness::Final
}
pub fn is_default(&self) -> bool {
2020-10-27 02:02:48 +01:00
matches!(*self, Defaultness::Default { .. })
}
}
#[derive(Debug, HashStable_Generic)]
2020-02-15 04:10:59 +01:00
pub enum FnRetTy<'hir> {
2015-07-31 09:04:06 +02: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 14:53:55 +01:00
/// Everything else.
2019-11-30 17:46:46 +01:00
Return(&'hir Ty<'hir>),
2015-07-31 09:04:06 +02:00
}
2020-02-15 04:10:59 +01:00
impl FnRetTy<'_> {
2015-07-31 09:04:06 +02:00
pub fn span(&self) -> Span {
match *self {
2020-01-02 03:48:12 +01:00
Self::DefaultReturn(span) => span,
Self::Return(ref ty) => ty.span,
2015-07-31 09:04:06 +02:00
}
}
}
#[derive(Encodable, Debug)]
2019-11-29 10:24:47 +01:00
pub struct Mod<'hir> {
2015-07-31 09:04:06 +02: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 10:24:47 +01:00
pub item_ids: &'hir [ItemId],
2015-07-31 09:04:06 +02:00
}
#[derive(Encodable, Debug, HashStable_Generic)]
2017-03-16 03:27:40 +01:00
pub struct GlobalAsm {
pub asm: Symbol,
}
#[derive(Debug, HashStable_Generic)]
2019-11-29 09:26:18 +01:00
pub struct EnumDef<'hir> {
pub variants: &'hir [Variant<'hir>],
2015-07-31 09:04:06 +02:00
}
#[derive(Debug, HashStable_Generic)]
2019-11-29 09:26:18 +01:00
pub struct Variant<'hir> {
/// Name of the variant.
2019-03-13 00:08:36 +01:00
#[stable_hasher(project(name))]
pub ident: Ident,
/// 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 09:26:18 +01:00
pub data: VariantData<'hir>,
2019-02-08 14:53:55 +01:00
/// Explicit discriminant (e.g., `Foo = 1`).
pub disr_expr: Option<AnonConst>,
2019-08-14 02:40:21 +02:00
/// Span
2019-12-22 23:42:04 +01:00
pub span: Span,
2015-07-31 09:04:06 +02:00
}
#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)]
pub enum UseKind {
/// One import, e.g., `use foo::bar` or `use foo::bar as baz`.
/// Also produced for each element of a list `use`, e.g.
/// `use foo::{a, b}` lowers to `use foo::a; use foo::b;`.
Single,
2015-07-31 09:04:06 +02:00
/// Glob import, e.g., `use foo::*`.
Glob,
2015-07-31 09:04:06 +02:00
/// Degenerate list import, e.g., `use foo::{a, b}` produces
/// an additional `use foo::{}` for performing checks such as
/// unstable feature gating. May be removed in the future.
ListStem,
2015-07-31 09:04:06 +02:00
}
2019-05-20 17:19:34 +02:00
/// References to traits in impls.
2015-07-31 09:04:06 +02:00
///
/// `resolve` maps each `TraitRef`'s `ref_id` to its defining trait; that's all
/// 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
/// within the resolution map.
#[derive(Debug, HashStable_Generic)]
2019-11-30 17:46:46 +01:00
pub struct TraitRef<'hir> {
pub path: &'hir Path<'hir>,
2019-06-18 00:40:24 +02:00
// Don't hash the `ref_id`. It is tracked via the thing it is used to access.
2018-12-03 01:14:35 +01:00
#[stable_hasher(ignore)]
pub hir_ref_id: HirId,
2015-07-31 09:04:06 +02:00
}
2019-11-30 17:46:46 +01:00
impl TraitRef<'_> {
2019-02-08 14:53:55 +01:00
/// Gets the `DefId` of the referenced trait. It _must_ actually be a trait or trait alias.
2020-03-23 20:27:59 +01:00
pub fn trait_def_id(&self) -> Option<DefId> {
match self.path.res {
2020-03-23 20:27:59 +01:00
Res::Def(DefKind::Trait | DefKind::TraitAlias, did) => Some(did),
Res::Err => None,
_ => unreachable!(),
}
}
}
#[derive(Debug, HashStable_Generic)]
2019-11-30 17:46:46 +01:00
pub struct PolyTraitRef<'hir> {
/// The `'a` in `for<'a> Foo<&'a T>`.
2019-11-30 17:46:46 +01:00
pub bound_generic_params: &'hir [GenericParam<'hir>],
2015-07-31 09:04:06 +02:00
2020-01-27 23:08:59 +01:00
/// The `Foo<&'a T>` in `for<'a> Foo<&'a T>`.
2019-11-30 17:46:46 +01:00
pub trait_ref: TraitRef<'hir>,
2015-07-31 09:04:06 +02:00
pub span: Span,
}
2019-11-30 17:46:46 +01:00
pub type Visibility<'hir> = Spanned<VisibilityKind<'hir>>;
#[derive(Debug)]
2019-11-30 17:46:46 +01:00
pub enum VisibilityKind<'hir> {
Public,
Crate(CrateSugar),
2019-11-30 17:46:46 +01:00
Restricted { path: &'hir Path<'hir>, hir_id: HirId },
Inherited,
2015-07-31 09:04:06 +02:00
}
2019-11-30 17:46:46 +01:00
impl VisibilityKind<'_> {
pub fn is_pub(&self) -> bool {
2020-10-27 02:02:48 +01:00
matches!(*self, VisibilityKind::Public)
}
pub fn is_pub_restricted(&self) -> bool {
match *self {
2019-12-22 23:42:04 +01:00
VisibilityKind::Public | VisibilityKind::Inherited => false,
VisibilityKind::Crate(..) | VisibilityKind::Restricted { .. } => true,
}
}
}
#[derive(Debug, HashStable_Generic)]
pub struct FieldDef<'hir> {
pub span: Span,
2018-12-03 01:14:35 +01:00
#[stable_hasher(project(name))]
2018-05-26 01:50:15 +02:00
pub ident: Ident,
2019-11-30 17:46:46 +01:00
pub vis: Visibility<'hir>,
2019-02-02 15:40:08 +01:00
pub hir_id: HirId,
2019-11-30 17:46:46 +01:00
pub ty: &'hir Ty<'hir>,
2015-07-31 09:04:06 +02:00
}
impl FieldDef<'_> {
// Still necessary in couple of places
pub fn is_positional(&self) -> bool {
2018-05-26 14:12:38 +02:00
let first = self.ident.as_str().as_bytes()[0];
2020-12-03 23:06:58 +01:00
(b'0'..=b'9').contains(&first)
}
}
2015-07-31 09:04:06 +02:00
2019-05-08 21:57:06 +02:00
/// Fields and constructor IDs of enum variants and structs.
#[derive(Debug, HashStable_Generic)]
2019-11-29 09:26:18 +01:00
pub enum VariantData<'hir> {
2019-05-08 21:57:06 +02:00
/// A struct variant.
///
2019-05-08 21:57:06 +02:00
/// E.g., `Bar { .. }` as in `enum Foo { Bar { .. } }`.
Struct(&'hir [FieldDef<'hir>], /* recovered */ bool),
2019-05-08 21:57:06 +02:00
/// A tuple variant.
///
/// E.g., `Bar(..)` as in `enum Foo { Bar(..) }`.
Tuple(&'hir [FieldDef<'hir>], HirId),
2019-05-08 21:57:06 +02:00
/// A unit variant.
///
/// E.g., `Bar = ..` as in `enum Foo { Bar = .. }`.
2019-03-01 09:52:20 +01:00
Unit(HirId),
2015-10-08 22:45:46 +02:00
}
2019-11-29 09:26:18 +01:00
impl VariantData<'hir> {
/// Return the fields of this variant.
pub fn fields(&self) -> &'hir [FieldDef<'hir>] {
2015-10-10 02:28:40 +02:00
match *self {
2019-02-02 15:40:08 +01:00
VariantData::Struct(ref fields, ..) | VariantData::Tuple(ref fields, ..) => fields,
_ => &[],
}
2015-10-08 22:45:46 +02:00
}
/// Return the `HirId` of this variant's constructor, if it has one.
pub fn ctor_hir_id(&self) -> Option<HirId> {
2019-02-02 15:40:08 +01:00
match *self {
VariantData::Struct(_, _) => None,
VariantData::Tuple(_, hir_id) | VariantData::Unit(hir_id) => Some(hir_id),
2015-10-10 02:28:40 +02:00
}
}
2015-07-31 09:04:06 +02:00
}
// The bodies for items are stored "out of line", in a separate
2020-11-26 19:11:43 +01:00
// hashmap in the `Crate`. Here we just record the hir-id of the item
// so it can fetched later.
2021-01-30 19:18:48 +01:00
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Encodable, Debug, Hash)]
pub struct ItemId {
pub def_id: LocalDefId,
}
2015-11-05 22:17:59 +01:00
2021-01-30 19:18:48 +01:00
impl ItemId {
#[inline]
2021-01-30 19:18:48 +01:00
pub fn hir_id(&self) -> HirId {
// Items are always HIR owners.
HirId::make_owner(self.def_id)
2021-01-30 19:18:48 +01:00
}
}
2015-07-31 09:04:06 +02:00
/// An item
///
/// The name might be a dummy name in case of anonymous items
#[derive(Debug)]
2019-11-28 19:28:50 +01:00
pub struct Item<'hir> {
pub ident: Ident,
pub def_id: LocalDefId,
2019-11-28 19:28:50 +01:00
pub kind: ItemKind<'hir>,
2019-11-30 17:46:46 +01:00
pub vis: Visibility<'hir>,
2015-07-31 09:04:06 +02:00
pub span: Span,
}
2021-01-30 19:18:48 +01:00
impl Item<'_> {
#[inline]
pub fn hir_id(&self) -> HirId {
// Items are always HIR owners.
HirId::make_owner(self.def_id)
}
2021-01-30 19:18:48 +01:00
pub fn item_id(&self) -> ItemId {
ItemId { def_id: self.def_id }
2021-01-30 19:18:48 +01:00
}
}
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
#[derive(Encodable, Decodable, HashStable_Generic)]
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)]
#[derive(Encodable, Decodable, HashStable_Generic)]
pub enum Constness {
Const,
NotConst,
}
#[derive(Copy, Clone, Encodable, Debug, HashStable_Generic)]
pub struct FnHeader {
pub unsafety: Unsafety,
pub constness: Constness,
pub asyncness: IsAsync,
pub abi: Abi,
}
impl FnHeader {
pub fn is_const(&self) -> bool {
2020-10-27 02:02:48 +01:00
matches!(&self.constness, Constness::Const)
}
}
#[derive(Debug, HashStable_Generic)]
2019-11-28 19:28:50 +01:00
pub enum ItemKind<'hir> {
/// An `extern crate` item, with optional *original* crate name if the crate was renamed.
2015-07-31 09:04:06 +02:00
///
2019-02-08 14:53:55 +01:00
/// E.g., `extern crate foo` or `extern crate foo_bar as foo`.
2020-04-19 13:00:18 +02:00
ExternCrate(Option<Symbol>),
/// `use foo::bar::*;` or `use foo::bar::baz as quux;`
///
/// or just
///
/// `use foo::bar::baz;` (with `as baz` implicitly on the right).
2019-11-30 17:46:46 +01:00
Use(&'hir Path<'hir>, UseKind),
2015-07-31 09:04:06 +02:00
/// A `static` item.
2019-11-30 17:46:46 +01:00
Static(&'hir Ty<'hir>, Mutability, BodyId),
/// A `const` item.
2019-11-30 17:46:46 +01:00
Const(&'hir Ty<'hir>, BodyId),
/// A function declaration.
2019-11-30 17:46:46 +01:00
Fn(FnSig<'hir>, Generics<'hir>, BodyId),
/// A module.
2019-11-29 10:24:47 +01:00
Mod(Mod<'hir>),
2019-10-11 03:36:01 +02:00
/// An external module, e.g. `extern { .. }`.
2020-11-11 22:40:09 +01:00
ForeignMod { abi: Abi, items: &'hir [ForeignItemRef<'hir>] },
/// Module-level inline assembly (from `global_asm!`).
2019-11-28 19:28:50 +01:00
GlobalAsm(&'hir GlobalAsm),
/// A type alias, e.g., `type Foo = Bar<u8>`.
2019-11-30 17:46:46 +01:00
TyAlias(&'hir Ty<'hir>, Generics<'hir>),
/// An opaque `impl Trait` type alias, e.g., `type Foo = impl Bar;`.
2019-11-30 17:46:46 +01:00
OpaqueTy(OpaqueTy<'hir>),
/// An enum definition, e.g., `enum Foo<A, B> {C<A>, D<B>}`.
2019-11-30 17:46:46 +01:00
Enum(EnumDef<'hir>, Generics<'hir>),
/// A struct definition, e.g., `struct Foo<A> {x: A}`.
2019-11-30 17:46:46 +01:00
Struct(VariantData<'hir>, Generics<'hir>),
/// A union definition, e.g., `union Foo<A, B> {x: A, y: B}`.
2019-11-30 17:46:46 +01:00
Union(VariantData<'hir>, Generics<'hir>),
/// A trait definition.
2019-11-30 17:46:46 +01:00
Trait(IsAuto, Unsafety, Generics<'hir>, GenericBounds<'hir>, &'hir [TraitItemRef]),
/// A trait alias.
2019-11-30 17:46:46 +01:00
TraitAlias(Generics<'hir>, GenericBounds<'hir>),
2015-07-31 09:04:06 +02:00
/// An implementation, e.g., `impl<A> Trait for Foo { .. }`.
Impl(Impl<'hir>),
}
#[derive(Debug, HashStable_Generic)]
pub struct Impl<'hir> {
pub unsafety: Unsafety,
pub polarity: ImplPolarity,
pub defaultness: Defaultness,
// 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.
pub defaultness_span: Option<Span>,
pub constness: Constness,
pub generics: Generics<'hir>,
/// The trait being implemented, if any.
pub of_trait: Option<TraitRef<'hir>>,
pub self_ty: &'hir Ty<'hir>,
pub items: &'hir [ImplItemRef<'hir>],
2015-07-31 09:04:06 +02:00
}
2019-11-28 19:28:50 +01:00
impl ItemKind<'_> {
2019-11-30 17:46:46 +01:00
pub fn generics(&self) -> Option<&Generics<'_>> {
2017-10-28 23:19:07 +02:00
Some(match *self {
2019-12-22 23:42:04 +01: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, _, _)
| ItemKind::Impl(Impl { ref generics, .. }) => generics,
2019-12-22 23:42:04 +01:00
_ => return None,
2017-10-28 23:19:07 +02:00
})
}
2015-07-31 09:04:06 +02: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 14:53:55 +01:00
/// passes to find the impl they want without loading the ID (which
/// means fewer edges in the incremental compilation graph).
#[derive(Encodable, Debug, HashStable_Generic)]
pub struct TraitItemRef {
pub id: TraitItemId,
2018-12-03 01:14:35 +01:00
#[stable_hasher(project(name))]
pub ident: Ident,
pub kind: AssocItemKind,
pub span: Span,
pub defaultness: Defaultness,
}
/// A reference from an impl to one of its associated items. This
2019-02-08 14:53:55 +01:00
/// 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 14:53:55 +01:00
/// passes to find the impl they want without loading the ID (which
/// means fewer edges in the incremental compilation graph).
#[derive(Debug, HashStable_Generic)]
2019-11-30 17:46:46 +01:00
pub struct ImplItemRef<'hir> {
pub id: ImplItemId,
2018-12-03 01:14:35 +01:00
#[stable_hasher(project(name))]
pub ident: Ident,
pub kind: AssocItemKind,
pub span: Span,
2019-11-30 17:46:46 +01:00
pub vis: Visibility<'hir>,
pub defaultness: Defaultness,
}
#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)]
pub enum AssocItemKind {
Const,
Fn { has_self: bool },
Type,
}
2020-11-11 21:57:54 +01:00
// The bodies for items are stored "out of line", in a separate
2020-11-26 19:11:43 +01:00
// hashmap in the `Crate`. Here we just record the hir-id of the item
2020-11-11 21:57:54 +01:00
// so it can fetched later.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Encodable, Debug)]
pub struct ForeignItemId {
pub def_id: LocalDefId,
}
impl ForeignItemId {
#[inline]
pub fn hir_id(&self) -> HirId {
// Items are always HIR owners.
HirId::make_owner(self.def_id)
}
2020-11-11 21:57:54 +01:00
}
/// A reference from a foreign block to one of its 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
/// passes to find the impl they want without loading the ID (which
/// means fewer edges in the incremental compilation graph).
#[derive(Debug, HashStable_Generic)]
pub struct ForeignItemRef<'hir> {
pub id: ForeignItemId,
#[stable_hasher(project(name))]
pub ident: Ident,
pub span: Span,
pub vis: Visibility<'hir>,
}
#[derive(Debug)]
2019-11-28 20:18:29 +01:00
pub struct ForeignItem<'hir> {
pub ident: Ident,
2019-11-28 20:18:29 +01:00
pub kind: ForeignItemKind<'hir>,
pub def_id: LocalDefId,
2015-07-31 09:04:06 +02:00
pub span: Span,
2019-11-30 17:46:46 +01:00
pub vis: Visibility<'hir>,
2015-07-31 09:04:06 +02:00
}
impl ForeignItem<'_> {
#[inline]
pub fn hir_id(&self) -> HirId {
// Items are always HIR owners.
HirId::make_owner(self.def_id)
}
pub fn foreign_item_id(&self) -> ForeignItemId {
ForeignItemId { def_id: self.def_id }
}
}
2019-02-08 14:53:55 +01:00
/// An item within an `extern` block.
#[derive(Debug, HashStable_Generic)]
2019-11-28 20:18:29 +01:00
pub enum ForeignItemKind<'hir> {
2019-02-08 14:53:55 +01:00
/// A foreign function.
2019-11-30 17:46:46 +01:00
Fn(&'hir FnDecl<'hir>, &'hir [Ident], Generics<'hir>),
/// A foreign static item (`static ext: u8`).
2019-11-30 17:46:46 +01:00
Static(&'hir Ty<'hir>, Mutability),
2019-02-08 14:53:55 +01:00
/// A foreign type.
2018-07-11 16:56:44 +02:00
Type,
2015-07-31 09:04:06 +02:00
}
/// A variable captured by a closure.
#[derive(Debug, Copy, Clone, Encodable, HashStable_Generic)]
pub struct Upvar {
2016-03-29 12:14:01 +02:00
// First span where it is accessed (there can be multiple).
2019-12-22 23:42:04 +01:00
pub span: Span,
2016-03-29 12:14:01 +02:00
}
2019-12-22 23:42:04 +01: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.
#[derive(Encodable, Decodable, Clone, Debug)]
pub struct TraitCandidate {
2016-04-19 15:43:10 +02:00
pub def_id: DefId,
pub import_ids: SmallVec<[LocalDefId; 1]>,
2020-02-13 16:47:51 +01:00
}
2020-02-07 11:14:47 +01:00
#[derive(Copy, Clone, Debug, HashStable_Generic)]
2018-08-25 16:56:16 +02:00
pub enum Node<'hir> {
2019-11-29 13:43:03 +01:00
Param(&'hir Param<'hir>),
2019-11-28 19:28:50 +01:00
Item(&'hir Item<'hir>),
2019-11-28 20:18:29 +01:00
ForeignItem(&'hir ForeignItem<'hir>),
2019-11-28 21:47:10 +01:00
TraitItem(&'hir TraitItem<'hir>),
2019-11-28 22:16:44 +01:00
ImplItem(&'hir ImplItem<'hir>),
2019-11-29 09:26:18 +01:00
Variant(&'hir Variant<'hir>),
Field(&'hir FieldDef<'hir>),
2018-08-25 16:56:16 +02:00
AnonConst(&'hir AnonConst),
2019-11-29 13:43:03 +01:00
Expr(&'hir Expr<'hir>),
Stmt(&'hir Stmt<'hir>),
2019-11-30 17:46:46 +01:00
PathSegment(&'hir PathSegment<'hir>),
Ty(&'hir Ty<'hir>),
TraitRef(&'hir TraitRef<'hir>),
2019-11-29 13:43:03 +01:00
Binding(&'hir Pat<'hir>),
Pat(&'hir Pat<'hir>),
Arm(&'hir Arm<'hir>),
Block(&'hir Block<'hir>),
Local(&'hir Local<'hir>),
2019-11-28 23:50:47 +01:00
MacroDef(&'hir MacroDef<'hir>),
2018-08-25 16:56:16 +02:00
/// `Ctor` refers to the constructor of an enum variant or struct. Only tuple or unit variants
/// with synthesized constructors.
2019-11-29 09:26:18 +01:00
Ctor(&'hir VariantData<'hir>),
2018-08-25 16:56:16 +02:00
Lifetime(&'hir Lifetime),
2019-11-30 17:46:46 +01:00
GenericParam(&'hir GenericParam<'hir>),
Visibility(&'hir Visibility<'hir>),
2018-08-25 16:56:16 +02:00
2020-02-07 16:43:36 +01:00
Crate(&'hir CrateItem<'hir>),
2018-08-25 16:56:16 +02:00
}
2020-07-09 22:18:22 +02:00
impl<'hir> Node<'hir> {
pub fn ident(&self) -> Option<Ident> {
match self {
2019-12-22 23:42:04 +01:00
Node::TraitItem(TraitItem { ident, .. })
| Node::ImplItem(ImplItem { ident, .. })
| Node::ForeignItem(ForeignItem { ident, .. })
| Node::Field(FieldDef { ident, .. })
| Node::Variant(Variant { ident, .. })
| Node::MacroDef(MacroDef { ident, .. })
2019-12-22 23:42:04 +01:00
| Node::Item(Item { ident, .. }) => Some(*ident),
_ => None,
}
}
2020-07-09 22:18:22 +02:00
pub fn fn_decl(&self) -> Option<&FnDecl<'hir>> {
match self {
2020-03-03 19:46:22 +01:00
Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. })
2020-03-05 16:57:34 +01:00
| Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. })
| Node::Item(Item { kind: ItemKind::Fn(fn_sig, _, _), .. }) => Some(fn_sig.decl),
Node::ForeignItem(ForeignItem { kind: ForeignItemKind::Fn(fn_decl, _, _), .. }) => {
Some(fn_decl)
}
_ => None,
}
}
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 22:18:22 +02:00
pub fn generics(&self) -> Option<&'hir Generics<'hir>> {
match self {
Node::TraitItem(TraitItem { generics, .. })
| Node::ImplItem(ImplItem { generics, .. }) => Some(generics),
Node::Item(item) => item.kind.generics(),
_ => None,
}
}
pub fn hir_id(&self) -> Option<HirId> {
match self {
Node::Item(Item { def_id, .. })
| Node::TraitItem(TraitItem { def_id, .. })
| Node::ImplItem(ImplItem { def_id, .. })
| Node::ForeignItem(ForeignItem { def_id, .. })
| Node::MacroDef(MacroDef { def_id, .. }) => Some(HirId::make_owner(*def_id)),
Node::Field(FieldDef { 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::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,
}
}
}
2021-01-29 19:27:56 +01:00
// Some nodes are used a lot. Make sure they don't unintentionally get bigger.
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
2021-01-29 19:27:56 +01:00
mod size_asserts {
rustc_data_structures::static_assert_size!(super::Block<'static>, 48);
2020-11-27 17:41:05 +01:00
rustc_data_structures::static_assert_size!(super::Expr<'static>, 64);
2021-01-29 19:27:56 +01:00
rustc_data_structures::static_assert_size!(super::Pat<'static>, 88);
rustc_data_structures::static_assert_size!(super::QPath<'static>, 24);
rustc_data_structures::static_assert_size!(super::Ty<'static>, 72);
2021-01-24 13:17:54 +01:00
rustc_data_structures::static_assert_size!(super::Item<'static>, 184);
2020-11-27 09:41:53 +01:00
rustc_data_structures::static_assert_size!(super::TraitItem<'static>, 128);
2020-11-27 09:55:10 +01:00
rustc_data_structures::static_assert_size!(super::ImplItem<'static>, 152);
2020-11-27 00:35:22 +01:00
rustc_data_structures::static_assert_size!(super::ForeignItem<'static>, 136);
2021-01-29 19:27:56 +01:00
}