2015-07-31 07:04:06 +00:00
|
|
|
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
|
|
|
// The Rust HIR.
|
|
|
|
|
|
|
|
pub use self::BinOp_::*;
|
|
|
|
pub use self::BlockCheckMode::*;
|
|
|
|
pub use self::CaptureClause::*;
|
|
|
|
pub use self::Decl_::*;
|
|
|
|
pub use self::Expr_::*;
|
|
|
|
pub use self::FunctionRetTy::*;
|
|
|
|
pub use self::ForeignItem_::*;
|
|
|
|
pub use self::Item_::*;
|
|
|
|
pub use self::Mutability::*;
|
|
|
|
pub use self::PrimTy::*;
|
|
|
|
pub use self::Stmt_::*;
|
|
|
|
pub use self::Ty_::*;
|
|
|
|
pub use self::TyParamBound::*;
|
|
|
|
pub use self::UnOp::*;
|
|
|
|
pub use self::UnsafeSource::*;
|
2016-04-02 20:24:02 +00:00
|
|
|
pub use self::Visibility::{Public, Inherited};
|
2015-07-31 07:04:06 +00:00
|
|
|
|
2016-03-29 10:14:01 +00:00
|
|
|
use hir::def::Def;
|
2017-11-23 13:05:58 +00:00
|
|
|
use hir::def_id::{DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX};
|
2017-02-21 15:55:40 +00:00
|
|
|
use util::nodemap::{NodeMap, FxHashSet};
|
2018-02-28 03:08:46 +00:00
|
|
|
use mir::mono::Linkage;
|
2016-03-29 10:14:01 +00:00
|
|
|
|
2017-03-17 04:04:41 +00:00
|
|
|
use syntax_pos::{Span, DUMMY_SP};
|
2016-12-04 01:18:11 +00:00
|
|
|
use syntax::codemap::{self, Spanned};
|
2018-04-25 16:30:39 +00:00
|
|
|
use rustc_target::spec::abi::Abi;
|
2018-05-25 20:53:49 +00:00
|
|
|
use syntax::ast::{self, CrateSugar, Ident, Name, NodeId, DUMMY_NODE_ID, AsmDialect};
|
2015-12-17 17:41:28 +00:00
|
|
|
use syntax::ast::{Attribute, Lit, StrStyle, FloatTy, IntTy, UintTy, MetaItem};
|
2018-01-31 03:39:23 +00:00
|
|
|
use syntax::attr::InlineAttr;
|
2017-03-17 04:04:41 +00:00
|
|
|
use syntax::ext::hygiene::SyntaxContext;
|
2015-07-31 07:04:06 +00:00
|
|
|
use syntax::ptr::P;
|
2016-12-21 10:32:59 +00:00
|
|
|
use syntax::symbol::{Symbol, keywords};
|
2017-02-21 05:05:59 +00:00
|
|
|
use syntax::tokenstream::TokenStream;
|
2016-06-18 04:01:57 +00:00
|
|
|
use syntax::util::ThinVec;
|
2018-01-15 23:09:39 +00:00
|
|
|
use syntax::util::parser::ExprPrecedence;
|
2017-08-16 16:45:54 +00:00
|
|
|
use ty::AdtKind;
|
2018-06-13 13:44:43 +00:00
|
|
|
use ty::query::Providers;
|
2015-07-31 07:04:06 +00:00
|
|
|
|
2017-03-14 14:50:40 +00:00
|
|
|
use rustc_data_structures::indexed_vec;
|
2018-04-25 22:50:33 +00:00
|
|
|
use rustc_data_structures::sync::{ParallelIterator, par_iter, Send, Sync, scope};
|
2017-03-14 14:50:40 +00:00
|
|
|
|
2017-11-14 11:03:57 +00:00
|
|
|
use serialize::{self, Encoder, Encodable, Decoder, Decodable};
|
2016-03-29 05:50:44 +00:00
|
|
|
use std::collections::BTreeMap;
|
2015-07-31 07:04:06 +00:00
|
|
|
use std::fmt;
|
2015-12-01 17:38:40 +00:00
|
|
|
|
2017-07-31 22:46:36 +00:00
|
|
|
/// HIR doesn't commit to a concrete storage type and has its own alias for a vector.
|
2015-12-17 17:41:28 +00:00
|
|
|
/// It can be `Vec`, `P<[T]>` or potentially `Box<[T]>`, or some other container with similar
|
|
|
|
/// behavior. Unlike AST, HIR is mostly a static structure, so we can use an owned slice instead
|
|
|
|
/// of `Vec` to avoid keeping extra capacity.
|
2015-12-19 01:20:11 +00:00
|
|
|
pub type HirVec<T> = P<[T]>;
|
2015-12-17 17:41:28 +00:00
|
|
|
|
|
|
|
macro_rules! hir_vec {
|
|
|
|
($elem:expr; $n:expr) => (
|
|
|
|
$crate::hir::HirVec::from(vec![$elem; $n])
|
|
|
|
);
|
|
|
|
($($x:expr),*) => (
|
|
|
|
$crate::hir::HirVec::from(vec![$($x),*])
|
|
|
|
);
|
2016-03-29 06:32:58 +00:00
|
|
|
($($x:expr,)*) => (hir_vec![$($x),*])
|
2015-12-17 17:41:28 +00:00
|
|
|
}
|
|
|
|
|
2016-03-29 05:50:44 +00:00
|
|
|
pub mod check_attr;
|
2016-03-29 09:54:26 +00:00
|
|
|
pub mod def;
|
|
|
|
pub mod def_id;
|
2016-03-29 05:50:44 +00:00
|
|
|
pub mod intravisit;
|
2016-11-02 22:22:59 +00:00
|
|
|
pub mod itemlikevisit;
|
2016-03-29 05:50:44 +00:00
|
|
|
pub mod lowering;
|
|
|
|
pub mod map;
|
2016-03-29 09:54:26 +00:00
|
|
|
pub mod pat_util;
|
2016-03-29 05:50:44 +00:00
|
|
|
pub mod print;
|
|
|
|
pub mod svh;
|
|
|
|
|
2017-07-31 22:46:36 +00:00
|
|
|
/// A HirId uniquely identifies a node in the HIR of the current crate. It is
|
2017-03-14 14:50:40 +00:00
|
|
|
/// composed of the `owner`, which is the DefIndex of the directly enclosing
|
|
|
|
/// hir::Item, hir::TraitItem, or hir::ImplItem (i.e. the closest "item-like"),
|
|
|
|
/// and the `local_id` which is unique within the given owner.
|
|
|
|
///
|
|
|
|
/// This two-level structure makes for more stable values: One can move an item
|
|
|
|
/// around within the source code, or add or remove stuff before it, without
|
2017-07-31 22:46:36 +00:00
|
|
|
/// the local_id part of the HirId changing, which is a very useful property in
|
2017-03-14 14:50:40 +00:00
|
|
|
/// incremental compilation where we have to persist things through changes to
|
|
|
|
/// the code base.
|
2017-11-14 11:03:57 +00:00
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
|
2017-03-14 14:50:40 +00:00
|
|
|
pub struct HirId {
|
|
|
|
pub owner: DefIndex,
|
|
|
|
pub local_id: ItemLocalId,
|
|
|
|
}
|
|
|
|
|
2017-11-23 13:05:58 +00:00
|
|
|
impl HirId {
|
|
|
|
pub fn owner_def_id(self) -> DefId {
|
|
|
|
DefId::local(self.owner)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn owner_local_def_id(self) -> LocalDefId {
|
|
|
|
LocalDefId::from_def_id(DefId::local(self.owner))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-14 11:03:57 +00:00
|
|
|
impl serialize::UseSpecializedEncodable for HirId {
|
|
|
|
fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
|
|
|
|
let HirId {
|
|
|
|
owner,
|
|
|
|
local_id,
|
|
|
|
} = *self;
|
|
|
|
|
|
|
|
owner.encode(s)?;
|
|
|
|
local_id.encode(s)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl serialize::UseSpecializedDecodable for HirId {
|
|
|
|
fn default_decode<D: Decoder>(d: &mut D) -> Result<HirId, D::Error> {
|
|
|
|
let owner = DefIndex::decode(d)?;
|
|
|
|
let local_id = ItemLocalId::decode(d)?;
|
|
|
|
|
|
|
|
Ok(HirId {
|
|
|
|
owner,
|
|
|
|
local_id
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-03-14 14:50:40 +00:00
|
|
|
/// An `ItemLocalId` uniquely identifies something within a given "item-like",
|
|
|
|
/// that is within a hir::Item, hir::TraitItem, or hir::ImplItem. There is no
|
|
|
|
/// guarantee that the numerical value of a given `ItemLocalId` corresponds to
|
|
|
|
/// the node's position within the owning item in any way, but there is a
|
|
|
|
/// guarantee that the `LocalItemId`s within an owner occupy a dense range of
|
|
|
|
/// integers starting at zero, so a mapping that maps all or most nodes within
|
|
|
|
/// an "item-like" to something else can be implement by a `Vec` instead of a
|
|
|
|
/// tree or hash map.
|
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug,
|
|
|
|
RustcEncodable, RustcDecodable)]
|
|
|
|
pub struct ItemLocalId(pub u32);
|
|
|
|
|
|
|
|
impl ItemLocalId {
|
|
|
|
pub fn as_usize(&self) -> usize {
|
|
|
|
self.0 as usize
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl indexed_vec::Idx for ItemLocalId {
|
|
|
|
fn new(idx: usize) -> Self {
|
|
|
|
debug_assert!((idx as u32) as usize == idx);
|
|
|
|
ItemLocalId(idx as u32)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn index(self) -> usize {
|
|
|
|
self.0 as usize
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// The `HirId` corresponding to CRATE_NODE_ID and CRATE_DEF_INDEX
|
|
|
|
pub const CRATE_HIR_ID: HirId = HirId {
|
|
|
|
owner: CRATE_DEF_INDEX,
|
|
|
|
local_id: ItemLocalId(0)
|
|
|
|
};
|
|
|
|
|
|
|
|
pub const DUMMY_HIR_ID: HirId = HirId {
|
|
|
|
owner: CRATE_DEF_INDEX,
|
2017-08-04 07:49:40 +00:00
|
|
|
local_id: DUMMY_ITEM_LOCAL_ID,
|
2017-03-14 14:50:40 +00:00
|
|
|
};
|
|
|
|
|
2017-08-04 07:49:40 +00:00
|
|
|
pub const DUMMY_ITEM_LOCAL_ID: ItemLocalId = ItemLocalId(!0);
|
|
|
|
|
2018-01-15 22:44:32 +00:00
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
|
|
|
|
pub struct Label {
|
|
|
|
pub name: Name,
|
|
|
|
pub span: Span,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Debug for Label {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
write!(f, "label({:?})", self.name)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-31 07:04:06 +00:00
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
|
|
|
|
pub struct Lifetime {
|
|
|
|
pub id: NodeId,
|
|
|
|
pub span: Span,
|
2017-01-09 15:46:11 +00:00
|
|
|
|
|
|
|
/// Either "'a", referring to a named lifetime definition,
|
|
|
|
/// or "" (aka keywords::Invalid), 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-19 23:36:54 +00:00
|
|
|
pub name: LifetimeName,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
|
|
|
|
pub enum LifetimeName {
|
2018-03-21 20:30:09 +00:00
|
|
|
/// User typed nothing. e.g. the lifetime in `&u32`.
|
2017-09-19 23:36:54 +00:00
|
|
|
Implicit,
|
2018-03-21 20:30:09 +00:00
|
|
|
|
|
|
|
/// User typed `'_`.
|
2017-09-19 23:36:54 +00:00
|
|
|
Underscore,
|
2018-03-21 20:30:09 +00:00
|
|
|
|
2018-03-21 21:12:39 +00: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),
|
|
|
|
|
2018-03-21 20:30:09 +00:00
|
|
|
/// User wrote `'static`
|
2017-09-19 23:36:54 +00:00
|
|
|
Static,
|
2018-03-21 20:30:09 +00:00
|
|
|
|
|
|
|
/// Some user-given name like `'x`
|
2017-09-19 23:36:54 +00:00
|
|
|
Name(Name),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl LifetimeName {
|
|
|
|
pub fn name(&self) -> Name {
|
|
|
|
use self::LifetimeName::*;
|
|
|
|
match *self {
|
|
|
|
Implicit => keywords::Invalid.name(),
|
2018-03-21 21:12:39 +00:00
|
|
|
Fresh(_) | Underscore => keywords::UnderscoreLifetime.name(),
|
2017-09-19 23:36:54 +00:00
|
|
|
Static => keywords::StaticLifetime.name(),
|
|
|
|
Name(name) => name,
|
|
|
|
}
|
|
|
|
}
|
2018-05-25 23:27:54 +00:00
|
|
|
|
|
|
|
fn is_elided(&self) -> bool {
|
|
|
|
use self::LifetimeName::*;
|
|
|
|
match self {
|
|
|
|
Implicit | Underscore => true,
|
|
|
|
|
|
|
|
// 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.
|
|
|
|
Fresh(_) | Static | Name(_) => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn is_static(&self) -> bool {
|
|
|
|
self == &LifetimeName::Static
|
|
|
|
}
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Debug for Lifetime {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2015-09-27 19:23:31 +00:00
|
|
|
write!(f,
|
|
|
|
"lifetime({}: {})",
|
|
|
|
self.id,
|
2016-12-27 08:00:18 +00:00
|
|
|
print::to_string(print::NO_ANN, |s| s.print_lifetime(self)))
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-09 15:46:11 +00:00
|
|
|
impl Lifetime {
|
|
|
|
pub fn is_elided(&self) -> bool {
|
2018-05-25 23:27:54 +00:00
|
|
|
self.name.is_elided()
|
2017-01-09 15:46:11 +00:00
|
|
|
}
|
2017-03-21 12:35:57 +00:00
|
|
|
|
|
|
|
pub fn is_static(&self) -> bool {
|
2018-05-25 23:27:54 +00:00
|
|
|
self.name.is_static()
|
2017-03-21 12:35:57 +00:00
|
|
|
}
|
2017-01-09 15:46:11 +00:00
|
|
|
}
|
|
|
|
|
2015-07-31 07:04:06 +00:00
|
|
|
/// A "Path" is essentially Rust's notion of a name; for instance:
|
2018-01-04 20:23:14 +00:00
|
|
|
/// `std::cmp::PartialEq`. It's represented as a sequence of identifiers,
|
2015-07-31 07:04:06 +00:00
|
|
|
/// along with a bunch of supporting information.
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
|
|
|
|
pub struct Path {
|
|
|
|
pub span: Span,
|
2016-11-25 11:21:19 +00:00
|
|
|
/// The definition that the path resolved to.
|
|
|
|
pub def: Def,
|
2015-07-31 07:04:06 +00:00
|
|
|
/// The segments in the path: the things separated by `::`.
|
2015-12-17 17:41:28 +00:00
|
|
|
pub segments: HirVec<PathSegment>,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2016-12-05 03:51:11 +00:00
|
|
|
impl Path {
|
|
|
|
pub fn is_global(&self) -> bool {
|
|
|
|
!self.segments.is_empty() && self.segments[0].name == keywords::CrateRoot.name()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-31 07:04:06 +00:00
|
|
|
impl fmt::Debug for Path {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2017-11-18 15:49:37 +00:00
|
|
|
write!(f, "path({})", print::to_string(print::NO_ANN, |s| s.print_path(self, false)))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Display for Path {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
write!(f, "{}", print::to_string(print::NO_ANN, |s| s.print_path(self, false)))
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// A segment of a path: an identifier, an optional lifetime, and a set of
|
|
|
|
/// types.
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub struct PathSegment {
|
|
|
|
/// The identifier portion of this path segment.
|
2016-03-06 12:54:44 +00:00
|
|
|
pub name: Name,
|
2015-07-31 07:04:06 +00:00
|
|
|
|
|
|
|
/// Type/lifetime parameters attached to this path. They come in
|
|
|
|
/// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`. Note that
|
|
|
|
/// this is more than just simple syntactic sugar; the use of
|
|
|
|
/// parens affects the region binding rules, so we preserve the
|
|
|
|
/// distinction.
|
2018-02-23 17:48:54 +00:00
|
|
|
pub args: Option<P<GenericArgs>>,
|
2017-09-21 20:24:26 +00:00
|
|
|
|
|
|
|
/// Whether to infer remaining type parameters, if any.
|
|
|
|
/// This only applies to expression and pattern paths, and
|
|
|
|
/// out of those only the segments with no type parameters
|
|
|
|
/// to begin with, e.g. `Vec::new` is `<Vec<..>>::new::<..>`.
|
|
|
|
pub infer_types: bool,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2016-11-25 11:21:19 +00:00
|
|
|
impl PathSegment {
|
|
|
|
/// Convert an identifier to the corresponding segment.
|
|
|
|
pub fn from_name(name: Name) -> PathSegment {
|
|
|
|
PathSegment {
|
2017-07-03 18:19:51 +00:00
|
|
|
name,
|
2017-09-21 20:24:26 +00:00
|
|
|
infer_types: true,
|
2018-02-23 17:48:54 +00:00
|
|
|
args: None,
|
2016-11-25 11:21:19 +00:00
|
|
|
}
|
|
|
|
}
|
2017-09-21 20:24:26 +00:00
|
|
|
|
2018-02-23 17:48:54 +00:00
|
|
|
pub fn new(name: Name, args: GenericArgs, infer_types: bool) -> Self {
|
2017-09-21 20:24:26 +00:00
|
|
|
PathSegment {
|
|
|
|
name,
|
|
|
|
infer_types,
|
2018-02-23 17:48:54 +00:00
|
|
|
args: if args.is_empty() {
|
2017-09-21 20:24:26 +00:00
|
|
|
None
|
|
|
|
} else {
|
2018-02-23 17:48:54 +00:00
|
|
|
Some(P(args))
|
2017-09-21 20:24:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// FIXME: hack required because you can't create a static
|
2018-02-13 11:32:37 +00:00
|
|
|
// GenericArgs, so you can't just return a &GenericArgs.
|
2018-05-16 11:57:45 +00:00
|
|
|
pub fn with_generic_args<F, R>(&self, f: F) -> R
|
2018-02-13 11:32:37 +00:00
|
|
|
where F: FnOnce(&GenericArgs) -> R
|
2017-09-21 20:24:26 +00:00
|
|
|
{
|
2018-02-13 11:32:37 +00:00
|
|
|
let dummy = GenericArgs::none();
|
2018-02-23 17:48:54 +00:00
|
|
|
f(if let Some(ref args) = self.args {
|
|
|
|
&args
|
2017-09-21 20:24:26 +00:00
|
|
|
} else {
|
|
|
|
&dummy
|
|
|
|
})
|
|
|
|
}
|
2016-11-25 11:21:19 +00:00
|
|
|
}
|
|
|
|
|
2018-02-08 08:58:13 +00:00
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
2018-02-13 11:32:37 +00:00
|
|
|
pub enum GenericArg {
|
2018-02-08 08:58:13 +00:00
|
|
|
Lifetime(Lifetime),
|
|
|
|
Type(P<Ty>),
|
|
|
|
}
|
|
|
|
|
2015-07-31 07:04:06 +00:00
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
2018-02-13 11:32:37 +00:00
|
|
|
pub struct GenericArgs {
|
2018-02-23 17:48:54 +00:00
|
|
|
/// The generic arguments for this path segment.
|
|
|
|
pub args: HirVec<GenericArg>,
|
2015-07-31 07:04:06 +00:00
|
|
|
/// Bindings (equality constraints) on associated types, if present.
|
|
|
|
/// E.g., `Foo<A=Bar>`.
|
2015-12-19 01:20:11 +00:00
|
|
|
pub bindings: HirVec<TypeBinding>,
|
2018-02-23 17:48:54 +00:00
|
|
|
/// Were arguments written in parenthesized form `Fn(T) -> U`?
|
2017-07-28 22:13:40 +00:00
|
|
|
/// This is required mostly for pretty-printing and diagnostics,
|
|
|
|
/// but also for changing lifetime elision rules to be "function-like".
|
|
|
|
pub parenthesized: bool,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2018-02-13 11:32:37 +00:00
|
|
|
impl GenericArgs {
|
2017-07-28 22:13:40 +00:00
|
|
|
pub fn none() -> Self {
|
|
|
|
Self {
|
2018-02-23 17:48:54 +00:00
|
|
|
args: HirVec::new(),
|
2017-07-28 22:13:40 +00:00
|
|
|
bindings: HirVec::new(),
|
|
|
|
parenthesized: false,
|
|
|
|
}
|
|
|
|
}
|
2015-07-31 07:04:06 +00:00
|
|
|
|
2017-09-21 20:24:26 +00:00
|
|
|
pub fn is_empty(&self) -> bool {
|
2018-02-23 17:48:54 +00:00
|
|
|
self.args.is_empty() && self.bindings.is_empty() && !self.parenthesized
|
2017-09-21 20:24:26 +00:00
|
|
|
}
|
|
|
|
|
2017-07-28 22:13:40 +00:00
|
|
|
pub fn inputs(&self) -> &[P<Ty>] {
|
|
|
|
if self.parenthesized {
|
2018-02-13 11:32:37 +00:00
|
|
|
if let Some(ref ty) = self.types().next() {
|
2017-07-28 22:13:40 +00:00
|
|
|
if let TyTup(ref tys) = ty.node {
|
|
|
|
return tys;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-02-13 11:32:37 +00:00
|
|
|
bug!("GenericArgs::inputs: not a `Fn(T) -> U`");
|
2017-07-28 22:13:40 +00:00
|
|
|
}
|
2018-02-08 08:58:13 +00:00
|
|
|
|
2018-02-13 11:32:37 +00:00
|
|
|
pub fn lifetimes(&self) -> impl DoubleEndedIterator<Item = &Lifetime> {
|
2018-02-23 17:48:54 +00:00
|
|
|
self.args.iter().filter_map(|p| {
|
2018-02-13 11:32:37 +00:00
|
|
|
if let GenericArg::Lifetime(lt) = p {
|
2018-02-08 08:58:13 +00:00
|
|
|
Some(lt)
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
2018-02-13 11:32:37 +00:00
|
|
|
})
|
2018-02-08 08:58:13 +00:00
|
|
|
}
|
|
|
|
|
2018-02-13 11:32:37 +00:00
|
|
|
pub fn types(&self) -> impl DoubleEndedIterator<Item = &P<Ty>> {
|
2018-02-23 17:48:54 +00:00
|
|
|
self.args.iter().filter_map(|p| {
|
2018-02-13 11:32:37 +00:00
|
|
|
if let GenericArg::Type(ty) = p {
|
2018-02-08 08:58:13 +00:00
|
|
|
Some(ty)
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
2018-02-13 11:32:37 +00:00
|
|
|
})
|
2018-02-08 08:58:13 +00:00
|
|
|
}
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// The AST represents all type param bounds as types.
|
|
|
|
/// typeck::collect::compute_bounds matches these against
|
|
|
|
/// the "special" built-in traits (see middle::lang_items) and
|
|
|
|
/// detects Copy, Send and Sync.
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub enum TyParamBound {
|
|
|
|
TraitTyParamBound(PolyTraitRef, TraitBoundModifier),
|
2015-09-27 19:23:31 +00:00
|
|
|
RegionTyParamBound(Lifetime),
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2018-03-10 12:32:11 +00:00
|
|
|
impl TyParamBound {
|
|
|
|
pub fn span(&self) -> Span {
|
|
|
|
match self {
|
|
|
|
&TraitTyParamBound(ref t, ..) => t.span,
|
|
|
|
&RegionTyParamBound(ref l) => l.span,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-31 07:04:06 +00:00
|
|
|
/// A modifier on a bound, currently this is only used for `?Sized`, where the
|
|
|
|
/// modifier is `Maybe`. Negative bounds should also be handled here.
|
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub enum TraitBoundModifier {
|
|
|
|
None,
|
|
|
|
Maybe,
|
|
|
|
}
|
|
|
|
|
2015-12-19 01:20:11 +00:00
|
|
|
pub type TyParamBounds = HirVec<TyParamBound>;
|
2015-07-31 07:04:06 +00:00
|
|
|
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
2018-05-25 23:27:54 +00:00
|
|
|
pub enum GenericParamKind {
|
|
|
|
/// A lifetime definition, eg `'a: 'b + 'c + 'd`.
|
|
|
|
Lifetime {
|
|
|
|
/// Either "'a", referring to a named lifetime definition,
|
|
|
|
/// or "" (aka keywords::Invalid), 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`.
|
|
|
|
name: LifetimeName,
|
|
|
|
bounds: HirVec<Lifetime>,
|
|
|
|
// Indicates that the lifetime definition was synthetically added
|
|
|
|
// as a result of an in-band lifetime usage like:
|
|
|
|
// `fn foo(x: &'a u8) -> &'a u8 { x }`
|
|
|
|
in_band: bool,
|
|
|
|
// We keep a `Lifetime` around for now just so we can `visit_lifetime`.
|
|
|
|
lifetime_deprecated: Lifetime,
|
|
|
|
},
|
|
|
|
Type {
|
|
|
|
name: Name,
|
|
|
|
bounds: TyParamBounds,
|
|
|
|
default: Option<P<Ty>>,
|
|
|
|
synthetic: Option<SyntheticTyParamKind>,
|
|
|
|
attrs: HirVec<Attribute>,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub struct GenericParam {
|
2015-07-31 07:04:06 +00:00
|
|
|
pub id: NodeId,
|
2015-09-27 19:23:31 +00:00
|
|
|
pub span: Span,
|
2016-10-11 14:06:43 +00:00
|
|
|
pub pure_wrt_drop: bool,
|
2015-07-31 07:04:06 +00:00
|
|
|
|
2018-05-25 23:27:54 +00:00
|
|
|
pub kind: GenericParamKind,
|
2017-10-16 19:07:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl GenericParam {
|
|
|
|
pub fn is_lifetime_param(&self) -> bool {
|
2018-05-25 23:27:54 +00:00
|
|
|
match self.kind {
|
|
|
|
GenericParamKind::Lifetime { .. } => true,
|
2017-10-16 19:07:26 +00:00
|
|
|
_ => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn is_type_param(&self) -> bool {
|
2018-05-25 23:27:54 +00:00
|
|
|
match self.kind {
|
|
|
|
GenericParamKind::Type { .. } => true,
|
2017-10-16 19:07:26 +00:00
|
|
|
_ => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-25 23:27:54 +00:00
|
|
|
pub fn name(&self) -> Name {
|
|
|
|
match self.kind {
|
|
|
|
GenericParamKind::Lifetime { name, .. } => name.name(),
|
|
|
|
GenericParamKind::Type { name, .. } => name,
|
|
|
|
}
|
2017-10-16 19:07:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-31 07:04:06 +00:00
|
|
|
/// Represents lifetimes and type parameters attached to a declaration
|
|
|
|
/// of a function, enum, trait, etc.
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub struct Generics {
|
2017-10-16 19:07:26 +00:00
|
|
|
pub params: HirVec<GenericParam>,
|
2015-07-31 07:04:06 +00:00
|
|
|
pub where_clause: WhereClause,
|
2016-08-10 17:39:12 +00:00
|
|
|
pub span: Span,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Generics {
|
2016-03-29 06:32:58 +00:00
|
|
|
pub fn empty() -> Generics {
|
|
|
|
Generics {
|
2017-10-16 19:07:26 +00:00
|
|
|
params: HirVec::new(),
|
2016-03-29 06:32:58 +00:00
|
|
|
where_clause: WhereClause {
|
|
|
|
id: DUMMY_NODE_ID,
|
|
|
|
predicates: HirVec::new(),
|
|
|
|
},
|
2016-08-10 17:39:12 +00:00
|
|
|
span: DUMMY_SP,
|
2016-03-29 06:32:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-31 07:04:06 +00:00
|
|
|
pub fn is_lt_parameterized(&self) -> bool {
|
2018-05-25 23:27:54 +00:00
|
|
|
self.params.iter().any(|param| {
|
|
|
|
match param.kind {
|
|
|
|
GenericParamKind::Lifetime { .. } => true,
|
|
|
|
_ => false,
|
|
|
|
}
|
|
|
|
})
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2016-03-29 06:32:58 +00:00
|
|
|
|
2015-07-31 07:04:06 +00:00
|
|
|
pub fn is_type_parameterized(&self) -> bool {
|
2018-05-25 23:27:54 +00:00
|
|
|
self.params.iter().any(|param| {
|
|
|
|
match param.kind {
|
|
|
|
GenericParamKind::Type { .. } => true,
|
|
|
|
_ => false,
|
|
|
|
}
|
|
|
|
})
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2018-05-25 23:27:54 +00:00
|
|
|
pub fn lifetimes<'a>(&'a self) -> impl DoubleEndedIterator<Item = &'a GenericParam> {
|
|
|
|
self.params.iter().filter(|param| {
|
|
|
|
match param.kind {
|
|
|
|
GenericParamKind::Lifetime { .. } => true,
|
|
|
|
_ => false,
|
|
|
|
}
|
|
|
|
})
|
2016-10-12 12:23:38 +00:00
|
|
|
}
|
|
|
|
|
2018-05-25 23:27:54 +00:00
|
|
|
pub fn ty_params<'a>(&'a self) -> impl DoubleEndedIterator<Item = &'a GenericParam> {
|
|
|
|
self.params.iter().filter(|param| {
|
|
|
|
match param.kind {
|
|
|
|
GenericParamKind::Type { .. } => true,
|
|
|
|
_ => false,
|
2016-10-12 12:23:38 +00:00
|
|
|
}
|
2018-05-25 23:27:54 +00:00
|
|
|
})
|
2016-10-12 12:23:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-09-26 09:43:33 +00:00
|
|
|
/// Synthetic Type Parameters are converted to an other form during lowering, this allows
|
2018-02-16 14:56:50 +00:00
|
|
|
/// to track the original form they had. Useful for error messages.
|
2017-09-26 09:43:33 +00:00
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub enum SyntheticTyParamKind {
|
|
|
|
ImplTrait
|
|
|
|
}
|
|
|
|
|
2015-07-31 07:04:06 +00:00
|
|
|
/// A `where` clause in a definition
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub struct WhereClause {
|
|
|
|
pub id: NodeId,
|
2015-12-17 17:41:28 +00:00
|
|
|
pub predicates: HirVec<WherePredicate>,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2018-05-23 02:27:41 +00:00
|
|
|
impl WhereClause {
|
|
|
|
pub fn span(&self) -> Option<Span> {
|
|
|
|
self.predicates.iter().map(|predicate| predicate.span())
|
|
|
|
.fold(None, |acc, i| match (acc, i) {
|
|
|
|
(None, i) => Some(i),
|
|
|
|
(Some(acc), i) => {
|
|
|
|
Some(acc.to(i))
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-31 07:04:06 +00:00
|
|
|
/// A single predicate in a `where` clause
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub enum WherePredicate {
|
|
|
|
/// A type binding, eg `for<'c> Foo: Send+Clone+'c`
|
|
|
|
BoundPredicate(WhereBoundPredicate),
|
|
|
|
/// A lifetime predicate, e.g. `'a: 'b+'c`
|
|
|
|
RegionPredicate(WhereRegionPredicate),
|
|
|
|
/// An equality predicate (unsupported)
|
2015-09-27 19:23:31 +00:00
|
|
|
EqPredicate(WhereEqPredicate),
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2018-03-10 12:32:11 +00:00
|
|
|
impl WherePredicate {
|
|
|
|
pub fn span(&self) -> Span {
|
|
|
|
match self {
|
|
|
|
&WherePredicate::BoundPredicate(ref p) => p.span,
|
|
|
|
&WherePredicate::RegionPredicate(ref p) => p.span,
|
|
|
|
&WherePredicate::EqPredicate(ref p) => p.span,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-31 07:04:06 +00:00
|
|
|
/// A type bound, eg `for<'c> Foo: Send+Clone+'c`
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub struct WhereBoundPredicate {
|
|
|
|
pub span: Span,
|
2017-10-16 19:07:26 +00:00
|
|
|
/// Any generics from a `for` binding
|
|
|
|
pub bound_generic_params: HirVec<GenericParam>,
|
2015-07-31 07:04:06 +00:00
|
|
|
/// The type being bounded
|
|
|
|
pub bounded_ty: P<Ty>,
|
|
|
|
/// Trait and lifetime bounds (`Clone+Send+'static`)
|
2015-12-16 18:44:33 +00:00
|
|
|
pub bounds: TyParamBounds,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// A lifetime predicate, e.g. `'a: 'b+'c`
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub struct WhereRegionPredicate {
|
|
|
|
pub span: Span,
|
|
|
|
pub lifetime: Lifetime,
|
2015-12-17 17:41:28 +00:00
|
|
|
pub bounds: HirVec<Lifetime>,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// An equality predicate (unsupported), e.g. `T=int`
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub struct WhereEqPredicate {
|
|
|
|
pub id: NodeId,
|
|
|
|
pub span: Span,
|
2017-01-16 18:32:13 +00:00
|
|
|
pub lhs_ty: P<Ty>,
|
|
|
|
pub rhs_ty: P<Ty>,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2015-12-17 17:41:28 +00:00
|
|
|
pub type CrateConfig = HirVec<P<MetaItem>>;
|
|
|
|
|
2017-08-31 18:33:19 +00:00
|
|
|
/// The top-level data structure that stores the entire contents of
|
|
|
|
/// the crate currently being compiled.
|
|
|
|
///
|
2018-02-25 21:24:14 +00:00
|
|
|
/// For more details, see the [rustc guide].
|
2017-12-31 16:08:04 +00:00
|
|
|
///
|
2018-02-25 21:24:14 +00:00
|
|
|
/// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/hir.html
|
2015-11-17 22:32:12 +00:00
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug)]
|
2015-07-31 07:04:06 +00:00
|
|
|
pub struct Crate {
|
|
|
|
pub module: Mod,
|
2015-12-17 17:41:28 +00:00
|
|
|
pub attrs: HirVec<Attribute>,
|
2015-07-31 07:04:06 +00:00
|
|
|
pub span: Span,
|
2015-12-17 17:41:28 +00:00
|
|
|
pub exported_macros: HirVec<MacroDef>,
|
2015-11-18 09:16:25 +00:00
|
|
|
|
|
|
|
// NB: 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
|
|
|
|
// detected, which in turn can make compile-fail tests yield
|
|
|
|
// slightly different results.
|
|
|
|
pub items: BTreeMap<NodeId, Item>,
|
2016-11-02 22:25:31 +00:00
|
|
|
|
2016-12-04 02:21:06 +00:00
|
|
|
pub trait_items: BTreeMap<TraitItemId, TraitItem>,
|
2016-11-02 22:25:31 +00:00
|
|
|
pub impl_items: BTreeMap<ImplItemId, ImplItem>,
|
2017-02-21 15:55:40 +00:00
|
|
|
pub bodies: BTreeMap<BodyId, Body>,
|
2017-02-19 12:46:29 +00:00
|
|
|
pub trait_impls: BTreeMap<DefId, Vec<NodeId>>,
|
2017-10-09 16:59:20 +00:00
|
|
|
pub trait_auto_impl: BTreeMap<DefId, NodeId>,
|
2017-02-21 17:23:47 +00:00
|
|
|
|
|
|
|
/// A list of the body ids written out in the order in which they
|
|
|
|
/// appear in the crate. If you're going to process all the bodies
|
|
|
|
/// in the crate, you should iterate over this list rather than the keys
|
|
|
|
/// of bodies.
|
|
|
|
pub body_ids: Vec<BodyId>,
|
2015-11-17 22:32:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Crate {
|
|
|
|
pub fn item(&self, id: NodeId) -> &Item {
|
|
|
|
&self.items[&id]
|
|
|
|
}
|
|
|
|
|
2016-12-04 02:21:06 +00:00
|
|
|
pub fn trait_item(&self, id: TraitItemId) -> &TraitItem {
|
|
|
|
&self.trait_items[&id]
|
|
|
|
}
|
|
|
|
|
2016-11-02 22:25:31 +00:00
|
|
|
pub fn impl_item(&self, id: ImplItemId) -> &ImplItem {
|
|
|
|
&self.impl_items[&id]
|
|
|
|
}
|
|
|
|
|
2017-08-11 18:34:14 +00:00
|
|
|
/// Visits all items in the crate in some deterministic (but
|
2015-11-17 22:32:12 +00:00
|
|
|
/// unspecified) order. If you just need to process every item,
|
|
|
|
/// but don't care about nesting, this method is the best choice.
|
|
|
|
///
|
|
|
|
/// If you do care about nesting -- usually because your algorithm
|
|
|
|
/// follows lexical scoping rules -- then you want a different
|
|
|
|
/// approach. You should override `visit_nested_item` in your
|
|
|
|
/// visitor and then call `intravisit::walk_crate` instead.
|
2016-11-02 22:22:59 +00:00
|
|
|
pub fn visit_all_item_likes<'hir, V>(&'hir self, visitor: &mut V)
|
|
|
|
where V: itemlikevisit::ItemLikeVisitor<'hir>
|
2016-03-29 05:50:44 +00:00
|
|
|
{
|
2015-11-18 09:16:25 +00:00
|
|
|
for (_, item) in &self.items {
|
2015-11-17 22:32:12 +00:00
|
|
|
visitor.visit_item(item);
|
|
|
|
}
|
2016-11-02 22:25:31 +00:00
|
|
|
|
2016-12-04 02:21:06 +00:00
|
|
|
for (_, trait_item) in &self.trait_items {
|
|
|
|
visitor.visit_trait_item(trait_item);
|
|
|
|
}
|
|
|
|
|
2016-11-02 22:25:31 +00:00
|
|
|
for (_, impl_item) in &self.impl_items {
|
|
|
|
visitor.visit_impl_item(impl_item);
|
|
|
|
}
|
2015-11-17 22:32:12 +00:00
|
|
|
}
|
2016-10-28 20:58:32 +00:00
|
|
|
|
2018-04-25 22:50:33 +00:00
|
|
|
/// A parallel version of visit_all_item_likes
|
|
|
|
pub fn par_visit_all_item_likes<'hir, V>(&'hir self, visitor: &V)
|
|
|
|
where V: itemlikevisit::ParItemLikeVisitor<'hir> + Sync + Send
|
|
|
|
{
|
|
|
|
scope(|s| {
|
|
|
|
s.spawn(|_| {
|
|
|
|
par_iter(&self.items).for_each(|(_, item)| {
|
|
|
|
visitor.visit_item(item);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
s.spawn(|_| {
|
|
|
|
par_iter(&self.trait_items).for_each(|(_, trait_item)| {
|
|
|
|
visitor.visit_trait_item(trait_item);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
s.spawn(|_| {
|
|
|
|
par_iter(&self.impl_items).for_each(|(_, impl_item)| {
|
|
|
|
visitor.visit_impl_item(impl_item);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2016-12-21 10:32:59 +00:00
|
|
|
pub fn body(&self, id: BodyId) -> &Body {
|
|
|
|
&self.bodies[&id]
|
2016-10-28 20:58:32 +00:00
|
|
|
}
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// A macro definition, in this crate or imported from another.
|
|
|
|
///
|
|
|
|
/// Not parsed directly, but created on macro import or `macro_rules!` expansion.
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub struct MacroDef {
|
2015-09-20 11:51:40 +00:00
|
|
|
pub name: Name,
|
2017-03-25 01:46:38 +00:00
|
|
|
pub vis: Visibility,
|
2015-12-17 17:41:28 +00:00
|
|
|
pub attrs: HirVec<Attribute>,
|
2015-07-31 07:04:06 +00:00
|
|
|
pub id: NodeId,
|
|
|
|
pub span: Span,
|
2017-02-21 05:05:59 +00:00
|
|
|
pub body: TokenStream,
|
2017-03-18 01:55:51 +00:00
|
|
|
pub legacy: bool,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub struct Block {
|
|
|
|
/// Statements in a block
|
2015-12-17 17:41:28 +00:00
|
|
|
pub stmts: HirVec<Stmt>,
|
2015-07-31 07:04:06 +00:00
|
|
|
/// An expression at the end of the block
|
|
|
|
/// without a semicolon, if any
|
|
|
|
pub expr: Option<P<Expr>>,
|
|
|
|
pub id: NodeId,
|
2017-08-04 07:49:40 +00:00
|
|
|
pub hir_id: HirId,
|
2015-07-31 07:04:06 +00:00
|
|
|
/// Distinguishes between `unsafe { ... }` and `{ ... }`
|
|
|
|
pub rules: BlockCheckMode,
|
|
|
|
pub span: Span,
|
2017-03-22 15:40:29 +00:00
|
|
|
/// If true, then there may exist `break 'a` values that aim to
|
2018-04-25 17:28:04 +00:00
|
|
|
/// break out of this block early.
|
2018-05-16 07:18:26 +00:00
|
|
|
/// Used by `'label: {}` blocks and by `catch` statements.
|
2017-03-22 15:40:29 +00:00
|
|
|
pub targeted_by_break: bool,
|
2017-12-14 07:05:49 +00:00
|
|
|
/// If true, don't emit return value type errors as the parser had
|
|
|
|
/// to recover from a parse error so this block will not have an
|
|
|
|
/// appropriate type. A parse error will have been emitted so the
|
|
|
|
/// compilation will never succeed if this is true.
|
|
|
|
pub recovered: bool,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
|
|
|
|
pub struct Pat {
|
|
|
|
pub id: NodeId,
|
2017-08-04 07:49:40 +00:00
|
|
|
pub hir_id: HirId,
|
2016-02-14 12:25:12 +00:00
|
|
|
pub node: PatKind,
|
2015-07-31 07:04:06 +00:00
|
|
|
pub span: Span,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Debug for Pat {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2016-12-27 08:00:18 +00:00
|
|
|
write!(f, "pat({}: {})", self.id,
|
|
|
|
print::to_string(print::NO_ANN, |s| s.print_pat(self)))
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-29 06:32:58 +00:00
|
|
|
impl Pat {
|
|
|
|
// FIXME(#19596) this is a workaround, but there should be a better way
|
|
|
|
fn walk_<G>(&self, it: &mut G) -> bool
|
|
|
|
where G: FnMut(&Pat) -> bool
|
|
|
|
{
|
|
|
|
if !it(self) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
match self.node {
|
2016-08-26 16:23:42 +00:00
|
|
|
PatKind::Binding(.., Some(ref p)) => p.walk_(it),
|
2016-03-29 06:32:58 +00:00
|
|
|
PatKind::Struct(_, ref fields, _) => {
|
|
|
|
fields.iter().all(|field| field.node.pat.walk_(it))
|
|
|
|
}
|
2016-03-06 12:54:44 +00:00
|
|
|
PatKind::TupleStruct(_, ref s, _) | PatKind::Tuple(ref s, _) => {
|
2016-03-29 06:32:58 +00:00
|
|
|
s.iter().all(|p| p.walk_(it))
|
|
|
|
}
|
|
|
|
PatKind::Box(ref s) | PatKind::Ref(ref s, _) => {
|
|
|
|
s.walk_(it)
|
|
|
|
}
|
2016-09-20 00:14:46 +00:00
|
|
|
PatKind::Slice(ref before, ref slice, ref after) => {
|
2016-03-29 06:32:58 +00:00
|
|
|
before.iter().all(|p| p.walk_(it)) &&
|
|
|
|
slice.iter().all(|p| p.walk_(it)) &&
|
|
|
|
after.iter().all(|p| p.walk_(it))
|
|
|
|
}
|
|
|
|
PatKind::Wild |
|
|
|
|
PatKind::Lit(_) |
|
2016-08-26 16:23:42 +00:00
|
|
|
PatKind::Range(..) |
|
2016-03-06 12:54:44 +00:00
|
|
|
PatKind::Binding(..) |
|
2016-10-27 02:17:42 +00:00
|
|
|
PatKind::Path(_) => {
|
2016-03-29 06:32:58 +00:00
|
|
|
true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn walk<F>(&self, mut it: F) -> bool
|
|
|
|
where F: FnMut(&Pat) -> bool
|
|
|
|
{
|
|
|
|
self.walk_(&mut it)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-31 07:04:06 +00:00
|
|
|
/// A single field in a struct pattern
|
|
|
|
///
|
|
|
|
/// Patterns like the fields of Foo `{ x, ref y, ref mut z }`
|
|
|
|
/// are treated the same as` x: x, y: ref y, z: ref mut z`,
|
|
|
|
/// except is_shorthand is true
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub struct FieldPat {
|
2018-04-05 00:20:21 +00:00
|
|
|
pub id: NodeId,
|
2015-07-31 07:04:06 +00:00
|
|
|
/// The identifier for the field
|
2018-05-25 23:50:15 +00:00
|
|
|
pub ident: Ident,
|
2015-07-31 07:04:06 +00:00
|
|
|
/// The pattern the field is destructured to
|
|
|
|
pub pat: P<Pat>,
|
|
|
|
pub is_shorthand: bool,
|
|
|
|
}
|
|
|
|
|
2017-07-21 23:29:43 +00:00
|
|
|
/// Explicit binding annotations given in the HIR for a binding. Note
|
|
|
|
/// that this is not the final binding *mode* that we infer after type
|
|
|
|
/// inference.
|
2015-07-31 07:04:06 +00:00
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
|
2017-07-21 23:29:43 +00:00
|
|
|
pub enum BindingAnnotation {
|
|
|
|
/// 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,
|
|
|
|
|
|
|
|
/// Annotated with `mut x` -- could be either ref or not, similar to `None`.
|
|
|
|
Mutable,
|
|
|
|
|
|
|
|
/// Annotated as `ref`, like `ref x`
|
|
|
|
Ref,
|
|
|
|
|
|
|
|
/// Annotated as `ref mut x`.
|
|
|
|
RefMut,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2017-08-03 21:41:44 +00:00
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
2017-01-10 21:13:53 +00:00
|
|
|
pub enum RangeEnd {
|
|
|
|
Included,
|
|
|
|
Excluded,
|
|
|
|
}
|
|
|
|
|
2015-07-31 07:04:06 +00:00
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
2016-02-14 12:25:12 +00:00
|
|
|
pub enum PatKind {
|
2015-10-31 00:44:43 +00:00
|
|
|
/// Represents a wildcard pattern (`_`)
|
2016-02-14 12:25:12 +00:00
|
|
|
Wild,
|
2015-07-31 07:04:06 +00:00
|
|
|
|
2016-03-06 12:54:44 +00:00
|
|
|
/// A fresh binding `ref mut binding @ OPT_SUBPATTERN`.
|
2017-04-29 11:39:47 +00:00
|
|
|
/// The `NodeId` is the canonical ID for the variable being bound,
|
|
|
|
/// e.g. in `Ok(x) | Err(x)`, both `x` use the same canonical ID,
|
|
|
|
/// which is the pattern ID of the first `x`.
|
|
|
|
Binding(BindingAnnotation, NodeId, Spanned<Name>, Option<P<Pat>>),
|
2015-07-31 07:04:06 +00:00
|
|
|
|
2016-02-15 21:40:38 +00:00
|
|
|
/// A struct or struct variant pattern, e.g. `Variant {x, y, ..}`.
|
|
|
|
/// The `bool` is `true` in the presence of a `..`.
|
2016-10-27 02:17:42 +00:00
|
|
|
Struct(QPath, HirVec<Spanned<FieldPat>>, bool),
|
2016-02-15 21:40:38 +00:00
|
|
|
|
2016-03-06 12:54:44 +00:00
|
|
|
/// A tuple struct/variant pattern `Variant(x, y, .., z)`.
|
2016-03-06 12:54:44 +00:00
|
|
|
/// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
|
2016-03-06 12:54:44 +00:00
|
|
|
/// 0 <= position <= subpats.len()
|
2016-10-27 02:17:42 +00:00
|
|
|
TupleStruct(QPath, HirVec<P<Pat>>, Option<usize>),
|
2016-02-15 21:40:38 +00:00
|
|
|
|
2016-10-27 02:17:42 +00:00
|
|
|
/// A path pattern for an unit struct/variant or a (maybe-associated) constant.
|
|
|
|
Path(QPath),
|
2015-07-31 07:04:06 +00:00
|
|
|
|
2016-03-06 12:54:44 +00:00
|
|
|
/// A tuple pattern `(a, b)`.
|
2016-03-06 12:54:44 +00:00
|
|
|
/// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
|
2016-03-06 12:54:44 +00:00
|
|
|
/// 0 <= position <= subpats.len()
|
|
|
|
Tuple(HirVec<P<Pat>>, Option<usize>),
|
2015-07-31 07:04:06 +00:00
|
|
|
/// A `box` pattern
|
2016-02-14 12:25:12 +00:00
|
|
|
Box(P<Pat>),
|
2015-07-31 07:04:06 +00:00
|
|
|
/// A reference pattern, e.g. `&mut (a, b)`
|
2016-02-14 12:25:12 +00:00
|
|
|
Ref(P<Pat>, Mutability),
|
2015-07-31 07:04:06 +00:00
|
|
|
/// A literal
|
2016-02-14 12:25:12 +00:00
|
|
|
Lit(P<Expr>),
|
2017-01-10 21:13:53 +00:00
|
|
|
/// A range pattern, e.g. `1...2` or `1..2`
|
|
|
|
Range(P<Expr>, P<Expr>, RangeEnd),
|
2015-11-01 11:07:12 +00:00
|
|
|
/// `[a, b, ..i, y, z]` is represented as:
|
2016-09-20 00:14:46 +00:00
|
|
|
/// `PatKind::Slice(box [a, b], Some(i), box [y, z])`
|
|
|
|
Slice(HirVec<P<Pat>>, Option<P<Pat>>, HirVec<P<Pat>>),
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2018-05-17 21:42:02 +00:00
|
|
|
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
|
2015-07-31 07:04:06 +00:00
|
|
|
pub enum Mutability {
|
|
|
|
MutMutable,
|
|
|
|
MutImmutable,
|
|
|
|
}
|
|
|
|
|
2017-07-21 19:43:09 +00:00
|
|
|
impl Mutability {
|
|
|
|
/// Return MutMutable only if both arguments are mutable.
|
|
|
|
pub fn and(self, other: Self) -> Self {
|
|
|
|
match self {
|
|
|
|
MutMutable => other,
|
|
|
|
MutImmutable => MutImmutable,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-31 07:04:06 +00:00
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
|
|
|
|
pub enum BinOp_ {
|
|
|
|
/// The `+` operator (addition)
|
|
|
|
BiAdd,
|
|
|
|
/// The `-` operator (subtraction)
|
|
|
|
BiSub,
|
|
|
|
/// The `*` operator (multiplication)
|
|
|
|
BiMul,
|
|
|
|
/// The `/` operator (division)
|
|
|
|
BiDiv,
|
|
|
|
/// The `%` operator (modulus)
|
|
|
|
BiRem,
|
|
|
|
/// The `&&` operator (logical and)
|
|
|
|
BiAnd,
|
|
|
|
/// The `||` operator (logical or)
|
|
|
|
BiOr,
|
|
|
|
/// The `^` operator (bitwise xor)
|
|
|
|
BiBitXor,
|
|
|
|
/// The `&` operator (bitwise and)
|
|
|
|
BiBitAnd,
|
|
|
|
/// The `|` operator (bitwise or)
|
|
|
|
BiBitOr,
|
|
|
|
/// The `<<` operator (shift left)
|
|
|
|
BiShl,
|
|
|
|
/// The `>>` operator (shift right)
|
|
|
|
BiShr,
|
|
|
|
/// The `==` operator (equality)
|
|
|
|
BiEq,
|
|
|
|
/// The `<` operator (less than)
|
|
|
|
BiLt,
|
|
|
|
/// The `<=` operator (less than or equal to)
|
|
|
|
BiLe,
|
|
|
|
/// The `!=` operator (not equal to)
|
|
|
|
BiNe,
|
|
|
|
/// The `>=` operator (greater than or equal to)
|
|
|
|
BiGe,
|
|
|
|
/// The `>` operator (greater than)
|
|
|
|
BiGt,
|
|
|
|
}
|
|
|
|
|
2016-03-29 06:32:58 +00:00
|
|
|
impl BinOp_ {
|
|
|
|
pub fn as_str(self) -> &'static str {
|
|
|
|
match self {
|
|
|
|
BiAdd => "+",
|
|
|
|
BiSub => "-",
|
|
|
|
BiMul => "*",
|
|
|
|
BiDiv => "/",
|
|
|
|
BiRem => "%",
|
|
|
|
BiAnd => "&&",
|
|
|
|
BiOr => "||",
|
|
|
|
BiBitXor => "^",
|
|
|
|
BiBitAnd => "&",
|
|
|
|
BiBitOr => "|",
|
|
|
|
BiShl => "<<",
|
|
|
|
BiShr => ">>",
|
|
|
|
BiEq => "==",
|
|
|
|
BiLt => "<",
|
|
|
|
BiLe => "<=",
|
|
|
|
BiNe => "!=",
|
|
|
|
BiGe => ">=",
|
|
|
|
BiGt => ">",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn is_lazy(self) -> bool {
|
|
|
|
match self {
|
|
|
|
BiAnd | BiOr => true,
|
|
|
|
_ => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn is_shift(self) -> bool {
|
|
|
|
match self {
|
|
|
|
BiShl | BiShr => true,
|
|
|
|
_ => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn is_comparison(self) -> bool {
|
|
|
|
match self {
|
|
|
|
BiEq | BiLt | BiLe | BiNe | BiGt | BiGe => true,
|
|
|
|
BiAnd |
|
|
|
|
BiOr |
|
|
|
|
BiAdd |
|
|
|
|
BiSub |
|
|
|
|
BiMul |
|
|
|
|
BiDiv |
|
|
|
|
BiRem |
|
|
|
|
BiBitXor |
|
|
|
|
BiBitAnd |
|
|
|
|
BiBitOr |
|
|
|
|
BiShl |
|
|
|
|
BiShr => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns `true` if the binary operator takes its arguments by value
|
|
|
|
pub fn is_by_value(self) -> bool {
|
|
|
|
!self.is_comparison()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-10 19:40:16 +00:00
|
|
|
impl Into<ast::BinOpKind> for BinOp_ {
|
|
|
|
fn into(self) -> ast::BinOpKind {
|
|
|
|
match self {
|
|
|
|
BiAdd => ast::BinOpKind::Add,
|
|
|
|
BiSub => ast::BinOpKind::Sub,
|
|
|
|
BiMul => ast::BinOpKind::Mul,
|
|
|
|
BiDiv => ast::BinOpKind::Div,
|
|
|
|
BiRem => ast::BinOpKind::Rem,
|
|
|
|
BiAnd => ast::BinOpKind::And,
|
|
|
|
BiOr => ast::BinOpKind::Or,
|
|
|
|
BiBitXor => ast::BinOpKind::BitXor,
|
|
|
|
BiBitAnd => ast::BinOpKind::BitAnd,
|
|
|
|
BiBitOr => ast::BinOpKind::BitOr,
|
|
|
|
BiShl => ast::BinOpKind::Shl,
|
|
|
|
BiShr => ast::BinOpKind::Shr,
|
|
|
|
BiEq => ast::BinOpKind::Eq,
|
|
|
|
BiLt => ast::BinOpKind::Lt,
|
|
|
|
BiLe => ast::BinOpKind::Le,
|
|
|
|
BiNe => ast::BinOpKind::Ne,
|
|
|
|
BiGe => ast::BinOpKind::Ge,
|
|
|
|
BiGt => ast::BinOpKind::Gt,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-31 07:04:06 +00:00
|
|
|
pub type BinOp = Spanned<BinOp_>;
|
|
|
|
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
|
|
|
|
pub enum UnOp {
|
|
|
|
/// The `*` operator for dereferencing
|
|
|
|
UnDeref,
|
|
|
|
/// The `!` operator for logical inversion
|
|
|
|
UnNot,
|
|
|
|
/// The `-` operator for negation
|
2015-09-27 19:23:31 +00:00
|
|
|
UnNeg,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2016-03-29 06:32:58 +00:00
|
|
|
impl UnOp {
|
|
|
|
pub fn as_str(self) -> &'static str {
|
|
|
|
match self {
|
|
|
|
UnDeref => "*",
|
|
|
|
UnNot => "!",
|
|
|
|
UnNeg => "-",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns `true` if the unary operator takes its argument by value
|
|
|
|
pub fn is_by_value(self) -> bool {
|
|
|
|
match self {
|
|
|
|
UnNeg | UnNot => true,
|
|
|
|
_ => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-31 07:04:06 +00:00
|
|
|
/// A statement
|
|
|
|
pub type Stmt = Spanned<Stmt_>;
|
|
|
|
|
|
|
|
impl fmt::Debug for Stmt_ {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
// Sadness.
|
|
|
|
let spanned = codemap::dummy_spanned(self.clone());
|
2015-09-27 19:23:31 +00:00
|
|
|
write!(f,
|
|
|
|
"stmt({}: {})",
|
2016-03-29 06:32:58 +00:00
|
|
|
spanned.node.id(),
|
2016-12-27 08:00:18 +00:00
|
|
|
print::to_string(print::NO_ANN, |s| s.print_stmt(&spanned)))
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
|
|
|
|
pub enum Stmt_ {
|
|
|
|
/// Could be an item or a local (let) binding:
|
|
|
|
StmtDecl(P<Decl>, NodeId),
|
|
|
|
|
|
|
|
/// Expr without trailing semi-colon (must have unit type):
|
|
|
|
StmtExpr(P<Expr>, NodeId),
|
|
|
|
|
|
|
|
/// Expr with trailing semi-colon (may have any type):
|
|
|
|
StmtSemi(P<Expr>, NodeId),
|
|
|
|
}
|
|
|
|
|
2016-03-10 02:12:36 +00:00
|
|
|
impl Stmt_ {
|
|
|
|
pub fn attrs(&self) -> &[Attribute] {
|
|
|
|
match *self {
|
|
|
|
StmtDecl(ref d, _) => d.node.attrs(),
|
|
|
|
StmtExpr(ref e, _) |
|
2016-06-18 04:01:57 +00:00
|
|
|
StmtSemi(ref e, _) => &e.attrs,
|
2016-03-10 02:12:36 +00:00
|
|
|
}
|
|
|
|
}
|
2016-03-29 06:32:58 +00:00
|
|
|
|
|
|
|
pub fn id(&self) -> NodeId {
|
|
|
|
match *self {
|
|
|
|
StmtDecl(_, id) => id,
|
|
|
|
StmtExpr(_, id) => id,
|
|
|
|
StmtSemi(_, id) => id,
|
|
|
|
}
|
|
|
|
}
|
2016-03-10 02:12:36 +00:00
|
|
|
}
|
|
|
|
|
2015-07-31 07:04:06 +00:00
|
|
|
/// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub struct Local {
|
|
|
|
pub pat: P<Pat>,
|
|
|
|
pub ty: Option<P<Ty>>,
|
|
|
|
/// Initializer expression to set the value, if any
|
|
|
|
pub init: Option<P<Expr>>,
|
|
|
|
pub id: NodeId,
|
2017-08-07 12:43:43 +00:00
|
|
|
pub hir_id: HirId,
|
2015-07-31 07:04:06 +00:00
|
|
|
pub span: Span,
|
2016-06-18 04:01:57 +00:00
|
|
|
pub attrs: ThinVec<Attribute>,
|
2017-05-27 18:20:17 +00:00
|
|
|
pub source: LocalSource,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub type Decl = Spanned<Decl_>;
|
|
|
|
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub enum Decl_ {
|
|
|
|
/// A local (let) binding:
|
|
|
|
DeclLocal(P<Local>),
|
|
|
|
/// An item binding:
|
2015-11-17 22:32:12 +00:00
|
|
|
DeclItem(ItemId),
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2016-03-10 02:12:36 +00:00
|
|
|
impl Decl_ {
|
|
|
|
pub fn attrs(&self) -> &[Attribute] {
|
|
|
|
match *self {
|
2016-06-18 04:01:57 +00:00
|
|
|
DeclLocal(ref l) => &l.attrs,
|
2016-03-10 02:12:36 +00:00
|
|
|
DeclItem(_) => &[]
|
|
|
|
}
|
|
|
|
}
|
2017-07-15 22:17:35 +00:00
|
|
|
|
|
|
|
pub fn is_local(&self) -> bool {
|
|
|
|
match *self {
|
|
|
|
Decl_::DeclLocal(_) => true,
|
|
|
|
_ => false,
|
|
|
|
}
|
|
|
|
}
|
2016-03-10 02:12:36 +00:00
|
|
|
}
|
|
|
|
|
2015-07-31 07:04:06 +00:00
|
|
|
/// represents one arm of a 'match'
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub struct Arm {
|
2015-12-17 17:41:28 +00:00
|
|
|
pub attrs: HirVec<Attribute>,
|
|
|
|
pub pats: HirVec<P<Pat>>,
|
2015-07-31 07:04:06 +00:00
|
|
|
pub guard: Option<P<Expr>>,
|
|
|
|
pub body: P<Expr>,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub struct Field {
|
2018-04-05 00:20:21 +00:00
|
|
|
pub id: NodeId,
|
2018-05-25 23:50:15 +00:00
|
|
|
pub ident: Ident,
|
2015-07-31 07:04:06 +00:00
|
|
|
pub expr: P<Expr>,
|
|
|
|
pub span: Span,
|
2016-10-27 00:15:13 +00:00
|
|
|
pub is_shorthand: bool,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
|
|
|
|
pub enum BlockCheckMode {
|
|
|
|
DefaultBlock,
|
|
|
|
UnsafeBlock(UnsafeSource),
|
|
|
|
PushUnsafeBlock(UnsafeSource),
|
|
|
|
PopUnsafeBlock(UnsafeSource),
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
|
|
|
|
pub enum UnsafeSource {
|
|
|
|
CompilerGenerated,
|
|
|
|
UserProvided,
|
|
|
|
}
|
|
|
|
|
2016-12-27 09:15:26 +00:00
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash, Debug)]
|
2016-12-21 10:32:59 +00:00
|
|
|
pub struct BodyId {
|
|
|
|
pub node_id: NodeId,
|
|
|
|
}
|
|
|
|
|
2017-08-31 18:33:19 +00:00
|
|
|
/// The body of a function, closure, or constant value. In the case of
|
|
|
|
/// a function, the body contains not only the function body itself
|
|
|
|
/// (which is an expression), but also the argument patterns, since
|
|
|
|
/// those are something that the caller doesn't really care about.
|
|
|
|
///
|
2017-09-15 20:19:44 +00:00
|
|
|
/// # Examples
|
2017-08-31 18:33:19 +00:00
|
|
|
///
|
2017-09-15 20:19:44 +00:00
|
|
|
/// ```
|
2017-08-31 18:33:19 +00:00
|
|
|
/// fn foo((x, y): (u32, u32)) -> u32 {
|
|
|
|
/// x + y
|
|
|
|
/// }
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// Here, the `Body` associated with `foo()` would contain:
|
|
|
|
///
|
|
|
|
/// - an `arguments` array containing the `(x, y)` pattern
|
|
|
|
/// - a `value` containing the `x + y` expression (maybe wrapped in a block)
|
|
|
|
/// - `is_generator` would be false
|
|
|
|
///
|
|
|
|
/// All bodies have an **owner**, which can be accessed via the HIR
|
|
|
|
/// map using `body_owner_def_id()`.
|
2016-12-21 10:32:59 +00:00
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub struct Body {
|
2016-12-20 20:46:11 +00:00
|
|
|
pub arguments: HirVec<Arg>,
|
2016-12-26 13:34:03 +00:00
|
|
|
pub value: Expr,
|
2017-07-11 19:57:05 +00:00
|
|
|
pub is_generator: bool,
|
2016-12-21 10:32:59 +00:00
|
|
|
}
|
2016-10-27 20:04:22 +00:00
|
|
|
|
2016-12-21 10:32:59 +00:00
|
|
|
impl Body {
|
|
|
|
pub fn id(&self) -> BodyId {
|
|
|
|
BodyId {
|
|
|
|
node_id: self.value.id
|
|
|
|
}
|
2016-10-27 20:04:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-10 17:20:35 +00:00
|
|
|
#[derive(Copy, Clone, Debug)]
|
|
|
|
pub enum BodyOwnerKind {
|
|
|
|
/// Functions and methods.
|
|
|
|
Fn,
|
|
|
|
|
|
|
|
/// Constants and associated constants.
|
|
|
|
Const,
|
|
|
|
|
|
|
|
/// Initializer of a `static` item.
|
|
|
|
Static(Mutability),
|
|
|
|
}
|
|
|
|
|
2018-05-17 18:28:50 +00:00
|
|
|
/// A constant (expression) that's not an item or associated item,
|
|
|
|
/// but needs its own `DefId` for type-checking, const-eval, etc.
|
|
|
|
/// These are usually found nested inside types (e.g. array lengths)
|
|
|
|
/// or expressions (e.g. repeat counts), and also used to define
|
|
|
|
/// explicit discriminant values for enum variants.
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub struct AnonConst {
|
|
|
|
pub id: NodeId,
|
|
|
|
pub hir_id: HirId,
|
|
|
|
pub body: BodyId,
|
|
|
|
}
|
|
|
|
|
2015-07-31 07:04:06 +00:00
|
|
|
/// An expression
|
2015-10-06 19:26:22 +00:00
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
|
2015-07-31 07:04:06 +00:00
|
|
|
pub struct Expr {
|
|
|
|
pub id: NodeId,
|
|
|
|
pub span: Span,
|
2016-11-03 03:58:32 +00:00
|
|
|
pub node: Expr_,
|
2016-06-18 04:01:57 +00:00
|
|
|
pub attrs: ThinVec<Attribute>,
|
2017-08-04 07:49:40 +00:00
|
|
|
pub hir_id: HirId,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2018-01-10 19:40:16 +00:00
|
|
|
impl Expr {
|
|
|
|
pub fn precedence(&self) -> ExprPrecedence {
|
|
|
|
match self.node {
|
|
|
|
ExprBox(_) => ExprPrecedence::Box,
|
|
|
|
ExprArray(_) => ExprPrecedence::Array,
|
|
|
|
ExprCall(..) => ExprPrecedence::Call,
|
|
|
|
ExprMethodCall(..) => ExprPrecedence::MethodCall,
|
|
|
|
ExprTup(_) => ExprPrecedence::Tup,
|
|
|
|
ExprBinary(op, ..) => ExprPrecedence::Binary(op.node.into()),
|
|
|
|
ExprUnary(..) => ExprPrecedence::Unary,
|
|
|
|
ExprLit(_) => ExprPrecedence::Lit,
|
|
|
|
ExprType(..) | ExprCast(..) => ExprPrecedence::Cast,
|
|
|
|
ExprIf(..) => ExprPrecedence::If,
|
|
|
|
ExprWhile(..) => ExprPrecedence::While,
|
|
|
|
ExprLoop(..) => ExprPrecedence::Loop,
|
|
|
|
ExprMatch(..) => ExprPrecedence::Match,
|
|
|
|
ExprClosure(..) => ExprPrecedence::Closure,
|
|
|
|
ExprBlock(..) => ExprPrecedence::Block,
|
|
|
|
ExprAssign(..) => ExprPrecedence::Assign,
|
|
|
|
ExprAssignOp(..) => ExprPrecedence::AssignOp,
|
|
|
|
ExprField(..) => ExprPrecedence::Field,
|
|
|
|
ExprIndex(..) => ExprPrecedence::Index,
|
|
|
|
ExprPath(..) => ExprPrecedence::Path,
|
|
|
|
ExprAddrOf(..) => ExprPrecedence::AddrOf,
|
|
|
|
ExprBreak(..) => ExprPrecedence::Break,
|
|
|
|
ExprAgain(..) => ExprPrecedence::Continue,
|
|
|
|
ExprRet(..) => ExprPrecedence::Ret,
|
|
|
|
ExprInlineAsm(..) => ExprPrecedence::InlineAsm,
|
|
|
|
ExprStruct(..) => ExprPrecedence::Struct,
|
|
|
|
ExprRepeat(..) => ExprPrecedence::Repeat,
|
|
|
|
ExprYield(..) => ExprPrecedence::Yield,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-31 07:04:06 +00:00
|
|
|
impl fmt::Debug for Expr {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2016-12-27 08:00:18 +00:00
|
|
|
write!(f, "expr({}: {})", self.id,
|
|
|
|
print::to_string(print::NO_ANN, |s| s.print_expr(self)))
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub enum Expr_ {
|
2015-09-24 15:00:08 +00:00
|
|
|
/// A `box x` expression.
|
|
|
|
ExprBox(P<Expr>),
|
2015-07-31 07:04:06 +00:00
|
|
|
/// An array (`[a, b, c, d]`)
|
2016-10-28 10:16:44 +00:00
|
|
|
ExprArray(HirVec<Expr>),
|
2015-07-31 07:04:06 +00:00
|
|
|
/// A function call
|
|
|
|
///
|
2016-06-28 10:32:45 +00:00
|
|
|
/// The first field resolves to the function itself (usually an `ExprPath`),
|
2017-10-27 18:27:59 +00:00
|
|
|
/// and the second field is the list of arguments.
|
|
|
|
/// This also represents calling the constructor of
|
|
|
|
/// tuple-like ADTs such as tuple structs and enum variants.
|
2016-10-28 10:16:44 +00:00
|
|
|
ExprCall(P<Expr>, HirVec<Expr>),
|
2017-07-07 12:57:51 +00:00
|
|
|
/// A method call (`x.foo::<'static, Bar, Baz>(a, b, c, d)`)
|
2015-07-31 07:04:06 +00:00
|
|
|
///
|
2017-07-07 12:57:51 +00:00
|
|
|
/// The `PathSegment`/`Span` represent the method name and its generic arguments
|
2015-07-31 07:04:06 +00:00
|
|
|
/// (within the angle brackets).
|
2017-07-07 12:57:51 +00:00
|
|
|
/// The first element of the vector of `Expr`s is the expression that evaluates
|
|
|
|
/// to the object on which the method is being called on (the receiver),
|
|
|
|
/// and the remaining elements are the rest of the arguments.
|
2015-07-31 07:04:06 +00:00
|
|
|
/// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as
|
2017-07-07 12:57:51 +00:00
|
|
|
/// `ExprKind::MethodCall(PathSegment { foo, [Bar, Baz] }, [x, a, b, c, d])`.
|
|
|
|
ExprMethodCall(PathSegment, Span, HirVec<Expr>),
|
2015-07-31 07:04:06 +00:00
|
|
|
/// A tuple (`(a, b, c ,d)`)
|
2016-10-28 10:16:44 +00:00
|
|
|
ExprTup(HirVec<Expr>),
|
2015-07-31 07:04:06 +00:00
|
|
|
/// A binary operation (For example: `a + b`, `a * b`)
|
|
|
|
ExprBinary(BinOp, P<Expr>, P<Expr>),
|
|
|
|
/// A unary operation (For example: `!x`, `*x`)
|
|
|
|
ExprUnary(UnOp, P<Expr>),
|
2016-03-10 20:02:03 +00:00
|
|
|
/// A literal (For example: `1`, `"foo"`)
|
2015-07-31 07:04:06 +00:00
|
|
|
ExprLit(P<Lit>),
|
|
|
|
/// A cast (`foo as f64`)
|
|
|
|
ExprCast(P<Expr>, P<Ty>),
|
2015-12-03 02:37:48 +00:00
|
|
|
ExprType(P<Expr>, P<Ty>),
|
2015-07-31 07:04:06 +00:00
|
|
|
/// An `if` block, with an optional else block
|
|
|
|
///
|
2017-03-09 14:57:26 +00:00
|
|
|
/// `if expr { expr } else { expr }`
|
2017-03-09 14:53:00 +00:00
|
|
|
ExprIf(P<Expr>, P<Expr>, Option<P<Expr>>),
|
2015-07-31 07:04:06 +00:00
|
|
|
/// A while loop, with an optional label
|
|
|
|
///
|
|
|
|
/// `'label: while expr { block }`
|
2018-01-15 22:44:32 +00:00
|
|
|
ExprWhile(P<Expr>, P<Block>, Option<Label>),
|
2015-07-31 07:04:06 +00:00
|
|
|
/// Conditionless loop (can be exited with break, continue, or return)
|
|
|
|
///
|
|
|
|
/// `'label: loop { block }`
|
2018-01-15 22:44:32 +00:00
|
|
|
ExprLoop(P<Block>, Option<Label>, LoopSource),
|
2015-07-31 07:04:06 +00:00
|
|
|
/// A `match` block, with a source that indicates whether or not it is
|
|
|
|
/// the result of a desugaring, and if so, which kind.
|
2015-12-17 17:41:28 +00:00
|
|
|
ExprMatch(P<Expr>, HirVec<Arm>, MatchSource),
|
2016-04-20 18:44:07 +00:00
|
|
|
/// A closure (for example, `move |a, b, c| {a + b + c}`).
|
|
|
|
///
|
|
|
|
/// The final span is the span of the argument block `|...|`
|
2017-07-10 20:07:55 +00:00
|
|
|
///
|
2017-07-28 20:09:33 +00:00
|
|
|
/// This may also be a generator literal, indicated by the final boolean,
|
|
|
|
/// in that case there is an GeneratorClause.
|
2017-10-07 14:36:28 +00:00
|
|
|
ExprClosure(CaptureClause, P<FnDecl>, BodyId, Span, Option<GeneratorMovability>),
|
2018-04-16 03:44:39 +00:00
|
|
|
/// A block (`'label: { ... }`)
|
|
|
|
ExprBlock(P<Block>, Option<Label>),
|
2015-07-31 07:04:06 +00:00
|
|
|
|
|
|
|
/// An assignment (`a = foo()`)
|
|
|
|
ExprAssign(P<Expr>, P<Expr>),
|
|
|
|
/// An assignment with an operator
|
|
|
|
///
|
|
|
|
/// For example, `a += 1`.
|
|
|
|
ExprAssignOp(BinOp, P<Expr>, P<Expr>),
|
2018-04-01 18:48:39 +00:00
|
|
|
/// Access of a named (`obj.foo`) or unnamed (`obj.0`) struct or tuple field
|
2018-05-25 23:50:15 +00:00
|
|
|
ExprField(P<Expr>, Ident),
|
2015-07-31 07:04:06 +00:00
|
|
|
/// An indexing operation (`foo[2]`)
|
|
|
|
ExprIndex(P<Expr>, P<Expr>),
|
|
|
|
|
2016-10-27 02:17:42 +00:00
|
|
|
/// Path to a definition, possibly containing lifetime or type parameters.
|
|
|
|
ExprPath(QPath),
|
2015-07-31 07:04:06 +00:00
|
|
|
|
|
|
|
/// A referencing operation (`&a` or `&mut a`)
|
|
|
|
ExprAddrOf(Mutability, P<Expr>),
|
|
|
|
/// A `break`, with an optional label to break
|
2017-02-18 02:55:28 +00:00
|
|
|
ExprBreak(Destination, Option<P<Expr>>),
|
2015-07-31 07:04:06 +00:00
|
|
|
/// A `continue`, with an optional label
|
2017-02-18 02:55:28 +00:00
|
|
|
ExprAgain(Destination),
|
2015-07-31 07:04:06 +00:00
|
|
|
/// A `return`, with an optional value to be returned
|
|
|
|
ExprRet(Option<P<Expr>>),
|
|
|
|
|
2016-03-09 20:17:02 +00:00
|
|
|
/// Inline assembly (from `asm!`), with its outputs and inputs.
|
2016-10-28 10:16:44 +00:00
|
|
|
ExprInlineAsm(P<InlineAsm>, HirVec<Expr>, HirVec<Expr>),
|
2015-07-31 07:04:06 +00:00
|
|
|
|
2016-06-28 16:07:39 +00:00
|
|
|
/// A struct or struct-like variant literal expression.
|
2015-07-31 07:04:06 +00:00
|
|
|
///
|
|
|
|
/// For example, `Foo {x: 1, y: 2}`, or
|
|
|
|
/// `Foo {x: 1, .. base}`, where `base` is the `Option<Expr>`.
|
2016-10-27 02:17:42 +00:00
|
|
|
ExprStruct(QPath, HirVec<Field>, Option<P<Expr>>),
|
2015-07-31 07:04:06 +00:00
|
|
|
|
2016-06-28 10:32:45 +00:00
|
|
|
/// An array literal constructed from one repeated element.
|
2015-07-31 07:04:06 +00:00
|
|
|
///
|
2016-03-10 20:02:03 +00:00
|
|
|
/// For example, `[1; 5]`. The first expression is the element
|
2015-07-31 07:04:06 +00:00
|
|
|
/// to be repeated; the second is the number of times to repeat it.
|
2018-05-17 18:28:50 +00:00
|
|
|
ExprRepeat(P<Expr>, AnonConst),
|
2016-12-26 13:34:03 +00:00
|
|
|
|
2017-07-10 19:11:31 +00:00
|
|
|
/// A suspension point for generators. This is `yield <expr>` in Rust.
|
|
|
|
ExprYield(P<Expr>),
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2016-10-27 02:17:42 +00:00
|
|
|
/// Optionally `Self`-qualified value/type path or associated extension.
|
2015-07-31 07:04:06 +00:00
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
2016-10-27 02:17:42 +00:00
|
|
|
pub enum QPath {
|
|
|
|
/// Path to a definition, optionally "fully-qualified" with a `Self`
|
|
|
|
/// type, if the path points to an associated item in a trait.
|
|
|
|
///
|
|
|
|
/// 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`.
|
|
|
|
Resolved(Option<P<Ty>>, P<Path>),
|
|
|
|
|
|
|
|
/// 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`,
|
2017-01-24 08:42:00 +00:00
|
|
|
/// the `X` and `Y` nodes each being a `TyPath(QPath::TypeRelative(..))`.
|
2016-10-27 02:17:42 +00:00
|
|
|
TypeRelative(P<Ty>, P<PathSegment>)
|
|
|
|
}
|
|
|
|
|
2017-05-27 18:20:17 +00:00
|
|
|
/// Hints at the original code for a let statement
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
|
|
|
|
pub enum LocalSource {
|
|
|
|
/// A `match _ { .. }`
|
|
|
|
Normal,
|
|
|
|
/// A desugared `for _ in _ { .. }` loop
|
|
|
|
ForLoopDesugar,
|
|
|
|
}
|
|
|
|
|
2016-06-28 10:32:45 +00:00
|
|
|
/// Hints at the original code for a `match _ { .. }`
|
2015-07-31 07:04:06 +00:00
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
|
|
|
|
pub enum MatchSource {
|
2016-06-28 10:32:45 +00:00
|
|
|
/// A `match _ { .. }`
|
2015-07-31 07:04:06 +00:00
|
|
|
Normal,
|
2016-06-28 16:07:39 +00:00
|
|
|
/// An `if let _ = _ { .. }` (optionally with `else { .. }`)
|
2015-09-27 19:23:31 +00:00
|
|
|
IfLetDesugar {
|
|
|
|
contains_else_clause: bool,
|
|
|
|
},
|
2016-06-28 10:32:45 +00:00
|
|
|
/// A `while let _ = _ { .. }` (which was desugared to a
|
2016-06-28 16:07:39 +00:00
|
|
|
/// `loop { match _ { .. } }`)
|
2015-07-31 07:04:06 +00:00
|
|
|
WhileLetDesugar,
|
2016-06-28 10:32:45 +00:00
|
|
|
/// A desugared `for _ in _ { .. }` loop
|
2015-07-31 07:04:06 +00:00
|
|
|
ForLoopDesugar,
|
2016-06-28 10:32:45 +00:00
|
|
|
/// A desugared `?` operator
|
2016-02-28 22:38:48 +00:00
|
|
|
TryDesugar,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
Implement the `loop_break_value` feature.
This implements RFC 1624, tracking issue #37339.
- `FnCtxt` (in typeck) gets a stack of `LoopCtxt`s, which store the
currently deduced type of that loop, the desired type, and a list of
break expressions currently seen. `loop` loops get a fresh type
variable as their initial type (this logic is stolen from that for
arrays). `while` loops get `()`.
- `break {expr}` looks up the broken loop, and unifies the type of
`expr` with the type of the loop.
- `break` with no expr unifies the loop's type with `()`.
- When building MIR, `loop` loops no longer construct a `()` value at
termination of the loop; rather, the `break` expression assigns the
result of the loop. `while` loops are unchanged.
- `break` respects contexts in which expressions may not end with braced
blocks. That is, `while break { break-value } { while-body }` is
illegal; this preserves backwards compatibility.
- The RFC did not make it clear, but I chose to make `break ()` inside
of a `while` loop illegal, just in case we wanted to do anything with
that design space in the future.
This is my first time dealing with this part of rustc so I'm sure
there's plenty of problems to pick on here ^_^
2016-10-29 22:15:06 +00:00
|
|
|
/// The loop type that yielded an ExprLoop
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
|
|
|
|
pub enum LoopSource {
|
|
|
|
/// A `loop { .. }` loop
|
|
|
|
Loop,
|
|
|
|
/// A `while let _ = _ { .. }` loop
|
|
|
|
WhileLet,
|
|
|
|
/// A `for _ in _ { .. }` loop
|
|
|
|
ForLoop,
|
|
|
|
}
|
|
|
|
|
2017-02-16 07:28:59 +00:00
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
|
|
|
|
pub enum LoopIdError {
|
|
|
|
OutsideLoopScope,
|
|
|
|
UnlabeledCfInWhileCondition,
|
|
|
|
UnresolvedLabel,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Display for LoopIdError {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
fmt::Display::fmt(match *self {
|
|
|
|
LoopIdError::OutsideLoopScope => "not inside loop scope",
|
|
|
|
LoopIdError::UnlabeledCfInWhileCondition =>
|
|
|
|
"unlabeled control flow (break or continue) in while condition",
|
|
|
|
LoopIdError::UnresolvedLabel => "label not found",
|
|
|
|
}, f)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-25 11:21:19 +00:00
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
|
2017-02-18 02:55:28 +00:00
|
|
|
pub struct Destination {
|
2017-02-16 07:28:59 +00:00
|
|
|
// This is `Some(_)` iff there is an explicit user-specified `label
|
2018-01-15 22:44:32 +00:00
|
|
|
pub label: Option<Label>,
|
2017-02-16 07:28:59 +00:00
|
|
|
|
|
|
|
// These errors are caught and then reported during the diagnostics pass in
|
|
|
|
// librustc_passes/loops.rs
|
2018-05-14 17:07:05 +00:00
|
|
|
pub target_id: Result<NodeId, LoopIdError>,
|
2016-11-25 11:21:19 +00:00
|
|
|
}
|
|
|
|
|
2018-05-17 21:42:02 +00:00
|
|
|
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
|
2017-10-07 14:36:28 +00:00
|
|
|
pub enum GeneratorMovability {
|
|
|
|
Static,
|
|
|
|
Movable,
|
|
|
|
}
|
|
|
|
|
2015-07-31 07:04:06 +00:00
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
|
|
|
|
pub enum CaptureClause {
|
|
|
|
CaptureByValue,
|
|
|
|
CaptureByRef,
|
|
|
|
}
|
|
|
|
|
|
|
|
// NB: If you change this, you'll probably want to change the corresponding
|
|
|
|
// type structure in middle/ty.rs as well.
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub struct MutTy {
|
|
|
|
pub ty: P<Ty>,
|
|
|
|
pub mutbl: Mutability,
|
|
|
|
}
|
|
|
|
|
2016-06-28 10:32:45 +00:00
|
|
|
/// Represents a method's signature in a trait declaration or implementation.
|
2015-07-31 07:04:06 +00:00
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub struct MethodSig {
|
|
|
|
pub unsafety: Unsafety,
|
|
|
|
pub constness: Constness,
|
|
|
|
pub abi: Abi,
|
|
|
|
pub decl: P<FnDecl>,
|
|
|
|
}
|
|
|
|
|
2016-12-04 02:21:06 +00:00
|
|
|
// The bodies for items are stored "out of line", in a separate
|
|
|
|
// hashmap in the `Crate`. Here we just record the node-id of the item
|
|
|
|
// so it can fetched later.
|
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub struct TraitItemId {
|
|
|
|
pub node_id: NodeId,
|
|
|
|
}
|
|
|
|
|
2015-12-18 22:38:28 +00:00
|
|
|
/// Represents an item declaration within a trait declaration,
|
|
|
|
/// possibly including a default implementation. A trait item is
|
|
|
|
/// either required (meaning it doesn't have an implementation, just a
|
|
|
|
/// signature) or provided (meaning it has a default implementation).
|
2015-07-31 07:04:06 +00:00
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub struct TraitItem {
|
|
|
|
pub id: NodeId,
|
2015-09-20 01:50:30 +00:00
|
|
|
pub name: Name,
|
2017-08-18 18:24:19 +00:00
|
|
|
pub hir_id: HirId,
|
2015-12-17 17:41:28 +00:00
|
|
|
pub attrs: HirVec<Attribute>,
|
2017-09-25 21:24:20 +00:00
|
|
|
pub generics: Generics,
|
2016-12-04 02:21:06 +00:00
|
|
|
pub node: TraitItemKind,
|
2015-07-31 07:04:06 +00:00
|
|
|
pub span: Span,
|
|
|
|
}
|
|
|
|
|
2016-12-20 20:46:11 +00:00
|
|
|
/// A trait method's body (or just argument names).
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub enum TraitMethod {
|
|
|
|
/// No default body in the trait, just a signature.
|
|
|
|
Required(HirVec<Spanned<Name>>),
|
|
|
|
|
|
|
|
/// Both signature and body are provided in the trait.
|
|
|
|
Provided(BodyId),
|
|
|
|
}
|
|
|
|
|
2016-06-28 10:32:45 +00:00
|
|
|
/// Represents a trait method or associated constant or type
|
2015-07-31 07:04:06 +00:00
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
2016-12-04 02:21:06 +00:00
|
|
|
pub enum TraitItemKind {
|
2016-06-28 10:32:45 +00:00
|
|
|
/// An associated constant with an optional value (otherwise `impl`s
|
|
|
|
/// must contain a value)
|
2016-12-21 10:32:59 +00:00
|
|
|
Const(P<Ty>, Option<BodyId>),
|
2016-06-28 10:32:45 +00:00
|
|
|
/// A method with an optional body
|
2016-12-20 20:46:11 +00:00
|
|
|
Method(MethodSig, TraitMethod),
|
2016-06-28 10:32:45 +00:00
|
|
|
/// An associated type with (possibly empty) bounds and optional concrete
|
|
|
|
/// type
|
2016-12-04 02:21:06 +00:00
|
|
|
Type(TyParamBounds, Option<P<Ty>>),
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2016-11-02 22:25:31 +00:00
|
|
|
// The bodies for items are stored "out of line", in a separate
|
|
|
|
// hashmap in the `Crate`. Here we just record the node-id of the item
|
|
|
|
// so it can fetched later.
|
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub struct ImplItemId {
|
2016-11-10 14:47:00 +00:00
|
|
|
pub node_id: NodeId,
|
2016-11-02 22:25:31 +00:00
|
|
|
}
|
|
|
|
|
2016-06-28 10:32:45 +00:00
|
|
|
/// Represents anything within an `impl` block
|
2015-07-31 07:04:06 +00:00
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub struct ImplItem {
|
|
|
|
pub id: NodeId,
|
2015-09-20 01:50:30 +00:00
|
|
|
pub name: Name,
|
2017-08-18 18:24:19 +00:00
|
|
|
pub hir_id: HirId,
|
2015-07-31 07:04:06 +00:00
|
|
|
pub vis: Visibility,
|
2015-12-18 22:38:28 +00:00
|
|
|
pub defaultness: Defaultness,
|
2015-12-17 17:41:28 +00:00
|
|
|
pub attrs: HirVec<Attribute>,
|
2017-09-25 21:24:20 +00:00
|
|
|
pub generics: Generics,
|
2015-11-12 14:57:51 +00:00
|
|
|
pub node: ImplItemKind,
|
2015-07-31 07:04:06 +00:00
|
|
|
pub span: Span,
|
|
|
|
}
|
|
|
|
|
2016-06-28 10:32:45 +00:00
|
|
|
/// Represents different contents within `impl`s
|
2015-07-31 07:04:06 +00:00
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
2015-11-12 14:57:51 +00:00
|
|
|
pub enum ImplItemKind {
|
2016-06-28 10:32:45 +00:00
|
|
|
/// An associated constant of the given type, set to the constant result
|
|
|
|
/// of the expression
|
2016-12-21 10:32:59 +00:00
|
|
|
Const(P<Ty>, BodyId),
|
2016-06-28 10:32:45 +00:00
|
|
|
/// A method implementation with the given signature and body
|
2016-12-21 10:32:59 +00:00
|
|
|
Method(MethodSig, BodyId),
|
2016-06-28 10:32:45 +00:00
|
|
|
/// An associated type
|
2015-11-11 09:37:25 +00:00
|
|
|
Type(P<Ty>),
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Bind a type to an associated type: `A=Foo`.
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub struct TypeBinding {
|
|
|
|
pub id: NodeId,
|
2015-09-20 13:47:24 +00:00
|
|
|
pub name: Name,
|
2015-07-31 07:04:06 +00:00
|
|
|
pub ty: P<Ty>,
|
|
|
|
pub span: Span,
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
|
|
|
|
pub struct Ty {
|
|
|
|
pub id: NodeId,
|
|
|
|
pub node: Ty_,
|
|
|
|
pub span: Span,
|
2017-09-13 15:29:59 +00:00
|
|
|
pub hir_id: HirId,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Debug for Ty {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2016-12-27 08:00:18 +00:00
|
|
|
write!(f, "type({})",
|
|
|
|
print::to_string(print::NO_ANN, |s| s.print_type(self)))
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Not represented directly in the AST, referred to by name through a ty_path.
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
|
|
|
|
pub enum PrimTy {
|
|
|
|
TyInt(IntTy),
|
|
|
|
TyUint(UintTy),
|
|
|
|
TyFloat(FloatTy),
|
|
|
|
TyStr,
|
|
|
|
TyBool,
|
2015-09-27 19:23:31 +00:00
|
|
|
TyChar,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub struct BareFnTy {
|
|
|
|
pub unsafety: Unsafety,
|
|
|
|
pub abi: Abi,
|
2017-10-16 19:07:26 +00:00
|
|
|
pub generic_params: HirVec<GenericParam>,
|
2015-09-27 19:23:31 +00:00
|
|
|
pub decl: P<FnDecl>,
|
2017-09-26 22:43:37 +00:00
|
|
|
pub arg_names: HirVec<Spanned<Name>>,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2017-10-15 20:43:06 +00:00
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub struct ExistTy {
|
|
|
|
pub generics: Generics,
|
|
|
|
pub bounds: TyParamBounds,
|
2018-05-22 12:31:56 +00:00
|
|
|
pub impl_trait_fn: Option<DefId>,
|
2017-10-15 20:43:06 +00:00
|
|
|
}
|
|
|
|
|
2015-07-31 07:04:06 +00:00
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
/// The different kinds of types recognized by the compiler
|
|
|
|
pub enum Ty_ {
|
2016-09-20 00:14:46 +00:00
|
|
|
/// A variable length slice (`[T]`)
|
|
|
|
TySlice(P<Ty>),
|
2015-07-31 07:04:06 +00:00
|
|
|
/// A fixed length array (`[T; n]`)
|
2018-05-17 18:28:50 +00:00
|
|
|
TyArray(P<Ty>, AnonConst),
|
2015-07-31 07:04:06 +00:00
|
|
|
/// A raw pointer (`*const T` or `*mut T`)
|
|
|
|
TyPtr(MutTy),
|
|
|
|
/// A reference (`&'a T` or `&'a mut T`)
|
2017-01-09 15:46:11 +00:00
|
|
|
TyRptr(Lifetime, MutTy),
|
2015-07-31 07:04:06 +00:00
|
|
|
/// A bare function (e.g. `fn(usize) -> bool`)
|
|
|
|
TyBareFn(P<BareFnTy>),
|
2016-08-02 07:56:20 +00:00
|
|
|
/// The never type (`!`)
|
|
|
|
TyNever,
|
2015-07-31 07:04:06 +00:00
|
|
|
/// A tuple (`(A, B, C, D,...)`)
|
2015-12-17 17:41:28 +00:00
|
|
|
TyTup(HirVec<P<Ty>>),
|
2016-10-27 02:17:42 +00:00
|
|
|
/// A path to a type definition (`module::module::...::Type`), or an
|
|
|
|
/// associated type, e.g. `<Vec<T> as Trait>::Type` or `<T>::Target`.
|
2015-07-31 07:04:06 +00:00
|
|
|
///
|
2016-10-27 02:17:42 +00:00
|
|
|
/// Type parameters may be stored in each `PathSegment`.
|
|
|
|
TyPath(QPath),
|
2017-01-16 20:33:45 +00:00
|
|
|
/// A trait object type `Bound1 + Bound2 + Bound3`
|
|
|
|
/// where `Bound` is a trait or a lifetime.
|
2017-01-24 15:17:06 +00:00
|
|
|
TyTraitObject(HirVec<PolyTraitRef>, Lifetime),
|
2017-12-15 20:27:20 +00:00
|
|
|
/// An existentially quantified (there exists a type satisfying) `impl
|
2017-11-10 17:23:59 +00:00
|
|
|
/// Bound1 + Bound2 + Bound3` type where `Bound` is a trait or a lifetime.
|
2017-10-15 20:43:06 +00:00
|
|
|
///
|
2018-05-22 12:31:56 +00:00
|
|
|
/// The `Item` is the generated
|
|
|
|
/// `existential type Foo<'a, 'b>: MyTrait<'a, 'b>;`.
|
2017-10-15 20:43:06 +00:00
|
|
|
///
|
|
|
|
/// The `HirVec<Lifetime>` is the list of lifetimes applied as parameters
|
|
|
|
/// to the `abstract type`, e.g. the `'c` and `'d` in `-> Foo<'c, 'd>`.
|
|
|
|
/// This list is only a list of lifetimes and not type parameters
|
|
|
|
/// because all in-scope type parameters are captured by `impl Trait`,
|
|
|
|
/// so they are resolved directly through the parent `Generics`.
|
2018-05-22 12:31:56 +00:00
|
|
|
TyImplTraitExistential(ItemId, DefId, HirVec<Lifetime>),
|
2015-07-31 07:04:06 +00:00
|
|
|
/// Unused for now
|
2018-05-17 18:28:50 +00:00
|
|
|
TyTypeof(AnonConst),
|
2015-07-31 07:04:06 +00:00
|
|
|
/// TyInfer means the type should be inferred instead of it having been
|
|
|
|
/// specified. This can appear anywhere in a type.
|
|
|
|
TyInfer,
|
2017-03-29 01:56:29 +00:00
|
|
|
/// Placeholder for a type that has failed to be defined.
|
|
|
|
TyErr,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2015-12-05 08:18:24 +00:00
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub struct InlineAsmOutput {
|
2016-11-16 10:52:37 +00:00
|
|
|
pub constraint: Symbol,
|
2015-12-05 08:18:24 +00:00
|
|
|
pub is_rw: bool,
|
|
|
|
pub is_indirect: bool,
|
|
|
|
}
|
|
|
|
|
2015-07-31 07:04:06 +00:00
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub struct InlineAsm {
|
2016-11-16 10:52:37 +00:00
|
|
|
pub asm: Symbol,
|
2015-07-31 07:04:06 +00:00
|
|
|
pub asm_str_style: StrStyle,
|
2015-12-17 17:41:28 +00:00
|
|
|
pub outputs: HirVec<InlineAsmOutput>,
|
2016-11-16 10:52:37 +00:00
|
|
|
pub inputs: HirVec<Symbol>,
|
|
|
|
pub clobbers: HirVec<Symbol>,
|
2015-07-31 07:04:06 +00:00
|
|
|
pub volatile: bool,
|
|
|
|
pub alignstack: bool,
|
|
|
|
pub dialect: AsmDialect,
|
2017-03-17 04:04:41 +00:00
|
|
|
pub ctxt: SyntaxContext,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// represents an argument in a function header
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub struct Arg {
|
|
|
|
pub pat: P<Pat>,
|
|
|
|
pub id: NodeId,
|
2017-08-04 07:49:40 +00:00
|
|
|
pub hir_id: HirId,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Represents the header (not the body) of a function declaration
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub struct FnDecl {
|
2016-12-20 20:46:11 +00:00
|
|
|
pub inputs: HirVec<P<Ty>>,
|
2015-07-31 07:04:06 +00:00
|
|
|
pub output: FunctionRetTy,
|
2015-09-27 19:23:31 +00:00
|
|
|
pub variadic: bool,
|
2017-03-26 22:35:50 +00:00
|
|
|
/// True if this function has an `self`, `&self` or `&mut self` receiver
|
|
|
|
/// (but not a `self: Xxx` one).
|
|
|
|
pub has_implicit_self: bool,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2017-10-12 12:51:31 +00:00
|
|
|
/// Is the trait definition an auto trait?
|
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub enum IsAuto {
|
|
|
|
Yes,
|
|
|
|
No
|
|
|
|
}
|
|
|
|
|
2018-05-17 21:42:02 +00:00
|
|
|
#[derive(Copy, Clone, PartialEq, Eq,PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash, Debug)]
|
2015-07-31 07:04:06 +00:00
|
|
|
pub enum Unsafety {
|
|
|
|
Unsafe,
|
|
|
|
Normal,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub enum Constness {
|
|
|
|
Const,
|
|
|
|
NotConst,
|
|
|
|
}
|
|
|
|
|
2015-12-18 22:38:28 +00:00
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub enum Defaultness {
|
2016-11-14 16:00:02 +00:00
|
|
|
Default { has_value: bool },
|
2015-12-18 22:38:28 +00:00
|
|
|
Final,
|
|
|
|
}
|
|
|
|
|
2016-02-16 18:36:47 +00:00
|
|
|
impl Defaultness {
|
2016-11-14 16:00:02 +00:00
|
|
|
pub fn has_value(&self) -> bool {
|
|
|
|
match *self {
|
|
|
|
Defaultness::Default { has_value, .. } => has_value,
|
|
|
|
Defaultness::Final => true,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-16 18:36:47 +00:00
|
|
|
pub fn is_final(&self) -> bool {
|
|
|
|
*self == Defaultness::Final
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn is_default(&self) -> bool {
|
2016-11-14 16:00:02 +00:00
|
|
|
match *self {
|
|
|
|
Defaultness::Default { .. } => true,
|
|
|
|
_ => false,
|
|
|
|
}
|
2016-02-16 18:36:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-31 07:04:06 +00:00
|
|
|
impl fmt::Display for Unsafety {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
fmt::Display::fmt(match *self {
|
2015-09-27 19:23:31 +00:00
|
|
|
Unsafety::Normal => "normal",
|
|
|
|
Unsafety::Unsafe => "unsafe",
|
|
|
|
},
|
|
|
|
f)
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
|
|
|
|
pub enum ImplPolarity {
|
|
|
|
/// `impl Trait for Type`
|
|
|
|
Positive,
|
|
|
|
/// `impl !Trait for Type`
|
|
|
|
Negative,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Debug for ImplPolarity {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
match *self {
|
|
|
|
ImplPolarity::Positive => "positive".fmt(f),
|
|
|
|
ImplPolarity::Negative => "negative".fmt(f),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub enum FunctionRetTy {
|
|
|
|
/// Return type is not specified.
|
|
|
|
///
|
|
|
|
/// Functions default to `()` and
|
|
|
|
/// closures default to inference. Span points to where return
|
|
|
|
/// type would be inserted.
|
|
|
|
DefaultReturn(Span),
|
|
|
|
/// Everything else
|
|
|
|
Return(P<Ty>),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl FunctionRetTy {
|
|
|
|
pub fn span(&self) -> Span {
|
|
|
|
match *self {
|
|
|
|
DefaultReturn(span) => span,
|
2015-09-27 19:23:31 +00:00
|
|
|
Return(ref ty) => ty.span,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub struct Mod {
|
|
|
|
/// 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,
|
2015-12-17 17:41:28 +00:00
|
|
|
pub item_ids: HirVec<ItemId>,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub struct ForeignMod {
|
|
|
|
pub abi: Abi,
|
2015-12-17 17:41:28 +00:00
|
|
|
pub items: HirVec<ForeignItem>,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2017-03-16 02:27:40 +00:00
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub struct GlobalAsm {
|
|
|
|
pub asm: Symbol,
|
|
|
|
pub ctxt: SyntaxContext,
|
|
|
|
}
|
|
|
|
|
2015-07-31 07:04:06 +00:00
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub struct EnumDef {
|
2015-12-17 17:41:28 +00:00
|
|
|
pub variants: HirVec<Variant>,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub struct Variant_ {
|
2015-09-20 13:47:24 +00:00
|
|
|
pub name: Name,
|
2015-12-17 17:41:28 +00:00
|
|
|
pub attrs: HirVec<Attribute>,
|
2015-10-25 15:33:51 +00:00
|
|
|
pub data: VariantData,
|
2015-07-31 07:04:06 +00:00
|
|
|
/// Explicit discriminant, eg `Foo = 1`
|
2018-05-17 18:28:50 +00:00
|
|
|
pub disr_expr: Option<AnonConst>,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub type Variant = Spanned<Variant_>;
|
|
|
|
|
2016-11-24 04:11:31 +00:00
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
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 07:04:06 +00:00
|
|
|
|
2016-11-24 04:11:31 +00:00
|
|
|
/// Glob import, e.g. `use foo::*`.
|
|
|
|
Glob,
|
2015-07-31 07:04:06 +00:00
|
|
|
|
2016-11-24 04:11:31 +00: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 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// TraitRef's appear in impls.
|
|
|
|
///
|
|
|
|
/// resolve maps each TraitRef's ref_id to its defining trait; that's all
|
2016-07-28 09:58:45 +00:00
|
|
|
/// that the ref_id is for. Note that ref_id's value is not the NodeId of the
|
|
|
|
/// trait being referred to but just a unique NodeId that serves as a key
|
|
|
|
/// within the DefMap.
|
2015-07-31 07:04:06 +00:00
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub struct TraitRef {
|
|
|
|
pub path: Path,
|
|
|
|
pub ref_id: NodeId,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub struct PolyTraitRef {
|
|
|
|
/// The `'a` in `<'a> Foo<&'a T>`
|
2017-10-16 19:07:26 +00:00
|
|
|
pub bound_generic_params: HirVec<GenericParam>,
|
2015-07-31 07:04:06 +00:00
|
|
|
|
|
|
|
/// The `Foo<&'a T>` in `<'a> Foo<&'a T>`
|
|
|
|
pub trait_ref: TraitRef,
|
|
|
|
|
|
|
|
pub span: Span,
|
|
|
|
}
|
|
|
|
|
2016-03-25 06:08:11 +00:00
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
2015-07-31 07:04:06 +00:00
|
|
|
pub enum Visibility {
|
|
|
|
Public,
|
2018-05-25 20:53:49 +00:00
|
|
|
Crate(CrateSugar),
|
2016-04-02 20:24:02 +00:00
|
|
|
Restricted { path: P<Path>, id: NodeId },
|
2015-07-31 07:04:06 +00:00
|
|
|
Inherited,
|
|
|
|
}
|
|
|
|
|
2017-03-18 03:38:32 +00:00
|
|
|
impl Visibility {
|
|
|
|
pub fn is_pub_restricted(&self) -> bool {
|
|
|
|
use self::Visibility::*;
|
|
|
|
match self {
|
|
|
|
&Public |
|
|
|
|
&Inherited => false,
|
2018-05-25 20:53:49 +00:00
|
|
|
&Crate(_) |
|
2017-03-18 03:38:32 +00:00
|
|
|
&Restricted { .. } => true,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-31 07:04:06 +00:00
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
2016-02-27 08:34:29 +00:00
|
|
|
pub struct StructField {
|
|
|
|
pub span: Span,
|
2018-05-25 23:50:15 +00:00
|
|
|
pub ident: Ident,
|
2016-02-26 20:59:35 +00:00
|
|
|
pub vis: Visibility,
|
2015-07-31 07:04:06 +00:00
|
|
|
pub id: NodeId,
|
|
|
|
pub ty: P<Ty>,
|
2015-12-17 17:41:28 +00:00
|
|
|
pub attrs: HirVec<Attribute>,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2016-02-27 08:34:29 +00:00
|
|
|
impl StructField {
|
2016-02-27 00:05:14 +00:00
|
|
|
// Still necessary in couple of places
|
|
|
|
pub fn is_positional(&self) -> bool {
|
2018-05-26 12:12:38 +00:00
|
|
|
let first = self.ident.as_str().as_bytes()[0];
|
2016-02-27 00:05:14 +00:00
|
|
|
first >= b'0' && first <= b'9'
|
|
|
|
}
|
|
|
|
}
|
2015-07-31 07:04:06 +00:00
|
|
|
|
2015-10-13 13:18:33 +00:00
|
|
|
/// Fields and Ids of enum variants and structs
|
|
|
|
///
|
|
|
|
/// For enum variants: `NodeId` represents both an Id of the variant itself (relevant for all
|
|
|
|
/// variant kinds) and an Id of the variant's constructor (not relevant for `Struct`-variants).
|
|
|
|
/// One shared Id can be successfully used for these two purposes.
|
|
|
|
/// Id of the whole enum lives in `Item`.
|
|
|
|
///
|
|
|
|
/// For structs: `NodeId` represents an Id of the structure's constructor, so it is not actually
|
|
|
|
/// used for `Struct`-structs (but still presents). Structures don't have an analogue of "Id of
|
|
|
|
/// the variant itself" from enum variants.
|
|
|
|
/// Id of the whole struct lives in `Item`.
|
2015-10-08 20:45:46 +00:00
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
2015-10-10 00:28:40 +00:00
|
|
|
pub enum VariantData {
|
2015-12-17 17:41:28 +00:00
|
|
|
Struct(HirVec<StructField>, NodeId),
|
|
|
|
Tuple(HirVec<StructField>, NodeId),
|
2015-10-10 00:28:40 +00:00
|
|
|
Unit(NodeId),
|
2015-10-08 20:45:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl VariantData {
|
2015-10-25 15:33:51 +00:00
|
|
|
pub fn fields(&self) -> &[StructField] {
|
2015-10-10 00:28:40 +00:00
|
|
|
match *self {
|
2015-10-25 15:33:51 +00:00
|
|
|
VariantData::Struct(ref fields, _) | VariantData::Tuple(ref fields, _) => fields,
|
|
|
|
_ => &[],
|
|
|
|
}
|
2015-10-08 20:45:46 +00:00
|
|
|
}
|
2015-10-10 00:28:40 +00:00
|
|
|
pub fn id(&self) -> NodeId {
|
|
|
|
match *self {
|
2015-11-05 21:17:59 +00:00
|
|
|
VariantData::Struct(_, id) | VariantData::Tuple(_, id) | VariantData::Unit(id) => id,
|
2015-10-10 00:28:40 +00:00
|
|
|
}
|
|
|
|
}
|
2015-10-08 20:45:46 +00:00
|
|
|
pub fn is_struct(&self) -> bool {
|
2015-11-05 21:17:59 +00:00
|
|
|
if let VariantData::Struct(..) = *self {
|
|
|
|
true
|
|
|
|
} else {
|
|
|
|
false
|
|
|
|
}
|
2015-10-08 20:45:46 +00:00
|
|
|
}
|
|
|
|
pub fn is_tuple(&self) -> bool {
|
2015-11-05 21:17:59 +00:00
|
|
|
if let VariantData::Tuple(..) = *self {
|
|
|
|
true
|
|
|
|
} else {
|
|
|
|
false
|
|
|
|
}
|
2015-10-08 20:45:46 +00:00
|
|
|
}
|
|
|
|
pub fn is_unit(&self) -> bool {
|
2015-11-05 21:17:59 +00:00
|
|
|
if let VariantData::Unit(..) = *self {
|
|
|
|
true
|
|
|
|
} else {
|
|
|
|
false
|
|
|
|
}
|
2015-10-08 20:45:46 +00:00
|
|
|
}
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2015-11-17 22:32:12 +00:00
|
|
|
// The bodies for items are stored "out of line", in a separate
|
|
|
|
// hashmap in the `Crate`. Here we just record the node-id of the item
|
|
|
|
// so it can fetched later.
|
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub struct ItemId {
|
|
|
|
pub id: NodeId,
|
|
|
|
}
|
2015-11-05 21:17:59 +00:00
|
|
|
|
2015-07-31 07:04:06 +00:00
|
|
|
/// An item
|
|
|
|
///
|
|
|
|
/// The name might be a dummy name in case of anonymous items
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub struct Item {
|
2015-09-20 01:50:30 +00:00
|
|
|
pub name: Name,
|
2015-07-31 07:04:06 +00:00
|
|
|
pub id: NodeId,
|
2017-08-18 18:24:19 +00:00
|
|
|
pub hir_id: HirId,
|
|
|
|
pub attrs: HirVec<Attribute>,
|
2015-07-31 07:04:06 +00:00
|
|
|
pub node: Item_,
|
|
|
|
pub vis: Visibility,
|
|
|
|
pub span: Span,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub enum Item_ {
|
2018-03-09 15:51:48 +00:00
|
|
|
/// An `extern crate` item, with optional *original* crate name if the crate was renamed.
|
2015-07-31 07:04:06 +00:00
|
|
|
///
|
2018-03-09 15:51:48 +00:00
|
|
|
/// E.g. `extern crate foo` or `extern crate foo_bar as foo`
|
2015-07-31 07:04:06 +00:00
|
|
|
ItemExternCrate(Option<Name>),
|
2016-11-24 04:11:31 +00:00
|
|
|
|
|
|
|
/// `use foo::bar::*;` or `use foo::bar::baz as quux;`
|
|
|
|
///
|
|
|
|
/// or just
|
|
|
|
///
|
|
|
|
/// `use foo::bar::baz;` (with `as baz` implicitly on the right)
|
|
|
|
ItemUse(P<Path>, UseKind),
|
2015-07-31 07:04:06 +00:00
|
|
|
|
|
|
|
/// A `static` item
|
2016-12-21 10:32:59 +00:00
|
|
|
ItemStatic(P<Ty>, Mutability, BodyId),
|
2015-07-31 07:04:06 +00:00
|
|
|
/// A `const` item
|
2016-12-21 10:32:59 +00:00
|
|
|
ItemConst(P<Ty>, BodyId),
|
2015-07-31 07:04:06 +00:00
|
|
|
/// A function declaration
|
2016-12-21 10:32:59 +00:00
|
|
|
ItemFn(P<FnDecl>, Unsafety, Constness, Abi, Generics, BodyId),
|
2015-07-31 07:04:06 +00:00
|
|
|
/// A module
|
|
|
|
ItemMod(Mod),
|
|
|
|
/// An external module
|
|
|
|
ItemForeignMod(ForeignMod),
|
2017-03-16 02:27:40 +00:00
|
|
|
/// Module-level inline assembly (from global_asm!)
|
|
|
|
ItemGlobalAsm(P<GlobalAsm>),
|
2015-07-31 07:04:06 +00:00
|
|
|
/// A type alias, e.g. `type Foo = Bar<u8>`
|
|
|
|
ItemTy(P<Ty>, Generics),
|
2018-05-22 12:31:56 +00:00
|
|
|
/// A type alias, e.g. `type Foo = Bar<u8>`
|
|
|
|
ItemExistential(ExistTy),
|
2015-07-31 07:04:06 +00:00
|
|
|
/// An enum definition, e.g. `enum Foo<A, B> {C<A>, D<B>}`
|
|
|
|
ItemEnum(EnumDef, Generics),
|
|
|
|
/// A struct definition, e.g. `struct Foo<A> {x: A}`
|
2015-10-25 15:33:51 +00:00
|
|
|
ItemStruct(VariantData, Generics),
|
2016-08-06 18:36:28 +00:00
|
|
|
/// A union definition, e.g. `union Foo<A, B> {x: A, y: B}`
|
|
|
|
ItemUnion(VariantData, Generics),
|
2015-07-31 07:04:06 +00:00
|
|
|
/// Represents a Trait Declaration
|
2017-10-12 12:51:31 +00:00
|
|
|
ItemTrait(IsAuto, Unsafety, Generics, TyParamBounds, HirVec<TraitItemRef>),
|
2017-10-02 12:28:16 +00:00
|
|
|
/// Represents a Trait Alias Declaration
|
|
|
|
ItemTraitAlias(Generics, TyParamBounds),
|
2015-07-31 07:04:06 +00:00
|
|
|
|
|
|
|
/// An implementation, eg `impl<A> Trait for Foo { .. }`
|
|
|
|
ItemImpl(Unsafety,
|
|
|
|
ImplPolarity,
|
2016-11-18 16:14:42 +00:00
|
|
|
Defaultness,
|
2015-07-31 07:04:06 +00:00
|
|
|
Generics,
|
|
|
|
Option<TraitRef>, // (optional) trait this impl implements
|
|
|
|
P<Ty>, // self
|
2016-11-10 14:47:00 +00:00
|
|
|
HirVec<ImplItemRef>),
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Item_ {
|
|
|
|
pub fn descriptive_variant(&self) -> &str {
|
|
|
|
match *self {
|
|
|
|
ItemExternCrate(..) => "extern crate",
|
|
|
|
ItemUse(..) => "use",
|
|
|
|
ItemStatic(..) => "static item",
|
|
|
|
ItemConst(..) => "constant item",
|
|
|
|
ItemFn(..) => "function",
|
|
|
|
ItemMod(..) => "module",
|
|
|
|
ItemForeignMod(..) => "foreign module",
|
2017-03-16 02:27:40 +00:00
|
|
|
ItemGlobalAsm(..) => "global asm",
|
2015-07-31 07:04:06 +00:00
|
|
|
ItemTy(..) => "type alias",
|
2018-05-22 12:31:56 +00:00
|
|
|
ItemExistential(..) => "existential type",
|
2015-07-31 07:04:06 +00:00
|
|
|
ItemEnum(..) => "enum",
|
|
|
|
ItemStruct(..) => "struct",
|
2016-08-06 18:36:28 +00:00
|
|
|
ItemUnion(..) => "union",
|
2015-07-31 07:04:06 +00:00
|
|
|
ItemTrait(..) => "trait",
|
2017-10-02 12:28:16 +00:00
|
|
|
ItemTraitAlias(..) => "trait alias",
|
2017-12-01 12:01:23 +00:00
|
|
|
ItemImpl(..) => "item",
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
}
|
2017-08-16 16:45:54 +00:00
|
|
|
|
|
|
|
pub fn adt_kind(&self) -> Option<AdtKind> {
|
|
|
|
match *self {
|
|
|
|
ItemStruct(..) => Some(AdtKind::Struct),
|
|
|
|
ItemUnion(..) => Some(AdtKind::Union),
|
|
|
|
ItemEnum(..) => Some(AdtKind::Enum),
|
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
2017-10-28 21:19:07 +00:00
|
|
|
|
|
|
|
pub fn generics(&self) -> Option<&Generics> {
|
|
|
|
Some(match *self {
|
|
|
|
ItemFn(_, _, _, _, ref generics, _) |
|
|
|
|
ItemTy(_, ref generics) |
|
|
|
|
ItemEnum(_, ref generics) |
|
|
|
|
ItemStruct(_, ref generics) |
|
|
|
|
ItemUnion(_, ref generics) |
|
2017-11-01 11:47:18 +00:00
|
|
|
ItemTrait(_, _, ref generics, _, _) |
|
2017-10-28 21:19:07 +00:00
|
|
|
ItemImpl(_, _, _, ref generics, _, _, _)=> generics,
|
|
|
|
_ => return None
|
|
|
|
})
|
|
|
|
}
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2016-12-04 02:21:06 +00:00
|
|
|
/// A reference from an trait to one of its associated items. This
|
|
|
|
/// contains the item's id, naturally, but also the item's name and
|
|
|
|
/// some other high-level details (like whether it is an associated
|
|
|
|
/// type or method, and whether it is public). This allows other
|
|
|
|
/// passes to find the impl they want without loading the id (which
|
|
|
|
/// means fewer edges in the incremental compilation graph).
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub struct TraitItemRef {
|
|
|
|
pub id: TraitItemId,
|
|
|
|
pub name: Name,
|
|
|
|
pub kind: AssociatedItemKind,
|
|
|
|
pub span: Span,
|
|
|
|
pub defaultness: Defaultness,
|
|
|
|
}
|
|
|
|
|
2016-11-10 14:47:00 +00:00
|
|
|
/// A reference from an impl to one of its associated items. This
|
|
|
|
/// 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(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub struct ImplItemRef {
|
|
|
|
pub id: ImplItemId,
|
|
|
|
pub name: Name,
|
|
|
|
pub kind: AssociatedItemKind,
|
|
|
|
pub span: Span,
|
|
|
|
pub vis: Visibility,
|
|
|
|
pub defaultness: Defaultness,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub enum AssociatedItemKind {
|
|
|
|
Const,
|
|
|
|
Method { has_self: bool },
|
|
|
|
Type,
|
|
|
|
}
|
|
|
|
|
2015-07-31 07:04:06 +00:00
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub struct ForeignItem {
|
2015-09-20 01:50:30 +00:00
|
|
|
pub name: Name,
|
2015-12-17 17:41:28 +00:00
|
|
|
pub attrs: HirVec<Attribute>,
|
2015-07-31 07:04:06 +00:00
|
|
|
pub node: ForeignItem_,
|
|
|
|
pub id: NodeId,
|
|
|
|
pub span: Span,
|
|
|
|
pub vis: Visibility,
|
|
|
|
}
|
|
|
|
|
|
|
|
/// An item within an `extern` block
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub enum ForeignItem_ {
|
|
|
|
/// A foreign function
|
2016-12-20 20:46:11 +00:00
|
|
|
ForeignItemFn(P<FnDecl>, HirVec<Spanned<Name>>, Generics),
|
2015-07-31 07:04:06 +00:00
|
|
|
/// A foreign static item (`static ext: u8`), with optional mutability
|
|
|
|
/// (the boolean is true when mutable)
|
|
|
|
ForeignItemStatic(P<Ty>, bool),
|
2017-09-03 18:53:58 +00:00
|
|
|
/// A foreign type
|
|
|
|
ForeignItemType,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl ForeignItem_ {
|
|
|
|
pub fn descriptive_variant(&self) -> &str {
|
|
|
|
match *self {
|
|
|
|
ForeignItemFn(..) => "foreign function",
|
2015-09-27 19:23:31 +00:00
|
|
|
ForeignItemStatic(..) => "foreign static item",
|
2017-09-03 18:53:58 +00:00
|
|
|
ForeignItemType => "foreign type",
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-03-29 10:14:01 +00:00
|
|
|
|
|
|
|
/// A free variable referred to in a function.
|
2017-11-11 09:15:26 +00:00
|
|
|
#[derive(Debug, Copy, Clone, RustcEncodable, RustcDecodable)]
|
2016-03-29 10:14:01 +00:00
|
|
|
pub struct Freevar {
|
|
|
|
/// The variable being accessed free.
|
|
|
|
pub def: Def,
|
|
|
|
|
|
|
|
// First span where it is accessed (there can be multiple).
|
|
|
|
pub span: Span
|
|
|
|
}
|
|
|
|
|
2017-04-29 11:39:47 +00:00
|
|
|
impl Freevar {
|
|
|
|
pub fn var_id(&self) -> NodeId {
|
|
|
|
match self.def {
|
|
|
|
Def::Local(id) | Def::Upvar(id, ..) => id,
|
|
|
|
_ => bug!("Freevar::var_id: bad def ({:?})", self.def)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-29 10:14:01 +00:00
|
|
|
pub type FreevarMap = NodeMap<Vec<Freevar>>;
|
|
|
|
|
|
|
|
pub type CaptureModeMap = NodeMap<CaptureClause>;
|
|
|
|
|
2016-08-19 11:23:36 +00:00
|
|
|
#[derive(Clone, Debug)]
|
2016-04-19 13:43:10 +00:00
|
|
|
pub struct TraitCandidate {
|
|
|
|
pub def_id: DefId,
|
|
|
|
pub import_id: Option<NodeId>,
|
|
|
|
}
|
|
|
|
|
2016-03-29 10:14:01 +00:00
|
|
|
// Trait method resolution
|
2016-04-19 13:43:10 +00:00
|
|
|
pub type TraitMap = NodeMap<Vec<TraitCandidate>>;
|
2016-03-29 10:14:01 +00:00
|
|
|
|
|
|
|
// Map from the NodeId of a glob import to a list of items which are actually
|
|
|
|
// imported.
|
2016-11-08 03:02:55 +00:00
|
|
|
pub type GlobMap = NodeMap<FxHashSet<Name>>;
|
2018-02-19 15:46:40 +00:00
|
|
|
|
|
|
|
|
|
|
|
pub fn provide(providers: &mut Providers) {
|
|
|
|
providers.describe_def = map::describe_def;
|
|
|
|
}
|
2018-01-16 01:08:09 +00:00
|
|
|
|
|
|
|
#[derive(Clone, RustcEncodable, RustcDecodable, Hash)]
|
2018-05-08 13:10:16 +00:00
|
|
|
pub struct CodegenFnAttrs {
|
|
|
|
pub flags: CodegenFnAttrFlags,
|
2018-01-31 03:39:23 +00:00
|
|
|
pub inline: InlineAttr,
|
2018-02-07 03:13:14 +00:00
|
|
|
pub export_name: Option<Symbol>,
|
2018-02-28 01:12:32 +00:00
|
|
|
pub target_features: Vec<Symbol>,
|
2018-02-28 03:08:46 +00:00
|
|
|
pub linkage: Option<Linkage>,
|
2018-01-16 01:08:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bitflags! {
|
|
|
|
#[derive(RustcEncodable, RustcDecodable)]
|
2018-05-08 13:10:16 +00:00
|
|
|
pub struct CodegenFnAttrFlags: u8 {
|
2018-01-16 01:08:09 +00:00
|
|
|
const COLD = 0b0000_0001;
|
|
|
|
const ALLOCATOR = 0b0000_0010;
|
|
|
|
const UNWIND = 0b0000_0100;
|
|
|
|
const RUSTC_ALLOCATOR_NOUNWIND = 0b0000_1000;
|
|
|
|
const NAKED = 0b0001_0000;
|
2018-02-27 01:14:58 +00:00
|
|
|
const NO_MANGLE = 0b0010_0000;
|
2018-02-27 02:14:55 +00:00
|
|
|
const RUSTC_STD_INTERNAL_SYMBOL = 0b0100_0000;
|
2018-04-12 12:51:10 +00:00
|
|
|
const NO_DEBUG = 0b1000_0000;
|
2018-01-16 01:08:09 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-08 13:10:16 +00:00
|
|
|
impl CodegenFnAttrs {
|
|
|
|
pub fn new() -> CodegenFnAttrs {
|
|
|
|
CodegenFnAttrs {
|
|
|
|
flags: CodegenFnAttrFlags::empty(),
|
2018-01-31 03:39:23 +00:00
|
|
|
inline: InlineAttr::None,
|
2018-02-07 03:13:14 +00:00
|
|
|
export_name: None,
|
2018-02-28 01:12:32 +00:00
|
|
|
target_features: vec![],
|
2018-02-28 03:08:46 +00:00
|
|
|
linkage: None,
|
2018-01-31 03:39:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// True if `#[inline]` or `#[inline(always)]` is present.
|
|
|
|
pub fn requests_inline(&self) -> bool {
|
|
|
|
match self.inline {
|
|
|
|
InlineAttr::Hint | InlineAttr::Always => true,
|
|
|
|
InlineAttr::None | InlineAttr::Never => false,
|
2018-01-16 01:08:09 +00:00
|
|
|
}
|
|
|
|
}
|
2018-02-27 01:14:58 +00:00
|
|
|
|
|
|
|
/// True if `#[no_mangle]` or `#[export_name(...)]` is present.
|
|
|
|
pub fn contains_extern_indicator(&self) -> bool {
|
2018-05-08 13:10:16 +00:00
|
|
|
self.flags.contains(CodegenFnAttrFlags::NO_MANGLE) || self.export_name.is_some()
|
2018-02-27 01:14:58 +00:00
|
|
|
}
|
2018-01-16 01:08:09 +00:00
|
|
|
}
|