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::BindingMode::*;
|
|
|
|
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::TraitItem_::*;
|
|
|
|
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
|
|
|
pub use self::PathParameters::*;
|
|
|
|
|
2016-03-29 10:14:01 +00:00
|
|
|
use hir::def::Def;
|
|
|
|
use hir::def_id::DefId;
|
2016-11-08 03:02:55 +00:00
|
|
|
use util::nodemap::{NodeMap, FxHashSet};
|
2016-10-27 20:04:22 +00:00
|
|
|
use rustc_data_structures::fnv::FnvHashMap;
|
2016-03-29 10:14:01 +00:00
|
|
|
|
2016-08-10 17:39:12 +00:00
|
|
|
use syntax_pos::{mk_sp, Span, ExpnId, DUMMY_SP};
|
2016-06-21 22:08:13 +00:00
|
|
|
use syntax::codemap::{self, respan, Spanned};
|
2015-07-31 07:04:06 +00:00
|
|
|
use syntax::abi::Abi;
|
2016-06-20 15:49:33 +00:00
|
|
|
use syntax::ast::{Name, NodeId, DUMMY_NODE_ID, AsmDialect};
|
2015-12-17 17:41:28 +00:00
|
|
|
use syntax::ast::{Attribute, Lit, StrStyle, FloatTy, IntTy, UintTy, MetaItem};
|
2015-07-31 07:04:06 +00:00
|
|
|
use syntax::ptr::P;
|
2016-11-16 10:52:37 +00:00
|
|
|
use syntax::symbol::{Symbol, keywords};
|
2016-06-20 15:49:33 +00:00
|
|
|
use syntax::tokenstream::TokenTree;
|
2016-06-18 04:01:57 +00:00
|
|
|
use syntax::util::ThinVec;
|
2015-07-31 07:04:06 +00:00
|
|
|
|
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
|
|
|
|
2015-12-17 17:41:28 +00:00
|
|
|
/// HIR doesn't commit to a concrete storage type and have its own alias for a vector.
|
|
|
|
/// 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;
|
|
|
|
|
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,
|
2015-09-27 19:23:31 +00:00
|
|
|
pub name: Name,
|
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-03-29 05:50:44 +00:00
|
|
|
print::lifetime_to_string(self))
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// A lifetime definition, eg `'a: 'b+'c+'d`
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub struct LifetimeDef {
|
|
|
|
pub lifetime: Lifetime,
|
2015-12-17 17:41:28 +00:00
|
|
|
pub bounds: HirVec<Lifetime>,
|
2016-10-11 14:06:43 +00:00
|
|
|
pub pure_wrt_drop: bool,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// A "Path" is essentially Rust's notion of a name; for instance:
|
|
|
|
/// std::cmp::PartialEq . It's represented as a sequence of identifiers,
|
|
|
|
/// along with a bunch of supporting information.
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
|
|
|
|
pub struct Path {
|
|
|
|
pub span: Span,
|
|
|
|
/// A `::foo` path, is relative to the crate root rather than current
|
|
|
|
/// module (like paths in an import).
|
|
|
|
pub global: bool,
|
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
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Debug for Path {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2016-03-29 05:50:44 +00:00
|
|
|
write!(f, "path({})", print::path_to_string(self))
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Display for Path {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2016-03-29 05:50:44 +00:00
|
|
|
write!(f, "{}", print::path_to_string(self))
|
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.
|
|
|
|
pub parameters: PathParameters,
|
|
|
|
}
|
|
|
|
|
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 {
|
|
|
|
name: name,
|
|
|
|
parameters: PathParameters::none()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-31 07:04:06 +00:00
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub enum PathParameters {
|
|
|
|
/// The `<'a, A,B,C>` in `foo::bar::baz::<'a, A,B,C>`
|
|
|
|
AngleBracketedParameters(AngleBracketedParameterData),
|
|
|
|
/// The `(A,B)` and `C` in `Foo(A,B) -> C`
|
|
|
|
ParenthesizedParameters(ParenthesizedParameterData),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl PathParameters {
|
|
|
|
pub fn none() -> PathParameters {
|
|
|
|
AngleBracketedParameters(AngleBracketedParameterData {
|
2015-12-17 17:41:28 +00:00
|
|
|
lifetimes: HirVec::new(),
|
2015-12-19 01:20:11 +00:00
|
|
|
types: HirVec::new(),
|
2016-10-17 03:02:23 +00:00
|
|
|
infer_types: true,
|
2015-12-19 01:20:11 +00:00
|
|
|
bindings: HirVec::new(),
|
2015-07-31 07:04:06 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn is_empty(&self) -> bool {
|
|
|
|
match *self {
|
|
|
|
AngleBracketedParameters(ref data) => data.is_empty(),
|
|
|
|
|
|
|
|
// Even if the user supplied no types, something like
|
|
|
|
// `X()` is equivalent to `X<(),()>`.
|
|
|
|
ParenthesizedParameters(..) => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn has_lifetimes(&self) -> bool {
|
|
|
|
match *self {
|
|
|
|
AngleBracketedParameters(ref data) => !data.lifetimes.is_empty(),
|
|
|
|
ParenthesizedParameters(_) => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn has_types(&self) -> bool {
|
|
|
|
match *self {
|
|
|
|
AngleBracketedParameters(ref data) => !data.types.is_empty(),
|
|
|
|
ParenthesizedParameters(..) => true,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns the types that the user wrote. Note that these do not necessarily map to the type
|
|
|
|
/// parameters in the parenthesized case.
|
2015-12-17 17:41:28 +00:00
|
|
|
pub fn types(&self) -> HirVec<&P<Ty>> {
|
2015-07-31 07:04:06 +00:00
|
|
|
match *self {
|
|
|
|
AngleBracketedParameters(ref data) => {
|
|
|
|
data.types.iter().collect()
|
|
|
|
}
|
|
|
|
ParenthesizedParameters(ref data) => {
|
2015-09-27 19:23:31 +00:00
|
|
|
data.inputs
|
|
|
|
.iter()
|
2015-07-31 07:04:06 +00:00
|
|
|
.chain(data.output.iter())
|
|
|
|
.collect()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-17 17:41:28 +00:00
|
|
|
pub fn lifetimes(&self) -> HirVec<&Lifetime> {
|
2015-07-31 07:04:06 +00:00
|
|
|
match *self {
|
|
|
|
AngleBracketedParameters(ref data) => {
|
|
|
|
data.lifetimes.iter().collect()
|
|
|
|
}
|
|
|
|
ParenthesizedParameters(_) => {
|
2015-12-17 17:41:28 +00:00
|
|
|
HirVec::new()
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-17 17:41:28 +00:00
|
|
|
pub fn bindings(&self) -> HirVec<&TypeBinding> {
|
2015-07-31 07:04:06 +00:00
|
|
|
match *self {
|
|
|
|
AngleBracketedParameters(ref data) => {
|
|
|
|
data.bindings.iter().collect()
|
|
|
|
}
|
|
|
|
ParenthesizedParameters(_) => {
|
2015-12-17 17:41:28 +00:00
|
|
|
HirVec::new()
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// A path like `Foo<'a, T>`
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub struct AngleBracketedParameterData {
|
|
|
|
/// The lifetime parameters for this path segment.
|
2015-12-17 17:41:28 +00:00
|
|
|
pub lifetimes: HirVec<Lifetime>,
|
2015-07-31 07:04:06 +00:00
|
|
|
/// The type parameters for this path segment, if present.
|
2015-12-19 01:20:11 +00:00
|
|
|
pub types: HirVec<P<Ty>>,
|
2016-10-17 03:02:23 +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
|
|
|
/// 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>,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl AngleBracketedParameterData {
|
|
|
|
fn is_empty(&self) -> bool {
|
|
|
|
self.lifetimes.is_empty() && self.types.is_empty() && self.bindings.is_empty()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// A path like `Foo(A,B) -> C`
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub struct ParenthesizedParameterData {
|
|
|
|
/// Overall span
|
|
|
|
pub span: Span,
|
|
|
|
|
|
|
|
/// `(A,B)`
|
2015-12-17 17:41:28 +00:00
|
|
|
pub inputs: HirVec<P<Ty>>,
|
2015-07-31 07:04:06 +00:00
|
|
|
|
|
|
|
/// `C`
|
|
|
|
pub output: Option<P<Ty>>,
|
|
|
|
}
|
|
|
|
|
|
|
|
/// 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
|
|
|
}
|
|
|
|
|
|
|
|
/// 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)]
|
|
|
|
pub struct TyParam {
|
2015-09-20 13:47:24 +00:00
|
|
|
pub name: Name,
|
2015-07-31 07:04:06 +00:00
|
|
|
pub id: NodeId,
|
|
|
|
pub bounds: TyParamBounds,
|
|
|
|
pub default: Option<P<Ty>>,
|
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
|
|
|
}
|
|
|
|
|
|
|
|
/// 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 {
|
2015-12-17 17:41:28 +00:00
|
|
|
pub lifetimes: HirVec<LifetimeDef>,
|
2015-12-19 01:20:11 +00:00
|
|
|
pub ty_params: HirVec<TyParam>,
|
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 {
|
|
|
|
lifetimes: HirVec::new(),
|
|
|
|
ty_params: HirVec::new(),
|
|
|
|
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 {
|
|
|
|
!self.lifetimes.is_empty()
|
|
|
|
}
|
2016-03-29 06:32:58 +00:00
|
|
|
|
2015-07-31 07:04:06 +00:00
|
|
|
pub fn is_type_parameterized(&self) -> bool {
|
|
|
|
!self.ty_params.is_empty()
|
|
|
|
}
|
2016-03-29 06:32:58 +00:00
|
|
|
|
2015-07-31 07:04:06 +00:00
|
|
|
pub fn is_parameterized(&self) -> bool {
|
|
|
|
self.is_lt_parameterized() || self.is_type_parameterized()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-12 12:23:38 +00:00
|
|
|
pub enum UnsafeGeneric {
|
|
|
|
Region(LifetimeDef, &'static str),
|
|
|
|
Type(TyParam, &'static str),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl UnsafeGeneric {
|
|
|
|
pub fn attr_name(&self) -> &'static str {
|
|
|
|
match *self {
|
|
|
|
UnsafeGeneric::Region(_, s) => s,
|
|
|
|
UnsafeGeneric::Type(_, s) => s,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Generics {
|
|
|
|
pub fn carries_unsafe_attr(&self) -> Option<UnsafeGeneric> {
|
|
|
|
for r in &self.lifetimes {
|
|
|
|
if r.pure_wrt_drop {
|
|
|
|
return Some(UnsafeGeneric::Region(r.clone(), "may_dangle"));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for t in &self.ty_params {
|
|
|
|
if t.pure_wrt_drop {
|
|
|
|
return Some(UnsafeGeneric::Type(t.clone(), "may_dangle"));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
/// 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
|
|
|
}
|
|
|
|
|
|
|
|
/// A type bound, eg `for<'c> Foo: Send+Clone+'c`
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub struct WhereBoundPredicate {
|
|
|
|
pub span: Span,
|
|
|
|
/// Any lifetimes from a `for` binding
|
2015-12-17 17:41:28 +00:00
|
|
|
pub bound_lifetimes: HirVec<LifetimeDef>,
|
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,
|
|
|
|
pub path: Path,
|
|
|
|
pub ty: P<Ty>,
|
|
|
|
}
|
|
|
|
|
2015-12-17 17:41:28 +00:00
|
|
|
pub type CrateConfig = HirVec<P<MetaItem>>;
|
|
|
|
|
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
|
|
|
|
|
|
|
pub impl_items: BTreeMap<ImplItemId, ImplItem>,
|
2016-10-27 20:04:22 +00:00
|
|
|
pub exprs: FnvHashMap<ExprId, Expr>,
|
2015-11-17 22:32:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Crate {
|
|
|
|
pub fn item(&self, id: NodeId) -> &Item {
|
|
|
|
&self.items[&id]
|
|
|
|
}
|
|
|
|
|
2016-11-02 22:25:31 +00:00
|
|
|
pub fn impl_item(&self, id: ImplItemId) -> &ImplItem {
|
|
|
|
&self.impl_items[&id]
|
|
|
|
}
|
|
|
|
|
2015-11-17 22:32:12 +00:00
|
|
|
/// Visits all items in the crate in some determinstic (but
|
|
|
|
/// unspecified) order. If you just need to process every item,
|
|
|
|
/// but don't care about nesting, this method is the best choice.
|
|
|
|
///
|
|
|
|
/// If you do care about nesting -- usually because your algorithm
|
|
|
|
/// follows lexical scoping rules -- then you want a different
|
|
|
|
/// approach. You should override `visit_nested_item` in your
|
|
|
|
/// visitor and then call `intravisit::walk_crate` instead.
|
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
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
pub fn expr(&self, id: ExprId) -> &Expr {
|
|
|
|
&self.exprs[&id]
|
|
|
|
}
|
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,
|
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,
|
2015-12-17 17:41:28 +00:00
|
|
|
pub body: HirVec<TokenTree>,
|
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,
|
|
|
|
/// Distinguishes between `unsafe { ... }` and `{ ... }`
|
|
|
|
pub rules: BlockCheckMode,
|
|
|
|
pub span: Span,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
|
|
|
|
pub struct Pat {
|
|
|
|
pub id: NodeId,
|
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-03-29 05:50:44 +00:00
|
|
|
write!(f, "pat({}: {})", self.id, print::pat_to_string(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 {
|
|
|
|
/// The identifier for the field
|
2015-09-20 13:47:24 +00:00
|
|
|
pub name: Name,
|
2015-07-31 07:04:06 +00:00
|
|
|
/// The pattern the field is destructured to
|
|
|
|
pub pat: P<Pat>,
|
|
|
|
pub is_shorthand: bool,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
|
|
|
|
pub enum BindingMode {
|
|
|
|
BindByRef(Mutability),
|
|
|
|
BindByValue(Mutability),
|
|
|
|
}
|
|
|
|
|
|
|
|
#[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`.
|
2016-11-25 11:21:19 +00:00
|
|
|
/// The `DefId` is for the definition of the variable being bound.
|
|
|
|
Binding(BindingMode, DefId, 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>),
|
2015-07-31 07:04:06 +00:00
|
|
|
/// A range pattern, e.g. `1...2`
|
2016-02-14 12:25:12 +00:00
|
|
|
Range(P<Expr>, P<Expr>),
|
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
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
|
|
|
|
pub enum Mutability {
|
|
|
|
MutMutable,
|
|
|
|
MutImmutable,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[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()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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-03-29 05:50:44 +00:00
|
|
|
print::stmt_to_string(&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
|
|
|
// FIXME (pending discussion of #1697, #2178...): local should really be
|
|
|
|
// a refinement on pat.
|
|
|
|
/// 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,
|
|
|
|
pub span: Span,
|
2016-06-18 04:01:57 +00:00
|
|
|
pub attrs: ThinVec<Attribute>,
|
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(_) => &[]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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 {
|
2015-09-20 11:00:18 +00:00
|
|
|
pub name: Spanned<Name>,
|
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-10-27 20:04:22 +00:00
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub struct ExprId(NodeId);
|
|
|
|
|
|
|
|
impl ExprId {
|
|
|
|
pub fn node_id(self) -> NodeId {
|
|
|
|
self.0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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>,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2016-11-24 17:25:59 +00:00
|
|
|
impl Expr {
|
|
|
|
pub fn expr_id(&self) -> ExprId {
|
|
|
|
ExprId(self.id)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-31 07:04:06 +00:00
|
|
|
impl fmt::Debug for Expr {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2016-03-29 05:50:44 +00:00
|
|
|
write!(f, "expr({}: {})", self.id, print::expr_to_string(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`),
|
2015-07-31 07:04:06 +00:00
|
|
|
/// and the second field is the list of arguments
|
2016-10-28 10:16:44 +00:00
|
|
|
ExprCall(P<Expr>, HirVec<Expr>),
|
2015-07-31 07:04:06 +00:00
|
|
|
/// A method call (`x.foo::<Bar, Baz>(a, b, c, d)`)
|
|
|
|
///
|
2015-09-20 11:00:18 +00:00
|
|
|
/// The `Spanned<Name>` is the identifier for the method name.
|
2015-07-31 07:04:06 +00:00
|
|
|
/// The vector of `Ty`s are the ascripted type parameters for the method
|
|
|
|
/// (within the angle brackets).
|
|
|
|
///
|
2016-06-28 10:32:45 +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
|
|
|
|
/// `ExprMethodCall(foo, [Bar, Baz], [x, a, b, c, d])`.
|
2016-10-28 10:16:44 +00:00
|
|
|
ExprMethodCall(Spanned<Name>, HirVec<P<Ty>>, 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
|
|
|
|
///
|
|
|
|
/// `if expr { block } else { expr }`
|
|
|
|
ExprIf(P<Expr>, P<Block>, Option<P<Expr>>),
|
|
|
|
/// A while loop, with an optional label
|
|
|
|
///
|
|
|
|
/// `'label: while expr { block }`
|
2016-05-02 16:22:03 +00:00
|
|
|
ExprWhile(P<Expr>, P<Block>, Option<Spanned<Name>>),
|
2015-07-31 07:04:06 +00:00
|
|
|
/// Conditionless loop (can be exited with break, continue, or return)
|
|
|
|
///
|
|
|
|
/// `'label: loop { block }`
|
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
|
|
|
ExprLoop(P<Block>, Option<Spanned<Name>>, 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 `|...|`
|
2016-10-28 20:58:32 +00:00
|
|
|
ExprClosure(CaptureClause, P<FnDecl>, ExprId, Span),
|
2015-07-31 07:04:06 +00:00
|
|
|
/// A block (`{ ... }`)
|
|
|
|
ExprBlock(P<Block>),
|
|
|
|
|
|
|
|
/// An assignment (`a = foo()`)
|
|
|
|
ExprAssign(P<Expr>, P<Expr>),
|
|
|
|
/// An assignment with an operator
|
|
|
|
///
|
|
|
|
/// For example, `a += 1`.
|
|
|
|
ExprAssignOp(BinOp, P<Expr>, P<Expr>),
|
|
|
|
/// Access of a named struct field (`obj.foo`)
|
2015-09-20 11:00:18 +00:00
|
|
|
ExprField(P<Expr>, Spanned<Name>),
|
2015-07-31 07:04:06 +00:00
|
|
|
/// Access of an unnamed field of a struct or tuple-struct
|
|
|
|
///
|
|
|
|
/// For example, `foo.0`.
|
|
|
|
ExprTupField(P<Expr>, Spanned<usize>),
|
|
|
|
/// 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
|
2016-11-25 11:21:19 +00:00
|
|
|
ExprBreak(Option<Label>, Option<P<Expr>>),
|
2015-07-31 07:04:06 +00:00
|
|
|
/// A `continue`, with an optional label
|
2016-11-25 11:21:19 +00:00
|
|
|
ExprAgain(Option<Label>),
|
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.
|
|
|
|
ExprRepeat(P<Expr>, P<Expr>),
|
|
|
|
}
|
|
|
|
|
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`,
|
|
|
|
/// the `X` and `Y` nodes being each a `TyPath(QPath::TypeRelative(..))`.
|
|
|
|
TypeRelative(P<Ty>, P<PathSegment>)
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Display for QPath {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
write!(f, "{}", print::qpath_to_string(self))
|
|
|
|
}
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
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,
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-11-25 11:21:19 +00:00
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
|
|
|
|
pub struct Label {
|
|
|
|
pub span: Span,
|
|
|
|
pub name: Name,
|
|
|
|
pub loop_id: NodeId
|
|
|
|
}
|
|
|
|
|
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>,
|
|
|
|
pub generics: Generics,
|
|
|
|
}
|
|
|
|
|
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,
|
2015-12-17 17:41:28 +00:00
|
|
|
pub attrs: HirVec<Attribute>,
|
2015-07-31 07:04:06 +00:00
|
|
|
pub node: TraitItem_,
|
|
|
|
pub span: Span,
|
|
|
|
}
|
|
|
|
|
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)]
|
|
|
|
pub enum TraitItem_ {
|
2016-06-28 10:32:45 +00:00
|
|
|
/// An associated constant with an optional value (otherwise `impl`s
|
|
|
|
/// must contain a value)
|
2015-07-31 07:04:06 +00:00
|
|
|
ConstTraitItem(P<Ty>, Option<P<Expr>>),
|
2016-06-28 10:32:45 +00:00
|
|
|
/// A method with an optional body
|
2016-10-28 20:58:32 +00:00
|
|
|
MethodTraitItem(MethodSig, Option<ExprId>),
|
2016-06-28 10:32:45 +00:00
|
|
|
/// An associated type with (possibly empty) bounds and optional concrete
|
|
|
|
/// type
|
2015-07-31 07:04:06 +00:00
|
|
|
TypeTraitItem(TyParamBounds, Option<P<Ty>>),
|
|
|
|
}
|
|
|
|
|
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,
|
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>,
|
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
|
2015-11-11 09:37:25 +00:00
|
|
|
Const(P<Ty>, P<Expr>),
|
2016-06-28 10:32:45 +00:00
|
|
|
/// A method implementation with the given signature and body
|
2016-10-28 20:58:32 +00:00
|
|
|
Method(MethodSig, ExprId),
|
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,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Debug for Ty {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2016-03-29 05:50:44 +00:00
|
|
|
write!(f, "type({})", print::ty_to_string(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,
|
2015-12-17 17:41:28 +00:00
|
|
|
pub lifetimes: HirVec<LifetimeDef>,
|
2015-09-27 19:23:31 +00:00
|
|
|
pub decl: P<FnDecl>,
|
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]`)
|
2016-09-20 00:14:46 +00:00
|
|
|
TyArray(P<Ty>, P<Expr>),
|
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`)
|
|
|
|
TyRptr(Option<Lifetime>, MutTy),
|
|
|
|
/// 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),
|
|
|
|
|
2015-07-31 07:04:06 +00:00
|
|
|
/// Something like `A+B`. Note that `B` must always be a path.
|
|
|
|
TyObjectSum(P<Ty>, TyParamBounds),
|
|
|
|
/// A type like `for<'a> Foo<&'a Bar>`
|
|
|
|
TyPolyTraitRef(TyParamBounds),
|
2016-08-01 01:25:32 +00:00
|
|
|
/// An `impl TraitA+TraitB` type.
|
|
|
|
TyImplTrait(TyParamBounds),
|
2015-07-31 07:04:06 +00:00
|
|
|
/// Unused for now
|
|
|
|
TyTypeof(P<Expr>),
|
|
|
|
/// TyInfer means the type should be inferred instead of it having been
|
|
|
|
/// specified. This can appear anywhere in a type.
|
|
|
|
TyInfer,
|
|
|
|
}
|
|
|
|
|
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,
|
|
|
|
pub expn_id: ExpnId,
|
|
|
|
}
|
|
|
|
|
|
|
|
/// represents an argument in a function header
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub struct Arg {
|
|
|
|
pub ty: P<Ty>,
|
|
|
|
pub pat: P<Pat>,
|
|
|
|
pub id: NodeId,
|
|
|
|
}
|
|
|
|
|
2016-05-08 18:19:29 +00:00
|
|
|
/// Alternative representation for `Arg`s describing `self` parameter of methods.
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub enum SelfKind {
|
|
|
|
/// `self`, `mut self`
|
|
|
|
Value(Mutability),
|
|
|
|
/// `&'lt self`, `&'lt mut self`
|
|
|
|
Region(Option<Lifetime>, Mutability),
|
|
|
|
/// `self: TYPE`, `mut self: TYPE`
|
|
|
|
Explicit(P<Ty>, Mutability),
|
|
|
|
}
|
|
|
|
|
|
|
|
pub type ExplicitSelf = Spanned<SelfKind>;
|
|
|
|
|
2015-07-31 07:04:06 +00:00
|
|
|
impl Arg {
|
2016-05-08 18:19:29 +00:00
|
|
|
pub fn to_self(&self) -> Option<ExplicitSelf> {
|
2016-11-25 11:21:19 +00:00
|
|
|
if let PatKind::Binding(BindByValue(mutbl), _, name, _) = self.pat.node {
|
2016-06-10 21:12:39 +00:00
|
|
|
if name.node == keywords::SelfValue.name() {
|
2016-05-08 18:19:29 +00:00
|
|
|
return match self.ty.node {
|
|
|
|
TyInfer => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
|
|
|
|
TyRptr(lt, MutTy{ref ty, mutbl}) if ty.node == TyInfer => {
|
|
|
|
Some(respan(self.pat.span, SelfKind::Region(lt, mutbl)))
|
|
|
|
}
|
|
|
|
_ => Some(respan(mk_sp(self.pat.span.lo, self.ty.span.hi),
|
|
|
|
SelfKind::Explicit(self.ty.clone(), mutbl)))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
None
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn is_self(&self) -> bool {
|
2016-11-25 11:21:19 +00:00
|
|
|
if let PatKind::Binding(_, _, name, _) = self.pat.node {
|
2016-06-10 21:12:39 +00:00
|
|
|
name.node == keywords::SelfValue.name()
|
2016-05-08 18:19:29 +00:00
|
|
|
} else {
|
|
|
|
false
|
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 {
|
2015-12-17 17:41:28 +00:00
|
|
|
pub inputs: HirVec<Arg>,
|
2015-07-31 07:04:06 +00:00
|
|
|
pub output: FunctionRetTy,
|
2015-09-27 19:23:31 +00:00
|
|
|
pub variadic: bool,
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2016-05-08 18:19:29 +00:00
|
|
|
impl FnDecl {
|
2016-03-06 12:54:44 +00:00
|
|
|
pub fn get_self(&self) -> Option<ExplicitSelf> {
|
|
|
|
self.inputs.get(0).and_then(Arg::to_self)
|
|
|
|
}
|
2016-05-08 18:19:29 +00:00
|
|
|
pub fn has_self(&self) -> bool {
|
|
|
|
self.inputs.get(0).map(Arg::is_self).unwrap_or(false)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-31 07:04:06 +00:00
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
#[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`
|
|
|
|
pub disr_expr: Option<P<Expr>>,
|
|
|
|
}
|
|
|
|
|
|
|
|
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>`
|
2015-12-17 17:41:28 +00:00
|
|
|
pub bound_lifetimes: HirVec<LifetimeDef>,
|
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,
|
2016-04-02 20:24:02 +00:00
|
|
|
Crate,
|
|
|
|
Restricted { path: P<Path>, id: NodeId },
|
2015-07-31 07:04:06 +00:00
|
|
|
Inherited,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
2016-02-27 08:34:29 +00:00
|
|
|
pub struct StructField {
|
|
|
|
pub span: Span,
|
2016-02-27 00:05:14 +00:00
|
|
|
pub name: Name,
|
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 {
|
|
|
|
let first = self.name.as_str().as_bytes()[0];
|
|
|
|
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
|
|
|
|
|
|
|
// FIXME (#3300): Should allow items to be anonymous. Right now
|
|
|
|
// we just use dummy names for anon items.
|
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-12-17 17:41:28 +00:00
|
|
|
pub attrs: HirVec<Attribute>,
|
2015-07-31 07:04:06 +00:00
|
|
|
pub id: NodeId,
|
|
|
|
pub node: Item_,
|
|
|
|
pub vis: Visibility,
|
|
|
|
pub span: Span,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
|
|
|
pub enum Item_ {
|
|
|
|
/// An`extern crate` item, with optional original crate name,
|
|
|
|
///
|
|
|
|
/// e.g. `extern crate foo` or `extern crate foo_bar as foo`
|
|
|
|
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
|
|
|
|
ItemStatic(P<Ty>, Mutability, P<Expr>),
|
|
|
|
/// A `const` item
|
|
|
|
ItemConst(P<Ty>, P<Expr>),
|
|
|
|
/// A function declaration
|
2016-10-28 20:58:32 +00:00
|
|
|
ItemFn(P<FnDecl>, Unsafety, Constness, Abi, Generics, ExprId),
|
2015-07-31 07:04:06 +00:00
|
|
|
/// A module
|
|
|
|
ItemMod(Mod),
|
|
|
|
/// An external module
|
|
|
|
ItemForeignMod(ForeignMod),
|
|
|
|
/// A type alias, e.g. `type Foo = Bar<u8>`
|
|
|
|
ItemTy(P<Ty>, Generics),
|
|
|
|
/// 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
|
2015-12-17 17:41:28 +00:00
|
|
|
ItemTrait(Unsafety, Generics, TyParamBounds, HirVec<TraitItem>),
|
2015-07-31 07:04:06 +00:00
|
|
|
|
|
|
|
// Default trait implementations
|
|
|
|
///
|
2015-11-05 21:17:59 +00:00
|
|
|
/// `impl Trait for .. {}`
|
2015-07-31 07:04:06 +00:00
|
|
|
ItemDefaultImpl(Unsafety, TraitRef),
|
|
|
|
/// An implementation, eg `impl<A> Trait for Foo { .. }`
|
|
|
|
ItemImpl(Unsafety,
|
|
|
|
ImplPolarity,
|
|
|
|
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",
|
|
|
|
ItemTy(..) => "type alias",
|
|
|
|
ItemEnum(..) => "enum",
|
|
|
|
ItemStruct(..) => "struct",
|
2016-08-06 18:36:28 +00:00
|
|
|
ItemUnion(..) => "union",
|
2015-07-31 07:04:06 +00:00
|
|
|
ItemTrait(..) => "trait",
|
|
|
|
ItemImpl(..) |
|
2015-09-27 19:23:31 +00:00
|
|
|
ItemDefaultImpl(..) => "item",
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
ForeignItemFn(P<FnDecl>, Generics),
|
|
|
|
/// A foreign static item (`static ext: u8`), with optional mutability
|
|
|
|
/// (the boolean is true when mutable)
|
|
|
|
ForeignItemStatic(P<Ty>, bool),
|
|
|
|
}
|
|
|
|
|
|
|
|
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",
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-03-29 10:14:01 +00:00
|
|
|
|
|
|
|
/// A free variable referred to in a function.
|
|
|
|
#[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
|
|
|
|
pub struct Freevar {
|
|
|
|
/// The variable being accessed free.
|
|
|
|
pub def: Def,
|
|
|
|
|
|
|
|
// First span where it is accessed (there can be multiple).
|
|
|
|
pub span: Span
|
|
|
|
}
|
|
|
|
|
|
|
|
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>>;
|