mod.rs 123.1 KB
Newer Older
1 2
// ignore-tidy-filelength

M
Mateusz Mikuła 已提交
3
#![allow(usage_of_ty_tykind)]
F
flip1995 已提交
4

S
Steven Fackler 已提交
5
pub use self::Variance::*;
6
pub use self::AssociatedItemContainer::*;
S
Steven Fackler 已提交
7 8
pub use self::BorrowKind::*;
pub use self::IntVarValue::*;
9
pub use self::fold::TypeFoldable;
S
Steven Fackler 已提交
10

M
Mark Mansi 已提交
11
use crate::hir::{map as hir_map, FreevarMap, GlobMap, TraitMap};
12
use crate::hir::{HirId, Node};
D
David Wood 已提交
13
use crate::hir::def::{Def, CtorOf, CtorKind, ExportMap};
M
Mark Mansi 已提交
14
use crate::hir::def_id::{CrateNum, DefId, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
15
use rustc_data_structures::svh::Svh;
16
use rustc_macros::HashStable;
M
Mark Mansi 已提交
17 18 19 20 21 22 23 24 25 26 27 28
use crate::ich::Fingerprint;
use crate::ich::StableHashingContext;
use crate::infer::canonical::Canonical;
use crate::middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem};
use crate::middle::resolve_lifetime::ObjectLifetimeDefault;
use crate::mir::Mir;
use crate::mir::interpret::{GlobalId, ErrorHandled};
use crate::mir::GeneratorLayout;
use crate::session::CrateDisambiguator;
use crate::traits::{self, Reveal};
use crate::ty;
use crate::ty::layout::VariantIdx;
C
csmoe 已提交
29
use crate::ty::subst::{Subst, InternalSubsts, SubstsRef};
M
Mark Mansi 已提交
30 31 32 33
use crate::ty::util::{IntTypeExt, Discr};
use crate::ty::walk::TypeWalker;
use crate::util::captures::Captures;
use crate::util::nodemap::{NodeSet, DefIdMap, FxHashMap};
J
John Kåre Alsaker 已提交
34
use arena::SyncDroplessArena;
M
Mark Mansi 已提交
35
use crate::session::DataTypeKind;
36

37
use serialize::{self, Encodable, Encoder};
W
Wesley Wiser 已提交
38
use std::cell::RefCell;
39
use std::cmp::{self, Ordering};
40
use std::fmt;
41
use std::hash::{Hash, Hasher};
42
use std::ops::Deref;
J
John Kåre Alsaker 已提交
43
use rustc_data_structures::sync::{self, Lrc, ParallelIterator, par_iter};
44
use std::slice;
45
use std::{mem, ptr};
L
ljedrz 已提交
46
use syntax::ast::{self, Name, Ident, NodeId};
47
use syntax::attr;
48
use syntax::ext::hygiene::Mark;
49
use syntax::symbol::{keywords, Symbol, LocalInternedString, InternedString};
50
use syntax_pos::Span;
51

52
use smallvec;
53
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
54 55
use rustc_data_structures::stable_hasher::{StableHasher, StableHasherResult,
                                           HashStable};
O
Oliver Schneider 已提交
56

M
Mark Mansi 已提交
57
use crate::hir;
58

S
scalexm 已提交
59
pub use self::sty::{Binder, BoundTy, BoundTyKind, BoundVar, DebruijnIndex, INNERMOST};
60
pub use self::sty::{FnSig, GenSig, CanonicalPolyFnSig, PolyFnSig, PolyGenSig};
V
varkor 已提交
61
pub use self::sty::{InferTy, ParamTy, ParamConst, InferConst, ProjectionTy, ExistentialPredicate};
62
pub use self::sty::{ClosureSubsts, GeneratorSubsts, UpvarSubsts, TypeAndMut};
V
varkor 已提交
63
pub use self::sty::{TraitRef, TyKind, PolyTraitRef};
64
pub use self::sty::{ExistentialTraitRef, PolyExistentialTraitRef};
O
Oliver Scherer 已提交
65
pub use self::sty::{ExistentialProjection, PolyExistentialProjection, Const};
66
pub use self::sty::{BoundRegion, EarlyBoundRegion, FreeRegion, Region};
N
Niko Matsakis 已提交
67
pub use self::sty::RegionKind;
V
varkor 已提交
68
pub use self::sty::{TyVid, IntVid, FloatVid, ConstVid, RegionVid};
69 70
pub use self::sty::BoundRegion::*;
pub use self::sty::InferTy::*;
N
Niko Matsakis 已提交
71
pub use self::sty::RegionKind::*;
V
varkor 已提交
72
pub use self::sty::TyKind::*;
73

74 75 76
pub use self::binding::BindingMode;
pub use self::binding::BindingMode::*;

77
pub use self::context::{TyCtxt, FreeRegionInfo, GlobalArenas, AllArenas, tls, keep_local};
78
pub use self::context::{Lift, TypeckTables, CtxtInterners, GlobalCtxt};
D
David Wood 已提交
79
pub use self::context::{
80
    UserTypeAnnotationIndex, UserType, CanonicalUserType,
81
    CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, ResolvedOpaqueTy,
D
David Wood 已提交
82
};
83

84 85
pub use self::instance::{Instance, InstanceDef};

86
pub use self::trait_def::TraitDef;
87

88
pub use self::query::queries;
89

90
pub mod adjustment;
91
pub mod binding;
92
pub mod cast;
93
#[macro_use]
94
pub mod codec;
95
mod constness;
96
pub mod error;
97
mod erase_regions;
98 99
pub mod fast_reject;
pub mod fold;
A
Andrew Cann 已提交
100
pub mod inhabitedness;
101
pub mod layout;
102 103
pub mod _match;
pub mod outlives;
104
pub mod print;
105
pub mod query;
106
pub mod relate;
107
pub mod steal;
108
pub mod subst;
109
pub mod trait_def;
110 111
pub mod walk;
pub mod wf;
112
pub mod util;
113

114 115
mod context;
mod flags;
116
mod instance;
117 118 119
mod structural_impls;
mod sty;

120
// Data types
121

122 123 124 125 126
#[derive(Clone)]
pub struct Resolutions {
    pub freevars: FreevarMap,
    pub trait_map: TraitMap,
    pub maybe_unused_trait_imports: NodeSet,
127
    pub maybe_unused_extern_crates: Vec<(NodeId, Span)>,
L
ljedrz 已提交
128
    pub export_map: ExportMap<NodeId>,
129
    pub glob_map: GlobMap,
V
Vadim Petrochenkov 已提交
130 131 132
    /// Extern prelude entries. The value is `true` if the entry was introduced
    /// via `extern crate` item and not `--extern` option or compiler built-in.
    pub extern_prelude: FxHashMap<Name, bool>,
133 134
}

135
#[derive(Clone, Copy, PartialEq, Eq, Debug, HashStable)]
136
pub enum AssociatedItemContainer {
N
Niko Matsakis 已提交
137 138
    TraitContainer(DefId),
    ImplContainer(DefId),
139 140
}

141
impl AssociatedItemContainer {
A
Alexander Regueiro 已提交
142 143
    /// Asserts that this is the `DefId` of an associated item declared
    /// in a trait, and returns the trait `DefId`.
144 145 146 147 148 149 150
    pub fn assert_trait(&self) -> DefId {
        match *self {
            TraitContainer(id) => id,
            _ => bug!("associated item has wrong container type: {:?}", self)
        }
    }

N
Niko Matsakis 已提交
151
    pub fn id(&self) -> DefId {
152 153 154 155 156 157 158
        match *self {
            TraitContainer(id) => id,
            ImplContainer(id) => id,
        }
    }
}

A
Aaron Turon 已提交
159 160
/// The "header" of an impl is everything outside the body: a Self type, a trait
/// ref (in the case of a trait impl), and a set of predicates (from the
A
Alexander Regueiro 已提交
161
/// bounds / where-clauses).
A
Aaron Turon 已提交
162 163 164 165 166 167 168 169
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub struct ImplHeader<'tcx> {
    pub impl_def_id: DefId,
    pub self_ty: Ty<'tcx>,
    pub trait_ref: Option<TraitRef<'tcx>>,
    pub predicates: Vec<Predicate<'tcx>>,
}

170
#[derive(Copy, Clone, Debug, PartialEq, HashStable)]
171 172
pub struct AssociatedItem {
    pub def_id: DefId,
173
    #[stable_hasher(project(name))]
174
    pub ident: Ident,
175 176 177 178
    pub kind: AssociatedKind,
    pub vis: Visibility,
    pub defaultness: hir::Defaultness,
    pub container: AssociatedItemContainer,
179

180 181 182 183
    /// Whether this is a method with an explicit self
    /// as its first argument, allowing method calls.
    pub method_has_self_argument: bool,
}
184

185
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, RustcEncodable, RustcDecodable, HashStable)]
186 187 188
pub enum AssociatedKind {
    Const,
    Method,
O
Oliver Schneider 已提交
189
    Existential,
190 191
    Type
}
192

193 194 195 196 197 198
impl AssociatedItem {
    pub fn def(&self) -> Def {
        match self.kind {
            AssociatedKind::Const => Def::AssociatedConst(self.def_id),
            AssociatedKind::Method => Def::Method(self.def_id),
            AssociatedKind::Type => Def::AssociatedTy(self.def_id),
O
Oliver Schneider 已提交
199
            AssociatedKind::Existential => Def::AssociatedExistential(self.def_id),
200 201
        }
    }
A
Andrew Cann 已提交
202 203 204 205 206

    /// Tests whether the associated item admits a non-trivial implementation
    /// for !
    pub fn relevant_for_never<'tcx>(&self) -> bool {
        match self.kind {
O
Oliver Schneider 已提交
207 208
            AssociatedKind::Existential |
            AssociatedKind::Const |
A
Andrew Cann 已提交
209
            AssociatedKind::Type => true,
A
Andrew Cann 已提交
210
            // FIXME(canndrew): Be more thorough here, check if any argument is uninhabited.
A
Andrew Cann 已提交
211 212 213
            AssociatedKind::Method => !self.method_has_self_argument,
        }
    }
214 215 216 217 218 219 220 221

    pub fn signature<'a, 'tcx>(&self, tcx: &TyCtxt<'a, 'tcx, 'tcx>) -> String {
        match self.kind {
            ty::AssociatedKind::Method => {
                // We skip the binder here because the binder would deanonymize all
                // late-bound regions, and we don't want method signatures to show up
                // `as for<'r> fn(&'r MyType)`.  Pretty-printing handles late-bound
                // regions just fine, showing `fn(&MyType)`.
L
ljedrz 已提交
222
                tcx.fn_sig(self.def_id).skip_binder().to_string()
223
            }
224
            ty::AssociatedKind::Type => format!("type {};", self.ident),
O
Oliver Schneider 已提交
225
            ty::AssociatedKind::Existential => format!("existential type {};", self.ident),
226
            ty::AssociatedKind::Const => {
227
                format!("const {}: {:?};", self.ident, tcx.type_of(self.def_id))
228 229 230
            }
        }
    }
231 232
}

233
#[derive(Clone, Debug, PartialEq, Eq, Copy, RustcEncodable, RustcDecodable, HashStable)]
234 235 236 237
pub enum Visibility {
    /// Visible everywhere (including in other crates).
    Public,
    /// Visible only in the given crate-local module.
238
    Restricted(DefId),
239
    /// Not visible anywhere in the local crate. This is the visibility of private external items.
240
    Invisible,
241 242
}

243 244
pub trait DefIdTree: Copy {
    fn parent(self, id: DefId) -> Option<DefId>;
A
Andrew Cann 已提交
245 246 247 248 249 250 251 252 253 254 255 256 257 258

    fn is_descendant_of(self, mut descendant: DefId, ancestor: DefId) -> bool {
        if descendant.krate != ancestor.krate {
            return false;
        }

        while descendant != ancestor {
            match self.parent(descendant) {
                Some(parent) => descendant = parent,
                None => return false,
            }
        }
        true
    }
259 260
}

261 262 263
impl<'a, 'gcx, 'tcx> DefIdTree for TyCtxt<'a, 'gcx, 'tcx> {
    fn parent(self, id: DefId) -> Option<DefId> {
        self.def_key(id).parent.map(|index| DefId { index: index, ..id })
264 265 266
    }
}

267
impl Visibility {
L
ljedrz 已提交
268
    pub fn from_hir(visibility: &hir::Visibility, id: hir::HirId, tcx: TyCtxt<'_, '_, '_>) -> Self {
269
        match visibility.node {
270 271 272
            hir::VisibilityKind::Public => Visibility::Public,
            hir::VisibilityKind::Crate(_) => Visibility::Restricted(DefId::local(CRATE_DEF_INDEX)),
            hir::VisibilityKind::Restricted { ref path, .. } => match path.def {
273 274
                // If there is no resolution, `resolve` will have already reported an error, so
                // assume that the visibility is public to avoid reporting more privacy errors.
275
                Def::Err => Visibility::Public,
276
                def => Visibility::Restricted(def.def_id()),
277
            },
278
            hir::VisibilityKind::Inherited => {
L
ljedrz 已提交
279
                Visibility::Restricted(tcx.hir().get_module_parent_by_hir_id(id))
280
            }
281 282
        }
    }
283

284
    /// Returns `true` if an item with this visibility is accessible from the given block.
A
Andrew Cann 已提交
285
    pub fn is_accessible_from<T: DefIdTree>(self, module: DefId, tree: T) -> bool {
286 287 288 289
        let restriction = match self {
            // Public items are visible everywhere.
            Visibility::Public => return true,
            // Private items from other crates are visible nowhere.
290
            Visibility::Invisible => return false,
291
            // Restricted items are visible in an arbitrary local module.
292
            Visibility::Restricted(other) if other.krate != module.krate => return false,
293 294 295
            Visibility::Restricted(module) => module,
        };

A
Andrew Cann 已提交
296
        tree.is_descendant_of(module, restriction)
297
    }
298

299
    /// Returns `true` if this visibility is at least as accessible as the given visibility
300
    pub fn is_at_least<T: DefIdTree>(self, vis: Visibility, tree: T) -> bool {
301 302
        let vis_restriction = match vis {
            Visibility::Public => return self == Visibility::Public,
303
            Visibility::Invisible => return true,
304 305 306
            Visibility::Restricted(module) => module,
        };

307
        self.is_accessible_from(vis_restriction, tree)
308
    }
309

310
    // Returns `true` if this item is visible anywhere in the local crate.
311 312 313 314 315 316 317
    pub fn is_visible_locally(self) -> bool {
        match self {
            Visibility::Public => true,
            Visibility::Restricted(def_id) => def_id.is_local(),
            Visibility::Invisible => false,
        }
    }
318 319
}

320
#[derive(Copy, Clone, PartialEq, Eq, RustcDecodable, RustcEncodable, Hash, HashStable)]
321
pub enum Variance {
322 323 324 325
    Covariant,      // T<A> <: T<B> iff A <: B -- e.g., function return type
    Invariant,      // T<A> <: T<B> iff B == A -- e.g., type of mutable cell
    Contravariant,  // T<A> <: T<B> iff B <: A -- e.g., function param type
    Bivariant,      // T<A> <: T<B>            -- e.g., unused type parameter
326
}
327

328 329 330 331
/// The crate variances map is computed during typeck and contains the
/// variance of every item in the local crate. You should not use it
/// directly, because to do so will make your pass dependent on the
/// HIR of every item in the local crate. Instead, use
332
/// `tcx.variances_of()` to get the variance for a *particular*
333
/// item.
334
#[derive(HashStable)]
335 336
pub struct CrateVariancesMap {
    /// For each item with generics, maps to a vector of the variance
A
Alexander Regueiro 已提交
337
    /// of its generics. If an item has no generics, it will have no
338
    /// entry.
339
    pub variances: FxHashMap<DefId, Lrc<Vec<ty::Variance>>>,
340 341

    /// An empty vector, useful for cloning.
342
    #[stable_hasher(ignore)]
343
    pub empty_variance: Lrc<Vec<ty::Variance>>,
344 345
}

346 347
impl Variance {
    /// `a.xform(b)` combines the variance of a context with the
A
Alexander Regueiro 已提交
348
    /// variance of a type with the following meaning. If we are in a
349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371
    /// context with variance `a`, and we encounter a type argument in
    /// a position with variance `b`, then `a.xform(b)` is the new
    /// variance with which the argument appears.
    ///
    /// Example 1:
    ///
    ///     *mut Vec<i32>
    ///
    /// Here, the "ambient" variance starts as covariant. `*mut T` is
    /// invariant with respect to `T`, so the variance in which the
    /// `Vec<i32>` appears is `Covariant.xform(Invariant)`, which
    /// yields `Invariant`. Now, the type `Vec<T>` is covariant with
    /// respect to its type argument `T`, and hence the variance of
    /// the `i32` here is `Invariant.xform(Covariant)`, which results
    /// (again) in `Invariant`.
    ///
    /// Example 2:
    ///
    ///     fn(*const Vec<i32>, *mut Vec<i32)
    ///
    /// The ambient variance is covariant. A `fn` type is
    /// contravariant with respect to its parameters, so the variance
    /// within which both pointer types appear is
A
Alexander Regueiro 已提交
372
    /// `Covariant.xform(Contravariant)`, or `Contravariant`. `*const
373 374
    /// T` is covariant with respect to `T`, so the variance within
    /// which the first `Vec<i32>` appears is
A
Alexander Regueiro 已提交
375
    /// `Contravariant.xform(Covariant)` or `Contravariant`. The same
376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405
    /// is true for its `i32` argument. In the `*mut T` case, the
    /// variance of `Vec<i32>` is `Contravariant.xform(Invariant)`,
    /// and hence the outermost type is `Invariant` with respect to
    /// `Vec<i32>` (and its `i32` argument).
    ///
    /// Source: Figure 1 of "Taming the Wildcards:
    /// Combining Definition- and Use-Site Variance" published in PLDI'11.
    pub fn xform(self, v: ty::Variance) -> ty::Variance {
        match (self, v) {
            // Figure 1, column 1.
            (ty::Covariant, ty::Covariant) => ty::Covariant,
            (ty::Covariant, ty::Contravariant) => ty::Contravariant,
            (ty::Covariant, ty::Invariant) => ty::Invariant,
            (ty::Covariant, ty::Bivariant) => ty::Bivariant,

            // Figure 1, column 2.
            (ty::Contravariant, ty::Covariant) => ty::Contravariant,
            (ty::Contravariant, ty::Contravariant) => ty::Covariant,
            (ty::Contravariant, ty::Invariant) => ty::Invariant,
            (ty::Contravariant, ty::Bivariant) => ty::Bivariant,

            // Figure 1, column 3.
            (ty::Invariant, _) => ty::Invariant,

            // Figure 1, column 4.
            (ty::Bivariant, _) => ty::Bivariant,
        }
    }
}

406 407 408
// Contains information needed to resolve types and (in the future) look up
// the types of AST nodes.
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
409
pub struct CReaderCacheKey {
410 411 412 413
    pub cnum: CrateNum,
    pub pos: usize,
}

414 415 416 417
// Flags that we track on types. These flags are propagated upwards
// through the type during type construction, so that we can quickly
// check whether the type has various kinds of types in it without
// recursing over the type itself.
418
bitflags! {
419 420 421 422 423
    pub struct TypeFlags: u32 {
        const HAS_PARAMS         = 1 << 0;
        const HAS_SELF           = 1 << 1;
        const HAS_TY_INFER       = 1 << 2;
        const HAS_RE_INFER       = 1 << 3;
424
        const HAS_RE_PLACEHOLDER = 1 << 4;
425 426 427 428 429

        /// Does this have any `ReEarlyBound` regions? Used to
        /// determine whether substitition is required, since those
        /// represent regions that are bound in a `ty::Generics` and
        /// hence may be substituted.
430
        const HAS_RE_EARLY_BOUND = 1 << 5;
431 432 433

        /// Does this have any region that "appears free" in the type?
        /// Basically anything but `ReLateBound` and `ReErased`.
434
        const HAS_FREE_REGIONS   = 1 << 6;
435 436

        /// Is an error type reachable?
437 438
        const HAS_TY_ERR         = 1 << 7;
        const HAS_PROJECTION     = 1 << 8;
J
John Kåre Alsaker 已提交
439 440

        // FIXME: Rename this to the actual property since it's used for generators too
441
        const HAS_TY_CLOSURE     = 1 << 9;
442

443 444
        /// `true` if there are "names" of types and regions and so forth
        /// that are local to a particular fn
445
        const HAS_FREE_LOCAL_NAMES    = 1 << 10;
446

447 448
        /// Present if the type belongs in a local type context.
        /// Only set for Infer other than Fresh.
449
        const KEEP_IN_LOCAL_TCX  = 1 << 11;
450

451 452
        // Is there a projection that does not involve a bound region?
        // Currently we can't normalize projections w/ bound regions.
453
        const HAS_NORMALIZABLE_PROJECTION = 1 << 12;
454

455 456
        /// Does this have any `ReLateBound` regions? Used to check
        /// if a global bound is safe to evaluate.
457
        const HAS_RE_LATE_BOUND = 1 << 13;
458

S
scalexm 已提交
459 460
        const HAS_TY_PLACEHOLDER = 1 << 14;

V
varkor 已提交
461 462
        const HAS_CT_INFER = 1 << 15;

463 464
        const NEEDS_SUBST        = TypeFlags::HAS_PARAMS.bits |
                                   TypeFlags::HAS_SELF.bits |
465
                                   TypeFlags::HAS_RE_EARLY_BOUND.bits;
466

467 468 469
        /// Flags representing the nominal content of a type,
        /// computed by FlagsComputation. If you add a new nominal
        /// flag, it should be added here too.
470 471 472 473
        const NOMINAL_FLAGS     = TypeFlags::HAS_PARAMS.bits |
                                  TypeFlags::HAS_SELF.bits |
                                  TypeFlags::HAS_TY_INFER.bits |
                                  TypeFlags::HAS_RE_INFER.bits |
V
varkor 已提交
474
                                  TypeFlags::HAS_CT_INFER.bits |
475
                                  TypeFlags::HAS_RE_PLACEHOLDER.bits |
476 477
                                  TypeFlags::HAS_RE_EARLY_BOUND.bits |
                                  TypeFlags::HAS_FREE_REGIONS.bits |
478
                                  TypeFlags::HAS_TY_ERR.bits |
479
                                  TypeFlags::HAS_PROJECTION.bits |
480
                                  TypeFlags::HAS_TY_CLOSURE.bits |
481
                                  TypeFlags::HAS_FREE_LOCAL_NAMES.bits |
482
                                  TypeFlags::KEEP_IN_LOCAL_TCX.bits |
S
scalexm 已提交
483 484
                                  TypeFlags::HAS_RE_LATE_BOUND.bits |
                                  TypeFlags::HAS_TY_PLACEHOLDER.bits;
485
    }
486 487
}

488
pub struct TyS<'tcx> {
V
varkor 已提交
489
    pub sty: TyKind<'tcx>,
490
    pub flags: TypeFlags,
491

492 493 494 495 496 497 498 499
    /// This is a kind of confusing thing: it stores the smallest
    /// binder such that
    ///
    /// (a) the binder itself captures nothing but
    /// (b) all the late-bound things within the type are captured
    ///     by some sub-binder.
    ///
    /// So, for a type without any late-bound things, like `u32`, this
500
    /// will be *innermost*, because that is the innermost binder that
501
    /// captures nothing. But for a type `&'D u32`, where `'D` is a
A
Alexander Regueiro 已提交
502
    /// late-bound region with De Bruijn index `D`, this would be `D + 1`
503 504
    /// -- the binder itself does not capture `D`, but `D` is captured
    /// by an inner binder.
505
    ///
506
    /// We call this concept an "exclusive" binder `D` because all
A
Alexander Regueiro 已提交
507
    /// De Bruijn indices within the type are contained within `0..D`
508
    /// (exclusive).
509
    outer_exclusive_binder: ty::DebruijnIndex,
510 511
}

512 513 514 515
// `TyS` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(target_arch = "x86_64")]
static_assert!(MEM_SIZE_OF_TY_S: ::std::mem::size_of::<TyS<'_>>() == 32);

516 517 518 519 520 521 522 523 524 525 526 527
impl<'tcx> Ord for TyS<'tcx> {
    fn cmp(&self, other: &TyS<'tcx>) -> Ordering {
        self.sty.cmp(&other.sty)
    }
}

impl<'tcx> PartialOrd for TyS<'tcx> {
    fn partial_cmp(&self, other: &TyS<'tcx>) -> Option<Ordering> {
        Some(self.sty.cmp(&other.sty))
    }
}

528
impl<'tcx> PartialEq for TyS<'tcx> {
529
    #[inline]
530
    fn eq(&self, other: &TyS<'tcx>) -> bool {
531
        ptr::eq(self, other)
532 533
    }
}
534
impl<'tcx> Eq for TyS<'tcx> {}
535

A
Alex Crichton 已提交
536 537
impl<'tcx> Hash for TyS<'tcx> {
    fn hash<H: Hasher>(&self, s: &mut H) {
538
        (self as *const TyS<'_>).hash(s)
A
Alex Crichton 已提交
539 540
    }
}
541

G
Guillaume Gomez 已提交
542 543 544
impl<'tcx> TyS<'tcx> {
    pub fn is_primitive_ty(&self) -> bool {
        match self.sty {
545
            TyKind::Bool |
546 547 548 549 550 551 552 553
            TyKind::Char |
            TyKind::Int(_) |
            TyKind::Uint(_) |
            TyKind::Float(_) |
            TyKind::Infer(InferTy::IntVar(_)) |
            TyKind::Infer(InferTy::FloatVar(_)) |
            TyKind::Infer(InferTy::FreshIntTy(_)) |
            TyKind::Infer(InferTy::FreshFloatTy(_)) => true,
V
varkor 已提交
554
            TyKind::Ref(_, x, _) => x.is_primitive_ty(),
G
Guillaume Gomez 已提交
555 556 557
            _ => false,
        }
    }
558 559 560

    pub fn is_suggestable(&self) -> bool {
        match self.sty {
561
            TyKind::Opaque(..) |
V
varkor 已提交
562 563 564 565 566 567
            TyKind::FnDef(..) |
            TyKind::FnPtr(..) |
            TyKind::Dynamic(..) |
            TyKind::Closure(..) |
            TyKind::Infer(..) |
            TyKind::Projection(..) => false,
568 569 570
            _ => true,
        }
    }
G
Guillaume Gomez 已提交
571 572
}

573
impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for ty::TyS<'gcx> {
574
    fn hash_stable<W: StableHasherResult>(&self,
575
                                          hcx: &mut StableHashingContext<'a>,
576 577 578 579 580 581 582
                                          hasher: &mut StableHasher<W>) {
        let ty::TyS {
            ref sty,

            // The other fields just provide fast access to information that is
            // also contained in `sty`, so no need to hash them.
            flags: _,
583 584

            outer_exclusive_binder: _,
585 586 587 588 589 590
        } = *self;

        sty.hash_stable(hcx, hasher);
    }
}

591
pub type Ty<'tcx> = &'tcx TyS<'tcx>;
592

593 594
impl<'tcx> serialize::UseSpecializedEncodable for Ty<'tcx> {}
impl<'tcx> serialize::UseSpecializedDecodable for Ty<'tcx> {}
595

596 597
pub type CanonicalTy<'gcx> = Canonical<'gcx, Ty<'gcx>>;

J
John Kåre Alsaker 已提交
598
extern {
V
varkor 已提交
599 600
    /// A dummy type used to force List to by unsized without requiring fat pointers
    type OpaqueListContents;
J
John Kåre Alsaker 已提交
601 602
}

A
Adam Perry 已提交
603
/// A wrapper for slices with the additional invariant
604 605
/// that the slice is interned and no other slice with
/// the same contents can exist in the same context.
J
John Kåre Alsaker 已提交
606
/// This means we can use pointer for both
607
/// equality comparisons and hashing.
V
varkor 已提交
608
/// Note: `Slice` was already taken by the `Ty`.
J
John Kåre Alsaker 已提交
609
#[repr(C)]
V
varkor 已提交
610
pub struct List<T> {
J
John Kåre Alsaker 已提交
611 612
    len: usize,
    data: [T; 0],
V
varkor 已提交
613
    opaque: OpaqueListContents,
J
John Kåre Alsaker 已提交
614 615
}

V
varkor 已提交
616
unsafe impl<T: Sync> Sync for List<T> {}
J
John Kåre Alsaker 已提交
617

V
varkor 已提交
618
impl<T: Copy> List<T> {
J
John Kåre Alsaker 已提交
619
    #[inline]
V
varkor 已提交
620
    fn from_arena<'tcx>(arena: &'tcx SyncDroplessArena, slice: &[T]) -> &'tcx List<T> {
J
John Kåre Alsaker 已提交
621 622 623 624
        assert!(!mem::needs_drop::<T>());
        assert!(mem::size_of::<T>() != 0);
        assert!(slice.len() != 0);

J
John Kåre Alsaker 已提交
625 626 627 628 629 630
        // Align up the size of the len (usize) field
        let align = mem::align_of::<T>();
        let align_mask = align - 1;
        let offset = mem::size_of::<usize>();
        let offset = (offset + align_mask) & !align_mask;

J
John Kåre Alsaker 已提交
631 632
        let size = offset + slice.len() * mem::size_of::<T>();

J
John Kåre Alsaker 已提交
633
        let mem = arena.alloc_raw(
J
John Kåre Alsaker 已提交
634
            size,
J
John Kåre Alsaker 已提交
635
            cmp::max(mem::align_of::<T>(), mem::align_of::<usize>()));
J
John Kåre Alsaker 已提交
636
        unsafe {
V
varkor 已提交
637
            let result = &mut *(mem.as_mut_ptr() as *mut List<T>);
J
John Kåre Alsaker 已提交
638
            // Write the length
J
John Kåre Alsaker 已提交
639
            result.len = slice.len();
J
John Kåre Alsaker 已提交
640 641

            // Write the elements
J
John Kåre Alsaker 已提交
642
            let arena_slice = slice::from_raw_parts_mut(result.data.as_mut_ptr(), result.len);
J
John Kåre Alsaker 已提交
643 644
            arena_slice.copy_from_slice(slice);

J
John Kåre Alsaker 已提交
645
            result
J
John Kåre Alsaker 已提交
646 647 648 649
        }
    }
}

V
varkor 已提交
650
impl<T: fmt::Debug> fmt::Debug for List<T> {
651
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
J
John Kåre Alsaker 已提交
652 653 654 655
        (**self).fmt(f)
    }
}

V
varkor 已提交
656
impl<T: Encodable> Encodable for List<T> {
J
John Kåre Alsaker 已提交
657 658 659 660 661
    #[inline]
    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
        (**self).encode(s)
    }
}
662

V
varkor 已提交
663 664
impl<T> Ord for List<T> where T: Ord {
    fn cmp(&self, other: &List<T>) -> Ordering {
665
        if self == other { Ordering::Equal } else {
J
John Kåre Alsaker 已提交
666
            <[T] as Ord>::cmp(&**self, &**other)
667 668 669 670
        }
    }
}

V
varkor 已提交
671 672
impl<T> PartialOrd for List<T> where T: PartialOrd {
    fn partial_cmp(&self, other: &List<T>) -> Option<Ordering> {
673
        if self == other { Some(Ordering::Equal) } else {
J
John Kåre Alsaker 已提交
674
            <[T] as PartialOrd>::partial_cmp(&**self, &**other)
675 676 677 678
        }
    }
}

V
varkor 已提交
679
impl<T: PartialEq> PartialEq for List<T> {
680
    #[inline]
V
varkor 已提交
681
    fn eq(&self, other: &List<T>) -> bool {
682
        ptr::eq(self, other)
683 684
    }
}
V
varkor 已提交
685
impl<T: Eq> Eq for List<T> {}
686

V
varkor 已提交
687
impl<T> Hash for List<T> {
J
John Kåre Alsaker 已提交
688
    #[inline]
689
    fn hash<H: Hasher>(&self, s: &mut H) {
V
varkor 已提交
690
        (self as *const List<T>).hash(s)
691 692 693
    }
}

V
varkor 已提交
694
impl<T> Deref for List<T> {
695
    type Target = [T];
J
John Kåre Alsaker 已提交
696
    #[inline(always)]
697
    fn deref(&self) -> &[T] {
J
John Kåre Alsaker 已提交
698
        unsafe {
J
John Kåre Alsaker 已提交
699
            slice::from_raw_parts(self.data.as_ptr(), self.len)
J
John Kåre Alsaker 已提交
700
        }
701 702 703
    }
}

V
varkor 已提交
704
impl<'a, T> IntoIterator for &'a List<T> {
705 706
    type Item = &'a T;
    type IntoIter = <&'a [T] as IntoIterator>::IntoIter;
J
John Kåre Alsaker 已提交
707
    #[inline(always)]
708 709 710 711 712
    fn into_iter(self) -> Self::IntoIter {
        self[..].iter()
    }
}

V
varkor 已提交
713
impl<'tcx> serialize::UseSpecializedDecodable for &'tcx List<Ty<'tcx>> {}
714

V
varkor 已提交
715
impl<T> List<T> {
J
John Kåre Alsaker 已提交
716
    #[inline(always)]
V
varkor 已提交
717
    pub fn empty<'a>() -> &'a List<T> {
J
John Kåre Alsaker 已提交
718 719 720 721
        #[repr(align(64), C)]
        struct EmptySlice([u8; 64]);
        static EMPTY_SLICE: EmptySlice = EmptySlice([0; 64]);
        assert!(mem::align_of::<T>() <= 64);
722
        unsafe {
V
varkor 已提交
723
            &*(&EMPTY_SLICE as *const _ as *const List<T>)
724 725 726 727
        }
    }
}

728
#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
729 730 731 732
pub struct UpvarPath {
    pub hir_id: hir::HirId,
}

A
Alexander Regueiro 已提交
733 734 735
/// Upvars do not get their own `NodeId`. Instead, we use the pair of
/// the original var ID (that is, the root variable that is referenced
/// by the upvar) and the ID of the closure expression.
736
#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
737
pub struct UpvarId {
738
    pub var_path: UpvarPath,
739
    pub closure_expr_id: LocalDefId,
740 741
}

742
#[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable, Copy, HashStable)]
743 744 745 746
pub enum BorrowKind {
    /// Data must be immutable and is aliasable.
    ImmBorrow,

A
Alexander Regueiro 已提交
747
    /// Data must be immutable but not aliasable. This kind of borrow
748
    /// cannot currently be expressed by the user and is used only in
K
king6cong 已提交
749
    /// implicit closure bindings. It is needed when the closure
750 751
    /// is borrowing or mutating a mutable referent, e.g.:
    ///
752
    ///    let x: &mut isize = ...;
753 754 755 756 757
    ///    let y = || *x += 5;
    ///
    /// If we were to try to translate this closure into a more explicit
    /// form, we'd encounter an error with the code as written:
    ///
758 759
    ///    struct Env { x: & &mut isize }
    ///    let x: &mut isize = ...;
760 761 762 763 764 765 766
    ///    let y = (&mut Env { &x }, fn_ptr);  // Closure is pair of env and fn
    ///    fn fn_ptr(env: &mut Env) { **env.x += 5; }
    ///
    /// This is then illegal because you cannot mutate a `&mut` found
    /// in an aliasable location. To solve, you'd have to translate with
    /// an `&mut` borrow:
    ///
767 768
    ///    struct Env { x: & &mut isize }
    ///    let x: &mut isize = ...;
769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787
    ///    let y = (&mut Env { &mut x }, fn_ptr); // changed from &x to &mut x
    ///    fn fn_ptr(env: &mut Env) { **env.x += 5; }
    ///
    /// Now the assignment to `**env.x` is legal, but creating a
    /// mutable pointer to `x` is not because `x` is not mutable. We
    /// could fix this by declaring `x` as `let mut x`. This is ok in
    /// user code, if awkward, but extra weird for closures, since the
    /// borrow is hidden.
    ///
    /// So we introduce a "unique imm" borrow -- the referent is
    /// immutable, but not aliasable. This solves the problem. For
    /// simplicity, we don't give users the way to express this
    /// borrow, it's just used when translating closures.
    UniqueImmBorrow,

    /// Data is mutable and not aliasable.
    MutBorrow
}

788 789
/// Information describing the capture of an upvar. This is computed
/// during `typeck`, specifically by `regionck`.
790
#[derive(PartialEq, Clone, Debug, Copy, RustcEncodable, RustcDecodable, HashStable)]
791
pub enum UpvarCapture<'tcx> {
792 793 794 795 796 797
    /// Upvar is captured by value. This is always true when the
    /// closure is labeled `move`, but can also be true in other cases
    /// depending on inference.
    ByValue,

    /// Upvar is captured by reference.
798
    ByRef(UpvarBorrow<'tcx>),
799 800
}

801
#[derive(PartialEq, Clone, Copy, RustcEncodable, RustcDecodable, HashStable)]
802
pub struct UpvarBorrow<'tcx> {
803 804 805
    /// The kind of borrow: by-ref upvars have access to shared
    /// immutable borrows, which are not part of the normal language
    /// syntax.
806
    pub kind: BorrowKind,
807 808

    /// Region of the resulting reference.
N
Niko Matsakis 已提交
809
    pub region: ty::Region<'tcx>,
810 811
}

812
pub type UpvarListMap = FxHashMap<DefId, Vec<UpvarId>>;
813
pub type UpvarCaptureMap<'tcx> = FxHashMap<UpvarId, UpvarCapture<'tcx>>;
814

815 816
#[derive(Copy, Clone)]
pub struct ClosureUpvar<'tcx> {
817
    pub def: Def,
818 819 820 821
    pub span: Span,
    pub ty: Ty<'tcx>,
}

822
#[derive(Clone, Copy, PartialEq, Eq)]
823
pub enum IntVarValue {
824 825
    IntType(ast::IntTy),
    UintType(ast::UintTy),
826 827
}

828 829 830
#[derive(Clone, Copy, PartialEq, Eq)]
pub struct FloatVarValue(pub ast::FloatTy);

831
impl ty::EarlyBoundRegion {
832
    pub fn to_bound_region(&self) -> ty::BoundRegion {
833
        ty::BoundRegion::BrNamed(self.def_id, self.name)
834
    }
835 836 837 838 839 840

    /// Does this early bound region have a name? Early bound regions normally
    /// always have names except when using anonymous lifetimes (`'_`).
    pub fn has_name(&self) -> bool {
        self.name != keywords::UnderscoreLifetime.name().as_interned_str()
    }
841 842
}

843
#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
844
pub enum GenericParamDefKind {
V
varkor 已提交
845
    Lifetime,
846 847 848 849
    Type {
        has_default: bool,
        object_lifetime_default: ObjectLifetimeDefault,
        synthetic: Option<hir::SyntheticTyParamKind>,
V
varkor 已提交
850 851
    },
    Const,
V
varkor 已提交
852 853
}

854
#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
855 856 857 858
pub struct GenericParamDef {
    pub name: InternedString,
    pub def_id: DefId,
    pub index: u32,
V
varkor 已提交
859 860 861 862 863 864

    /// `pure_wrt_drop`, set by the (unsafe) `#[may_dangle]` attribute
    /// on generic parameter `'a`/`T`, asserts data behind the parameter
    /// `'a`/`T` won't be accessed during the parent type's `Drop` impl.
    pub pure_wrt_drop: bool,

865 866 867
    pub kind: GenericParamDefKind,
}

V
varkor 已提交
868
impl GenericParamDef {
869
    pub fn to_early_bound_region_data(&self) -> ty::EarlyBoundRegion {
L
ljedrz 已提交
870 871 872 873 874
        if let GenericParamDefKind::Lifetime = self.kind {
            ty::EarlyBoundRegion {
                def_id: self.def_id,
                index: self.index,
                name: self.name,
875
            }
L
ljedrz 已提交
876 877
        } else {
            bug!("cannot convert a non-lifetime parameter def to an early bound region")
878 879 880 881
        }
    }

    pub fn to_bound_region(&self) -> ty::BoundRegion {
L
ljedrz 已提交
882 883 884 885
        if let GenericParamDefKind::Lifetime = self.kind {
            self.to_early_bound_region_data().to_bound_region()
        } else {
            bug!("cannot convert a non-lifetime parameter def to an early bound region")
V
varkor 已提交
886 887 888 889
        }
    }
}

V
varkor 已提交
890
#[derive(Default)]
891 892 893
pub struct GenericParamCount {
    pub lifetimes: usize,
    pub types: usize,
V
varkor 已提交
894
    pub consts: usize,
895 896
}

897
/// Information about the formal type/lifetime parameters associated
898
/// with an item or method. Analogous to `hir::Generics`.
A
Ariel Ben-Yehuda 已提交
899
///
900 901
/// The ordering of parameters is the same as in `Subst` (excluding child generics):
/// `Self` (optionally), `Lifetime` params..., `Type` params...
902
#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
903
pub struct Generics {
904
    pub parent: Option<DefId>,
V
varkor 已提交
905
    pub parent_count: usize,
V
varkor 已提交
906
    pub params: Vec<GenericParamDef>,
907

V
varkor 已提交
908
    /// Reverse map to the `index` field of each `GenericParamDef`
909
    #[stable_hasher(ignore)]
910
    pub param_def_id_to_index: FxHashMap<DefId, u32>,
911

912
    pub has_self: bool,
913
    pub has_late_bound_regions: Option<Span>,
914 915
}

916
impl<'a, 'gcx, 'tcx> Generics {
917
    pub fn count(&self) -> usize {
V
varkor 已提交
918
        self.parent_count + self.params.len()
919
    }
920

V
varkor 已提交
921
    pub fn own_counts(&self) -> GenericParamCount {
922 923 924
        // We could cache this as a property of `GenericParamCount`, but
        // the aim is to refactor this away entirely eventually and the
        // presence of this method will be a constant reminder.
V
varkor 已提交
925
        let mut own_counts: GenericParamCount = Default::default();
926

V
varkor 已提交
927
        for param in &self.params {
928
            match param.kind {
V
varkor 已提交
929
                GenericParamDefKind::Lifetime => own_counts.lifetimes += 1,
930
                GenericParamDefKind::Type { .. } => own_counts.types += 1,
V
varkor 已提交
931
                GenericParamDefKind::Const => own_counts.consts += 1,
932 933 934
            };
        }

V
varkor 已提交
935
        own_counts
936 937
    }

938
    pub fn requires_monomorphization(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> bool {
V
varkor 已提交
939 940
        if self.own_requires_monomorphization() {
            return true;
V
varkor 已提交
941
        }
V
varkor 已提交
942

V
varkor 已提交
943 944
        if let Some(parent_def_id) = self.parent {
            let parent = tcx.generics_of(parent_def_id);
945
            parent.requires_monomorphization(tcx)
V
varkor 已提交
946 947 948
        } else {
            false
        }
V
varkor 已提交
949 950
    }

V
varkor 已提交
951 952 953 954 955 956 957 958 959 960
    pub fn own_requires_monomorphization(&self) -> bool {
        for param in &self.params {
            match param.kind {
                GenericParamDefKind::Type { .. } | GenericParamDefKind::Const => return true,
                GenericParamDefKind::Lifetime => {}
            }
        }
        false
    }

961 962 963
    pub fn region_param(&'tcx self,
                        param: &EarlyBoundRegion,
                        tcx: TyCtxt<'a, 'gcx, 'tcx>)
964
                        -> &'tcx GenericParamDef
965
    {
V
varkor 已提交
966
        if let Some(index) = param.index.checked_sub(self.parent_count as u32) {
V
varkor 已提交
967
            let param = &self.params[index as usize];
968
            match param.kind {
V
varkor 已提交
969
                GenericParamDefKind::Lifetime => param,
V
varkor 已提交
970
                _ => bug!("expected lifetime parameter, but found another generic parameter")
V
varkor 已提交
971
            }
972
        } else {
973
            tcx.generics_of(self.parent.expect("parent_count > 0 but no parent?"))
L
ljedrz 已提交
974
               .region_param(param, tcx)
975
        }
976 977
    }

978
    /// Returns the `GenericParamDef` associated with this `ParamTy`.
979 980
    pub fn type_param(&'tcx self,
                      param: &ParamTy,
A
Ariel Ben-Yehuda 已提交
981
                      tcx: TyCtxt<'a, 'gcx, 'tcx>)
982
                      -> &'tcx GenericParamDef {
983
        if let Some(index) = param.idx.checked_sub(self.parent_count as u32) {
V
varkor 已提交
984 985
            let param = &self.params[index as usize];
            match param.kind {
V
varkor 已提交
986
                GenericParamDefKind::Type { .. } => param,
V
varkor 已提交
987 988
                _ => bug!("expected type parameter, but found another generic parameter")
            }
989
        } else {
990
            tcx.generics_of(self.parent.expect("parent_count > 0 but no parent?"))
L
ljedrz 已提交
991
               .type_param(param, tcx)
992
        }
993
    }
V
varkor 已提交
994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010

    /// Returns the `ConstParameterDef` associated with this `ParamConst`.
    pub fn const_param(&'tcx self,
                       param: &ParamConst,
                       tcx: TyCtxt<'a, 'gcx, 'tcx>)
                       -> &GenericParamDef {
        if let Some(index) = param.index.checked_sub(self.parent_count as u32) {
            let param = &self.params[index as usize];
            match param.kind {
                GenericParamDefKind::Const => param,
                _ => bug!("expected const parameter, but found another generic parameter")
            }
        } else {
            tcx.generics_of(self.parent.expect("parent_count>0 but no parent?"))
                .const_param(param, tcx)
        }
    }
1011 1012
}

1013
/// Bounds on generics.
1014
#[derive(Clone, Default, Debug, HashStable)]
1015
pub struct GenericPredicates<'tcx> {
1016
    pub parent: Option<DefId>,
1017
    pub predicates: Vec<(Predicate<'tcx>, Span)>,
1018 1019
}

1020 1021 1022
impl<'tcx> serialize::UseSpecializedEncodable for GenericPredicates<'tcx> {}
impl<'tcx> serialize::UseSpecializedDecodable for GenericPredicates<'tcx> {}

1023
impl<'a, 'gcx, 'tcx> GenericPredicates<'tcx> {
C
csmoe 已提交
1024
    pub fn instantiate(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, substs: SubstsRef<'tcx>)
1025
                       -> InstantiatedPredicates<'tcx> {
1026 1027 1028 1029
        let mut instantiated = InstantiatedPredicates::empty();
        self.instantiate_into(tcx, &mut instantiated, substs);
        instantiated
    }
1030

C
csmoe 已提交
1031
    pub fn instantiate_own(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, substs: SubstsRef<'tcx>)
1032
                           -> InstantiatedPredicates<'tcx> {
1033
        InstantiatedPredicates {
1034
            predicates: self.predicates.iter().map(|(p, _)| p.subst(tcx, substs)).collect(),
1035 1036 1037 1038 1039
        }
    }

    fn instantiate_into(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
                        instantiated: &mut InstantiatedPredicates<'tcx>,
C
csmoe 已提交
1040
                        substs: SubstsRef<'tcx>) {
1041
        if let Some(def_id) = self.parent {
1042
            tcx.predicates_of(def_id).instantiate_into(tcx, instantiated, substs);
1043
        }
1044 1045 1046
        instantiated.predicates.extend(
            self.predicates.iter().map(|(p, _)| p.subst(tcx, substs)),
        );
1047
    }
1048

1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060
    pub fn instantiate_identity(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>)
                                -> InstantiatedPredicates<'tcx> {
        let mut instantiated = InstantiatedPredicates::empty();
        self.instantiate_identity_into(tcx, &mut instantiated);
        instantiated
    }

    fn instantiate_identity_into(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
                                 instantiated: &mut InstantiatedPredicates<'tcx>) {
        if let Some(def_id) = self.parent {
            tcx.predicates_of(def_id).instantiate_identity_into(tcx, instantiated);
        }
1061
        instantiated.predicates.extend(self.predicates.iter().map(|&(p, _)| p))
1062 1063
    }

1064
    pub fn instantiate_supertrait(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
1065 1066 1067
                                  poly_trait_ref: &ty::PolyTraitRef<'tcx>)
                                  -> InstantiatedPredicates<'tcx>
    {
1068
        assert_eq!(self.parent, None);
1069
        InstantiatedPredicates {
1070
            predicates: self.predicates.iter().map(|(pred, _)| {
1071
                pred.subst_supertrait(tcx, poly_trait_ref)
1072
            }).collect()
1073 1074
        }
    }
1075 1076
}

1077
#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
1078
pub enum Predicate<'tcx> {
1079
    /// Corresponds to `where Foo: Bar<A,B,C>`. `Foo` here would be
N
Niko Matsakis 已提交
1080
    /// the `Self` type of the trait reference and `A`, `B`, and `C`
1081
    /// would be the type parameters.
1082
    Trait(PolyTraitPredicate<'tcx>),
1083

1084
    /// where `'a: 'b`
1085
    RegionOutlives(PolyRegionOutlivesPredicate<'tcx>),
1086

1087
    /// where `T: 'a`
1088
    TypeOutlives(PolyTypeOutlivesPredicate<'tcx>),
1089

1090 1091
    /// where `<T as TraitRef>::Name == X`, approximately.
    /// See the `ProjectionPredicate` struct for details.
1092
    Projection(PolyProjectionPredicate<'tcx>),
1093

1094
    /// no syntax: `T` well-formed
1095 1096 1097
    WellFormed(Ty<'tcx>),

    /// trait must be object-safe
N
Niko Matsakis 已提交
1098
    ObjectSafe(DefId),
1099

1100
    /// No direct syntax. May be thought of as `where T: FnFoo<...>`
1101
    /// for some substitutions `...` and `T` being a closure type.
1102
    /// Satisfied (or refuted) once we know the closure's kind.
1103
    ClosureKind(DefId, ClosureSubsts<'tcx>, ClosureKind),
N
Niko Matsakis 已提交
1104 1105 1106

    /// `T1 <: T2`
    Subtype(PolySubtypePredicate<'tcx>),
1107 1108

    /// Constant initializer must evaluate successfully.
C
csmoe 已提交
1109
    ConstEvaluatable(DefId, SubstsRef<'tcx>),
1110 1111
}

1112 1113 1114 1115 1116 1117
/// The crate outlives map is computed during typeck and contains the
/// outlives of every item in the local crate. You should not use it
/// directly, because to do so will make your pass dependent on the
/// HIR of every item in the local crate. Instead, use
/// `tcx.inferred_outlives_of()` to get the outlives for a *particular*
/// item.
1118
#[derive(HashStable)]
1119 1120 1121 1122
pub struct CratePredicatesMap<'tcx> {
    /// For each struct with outlive bounds, maps to a vector of the
    /// predicate of its outlive bounds. If an item has no outlives
    /// bounds, it will have no entry.
J
John Kåre Alsaker 已提交
1123
    pub predicates: FxHashMap<DefId, &'tcx [ty::Predicate<'tcx>]>,
1124 1125
}

1126 1127 1128 1129 1130 1131
impl<'tcx> AsRef<Predicate<'tcx>> for Predicate<'tcx> {
    fn as_ref(&self) -> &Predicate<'tcx> {
        self
    }
}

1132
impl<'a, 'gcx, 'tcx> Predicate<'tcx> {
1133
    /// Performs a substitution suitable for going from a
1134 1135
    /// poly-trait-ref to supertraits that must hold if that
    /// poly-trait-ref holds. This is slightly different from a normal
A
Alexander Regueiro 已提交
1136
    /// substitution in terms of what happens with bound regions. See
1137
    /// lengthy comment below for details.
1138
    pub fn subst_supertrait(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
1139 1140 1141 1142 1143 1144 1145 1146
                            trait_ref: &ty::PolyTraitRef<'tcx>)
                            -> ty::Predicate<'tcx>
    {
        // The interaction between HRTB and supertraits is not entirely
        // obvious. Let me walk you (and myself) through an example.
        //
        // Let's start with an easy case. Consider two traits:
        //
1147
        //     trait Foo<'a>: Bar<'a,'a> { }
1148 1149
        //     trait Bar<'b,'c> { }
        //
1150 1151
        // Now, if we have a trait reference `for<'x> T: Foo<'x>`, then
        // we can deduce that `for<'x> T: Bar<'x,'x>`. Basically, if we
1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163
        // knew that `Foo<'x>` (for any 'x) then we also know that
        // `Bar<'x,'x>` (for any 'x). This more-or-less falls out from
        // normal substitution.
        //
        // In terms of why this is sound, the idea is that whenever there
        // is an impl of `T:Foo<'a>`, it must show that `T:Bar<'a,'a>`
        // holds.  So if there is an impl of `T:Foo<'a>` that applies to
        // all `'a`, then we must know that `T:Bar<'a,'a>` holds for all
        // `'a`.
        //
        // Another example to be careful of is this:
        //
1164
        //     trait Foo1<'a>: for<'b> Bar1<'a,'b> { }
1165 1166
        //     trait Bar1<'b,'c> { }
        //
1167 1168
        // Here, if we have `for<'x> T: Foo1<'x>`, then what do we know?
        // The answer is that we know `for<'x,'b> T: Bar1<'x,'b>`. The
1169
        // reason is similar to the previous example: any impl of
1170
        // `T:Foo1<'x>` must show that `for<'b> T: Bar1<'x, 'b>`.  So
1171 1172 1173 1174 1175 1176
        // basically we would want to collapse the bound lifetimes from
        // the input (`trait_ref`) and the supertraits.
        //
        // To achieve this in practice is fairly straightforward. Let's
        // consider the more complicated scenario:
        //
1177 1178
        // - We start out with `for<'x> T: Foo1<'x>`. In this case, `'x`
        //   has a De Bruijn index of 1. We want to produce `for<'x,'b> T: Bar1<'x,'b>`,
1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201
        //   where both `'x` and `'b` would have a DB index of 1.
        //   The substitution from the input trait-ref is therefore going to be
        //   `'a => 'x` (where `'x` has a DB index of 1).
        // - The super-trait-ref is `for<'b> Bar1<'a,'b>`, where `'a` is an
        //   early-bound parameter and `'b' is a late-bound parameter with a
        //   DB index of 1.
        // - If we replace `'a` with `'x` from the input, it too will have
        //   a DB index of 1, and thus we'll have `for<'x,'b> Bar1<'x,'b>`
        //   just as we wanted.
        //
        // There is only one catch. If we just apply the substitution `'a
        // => 'x` to `for<'b> Bar1<'a,'b>`, the substitution code will
        // adjust the DB index because we substituting into a binder (it
        // tries to be so smart...) resulting in `for<'x> for<'b>
        // Bar1<'x,'b>` (we have no syntax for this, so use your
        // imagination). Basically the 'x will have DB index of 2 and 'b
        // will have DB index of 1. Not quite what we want. So we apply
        // the substitution to the *contents* of the trait reference,
        // rather than the trait reference itself (put another way, the
        // substitution code expects equal binding levels in the values
        // from the substitution and the value being substituted into, and
        // this trick achieves that).

1202
        let substs = &trait_ref.skip_binder().substs;
1203
        match *self {
1204 1205 1206 1207 1208 1209 1210 1211 1212 1213
            Predicate::Trait(ref binder) =>
                Predicate::Trait(binder.map_bound(|data| data.subst(tcx, substs))),
            Predicate::Subtype(ref binder) =>
                Predicate::Subtype(binder.map_bound(|data| data.subst(tcx, substs))),
            Predicate::RegionOutlives(ref binder) =>
                Predicate::RegionOutlives(binder.map_bound(|data| data.subst(tcx, substs))),
            Predicate::TypeOutlives(ref binder) =>
                Predicate::TypeOutlives(binder.map_bound(|data| data.subst(tcx, substs))),
            Predicate::Projection(ref binder) =>
                Predicate::Projection(binder.map_bound(|data| data.subst(tcx, substs))),
1214 1215 1216 1217
            Predicate::WellFormed(data) =>
                Predicate::WellFormed(data.subst(tcx, substs)),
            Predicate::ObjectSafe(trait_def_id) =>
                Predicate::ObjectSafe(trait_def_id),
1218 1219
            Predicate::ClosureKind(closure_def_id, closure_substs, kind) =>
                Predicate::ClosureKind(closure_def_id, closure_substs.subst(tcx, substs), kind),
1220 1221
            Predicate::ConstEvaluatable(def_id, const_substs) =>
                Predicate::ConstEvaluatable(def_id, const_substs.subst(tcx, substs)),
1222 1223 1224 1225
        }
    }
}

1226
#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
1227
pub struct TraitPredicate<'tcx> {
1228
    pub trait_ref: TraitRef<'tcx>
1229
}
1230

1231 1232 1233
pub type PolyTraitPredicate<'tcx> = ty::Binder<TraitPredicate<'tcx>>;

impl<'tcx> TraitPredicate<'tcx> {
N
Niko Matsakis 已提交
1234
    pub fn def_id(&self) -> DefId {
1235 1236 1237
        self.trait_ref.def_id
    }

1238
    pub fn input_types<'a>(&'a self) -> impl DoubleEndedIterator<Item=Ty<'tcx>> + 'a {
1239
        self.trait_ref.input_types()
1240 1241 1242 1243 1244 1245 1246 1247
    }

    pub fn self_ty(&self) -> Ty<'tcx> {
        self.trait_ref.self_ty()
    }
}

impl<'tcx> PolyTraitPredicate<'tcx> {
N
Niko Matsakis 已提交
1248
    pub fn def_id(&self) -> DefId {
1249
        // ok to skip binder since trait def-id does not care about regions
1250
        self.skip_binder().def_id()
1251
    }
1252 1253
}

1254 1255
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord,
         Hash, Debug, RustcEncodable, RustcDecodable, HashStable)]
1256
pub struct OutlivesPredicate<A,B>(pub A, pub B); // `A: B`
1257
pub type PolyOutlivesPredicate<A,B> = ty::Binder<OutlivesPredicate<A,B>>;
S
scalexm 已提交
1258 1259 1260 1261 1262 1263
pub type RegionOutlivesPredicate<'tcx> = OutlivesPredicate<ty::Region<'tcx>,
                                                           ty::Region<'tcx>>;
pub type TypeOutlivesPredicate<'tcx> = OutlivesPredicate<Ty<'tcx>,
                                                         ty::Region<'tcx>>;
pub type PolyRegionOutlivesPredicate<'tcx> = ty::Binder<RegionOutlivesPredicate<'tcx>>;
pub type PolyTypeOutlivesPredicate<'tcx> = ty::Binder<TypeOutlivesPredicate<'tcx>>;
1264

1265
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable, HashStable)]
N
Niko Matsakis 已提交
1266 1267 1268 1269 1270 1271 1272
pub struct SubtypePredicate<'tcx> {
    pub a_is_expected: bool,
    pub a: Ty<'tcx>,
    pub b: Ty<'tcx>
}
pub type PolySubtypePredicate<'tcx> = ty::Binder<SubtypePredicate<'tcx>>;

1273 1274 1275
/// This kind of predicate has no *direct* correspondent in the
/// syntax, but it roughly corresponds to the syntactic forms:
///
A
Alexander Regueiro 已提交
1276
/// 1. `T: TraitRef<..., Item = Type>`
1277 1278 1279
/// 2. `<T as TraitRef<...>>::Item == Type` (NYI)
///
/// In particular, form #1 is "desugared" to the combination of a
A
Alexander Regueiro 已提交
1280
/// normal trait predicate (`T: TraitRef<...>`) and one of these
1281
/// predicates. Form #2 is a broader form in that it also permits
1282 1283
/// equality between arbitrary types. Processing an instance of
/// Form #2 eventually yields one of these `ProjectionPredicate`
1284
/// instances to normalize the LHS.
1285
#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
1286 1287 1288 1289 1290 1291 1292
pub struct ProjectionPredicate<'tcx> {
    pub projection_ty: ProjectionTy<'tcx>,
    pub ty: Ty<'tcx>,
}

pub type PolyProjectionPredicate<'tcx> = Binder<ProjectionPredicate<'tcx>>;

1293
impl<'tcx> PolyProjectionPredicate<'tcx> {
1294
    /// Returns the `DefId` of the associated item being projected.
1295 1296 1297 1298
    pub fn item_def_id(&self) -> DefId {
        self.skip_binder().projection_ty.item_def_id
    }

1299
    #[inline]
1300
    pub fn to_poly_trait_ref(&self, tcx: TyCtxt<'_, '_, '_>) -> PolyTraitRef<'tcx> {
1301 1302
        // Note: unlike with `TraitRef::to_poly_trait_ref()`,
        // `self.0.trait_ref` is permitted to have escaping regions.
1303 1304 1305
        // This is because here `self` has a `Binder` and so does our
        // return value, so we are preserving the number of binding
        // levels.
1306
        self.map_bound(|predicate| predicate.projection_ty.trait_ref(tcx))
1307
    }
1308 1309

    pub fn ty(&self) -> Binder<Ty<'tcx>> {
1310 1311 1312
        self.map_bound(|predicate| predicate.ty)
    }

1313
    /// The `DefId` of the `TraitItem` for the associated type.
1314
    ///
1315 1316
    /// Note that this is not the `DefId` of the `TraitRef` containing this
    /// associated type, which is in `tcx.associated_item(projection_def_id()).container`.
1317
    pub fn projection_def_id(&self) -> DefId {
1318
        // okay to skip binder since trait def-id does not care about regions
1319
        self.skip_binder().projection_ty.item_def_id
1320
    }
1321 1322
}

1323 1324 1325 1326
pub trait ToPolyTraitRef<'tcx> {
    fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx>;
}

1327
impl<'tcx> ToPolyTraitRef<'tcx> for TraitRef<'tcx> {
1328
    fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> {
1329
        ty::Binder::dummy(self.clone())
1330 1331 1332 1333 1334
    }
}

impl<'tcx> ToPolyTraitRef<'tcx> for PolyTraitPredicate<'tcx> {
    fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> {
1335
        self.map_bound_ref(|trait_pred| trait_pred.trait_ref)
1336 1337 1338
    }
}

1339 1340
pub trait ToPredicate<'tcx> {
    fn to_predicate(&self) -> Predicate<'tcx>;
1341 1342
}

1343 1344
impl<'tcx> ToPredicate<'tcx> for TraitRef<'tcx> {
    fn to_predicate(&self) -> Predicate<'tcx> {
1345
        ty::Predicate::Trait(ty::Binder::dummy(ty::TraitPredicate {
1346 1347 1348 1349 1350
            trait_ref: self.clone()
        }))
    }
}

1351 1352
impl<'tcx> ToPredicate<'tcx> for PolyTraitRef<'tcx> {
    fn to_predicate(&self) -> Predicate<'tcx> {
1353
        ty::Predicate::Trait(self.to_poly_trait_predicate())
1354 1355 1356
    }
}

1357
impl<'tcx> ToPredicate<'tcx> for PolyRegionOutlivesPredicate<'tcx> {
1358
    fn to_predicate(&self) -> Predicate<'tcx> {
1359 1360 1361 1362
        Predicate::RegionOutlives(self.clone())
    }
}

1363 1364
impl<'tcx> ToPredicate<'tcx> for PolyTypeOutlivesPredicate<'tcx> {
    fn to_predicate(&self) -> Predicate<'tcx> {
1365 1366
        Predicate::TypeOutlives(self.clone())
    }
1367 1368
}

1369 1370
impl<'tcx> ToPredicate<'tcx> for PolyProjectionPredicate<'tcx> {
    fn to_predicate(&self) -> Predicate<'tcx> {
1371 1372 1373 1374
        Predicate::Projection(self.clone())
    }
}

1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419
// A custom iterator used by Predicate::walk_tys.
enum WalkTysIter<'tcx, I, J, K>
    where I: Iterator<Item = Ty<'tcx>>,
          J: Iterator<Item = Ty<'tcx>>,
          K: Iterator<Item = Ty<'tcx>>
{
    None,
    One(Ty<'tcx>),
    Two(Ty<'tcx>, Ty<'tcx>),
    Types(I),
    InputTypes(J),
    ProjectionTypes(K)
}

impl<'tcx, I, J, K> Iterator for WalkTysIter<'tcx, I, J, K>
    where I: Iterator<Item = Ty<'tcx>>,
          J: Iterator<Item = Ty<'tcx>>,
          K: Iterator<Item = Ty<'tcx>>
{
    type Item = Ty<'tcx>;

    fn next(&mut self) -> Option<Ty<'tcx>> {
        match *self {
            WalkTysIter::None => None,
            WalkTysIter::One(item) => {
                *self = WalkTysIter::None;
                Some(item)
            },
            WalkTysIter::Two(item1, item2) => {
                *self = WalkTysIter::One(item2);
                Some(item1)
            },
            WalkTysIter::Types(ref mut iter) => {
                iter.next()
            },
            WalkTysIter::InputTypes(ref mut iter) => {
                iter.next()
            },
            WalkTysIter::ProjectionTypes(ref mut iter) => {
                iter.next()
            }
        }
    }
}

1420
impl<'tcx> Predicate<'tcx> {
1421 1422 1423
    /// Iterates over the types in this predicate. Note that in all
    /// cases this is skipping over a binder, so late-bound regions
    /// with depth 0 are bound by the predicate.
1424 1425
    pub fn walk_tys(&'a self) -> impl Iterator<Item = Ty<'tcx>> + 'a {
        match *self {
1426
            ty::Predicate::Trait(ref data) => {
1427
                WalkTysIter::InputTypes(data.skip_binder().input_types())
1428
            }
1429 1430
            ty::Predicate::Subtype(binder) => {
                let SubtypePredicate { a, b, a_is_expected: _ } = binder.skip_binder();
1431
                WalkTysIter::Two(a, b)
N
Niko Matsakis 已提交
1432
            }
1433
            ty::Predicate::TypeOutlives(binder) => {
1434
                WalkTysIter::One(binder.skip_binder().0)
1435 1436
            }
            ty::Predicate::RegionOutlives(..) => {
1437
                WalkTysIter::None
1438 1439
            }
            ty::Predicate::Projection(ref data) => {
1440
                let inner = data.skip_binder();
1441 1442
                WalkTysIter::ProjectionTypes(
                    inner.projection_ty.substs.types().chain(Some(inner.ty)))
1443
            }
1444
            ty::Predicate::WellFormed(data) => {
1445
                WalkTysIter::One(data)
1446 1447
            }
            ty::Predicate::ObjectSafe(_trait_def_id) => {
1448
                WalkTysIter::None
1449
            }
1450
            ty::Predicate::ClosureKind(_closure_def_id, closure_substs, _kind) => {
1451
                WalkTysIter::Types(closure_substs.substs.types())
1452
            }
1453
            ty::Predicate::ConstEvaluatable(_, substs) => {
1454
                WalkTysIter::Types(substs.types())
1455
            }
1456
        }
1457 1458
    }

1459
    pub fn to_opt_poly_trait_ref(&self) -> Option<PolyTraitRef<'tcx>> {
1460 1461
        match *self {
            Predicate::Trait(ref t) => {
1462
                Some(t.to_poly_trait_ref())
1463
            }
1464
            Predicate::Projection(..) |
N
Niko Matsakis 已提交
1465
            Predicate::Subtype(..) |
1466
            Predicate::RegionOutlives(..) |
1467 1468
            Predicate::WellFormed(..) |
            Predicate::ObjectSafe(..) |
1469
            Predicate::ClosureKind(..) |
1470 1471
            Predicate::TypeOutlives(..) |
            Predicate::ConstEvaluatable(..) => {
1472 1473
                None
            }
1474 1475
        }
    }
1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493

    pub fn to_opt_type_outlives(&self) -> Option<PolyTypeOutlivesPredicate<'tcx>> {
        match *self {
            Predicate::TypeOutlives(data) => {
                Some(data)
            }
            Predicate::Trait(..) |
            Predicate::Projection(..) |
            Predicate::Subtype(..) |
            Predicate::RegionOutlives(..) |
            Predicate::WellFormed(..) |
            Predicate::ObjectSafe(..) |
            Predicate::ClosureKind(..) |
            Predicate::ConstEvaluatable(..) => {
                None
            }
        }
    }
1494 1495
}

S
Steve Klabnik 已提交
1496
/// Represents the bounds declared on a particular set of type
A
Alexander Regueiro 已提交
1497 1498
/// parameters. Should eventually be generalized into a flag list of
/// where-clauses. You can obtain a `InstantiatedPredicates` list from a
1499 1500 1501 1502
/// `GenericPredicates` by using the `instantiate` method. Note that this method
/// reflects an important semantic invariant of `InstantiatedPredicates`: while
/// the `GenericPredicates` are expressed in terms of the bound type
/// parameters of the impl/trait/whatever, an `InstantiatedPredicates` instance
S
Steve Klabnik 已提交
1503 1504 1505 1506 1507 1508 1509 1510
/// represented a set of bounds for some particular instantiation,
/// meaning that the generic parameters have been substituted with
/// their values.
///
/// Example:
///
///     struct Foo<T,U:Bar<T>> { ... }
///
1511
/// Here, the `GenericPredicates` for `Foo` would contain a list of bounds like
A
Alexander Regueiro 已提交
1512
/// `[[], [U:Bar<T>]]`. Now if there were some particular reference
1513 1514
/// like `Foo<isize,usize>`, then the `InstantiatedPredicates` would be `[[],
/// [usize:Bar<isize>]]`.
1515
#[derive(Clone, Debug)]
1516
pub struct InstantiatedPredicates<'tcx> {
1517
    pub predicates: Vec<Predicate<'tcx>>,
1518 1519
}

1520 1521
impl<'tcx> InstantiatedPredicates<'tcx> {
    pub fn empty() -> InstantiatedPredicates<'tcx> {
1522
        InstantiatedPredicates { predicates: vec![] }
1523 1524
    }

1525 1526
    pub fn is_empty(&self) -> bool {
        self.predicates.is_empty()
1527
    }
1528 1529
}

1530
newtype_index! {
1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565
    /// "Universes" are used during type- and trait-checking in the
    /// presence of `for<..>` binders to control what sets of names are
    /// visible. Universes are arranged into a tree: the root universe
    /// contains names that are always visible. Each child then adds a new
    /// set of names that are visible, in addition to those of its parent.
    /// We say that the child universe "extends" the parent universe with
    /// new names.
    ///
    /// To make this more concrete, consider this program:
    ///
    /// ```
    /// struct Foo { }
    /// fn bar<T>(x: T) {
    ///   let y: for<'a> fn(&'a u8, Foo) = ...;
    /// }
    /// ```
    ///
    /// The struct name `Foo` is in the root universe U0. But the type
    /// parameter `T`, introduced on `bar`, is in an extended universe U1
    /// -- i.e., within `bar`, we can name both `T` and `Foo`, but outside
    /// of `bar`, we cannot name `T`. Then, within the type of `y`, the
    /// region `'a` is in a universe U2 that extends U1, because we can
    /// name it inside the fn type but not outside.
    ///
    /// Universes are used to do type- and trait-checking around these
    /// "forall" binders (also called **universal quantification**). The
    /// idea is that when, in the body of `bar`, we refer to `T` as a
    /// type, we aren't referring to any type in particular, but rather a
    /// kind of "fresh" type that is distinct from all other types we have
    /// actually declared. This is called a **placeholder** type, and we
    /// use universes to talk about this. In other words, a type name in
    /// universe 0 always corresponds to some "ground" type that the user
    /// declared, but a type name in a non-zero universe is a placeholder
    /// type -- an idealized representative of "types in general" that we
    /// use for checking generic functions.
1566 1567 1568 1569
    pub struct UniverseIndex {
        DEBUG_FORMAT = "U{}",
    }
}
1570 1571

impl_stable_hash_for!(struct UniverseIndex { private });
N
Niko Matsakis 已提交
1572 1573

impl UniverseIndex {
1574
    pub const ROOT: UniverseIndex = UniverseIndex::from_u32_const(0);
N
Niko Matsakis 已提交
1575

1576 1577
    /// Returns the "next" universe index in order -- this new index
    /// is considered to extend all previous universes. This
A
Alexander Regueiro 已提交
1578
    /// corresponds to entering a `forall` quantifier. So, for
1579
    /// example, suppose we have this type in universe `U`:
N
Niko Matsakis 已提交
1580 1581 1582 1583 1584 1585
    ///
    /// ```
    /// for<'a> fn(&'a u32)
    /// ```
    ///
    /// Once we "enter" into this `for<'a>` quantifier, we are in a
1586 1587 1588 1589
    /// new universe that extends `U` -- in this new universe, we can
    /// name the region `'a`, but that region was not nameable from
    /// `U` because it was not in scope there.
    pub fn next_universe(self) -> UniverseIndex {
1590
        UniverseIndex::from_u32(self.private.checked_add(1).unwrap())
1591 1592
    }

1593
    /// Returns `true` if `self` can name a name from `other` -- in other words,
1594
    /// if the set of names in `self` is a superset of those in
N
Niko Matsakis 已提交
1595
    /// `other` (`self >= other`).
1596 1597
    pub fn can_name(self, other: UniverseIndex) -> bool {
        self.private >= other.private
N
Niko Matsakis 已提交
1598
    }
N
Niko Matsakis 已提交
1599

1600
    /// Returns `true` if `self` cannot name some names from `other` -- in other
N
Niko Matsakis 已提交
1601 1602 1603 1604 1605
    /// words, if the set of names in `self` is a strict subset of
    /// those in `other` (`self < other`).
    pub fn cannot_name(self, other: UniverseIndex) -> bool {
        self.private < other.private
    }
N
Niko Matsakis 已提交
1606 1607
}

1608 1609 1610 1611 1612 1613 1614
/// The "placeholder index" fully defines a placeholder region.
/// Placeholder regions are identified by both a **universe** as well
/// as a "bound-region" within that universe. The `bound_region` is
/// basically a name -- distinct bound regions within the same
/// universe are just two regions with an unknown relationship to one
/// another.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, PartialOrd, Ord)]
S
scalexm 已提交
1615
pub struct Placeholder<T> {
1616
    pub universe: UniverseIndex,
S
scalexm 已提交
1617
    pub name: T,
1618 1619
}

S
scalexm 已提交
1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635
impl<'a, 'gcx, T> HashStable<StableHashingContext<'a>> for Placeholder<T>
    where T: HashStable<StableHashingContext<'a>>
{
    fn hash_stable<W: StableHasherResult>(
        &self,
        hcx: &mut StableHashingContext<'a>,
        hasher: &mut StableHasher<W>
    ) {
        self.universe.hash_stable(hcx, hasher);
        self.name.hash_stable(hcx, hasher);
    }
}

pub type PlaceholderRegion = Placeholder<BoundRegion>;

pub type PlaceholderType = Placeholder<BoundVar>;
1636

1637
/// When type checking, we use the `ParamEnv` to track
1638 1639
/// details about the set of where-clauses that are in scope at this
/// particular point.
1640
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)]
1641
pub struct ParamEnv<'tcx> {
1642 1643
    /// Obligations that the caller must satisfy. This is basically
    /// the set of bounds on the in-scope type parameters, translated
1644
    /// into Obligations, and elaborated and normalized.
V
varkor 已提交
1645
    pub caller_bounds: &'tcx List<ty::Predicate<'tcx>>,
1646

I
Irina Popa 已提交
1647
    /// Typically, this is `Reveal::UserFacing`, but during codegen we
1648 1649 1650
    /// want `Reveal::All` -- note that this is always paired with an
    /// empty environment. To get that, use `ParamEnv::reveal()`.
    pub reveal: traits::Reveal,
S
scalexm 已提交
1651 1652 1653 1654 1655

    /// If this `ParamEnv` comes from a call to `tcx.param_env(def_id)`,
    /// register that `def_id` (useful for transitioning to the chalk trait
    /// solver).
    pub def_id: Option<DefId>,
1656
}
1657

1658
impl<'tcx> ParamEnv<'tcx> {
1659
    /// Construct a trait environment suitable for contexts where
A
Alexander Regueiro 已提交
1660
    /// there are no where-clauses in scope. Hidden types (like `impl
1661 1662
    /// Trait`) are left hidden, so this is suitable for ordinary
    /// type-checking.
1663
    #[inline]
1664
    pub fn empty() -> Self {
S
scalexm 已提交
1665
        Self::new(List::empty(), Reveal::UserFacing, None)
1666 1667
    }

A
Alexander Regueiro 已提交
1668
    /// Construct a trait environment with no where-clauses in scope
1669 1670
    /// where the values of all `impl Trait` and other hidden types
    /// are revealed. This is suitable for monomorphized, post-typeck
I
Irina Popa 已提交
1671
    /// environments like codegen or doing optimizations.
1672
    ///
A
Alexander Regueiro 已提交
1673
    /// N.B., if you want to have predicates in scope, use `ParamEnv::new`,
1674
    /// or invoke `param_env.with_reveal_all()`.
1675
    #[inline]
1676
    pub fn reveal_all() -> Self {
S
scalexm 已提交
1677
        Self::new(List::empty(), Reveal::All, None)
1678 1679 1680
    }

    /// Construct a trait environment with the given set of predicates.
1681
    #[inline]
S
scalexm 已提交
1682 1683 1684 1685 1686 1687
    pub fn new(
        caller_bounds: &'tcx List<ty::Predicate<'tcx>>,
        reveal: Reveal,
        def_id: Option<DefId>
    ) -> Self {
        ty::ParamEnv { caller_bounds, reveal, def_id }
1688 1689 1690 1691
    }

    /// Returns a new parameter environment with the same clauses, but
    /// which "reveals" the true results of projections in all cases
A
Alexander Regueiro 已提交
1692
    /// (even for associated types that are specializable). This is
I
Irina Popa 已提交
1693
    /// the desired behavior during codegen and certain other special
1694 1695 1696 1697 1698 1699 1700 1701
    /// contexts; normally though we want to use `Reveal::UserFacing`,
    /// which is the default.
    pub fn with_reveal_all(self) -> Self {
        ty::ParamEnv { reveal: Reveal::All, ..self }
    }

    /// Returns this same environment but with no caller bounds.
    pub fn without_caller_bounds(self) -> Self {
V
varkor 已提交
1702
        ty::ParamEnv { caller_bounds: List::empty(), ..self }
1703 1704
    }

1705
    /// Creates a suitable environment in which to perform trait
1706 1707 1708 1709 1710
    /// queries on the given value. When type-checking, this is simply
    /// the pair of the environment plus value. But when reveal is set to
    /// All, then if `value` does not reference any type parameters, we will
    /// pair it with the empty environment. This improves caching and is generally
    /// invisible.
1711
    ///
1712
    /// N.B., we preserve the environment when type-checking because it
1713
    /// is possible for the user to have wacky where-clauses like
1714
    /// `where Box<u32>: Copy`, which are clearly never
1715 1716
    /// satisfiable. We generally want to behave as if they were true,
    /// although the surrounding function is never reachable.
1717
    pub fn and<T: TypeFoldable<'tcx>>(self, value: T) -> ParamEnvAnd<'tcx, T> {
1718 1719 1720 1721 1722 1723
        match self.reveal {
            Reveal::UserFacing => {
                ParamEnvAnd {
                    param_env: self,
                    value,
                }
1724
            }
1725 1726

            Reveal::All => {
1727
                if value.has_placeholders()
1728 1729 1730 1731
                    || value.needs_infer()
                    || value.has_param_types()
                    || value.has_self_ty()
                {
1732 1733 1734 1735 1736 1737 1738 1739 1740 1741
                    ParamEnvAnd {
                        param_env: self,
                        value,
                    }
                } else {
                    ParamEnvAnd {
                        param_env: self.without_caller_bounds(),
                        value,
                    }
                }
1742
            }
1743 1744 1745
        }
    }
}
1746

1747
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1748 1749
pub struct ParamEnvAnd<'tcx, T> {
    pub param_env: ParamEnv<'tcx>,
1750
    pub value: T,
1751 1752
}

1753 1754
impl<'tcx, T> ParamEnvAnd<'tcx, T> {
    pub fn into_parts(self) -> (ParamEnv<'tcx>, T) {
1755
        (self.param_env, self.value)
1756
    }
1757 1758
}

1759 1760
impl<'a, 'gcx, T> HashStable<StableHashingContext<'a>> for ParamEnvAnd<'gcx, T>
    where T: HashStable<StableHashingContext<'a>>
1761 1762
{
    fn hash_stable<W: StableHasherResult>(&self,
1763
                                          hcx: &mut StableHashingContext<'a>,
1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774
                                          hasher: &mut StableHasher<W>) {
        let ParamEnvAnd {
            ref param_env,
            ref value
        } = *self;

        param_env.hash_stable(hcx, hasher);
        value.hash_stable(hcx, hasher);
    }
}

1775
#[derive(Copy, Clone, Debug, HashStable)]
1776
pub struct Destructor {
A
Alexander Regueiro 已提交
1777
    /// The `DefId` of the destructor method
1778 1779 1780
    pub did: DefId,
}

1781
bitflags! {
1782
    #[derive(HashStable)]
1783 1784
    pub struct AdtFlags: u32 {
        const NO_ADT_FLAGS        = 0;
1785
        /// Indicates whether the ADT is an enum.
1786
        const IS_ENUM             = 1 << 0;
1787
        /// Indicates whether the ADT is a union.
A
Alexander Regueiro 已提交
1788
        const IS_UNION            = 1 << 1;
1789
        /// Indicates whether the ADT is a struct.
A
Alexander Regueiro 已提交
1790
        const IS_STRUCT           = 1 << 2;
1791
        /// Indicates whether the ADT is a struct and has a constructor.
1792
        const HAS_CTOR            = 1 << 3;
1793
        /// Indicates whether the type is a `PhantomData`.
A
Alexander Regueiro 已提交
1794
        const IS_PHANTOM_DATA     = 1 << 4;
1795
        /// Indicates whether the type has a `#[fundamental]` attribute.
A
Alexander Regueiro 已提交
1796
        const IS_FUNDAMENTAL      = 1 << 5;
1797
        /// Indicates whether the type is a `Box`.
A
Alexander Regueiro 已提交
1798
        const IS_BOX              = 1 << 6;
1799
        /// Indicates whether the type is an `Arc`.
A
Alexander Regueiro 已提交
1800
        const IS_ARC              = 1 << 7;
1801
        /// Indicates whether the type is an `Rc`.
A
Alexander Regueiro 已提交
1802
        const IS_RC               = 1 << 8;
1803 1804
        /// Indicates whether the variant list of this ADT is `#[non_exhaustive]`.
        /// (i.e., this flag is never set unless this ADT is an enum).
A
Alexander Regueiro 已提交
1805
        const IS_VARIANT_LIST_NON_EXHAUSTIVE = 1 << 9;
1806 1807 1808 1809
    }
}

bitflags! {
1810
    #[derive(HashStable)]
1811 1812 1813 1814
    pub struct VariantFlags: u32 {
        const NO_VARIANT_FLAGS        = 0;
        /// Indicates whether the field list of this variant is `#[non_exhaustive]`.
        const IS_FIELD_LIST_NON_EXHAUSTIVE = 1 << 0;
1815 1816 1817
    }
}

1818
/// Definition of a variant -- a struct's fields or a enum variant.
1819
#[derive(Debug)]
1820
pub struct VariantDef {
1821 1822 1823 1824 1825 1826
    /// `DefId` that identifies the variant itself.
    /// If this variant belongs to a struct or union, then this is a copy of its `DefId`.
    pub def_id: DefId,
    /// `DefId` that identifies the variant's constructor.
    /// If this variant is a struct variant, then this is `None`.
    pub ctor_def_id: Option<DefId>,
1827 1828 1829
    /// Variant or struct name.
    pub ident: Ident,
    /// Discriminant of this variant.
1830
    pub discr: VariantDiscr,
1831
    /// Fields of this variant.
1832
    pub fields: Vec<FieldDef>,
1833
    /// Type of constructor of variant.
1834
    pub ctor_kind: CtorKind,
1835
    /// Flags of the variant (e.g. is field list non-exhaustive)?
1836
    flags: VariantFlags,
1837
    /// Recovered?
1838
    pub recovered: bool,
1839 1840
}

1841
impl<'a, 'gcx, 'tcx> VariantDef {
A
Alexander Regueiro 已提交
1842
    /// Creates a new `VariantDef`.
1843
    ///
1844 1845
    /// `variant_did` is the `DefId` that identifies the enum variant (if this `VariantDef`
    /// represents an enum variant).
1846
    ///
1847 1848 1849 1850 1851 1852 1853
    /// `ctor_did` is the `DefId` that identifies the constructor of unit or
    /// tuple-variants/structs. If this is a `struct`-variant then this should be `None`.
    ///
    /// `parent_did` is the `DefId` of the `AdtDef` representing the enum or struct that
    /// owns this variant. It is used for checking if a struct has `#[non_exhaustive]` w/out having
    /// to go through the redirect of checking the ctor's attributes - but compiling a small crate
    /// requires loading the `AdtDef`s for all the structs in the universe (e.g., coherence for any
1854 1855 1856
    /// built-in trait), and we do not want to load attributes twice.
    ///
    /// If someone speeds up attribute loading to not be a performance concern, they can
A
Alexander Regueiro 已提交
1857
    /// remove this hack and use the constructor `DefId` everywhere.
1858 1859 1860
    pub fn new(
        tcx: TyCtxt<'a, 'gcx, 'tcx>,
        ident: Ident,
1861
        variant_did: Option<DefId>,
1862
        ctor_def_id: Option<DefId>,
1863 1864 1865
        discr: VariantDiscr,
        fields: Vec<FieldDef>,
        ctor_kind: CtorKind,
1866 1867
        adt_kind: AdtKind,
        parent_did: DefId,
1868 1869
        recovered: bool,
    ) -> Self {
1870
        debug!(
1871
            "VariantDef::new(ident = {:?}, variant_did = {:?}, ctor_def_id = {:?}, discr = {:?},
1872
             fields = {:?}, ctor_kind = {:?}, adt_kind = {:?}, parent_did = {:?})",
1873
             ident, variant_did, ctor_def_id, discr, fields, ctor_kind, adt_kind, parent_did,
1874 1875
        );

1876
        let mut flags = VariantFlags::NO_VARIANT_FLAGS;
1877 1878
        if adt_kind == AdtKind::Struct && tcx.has_attr(parent_did, "non_exhaustive") {
            debug!("found non-exhaustive field list for {:?}", parent_did);
1879
            flags = flags | VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE;
1880 1881 1882 1883 1884
        } else if let Some(variant_did) = variant_did {
            if tcx.has_attr(variant_did, "non_exhaustive") {
                debug!("found non-exhaustive field list for {:?}", variant_did);
                flags = flags | VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE;
            }
1885
        }
1886

1887
        VariantDef {
1888 1889
            def_id: variant_did.unwrap_or(parent_did),
            ctor_def_id,
1890
            ident,
1891 1892 1893
            discr,
            fields,
            ctor_kind,
1894 1895
            flags,
            recovered,
1896 1897 1898
        }
    }

1899
    /// Is this field list non-exhaustive?
1900 1901 1902 1903
    #[inline]
    pub fn is_field_list_non_exhaustive(&self) -> bool {
        self.flags.intersects(VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE)
    }
1904 1905
}

1906
impl_stable_hash_for!(struct VariantDef {
1907 1908
    def_id,
    ctor_def_id,
1909
    ident -> (ident.name),
1910 1911 1912
    discr,
    fields,
    ctor_kind,
1913 1914
    flags,
    recovered
1915 1916
});

1917
#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
1918
pub enum VariantDiscr {
1919
    /// Explicit value for this variant, i.e., `X = 123`.
1920 1921 1922 1923 1924 1925 1926
    /// The `DefId` corresponds to the embedded constant.
    Explicit(DefId),

    /// The previous variant's discriminant plus one.
    /// For efficiency reasons, the distance from the
    /// last `Explicit` discriminant is being stored,
    /// or `0` for the first variant, if it has none.
1927
    Relative(u32),
1928 1929
}

1930
#[derive(Debug, HashStable)]
1931
pub struct FieldDef {
1932
    pub did: DefId,
1933
    #[stable_hasher(project(name))]
1934
    pub ident: Ident,
1935
    pub vis: Visibility,
1936 1937
}

1938
/// The definition of an abstract data type -- a struct or enum.
A
Ariel Ben-Yehuda 已提交
1939
///
1940
/// These are all interned (by `intern_adt_def`) into the `adt_defs` table.
1941
pub struct AdtDef {
1942
    /// `DefId` of the struct, enum or union item.
1943
    pub did: DefId,
1944
    /// Variants of the ADT. If this is a struct or enum, then there will be a single variant.
1945
    pub variants: IndexVec<self::layout::VariantIdx, VariantDef>,
1946
    /// Flags of the ADT (e.g. is this a struct? is this non-exhaustive?)
1947
    flags: AdtFlags,
1948
    /// Repr options provided by the user.
1949
    pub repr: ReprOptions,
1950 1951
}

1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965
impl PartialOrd for AdtDef {
    fn partial_cmp(&self, other: &AdtDef) -> Option<Ordering> {
        Some(self.cmp(&other))
    }
}

/// There should be only one AdtDef for each `did`, therefore
/// it is fine to implement `Ord` only based on `did`.
impl Ord for AdtDef {
    fn cmp(&self, other: &AdtDef) -> Ordering {
        self.did.cmp(&other.did)
    }
}

1966 1967
impl PartialEq for AdtDef {
    // AdtDef are always interned and this is part of TyS equality
1968
    #[inline]
1969
    fn eq(&self, other: &Self) -> bool { ptr::eq(self, other) }
1970 1971
}

1972
impl Eq for AdtDef {}
1973

1974
impl Hash for AdtDef {
1975 1976
    #[inline]
    fn hash<H: Hasher>(&self, s: &mut H) {
1977
        (self as *const AdtDef).hash(s)
1978 1979 1980
    }
}

1981
impl<'tcx> serialize::UseSpecializedEncodable for &'tcx AdtDef {
1982
    fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
1983 1984 1985 1986
        self.did.encode(s)
    }
}

1987
impl<'tcx> serialize::UseSpecializedDecodable for &'tcx AdtDef {}
1988

1989

1990
impl<'a> HashStable<StableHashingContext<'a>> for AdtDef {
1991
    fn hash_stable<W: StableHasherResult>(&self,
1992
                                          hcx: &mut StableHashingContext<'a>,
1993
                                          hasher: &mut StableHasher<W>) {
W
Wesley Wiser 已提交
1994
        thread_local! {
1995
            static CACHE: RefCell<FxHashMap<usize, Fingerprint>> = Default::default();
W
Wesley Wiser 已提交
1996
        }
1997

W
Wesley Wiser 已提交
1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018
        let hash: Fingerprint = CACHE.with(|cache| {
            let addr = self as *const AdtDef as usize;
            *cache.borrow_mut().entry(addr).or_insert_with(|| {
                let ty::AdtDef {
                    did,
                    ref variants,
                    ref flags,
                    ref repr,
                } = *self;

                let mut hasher = StableHasher::new();
                did.hash_stable(hcx, &mut hasher);
                variants.hash_stable(hcx, &mut hasher);
                flags.hash_stable(hcx, &mut hasher);
                repr.hash_stable(hcx, &mut hasher);

                hasher.finish()
           })
        });

        hash.hash_stable(hcx, hasher);
2019 2020 2021
    }
}

2022
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
2023
pub enum AdtKind { Struct, Union, Enum }
2024

2025 2026 2027 2028 2029 2030 2031 2032 2033 2034
impl Into<DataTypeKind> for AdtKind {
    fn into(self) -> DataTypeKind {
        match self {
            AdtKind::Struct => DataTypeKind::Struct,
            AdtKind::Union => DataTypeKind::Union,
            AdtKind::Enum => DataTypeKind::Enum,
        }
    }
}

2035 2036
bitflags! {
    #[derive(RustcEncodable, RustcDecodable, Default)]
2037 2038
    pub struct ReprFlags: u8 {
        const IS_C               = 1 << 0;
2039 2040
        const IS_SIMD            = 1 << 1;
        const IS_TRANSPARENT     = 1 << 2;
2041
        // Internal only for now. If true, don't reorder fields.
2042
        const IS_LINEAR          = 1 << 3;
2043 2044 2045 2046

        // Any of these flags being set prevent field reordering optimisation.
        const IS_UNOPTIMISABLE   = ReprFlags::IS_C.bits |
                                   ReprFlags::IS_SIMD.bits |
2047
                                   ReprFlags::IS_LINEAR.bits;
2048 2049 2050 2051 2052 2053 2054
    }
}

impl_stable_hash_for!(struct ReprFlags {
    bits
});

2055
/// Represents the repr options provided by the user,
2056
#[derive(Copy, Clone, Debug, Eq, PartialEq, RustcEncodable, RustcDecodable, Default)]
2057 2058
pub struct ReprOptions {
    pub int: Option<attr::IntType>,
2059
    pub align: u32,
2060
    pub pack: u32,
2061
    pub flags: ReprFlags,
2062 2063
}

2064
impl_stable_hash_for!(struct ReprOptions {
2065
    align,
2066
    pack,
2067
    int,
2068
    flags
2069 2070
});

2071
impl ReprOptions {
2072
    pub fn new(tcx: TyCtxt<'_, '_, '_>, did: DefId) -> ReprOptions {
2073 2074
        let mut flags = ReprFlags::empty();
        let mut size = None;
2075
        let mut max_align = 0;
2076
        let mut min_pack = 0;
2077
        for attr in tcx.get_attrs(did).iter() {
C
csmoe 已提交
2078
            for r in attr::find_repr_attrs(&tcx.sess.parse_sess, attr) {
2079
                flags.insert(match r {
2080
                    attr::ReprC => ReprFlags::IS_C,
2081 2082 2083 2084 2085 2086 2087 2088
                    attr::ReprPacked(pack) => {
                        min_pack = if min_pack > 0 {
                            cmp::min(pack, min_pack)
                        } else {
                            pack
                        };
                        ReprFlags::empty()
                    },
R
Robin Kruppe 已提交
2089
                    attr::ReprTransparent => ReprFlags::IS_TRANSPARENT,
2090 2091 2092 2093 2094
                    attr::ReprSimd => ReprFlags::IS_SIMD,
                    attr::ReprInt(i) => {
                        size = Some(i);
                        ReprFlags::empty()
                    },
2095 2096 2097 2098
                    attr::ReprAlign(align) => {
                        max_align = cmp::max(align, max_align);
                        ReprFlags::empty()
                    },
2099
                });
2100 2101
            }
        }
2102

2103
        // This is here instead of layout because the choice must make it into metadata.
2104
        if !tcx.consider_optimizing(|| format!("Reorder fields of {:?}", tcx.def_path_str(did))) {
2105 2106
            flags.insert(ReprFlags::IS_LINEAR);
        }
2107
        ReprOptions { int: size, align: max_align, pack: min_pack, flags: flags }
2108
    }
2109

2110 2111 2112 2113 2114
    #[inline]
    pub fn simd(&self) -> bool { self.flags.contains(ReprFlags::IS_SIMD) }
    #[inline]
    pub fn c(&self) -> bool { self.flags.contains(ReprFlags::IS_C) }
    #[inline]
2115
    pub fn packed(&self) -> bool { self.pack > 0 }
2116
    #[inline]
R
Robin Kruppe 已提交
2117 2118
    pub fn transparent(&self) -> bool { self.flags.contains(ReprFlags::IS_TRANSPARENT) }
    #[inline]
2119 2120
    pub fn linear(&self) -> bool { self.flags.contains(ReprFlags::IS_LINEAR) }

2121
    pub fn discr_type(&self) -> attr::IntType {
2122
        self.int.unwrap_or(attr::SignedInt(ast::IntTy::Isize))
2123
    }
2124

2125
    /// Returns `true` if this `#[repr()]` should inhabit "smart enum
2126 2127 2128
    /// layout" optimizations, such as representing `Foo<&T>` as a
    /// single pointer.
    pub fn inhibit_enum_layout_opt(&self) -> bool {
2129
        self.c() || self.int.is_some()
2130
    }
2131

2132
    /// Returns `true` if this `#[repr()]` should inhibit struct field reordering
A
Alexander Regueiro 已提交
2133
    /// optimizations, such as with `repr(C)`, `repr(packed(1))`, or `repr(<int>)`.
2134
    pub fn inhibit_struct_field_reordering_opt(&self) -> bool {
2135 2136
        self.flags.intersects(ReprFlags::IS_UNOPTIMISABLE) || self.pack == 1 ||
            self.int.is_some()
2137
    }
2138

A
Alexander Regueiro 已提交
2139
    /// Returns `true` if this `#[repr()]` should inhibit union ABI optimisations.
2140 2141 2142 2143
    pub fn inhibit_union_abi_opt(&self) -> bool {
        self.c()
    }

2144 2145
}

2146
impl<'a, 'gcx, 'tcx> AdtDef {
2147 2148 2149 2150 2151 2152 2153 2154
    /// Creates a new `AdtDef`.
    fn new(
        tcx: TyCtxt<'_, '_, '_>,
        did: DefId,
        kind: AdtKind,
        variants: IndexVec<VariantIdx, VariantDef>,
        repr: ReprOptions
    ) -> Self {
2155
        debug!("AdtDef::new({:?}, {:?}, {:?}, {:?})", did, kind, variants, repr);
A
Ariel Ben-Yehuda 已提交
2156
        let mut flags = AdtFlags::NO_ADT_FLAGS;
A
Alexander Regueiro 已提交
2157 2158 2159 2160 2161

        if kind == AdtKind::Enum && tcx.has_attr(did, "non_exhaustive") {
            debug!("found non-exhaustive variant list for {:?}", did);
            flags = flags | AdtFlags::IS_VARIANT_LIST_NON_EXHAUSTIVE;
        }
2162

A
Alexander Regueiro 已提交
2163 2164 2165 2166 2167 2168
        flags |= match kind {
            AdtKind::Enum => AdtFlags::IS_ENUM,
            AdtKind::Union => AdtFlags::IS_UNION,
            AdtKind::Struct => AdtFlags::IS_STRUCT,
        };

2169
        if kind == AdtKind::Struct && variants[VariantIdx::new(0)].ctor_def_id.is_some() {
2170
            flags |= AdtFlags::HAS_CTOR;
A
Alexander Regueiro 已提交
2171 2172
        }

A
Ariel Ben-Yehuda 已提交
2173
        let attrs = tcx.get_attrs(did);
2174
        if attr::contains_name(&attrs, "fundamental") {
A
Alexander Regueiro 已提交
2175
            flags |= AdtFlags::IS_FUNDAMENTAL;
2176
        }
2177
        if Some(did) == tcx.lang_items().phantom_data() {
A
Alexander Regueiro 已提交
2178
            flags |= AdtFlags::IS_PHANTOM_DATA;
2179
        }
2180
        if Some(did) == tcx.lang_items().owned_box() {
A
Alexander Regueiro 已提交
2181
            flags |= AdtFlags::IS_BOX;
2182
        }
2183
        if Some(did) == tcx.lang_items().arc() {
A
Alexander Regueiro 已提交
2184
            flags |= AdtFlags::IS_ARC;
2185 2186
        }
        if Some(did) == tcx.lang_items().rc() {
A
Alexander Regueiro 已提交
2187
            flags |= AdtFlags::IS_RC;
2188
        }
A
Alexander Regueiro 已提交
2189

2190
        AdtDef {
2191 2192 2193 2194
            did,
            variants,
            flags,
            repr,
2195 2196 2197
        }
    }

2198
    /// Returns `true` if this is a struct.
2199 2200
    #[inline]
    pub fn is_struct(&self) -> bool {
A
Alexander Regueiro 已提交
2201 2202 2203
        self.flags.contains(AdtFlags::IS_STRUCT)
    }

2204
    /// Returns `true` if this is a union.
2205 2206
    #[inline]
    pub fn is_union(&self) -> bool {
A
Alexander Regueiro 已提交
2207
        self.flags.contains(AdtFlags::IS_UNION)
2208 2209
    }

2210
    /// Returns `true` if this is a enum.
2211 2212
    #[inline]
    pub fn is_enum(&self) -> bool {
A
Alexander Regueiro 已提交
2213
        self.flags.contains(AdtFlags::IS_ENUM)
2214 2215
    }

2216
    /// Returns `true` if the variant list of this ADT is `#[non_exhaustive]`.
2217
    #[inline]
2218
    pub fn is_variant_list_non_exhaustive(&self) -> bool {
A
Alexander Regueiro 已提交
2219
        self.flags.contains(AdtFlags::IS_VARIANT_LIST_NON_EXHAUSTIVE)
2220 2221
    }

A
Alexander Regueiro 已提交
2222
    /// Returns the kind of the ADT.
2223
    #[inline]
A
Ariel Ben-Yehuda 已提交
2224
    pub fn adt_kind(&self) -> AdtKind {
2225
        if self.is_enum() {
A
Ariel Ben-Yehuda 已提交
2226
            AdtKind::Enum
2227
        } else if self.is_union() {
2228
            AdtKind::Union
2229
        } else {
A
Ariel Ben-Yehuda 已提交
2230
            AdtKind::Struct
2231 2232 2233
        }
    }

2234
    /// Returns a description of this abstract data type.
2235 2236 2237 2238 2239 2240 2241 2242
    pub fn descr(&self) -> &'static str {
        match self.adt_kind() {
            AdtKind::Struct => "struct",
            AdtKind::Union => "union",
            AdtKind::Enum => "enum",
        }
    }

2243
    /// Returns a description of a variant of this abstract data type.
2244
    #[inline]
2245 2246 2247 2248 2249 2250 2251 2252
    pub fn variant_descr(&self) -> &'static str {
        match self.adt_kind() {
            AdtKind::Struct => "struct",
            AdtKind::Union => "union",
            AdtKind::Enum => "variant",
        }
    }

2253 2254 2255 2256 2257 2258
    /// If this function returns `true`, it implies that `is_struct` must return `true`.
    #[inline]
    pub fn has_ctor(&self) -> bool {
        self.flags.contains(AdtFlags::HAS_CTOR)
    }

A
Alexander Regueiro 已提交
2259
    /// Returns `true` if this type is `#[fundamental]` for the purposes
A
Ariel Ben-Yehuda 已提交
2260
    /// of coherence checking.
2261 2262
    #[inline]
    pub fn is_fundamental(&self) -> bool {
A
Alexander Regueiro 已提交
2263
        self.flags.contains(AdtFlags::IS_FUNDAMENTAL)
2264 2265
    }

A
Alexander Regueiro 已提交
2266
    /// Returns `true` if this is `PhantomData<T>`.
2267 2268
    #[inline]
    pub fn is_phantom_data(&self) -> bool {
A
Alexander Regueiro 已提交
2269
        self.flags.contains(AdtFlags::IS_PHANTOM_DATA)
2270 2271
    }

2272 2273
    /// Returns `true` if this is `Arc<T>`.
    pub fn is_arc(&self) -> bool {
A
Alexander Regueiro 已提交
2274
        self.flags.contains(AdtFlags::IS_ARC)
2275 2276 2277 2278
    }

    /// Returns `true` if this is `Rc<T>`.
    pub fn is_rc(&self) -> bool {
A
Alexander Regueiro 已提交
2279
        self.flags.contains(AdtFlags::IS_RC)
2280 2281
    }

2282
    /// Returns `true` if this is Box<T>.
2283 2284
    #[inline]
    pub fn is_box(&self) -> bool {
A
Alexander Regueiro 已提交
2285
        self.flags.contains(AdtFlags::IS_BOX)
2286 2287
    }

A
Alexander Regueiro 已提交
2288
    /// Returns `true` if this type has a destructor.
2289 2290
    pub fn has_dtor(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> bool {
        self.destructor(tcx).is_some()
2291 2292
    }

2293 2294 2295
    /// Asserts this is a struct or union and returns its unique variant.
    pub fn non_enum_variant(&self) -> &VariantDef {
        assert!(self.is_struct() || self.is_union());
2296
        &self.variants[VariantIdx::new(0)]
2297 2298 2299
    }

    #[inline]
2300
    pub fn predicates(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Lrc<GenericPredicates<'gcx>> {
2301
        tcx.predicates_of(self.did)
2302
    }
2303

A
Ariel Ben-Yehuda 已提交
2304 2305
    /// Returns an iterator over all fields contained
    /// by this ADT.
2306
    #[inline]
2307 2308
    pub fn all_fields<'s>(&'s self) -> impl Iterator<Item = &'s FieldDef> {
        self.variants.iter().flat_map(|v| v.fields.iter())
2309 2310 2311 2312 2313 2314 2315
    }

    pub fn is_payloadfree(&self) -> bool {
        !self.variants.is_empty() &&
            self.variants.iter().all(|v| v.fields.is_empty())
    }

2316
    /// Return a `VariantDef` given a variant id.
2317 2318 2319
    pub fn variant_with_id(&self, vid: DefId) -> &VariantDef {
        self.variants.iter().find(|v| v.def_id == vid)
            .expect("variant_with_id: unknown variant")
2320 2321
    }

2322
    /// Return a `VariantDef` given a constructor id.
2323
    pub fn variant_with_ctor_id(&self, cid: DefId) -> &VariantDef {
2324
        self.variants.iter().find(|v| v.ctor_def_id == Some(cid))
2325 2326 2327
            .expect("variant_with_ctor_id: unknown variant")
    }

2328
    /// Return the index of `VariantDef` given a variant id.
2329 2330 2331
    pub fn variant_index_with_id(&self, vid: DefId) -> VariantIdx {
        self.variants.iter_enumerated().find(|(_, v)| v.def_id == vid)
            .expect("variant_index_with_id: unknown variant").0
2332 2333
    }

2334
    /// Return the index of `VariantDef` given a constructor id.
2335
    pub fn variant_index_with_ctor_id(&self, cid: DefId) -> VariantIdx {
2336 2337
        self.variants.iter_enumerated().find(|(_, v)| v.ctor_def_id == Some(cid))
            .expect("variant_index_with_ctor_id: unknown variant").0
N
Niko Matsakis 已提交
2338 2339
    }

2340
    pub fn variant_of_def(&self, def: Def) -> &VariantDef {
2341
        match def {
2342
            Def::Variant(vid) => self.variant_with_id(vid),
D
David Wood 已提交
2343
            Def::Ctor(cid, ..) => self.variant_with_ctor_id(cid),
2344
            Def::Struct(..) | Def::Union(..) |
F
F001 已提交
2345 2346
            Def::TyAlias(..) | Def::AssociatedTy(..) | Def::SelfTy(..) |
            Def::SelfCtor(..) => self.non_enum_variant(),
2347
            _ => bug!("unexpected def {:?} in variant_of_def", def)
2348 2349
        }
    }
2350

O
Oliver Schneider 已提交
2351
    #[inline]
2352
    pub fn eval_explicit_discr(
O
Oliver Schneider 已提交
2353 2354 2355 2356
        &self,
        tcx: TyCtxt<'a, 'gcx, 'tcx>,
        expr_did: DefId,
    ) -> Option<Discr<'tcx>> {
2357
        let param_env = ParamEnv::empty();
O
Oliver Schneider 已提交
2358
        let repr_type = self.repr.discr_type();
C
csmoe 已提交
2359
        let substs = InternalSubsts::identity_for_item(tcx.global_tcx(), expr_did);
O
Oliver Schneider 已提交
2360 2361 2362 2363 2364 2365
        let instance = ty::Instance::new(expr_did, substs);
        let cid = GlobalId {
            instance,
            promoted: None
        };
        match tcx.const_eval(param_env.and(cid)) {
2366 2367
            Ok(val) => {
                // FIXME: Find the right type and use it instead of `val.ty` here
O
Oliver Schneider 已提交
2368
                if let Some(b) = val.assert_bits(tcx.global_tcx(), param_env.and(val.ty)) {
2369 2370 2371 2372 2373 2374 2375
                    trace!("discriminants: {} ({:?})", b, repr_type);
                    Some(Discr {
                        val: b,
                        ty: val.ty,
                    })
                } else {
                    info!("invalid enum discriminant: {:#?}", val);
M
Mark Mansi 已提交
2376
                    crate::mir::interpret::struct_error(
2377
                        tcx.at(tcx.def_span(expr_did)),
2378 2379 2380 2381
                        "constant evaluation of enum discriminant resulted in non-integer",
                    ).emit();
                    None
                }
O
Oliver Schneider 已提交
2382
            }
2383
            Err(ErrorHandled::Reported) => {
O
Oliver Schneider 已提交
2384 2385 2386
                if !expr_did.is_local() {
                    span_bug!(tcx.def_span(expr_did),
                        "variant discriminant evaluation succeeded \
L
ljedrz 已提交
2387
                         in its crate but failed locally");
O
Oliver Schneider 已提交
2388 2389 2390
                }
                None
            }
2391 2392 2393 2394
            Err(ErrorHandled::TooGeneric) => span_bug!(
                tcx.def_span(expr_did),
                "enum discriminant depends on generic arguments",
            ),
O
Oliver Schneider 已提交
2395 2396 2397
        }
    }

2398
    #[inline]
2399 2400 2401
    pub fn discriminants(
        &'a self,
        tcx: TyCtxt<'a, 'gcx, 'tcx>,
2402
    ) -> impl Iterator<Item=(VariantIdx, Discr<'tcx>)> + Captures<'gcx> + 'a {
2403
        let repr_type = self.repr.discr_type();
2404
        let initial = repr_type.initial_discriminant(tcx.global_tcx());
O
Oliver Schneider 已提交
2405
        let mut prev_discr = None::<Discr<'tcx>>;
2406
        self.variants.iter_enumerated().map(move |(i, v)| {
O
Oliver Schneider 已提交
2407
            let mut discr = prev_discr.map_or(initial, |d| d.wrap_incr(tcx));
2408
            if let VariantDiscr::Explicit(expr_did) = v.discr {
O
Oliver Schneider 已提交
2409 2410
                if let Some(new_discr) = self.eval_explicit_discr(tcx, expr_did) {
                    discr = new_discr;
2411 2412 2413 2414
                }
            }
            prev_discr = Some(discr);

2415
            (i, discr)
2416 2417 2418
        })
    }

A
Alexander Regueiro 已提交
2419
    /// Computes the discriminant value used by a specific variant.
2420 2421 2422 2423 2424 2425
    /// Unlike `discriminants`, this is (amortized) constant-time,
    /// only doing at most one query for evaluating an explicit
    /// discriminant (the last one before the requested variant),
    /// assuming there are no constant-evaluation errors there.
    pub fn discriminant_for_variant(&self,
                                    tcx: TyCtxt<'a, 'gcx, 'tcx>,
2426
                                    variant_index: VariantIdx)
O
Oliver Schneider 已提交
2427
                                    -> Discr<'tcx> {
2428 2429 2430 2431 2432 2433 2434
        let (val, offset) = self.discriminant_def_for_variant(variant_index);
        let explicit_value = val
            .and_then(|expr_did| self.eval_explicit_discr(tcx, expr_did))
            .unwrap_or_else(|| self.repr.discr_type().initial_discriminant(tcx.global_tcx()));
        explicit_value.checked_add(tcx, offset as u128).0
    }

A
Alexander Regueiro 已提交
2435
    /// Yields a `DefId` for the discriminant and an offset to add to it
2436
    /// Alternatively, if there is no explicit discriminant, returns the
A
Alexander Regueiro 已提交
2437
    /// inferred discriminant directly.
2438 2439
    pub fn discriminant_def_for_variant(
        &self,
2440 2441 2442
        variant_index: VariantIdx,
    ) -> (Option<DefId>, u32) {
        let mut explicit_index = variant_index.as_u32();
2443
        let expr_did;
2444
        loop {
2445
            match self.variants[VariantIdx::from_u32(explicit_index)].discr {
2446 2447 2448 2449
                ty::VariantDiscr::Relative(0) => {
                    expr_did = None;
                    break;
                },
2450 2451 2452
                ty::VariantDiscr::Relative(distance) => {
                    explicit_index -= distance;
                }
2453 2454 2455
                ty::VariantDiscr::Explicit(did) => {
                    expr_did = Some(did);
                    break;
2456 2457 2458
                }
            }
        }
2459
        (expr_did, variant_index.as_u32() - explicit_index)
2460 2461
    }

2462
    pub fn destructor(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Destructor> {
2463
        tcx.adt_destructor(self.did)
2464 2465
    }

2466
    /// Returns a list of types such that `Self: Sized` if and only
A
Alexander Regueiro 已提交
2467
    /// if that type is `Sized`, or `TyErr` if this type is recursive.
A
Ariel Ben-Yehuda 已提交
2468
    ///
A
Alexander Regueiro 已提交
2469
    /// Oddly enough, checking that the sized-constraint is `Sized` is
A
Ariel Ben-Yehuda 已提交
2470
    /// actually more expressive than checking all members:
A
Alexander Regueiro 已提交
2471 2472
    /// the `Sized` trait is inductive, so an associated type that references
    /// `Self` would prevent its containing ADT from being `Sized`.
A
Ariel Ben-Yehuda 已提交
2473 2474
    ///
    /// Due to normalization being eager, this applies even if
A
Alexander Regueiro 已提交
2475
    /// the associated type is behind a pointer (e.g., issue #31299).
2476
    pub fn sized_constraint(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> &'tcx [Ty<'tcx>] {
2477
        tcx.adt_sized_constraint(self.did).0
2478
    }
2479

2480 2481 2482 2483
    fn sized_constraint_for_ty(&self,
                               tcx: TyCtxt<'a, 'tcx, 'tcx>,
                               ty: Ty<'tcx>)
                               -> Vec<Ty<'tcx>> {
2484
        let result = match ty.sty {
2485
            Bool | Char | Int(..) | Uint(..) | Float(..) |
V
varkor 已提交
2486 2487
            RawPtr(..) | Ref(..) | FnDef(..) | FnPtr(_) |
            Array(..) | Closure(..) | Generator(..) | Never => {
A
Ariel Ben-Yehuda 已提交
2488
                vec![]
2489 2490
            }

2491
            Str |
V
varkor 已提交
2492 2493
            Dynamic(..) |
            Slice(_) |
V
varkor 已提交
2494
            Foreign(..) |
V
varkor 已提交
2495 2496
            Error |
            GeneratorWitness(..) => {
2497
                // these are never sized - return the target type
A
Ariel Ben-Yehuda 已提交
2498
                vec![ty]
2499 2500
            }

V
varkor 已提交
2501
            Tuple(ref tys) => {
2502 2503
                match tys.last() {
                    None => vec![],
V
varkor 已提交
2504
                    Some(ty) => self.sized_constraint_for_ty(tcx, ty.expect_ty()),
2505
                }
2506 2507
            }

V
varkor 已提交
2508
            Adt(adt, substs) => {
2509
                // recursive case
2510
                let adt_tys = adt.sized_constraint(tcx);
2511
                debug!("sized_constraint_for_ty({:?}) intermediate = {:?}",
2512 2513
                       ty, adt_tys);
                adt_tys.iter()
L
ljedrz 已提交
2514 2515 2516
                       .map(|ty| ty.subst(tcx, substs))
                       .flat_map(|ty| self.sized_constraint_for_ty(tcx, ty))
                       .collect()
2517 2518
            }

2519
            Projection(..) | Opaque(..) => {
2520 2521
                // must calculate explicitly.
                // FIXME: consider special-casing always-Sized projections
A
Ariel Ben-Yehuda 已提交
2522
                vec![ty]
2523 2524
            }

2525 2526
            UnnormalizedProjection(..) => bug!("only used with chalk-engine"),

V
varkor 已提交
2527
            Param(..) => {
A
Ariel Ben-Yehuda 已提交
2528 2529 2530 2531
                // perf hack: if there is a `T: Sized` bound, then
                // we know that `T` is Sized and do not need to check
                // it on the impl.

2532
                let sized_trait = match tcx.lang_items().sized_trait() {
2533
                    Some(x) => x,
A
Ariel Ben-Yehuda 已提交
2534
                    _ => return vec![ty]
2535
                };
2536
                let sized_predicate = Binder::dummy(TraitRef {
2537
                    def_id: sized_trait,
2538
                    substs: tcx.mk_substs_trait(ty, &[])
2539
                }).to_predicate();
2540 2541
                let predicates = &tcx.predicates_of(self.did).predicates;
                if predicates.iter().any(|(p, _)| *p == sized_predicate) {
A
Ariel Ben-Yehuda 已提交
2542
                    vec![]
2543
                } else {
A
Ariel Ben-Yehuda 已提交
2544
                    vec![ty]
2545 2546 2547
                }
            }

S
scalexm 已提交
2548
            Placeholder(..) |
S
scalexm 已提交
2549
            Bound(..) |
V
varkor 已提交
2550
            Infer(..) => {
2551 2552 2553 2554 2555 2556 2557
                bug!("unexpected type `{:?}` in sized_constraint_for_ty",
                     ty)
            }
        };
        debug!("sized_constraint_for_ty({:?}) = {:?}", ty, result);
        result
    }
2558 2559
}

2560
impl<'a, 'gcx, 'tcx> FieldDef {
C
csmoe 已提交
2561
    pub fn ty(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, subst: SubstsRef<'tcx>) -> Ty<'tcx> {
2562
        tcx.type_of(self.did).subst(tcx, subst)
2563
    }
2564 2565
}

A
Alexander Regueiro 已提交
2566
/// Represents the various closure traits in the language. This
2567
/// will determine the type of the environment (`self`, in the
A
Andy Russell 已提交
2568
/// desugaring) argument that the closure expects.
2569 2570 2571
///
/// You can get the environment type of a closure using
/// `tcx.closure_env_ty()`.
2572 2573
#[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash, Debug,
         RustcEncodable, RustcDecodable, HashStable)]
2574
pub enum ClosureKind {
2575 2576 2577
    // Warning: Ordering is significant here! The ordering is chosen
    // because the trait Fn is a subtrait of FnMut and so in turn, and
    // hence we order it so that Fn < FnMut < FnOnce.
2578 2579 2580
    Fn,
    FnMut,
    FnOnce,
2581 2582
}

2583
impl<'a, 'tcx> ClosureKind {
2584 2585 2586
    // This is the initial value used when doing upvar inference.
    pub const LATTICE_BOTTOM: ClosureKind = ClosureKind::Fn;

2587
    pub fn trait_did(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> DefId {
2588 2589
        match *self {
            ClosureKind::Fn => tcx.require_lang_item(FnTraitLangItem),
2590
            ClosureKind::FnMut => {
2591
                tcx.require_lang_item(FnMutTraitLangItem)
2592
            }
2593
            ClosureKind::FnOnce => {
2594
                tcx.require_lang_item(FnOnceTraitLangItem)
2595 2596 2597
            }
        }
    }
2598

2599
    /// Returns `true` if this a type that impls this closure kind
2600 2601 2602
    /// must also implement `other`.
    pub fn extends(self, other: ty::ClosureKind) -> bool {
        match (self, other) {
2603 2604 2605 2606 2607 2608
            (ClosureKind::Fn, ClosureKind::Fn) => true,
            (ClosureKind::Fn, ClosureKind::FnMut) => true,
            (ClosureKind::Fn, ClosureKind::FnOnce) => true,
            (ClosureKind::FnMut, ClosureKind::FnMut) => true,
            (ClosureKind::FnMut, ClosureKind::FnOnce) => true,
            (ClosureKind::FnOnce, ClosureKind::FnOnce) => true,
2609 2610 2611
            _ => false,
        }
    }
2612 2613 2614 2615 2616 2617 2618 2619 2620

    /// Returns the representative scalar type for this closure kind.
    /// See `TyS::to_opt_closure_kind` for more details.
    pub fn to_ty(self, tcx: TyCtxt<'_, '_, 'tcx>) -> Ty<'tcx> {
        match self {
            ty::ClosureKind::Fn => tcx.types.i8,
            ty::ClosureKind::FnMut => tcx.types.i16,
            ty::ClosureKind::FnOnce => tcx.types.i32,
        }
2621
    }
2622 2623
}

2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636
impl<'tcx> TyS<'tcx> {
    /// Iterator that walks `self` and any types reachable from
    /// `self`, in depth-first order. Note that just walks the types
    /// that appear in `self`, it does not descend into the fields of
    /// structs or variants. For example:
    ///
    /// ```notrust
    /// isize => { isize }
    /// Foo<Bar<isize>> => { Foo<Bar<isize>>, Bar<isize>, isize }
    /// [isize] => { [isize], isize }
    /// ```
    pub fn walk(&'tcx self) -> TypeWalker<'tcx> {
        TypeWalker::new(self)
2637 2638
    }

A
Alexander Regueiro 已提交
2639
    /// Iterator that walks the immediate children of `self`. Hence
2640 2641
    /// `Foo<Bar<i32>, u32>` yields the sequence `[Bar<i32>, u32]`
    /// (but not `i32`, like `walk`).
2642
    pub fn walk_shallow(&'tcx self) -> smallvec::IntoIter<walk::TypeWalkerArray<'tcx>> {
2643
        walk::walk_shallow(self)
2644 2645
    }

2646
    /// Walks `ty` and any types appearing within `ty`, invoking the
A
Alexander Regueiro 已提交
2647
    /// callback `f` on each type. If the callback returns `false`, then the
2648 2649 2650 2651
    /// children of the current type are ignored.
    ///
    /// Note: prefer `ty.walk()` where possible.
    pub fn maybe_walk<F>(&'tcx self, mut f: F)
2652
        where F: FnMut(Ty<'tcx>) -> bool
2653 2654 2655 2656 2657 2658 2659
    {
        let mut walker = self.walk();
        while let Some(ty) = walker.next() {
            if !f(ty) {
                walker.skip_current_subtree();
            }
        }
2660
    }
2661
}
2662

2663
impl BorrowKind {
2664
    pub fn from_mutbl(m: hir::Mutability) -> BorrowKind {
2665
        match m {
2666 2667
            hir::MutMutable => MutBorrow,
            hir::MutImmutable => ImmBorrow,
2668 2669
        }
    }
2670

2671 2672 2673 2674
    /// Returns a mutability `m` such that an `&m T` pointer could be used to obtain this borrow
    /// kind. Because borrow kinds are richer than mutabilities, we sometimes have to pick a
    /// mutability that is stronger than necessary so that it at least *would permit* the borrow in
    /// question.
2675
    pub fn to_mutbl_lossy(self) -> hir::Mutability {
2676
        match self {
2677 2678
            MutBorrow => hir::MutMutable,
            ImmBorrow => hir::MutImmutable,
2679 2680 2681 2682

            // We have no type corresponding to a unique imm borrow, so
            // use `&mut`. It gives all the capabilities of an `&uniq`
            // and hence is a safe "over approximation".
2683
            UniqueImmBorrow => hir::MutMutable,
2684
        }
2685
    }
2686

2687 2688 2689 2690 2691 2692
    pub fn to_user_str(&self) -> &'static str {
        match *self {
            MutBorrow => "mutable",
            ImmBorrow => "immutable",
            UniqueImmBorrow => "uniquely immutable",
        }
2693 2694 2695
    }
}

2696 2697
#[derive(Debug, Clone)]
pub enum Attributes<'gcx> {
2698
    Owned(Lrc<[ast::Attribute]>),
2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712
    Borrowed(&'gcx [ast::Attribute])
}

impl<'gcx> ::std::ops::Deref for Attributes<'gcx> {
    type Target = [ast::Attribute];

    fn deref(&self) -> &[ast::Attribute] {
        match self {
            &Attributes::Owned(ref data) => &data,
            &Attributes::Borrowed(data) => data
        }
    }
}

2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751
#[derive(Debug, PartialEq, Eq)]
pub enum ImplOverlapKind {
    /// These impls are always allowed to overlap.
    Permitted,
    /// These impls are allowed to overlap, but that raises
    /// an issue #33140 future-compatibility warning.
    ///
    /// Some background: in Rust 1.0, the trait-object types `Send + Sync` (today's
    /// `dyn Send + Sync`) and `Sync + Send` (now `dyn Sync + Send`) were different.
    ///
    /// The widely-used version 0.1.0 of the crate `traitobject` had accidentally relied
    /// that difference, making what reduces to the following set of impls:
    ///
    /// ```
    /// trait Trait {}
    /// impl Trait for dyn Send + Sync {}
    /// impl Trait for dyn Sync + Send {}
    /// ```
    ///
    /// Obviously, once we made these types be identical, that code causes a coherence
    /// error and a fairly big headache for us. However, luckily for us, the trait
    /// `Trait` used in this case is basically a marker trait, and therefore having
    /// overlapping impls for it is sound.
    ///
    /// To handle this, we basically regard the trait as a marker trait, with an additional
    /// future-compatibility warning. To avoid accidentally "stabilizing" this feature,
    /// it has the following restrictions:
    ///
    /// 1. The trait must indeed be a marker-like trait (i.e., no items), and must be
    /// positive impls.
    /// 2. The trait-ref of both impls must be equal.
    /// 3. The trait-ref of both impls must be a trait object type consisting only of
    /// marker traits.
    /// 4. Neither of the impls can have any where-clauses.
    ///
    /// Once `traitobject` 0.1.0 is no longer an active concern, this hack can be removed.
    Issue33140
}

2752
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
2753
    pub fn body_tables(self, body: hir::BodyId) -> &'gcx TypeckTables<'gcx> {
2754
        self.typeck_tables_of(self.hir().body_owner_def_id(body))
2755 2756
    }

A
Alexander Regueiro 已提交
2757
    /// Returns an iterator of the `DefId`s for all body-owners in this
N
Niko Matsakis 已提交
2758
    /// crate. If you would prefer to iterate over the bodies
2759
    /// themselves, you can do `self.hir().krate().body_ids.iter()`.
2760 2761 2762
    pub fn body_owners(
        self,
    ) -> impl Iterator<Item = DefId> + Captures<'tcx> + Captures<'gcx> + 'a {
2763 2764 2765 2766
        self.hir().krate()
                  .body_ids
                  .iter()
                  .map(move |&body_id| self.hir().body_owner_def_id(body_id))
N
Niko Matsakis 已提交
2767 2768
    }

J
John Kåre Alsaker 已提交
2769
    pub fn par_body_owners<F: Fn(DefId) + sync::Sync + sync::Send>(self, f: F) {
2770 2771
        par_iter(&self.hir().krate().body_ids).for_each(|&body_id| {
            f(self.hir().body_owner_def_id(body_id))
J
John Kåre Alsaker 已提交
2772 2773 2774
        });
    }

2775
    pub fn expr_span(self, id: NodeId) -> Span {
2776
        match self.hir().find(id) {
V
varkor 已提交
2777
            Some(Node::Expr(e)) => {
2778 2779 2780
                e.span
            }
            Some(f) => {
2781
                bug!("Node id {} is not an expr: {:?}", id, f);
2782 2783
            }
            None => {
2784
                bug!("Node id {} is not present in the node map", id);
2785
            }
2786
        }
2787 2788
    }

2789 2790
    pub fn provided_trait_methods(self, id: DefId) -> Vec<AssociatedItem> {
        self.associated_items(id)
2791
            .filter(|item| item.kind == AssociatedKind::Method && item.defaultness.has_value())
2792
            .collect()
2793 2794
    }

A
Andrew Cann 已提交
2795 2796 2797 2798 2799 2800
    pub fn trait_relevant_for_never(self, did: DefId) -> bool {
        self.associated_items(did).any(|item| {
            item.relevant_for_never()
        })
    }

2801
    pub fn opt_associated_item(self, def_id: DefId) -> Option<AssociatedItem> {
2802 2803
        let is_associated_item = if let Some(hir_id) = self.hir().as_local_hir_id(def_id) {
            match self.hir().get_by_hir_id(hir_id) {
V
varkor 已提交
2804
                Node::TraitItem(_) | Node::ImplItem(_) => true,
2805 2806 2807
                _ => false,
            }
        } else {
2808
            match self.describe_def(def_id).expect("no def for def-id") {
2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820
                Def::AssociatedConst(_) | Def::Method(_) | Def::AssociatedTy(_) => true,
                _ => false,
            }
        };

        if is_associated_item {
            Some(self.associated_item(def_id))
        } else {
            None
        }
    }

2821 2822
    fn associated_item_from_trait_item_ref(self,
                                           parent_def_id: DefId,
2823
                                           parent_vis: &hir::Visibility,
2824
                                           trait_item_ref: &hir::TraitItemRef)
2825
                                           -> AssociatedItem {
L
ljedrz 已提交
2826
        let def_id = self.hir().local_def_id_from_hir_id(trait_item_ref.id.hir_id);
2827 2828 2829 2830
        let (kind, has_self) = match trait_item_ref.kind {
            hir::AssociatedItemKind::Const => (ty::AssociatedKind::Const, false),
            hir::AssociatedItemKind::Method { has_self } => {
                (ty::AssociatedKind::Method, has_self)
2831
            }
2832
            hir::AssociatedItemKind::Type => (ty::AssociatedKind::Type, false),
O
Oliver Schneider 已提交
2833
            hir::AssociatedItemKind::Existential => bug!("only impls can have existentials"),
2834 2835 2836
        };

        AssociatedItem {
2837
            ident: trait_item_ref.ident,
2838
            kind,
2839
            // Visibility of trait items is inherited from their traits.
L
ljedrz 已提交
2840
            vis: Visibility::from_hir(parent_vis, trait_item_ref.id.hir_id, self),
2841
            defaultness: trait_item_ref.defaultness,
2842
            def_id,
2843 2844 2845 2846 2847 2848 2849 2850 2851
            container: TraitContainer(parent_def_id),
            method_has_self_argument: has_self
        }
    }

    fn associated_item_from_impl_item_ref(self,
                                          parent_def_id: DefId,
                                          impl_item_ref: &hir::ImplItemRef)
                                          -> AssociatedItem {
L
ljedrz 已提交
2852
        let def_id = self.hir().local_def_id_from_hir_id(impl_item_ref.id.hir_id);
2853 2854 2855 2856 2857 2858
        let (kind, has_self) = match impl_item_ref.kind {
            hir::AssociatedItemKind::Const => (ty::AssociatedKind::Const, false),
            hir::AssociatedItemKind::Method { has_self } => {
                (ty::AssociatedKind::Method, has_self)
            }
            hir::AssociatedItemKind::Type => (ty::AssociatedKind::Type, false),
O
Oliver Schneider 已提交
2859
            hir::AssociatedItemKind::Existential => (ty::AssociatedKind::Existential, false),
2860 2861
        };

2862 2863
        AssociatedItem {
            ident: impl_item_ref.ident,
2864
            kind,
2865
            // Visibility of trait impl items doesn't matter.
L
ljedrz 已提交
2866
            vis: ty::Visibility::from_hir(&impl_item_ref.vis, impl_item_ref.id.hir_id, self),
2867
            defaultness: impl_item_ref.defaultness,
2868
            def_id,
2869 2870 2871 2872 2873
            container: ImplContainer(parent_def_id),
            method_has_self_argument: has_self
        }
    }

L
ljedrz 已提交
2874
    pub fn field_index(self, hir_id: hir::HirId, tables: &TypeckTables<'_>) -> usize {
2875 2876 2877 2878 2879
        tables.field_indices().get(hir_id).cloned().expect("no index for a field")
    }

    pub fn find_field_index(self, ident: Ident, variant: &VariantDef) -> Option<usize> {
        variant.fields.iter().position(|field| {
2880
            self.adjust_ident(ident, variant.def_id, hir::DUMMY_HIR_ID).0 == field.ident.modern()
2881 2882 2883
        })
    }

2884 2885 2886
    pub fn associated_items(
        self,
        def_id: DefId,
2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897
    ) -> AssociatedItemsIterator<'a, 'gcx, 'tcx> {
        // Ideally, we would use `-> impl Iterator` here, but it falls
        // afoul of the conservative "capture [restrictions]" we put
        // in place, so we use a hand-written iterator.
        //
        // [restrictions]: https://github.com/rust-lang/rust/issues/34511#issuecomment-373423999
        AssociatedItemsIterator {
            tcx: self,
            def_ids: self.associated_item_def_ids(def_id),
            next_index: 0,
        }
2898 2899
    }

2900
    /// Returns `true` if the impls are the same polarity and the trait either
2901
    /// has no items or is annotated #[marker] and prevents item overrides.
2902 2903 2904 2905
    pub fn impls_are_allowed_to_overlap(self, def_id1: DefId, def_id2: DefId)
                                        -> Option<ImplOverlapKind>
    {
        let is_legit = if self.features().overlapping_marker_traits {
2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916
            let trait1_is_empty = self.impl_trait_ref(def_id1)
                .map_or(false, |trait_ref| {
                    self.associated_item_def_ids(trait_ref.def_id).is_empty()
                });
            let trait2_is_empty = self.impl_trait_ref(def_id2)
                .map_or(false, |trait_ref| {
                    self.associated_item_def_ids(trait_ref.def_id).is_empty()
                });
            self.impl_polarity(def_id1) == self.impl_polarity(def_id2)
                && trait1_is_empty
                && trait2_is_empty
2917
        } else {
2918 2919 2920 2921 2922 2923 2924
            let is_marker_impl = |def_id: DefId| -> bool {
                let trait_ref = self.impl_trait_ref(def_id);
                trait_ref.map_or(false, |tr| self.trait_def(tr.def_id).is_marker)
            };
            self.impl_polarity(def_id1) == self.impl_polarity(def_id2)
                && is_marker_impl(def_id1)
                && is_marker_impl(def_id2)
2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947
        };

        if is_legit {
            debug!("impls_are_allowed_to_overlap({:?}, {:?}) = Some(Permitted)",
                  def_id1, def_id2);
            Some(ImplOverlapKind::Permitted)
        } else {
            if let Some(self_ty1) = self.issue33140_self_ty(def_id1) {
                if let Some(self_ty2) = self.issue33140_self_ty(def_id2) {
                    if self_ty1 == self_ty2 {
                        debug!("impls_are_allowed_to_overlap({:?}, {:?}) - issue #33140 HACK",
                               def_id1, def_id2);
                        return Some(ImplOverlapKind::Issue33140);
                    } else {
                        debug!("impls_are_allowed_to_overlap({:?}, {:?}) - found {:?} != {:?}",
                              def_id1, def_id2, self_ty1, self_ty2);
                    }
                }
            }

            debug!("impls_are_allowed_to_overlap({:?}, {:?}) = None",
                  def_id1, def_id2);
            None
2948
        }
S
Sean Griffin 已提交
2949 2950
    }

2951 2952
    /// Returns `ty::VariantDef` if `def` refers to a struct,
    /// or variant or their constructors, panics otherwise.
2953
    pub fn expect_variant_def(self, def: Def) -> &'tcx VariantDef {
2954
        match def {
2955
            Def::Variant(did) => {
2956
                let enum_did = self.parent(did).unwrap();
2957
                self.adt_def(enum_did).variant_with_id(did)
2958
            }
2959
            Def::Struct(did) | Def::Union(did) => {
2960
                self.adt_def(did).non_enum_variant()
2961
            }
D
David Wood 已提交
2962
            Def::Ctor(variant_ctor_did, CtorOf::Variant, ..) => {
2963 2964 2965 2966
                let variant_did = self.parent(variant_ctor_did).unwrap();
                let enum_did = self.parent(variant_did).unwrap();
                self.adt_def(enum_did).variant_with_ctor_id(variant_ctor_did)
            }
D
David Wood 已提交
2967
            Def::Ctor(ctor_did, CtorOf::Struct, ..) => {
2968 2969
                let struct_did = self.parent(ctor_did).expect("struct ctor has no parent");
                self.adt_def(struct_did).non_enum_variant()
2970 2971 2972 2973 2974
            }
            _ => bug!("expect_variant_def used with unexpected def {:?}", def)
        }
    }

2975
    pub fn item_name(self, id: DefId) -> InternedString {
2976
        if id.index == CRATE_DEF_INDEX {
2977
            self.original_crate_name(id.krate).as_interned_str()
2978
        } else {
2979
            let def_key = self.def_key(id);
2980
            match def_key.disambiguated_data.data {
2981 2982
                // The name of a constructor is that of its parent.
                hir_map::DefPathData::Ctor =>
2983 2984 2985 2986 2987
                    self.item_name(DefId {
                        krate: id.krate,
                        index: def_key.parent.unwrap()
                    }),
                _ => def_key.disambiguated_data.data.get_opt_name().unwrap_or_else(|| {
2988
                    bug!("item_name: no name for {:?}", self.def_path(id));
2989
                }),
2990
            }
2991 2992 2993
        }
    }

A
Alexander Regueiro 已提交
2994
    /// Returns the possibly-auto-generated MIR of a `(DefId, Subst)` pair.
2995
    pub fn instance_mir(self, instance: ty::InstanceDef<'gcx>)
2996
                        -> &'gcx Mir<'gcx>
2997 2998
    {
        match instance {
N
Niko Matsakis 已提交
2999
            ty::InstanceDef::Item(did) => {
3000
                self.optimized_mir(did)
N
Niko Matsakis 已提交
3001
            }
M
Masaki Hara 已提交
3002
            ty::InstanceDef::VtableShim(..) |
N
Niko Matsakis 已提交
3003 3004 3005 3006
            ty::InstanceDef::Intrinsic(..) |
            ty::InstanceDef::FnPtrShim(..) |
            ty::InstanceDef::Virtual(..) |
            ty::InstanceDef::ClosureOnceShim { .. } |
3007
            ty::InstanceDef::DropGlue(..) |
S
scalexm 已提交
3008
            ty::InstanceDef::CloneShim(..) => {
3009
                self.mir_shims(instance)
N
Niko Matsakis 已提交
3010
            }
3011 3012 3013
        }
    }

A
Alexander Regueiro 已提交
3014
    /// Gets the attributes of a definition.
3015
    pub fn get_attrs(self, did: DefId) -> Attributes<'gcx> {
L
ljedrz 已提交
3016 3017
        if let Some(id) = self.hir().as_local_hir_id(did) {
            Attributes::Borrowed(self.hir().attrs_by_hir_id(id))
3018
        } else {
A
achernyak 已提交
3019
            Attributes::Owned(self.item_attrs(did))
3020
        }
3021 3022
    }

A
Alexander Regueiro 已提交
3023
    /// Determines whether an item is annotated with an attribute.
3024
    pub fn has_attr(self, did: DefId, attr: &str) -> bool {
3025
        attr::contains_name(&self.get_attrs(did), attr)
3026
    }
3027

3028
    /// Returns `true` if this is an `auto trait`.
3029
    pub fn trait_is_auto(self, trait_def_id: DefId) -> bool {
3030
        self.trait_def(trait_def_id).has_auto_impl
3031
    }
3032

J
John Kåre Alsaker 已提交
3033 3034 3035 3036
    pub fn generator_layout(self, def_id: DefId) -> &'tcx GeneratorLayout<'tcx> {
        self.optimized_mir(def_id).generator_layout.as_ref().unwrap()
    }

A
Alexander Regueiro 已提交
3037 3038
    /// Given the `DefId` of an impl, returns the `DefId` of the trait it implements.
    /// If it implements no trait, returns `None`.
3039
    pub fn trait_id_of_impl(self, def_id: DefId) -> Option<DefId> {
3040
        self.impl_trait_ref(def_id).map(|tr| tr.def_id)
3041
    }
3042

A
Alexander Regueiro 已提交
3043 3044
    /// If the given defid describes a method belonging to an impl, returns the
    /// `DefId` of the impl that the method belongs to; otherwise, returns `None`.
3045
    pub fn impl_of_method(self, def_id: DefId) -> Option<DefId> {
3046
        let item = if def_id.krate != LOCAL_CRATE {
A
achernyak 已提交
3047
            if let Some(Def::Method(_)) = self.describe_def(def_id) {
3048 3049 3050 3051 3052
                Some(self.associated_item(def_id))
            } else {
                None
            }
        } else {
3053
            self.opt_associated_item(def_id)
3054 3055
        };

3056 3057 3058 3059
        item.and_then(|trait_item|
            match trait_item.container {
                TraitContainer(_) => None,
                ImplContainer(def_id) => Some(def_id),
3060
            }
3061
        )
3062 3063
    }

3064 3065
    /// Looks up the span of `impl_did` if the impl is local; otherwise returns `Err`
    /// with the name of the crate containing the impl.
3066
    pub fn span_of_impl(self, impl_did: DefId) -> Result<Span, Symbol> {
3067
        if impl_did.is_local() {
L
ljedrz 已提交
3068 3069
            let hir_id = self.hir().as_local_hir_id(impl_did).unwrap();
            Ok(self.hir().span_by_hir_id(hir_id))
3070
        } else {
3071
            Err(self.crate_name(impl_did.krate))
3072 3073
        }
    }
J
Jeffrey Seyfried 已提交
3074

A
Alexander Regueiro 已提交
3075 3076 3077
    /// Hygienically compares a use-site name (`use_name`) for a field or an associated item with
    /// its supposed definition name (`def_name`). The method also needs `DefId` of the supposed
    /// definition's parent/scope to perform comparison.
3078
    pub fn hygienic_eq(self, use_name: Ident, def_name: Ident, def_parent_def_id: DefId) -> bool {
L
ljedrz 已提交
3079
        self.adjust_ident(use_name, def_parent_def_id, hir::DUMMY_HIR_ID).0 == def_name.modern()
J
Jeffrey Seyfried 已提交
3080 3081
    }

L
ljedrz 已提交
3082
    pub fn adjust_ident(self, mut ident: Ident, scope: DefId, block: hir::HirId) -> (Ident, DefId) {
3083 3084
        ident = ident.modern();
        let target_expansion = match scope.krate {
3085
            LOCAL_CRATE => self.hir().definitions().expansion_that_defined(scope.index),
J
Jeffrey Seyfried 已提交
3086 3087
            _ => Mark::root(),
        };
3088 3089
        let scope = match ident.span.adjust(target_expansion) {
            Some(actual_expansion) =>
3090
                self.hir().definitions().parent_module_of_macro_def(actual_expansion),
L
ljedrz 已提交
3091 3092
            None if block == hir::DUMMY_HIR_ID => DefId::local(CRATE_DEF_INDEX), // Dummy DefId
            None => self.hir().get_module_parent_by_hir_id(block),
J
Jeffrey Seyfried 已提交
3093 3094 3095
        };
        (ident, scope)
    }
3096
}
3097

3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113
pub struct AssociatedItemsIterator<'a, 'gcx: 'tcx, 'tcx: 'a> {
    tcx: TyCtxt<'a, 'gcx, 'tcx>,
    def_ids: Lrc<Vec<DefId>>,
    next_index: usize,
}

impl Iterator for AssociatedItemsIterator<'_, '_, '_> {
    type Item = AssociatedItem;

    fn next(&mut self) -> Option<AssociatedItem> {
        let def_id = self.def_ids.get(self.next_index)?;
        self.next_index += 1;
        Some(self.tcx.associated_item(*def_id))
    }
}

3114
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
3115
    pub fn with_freevars<T, F>(self, fid: HirId, f: F) -> T where
3116
        F: FnOnce(&[hir::Freevar]) -> T,
3117
    {
3118
        let def_id = self.hir().local_def_id_from_hir_id(fid);
A
Alex Crichton 已提交
3119
        match self.freevars(def_id) {
3120
            None => f(&[]),
3121
            Some(d) => f(&d),
3122 3123
        }
    }
3124
}
3125

L
ljedrz 已提交
3126
fn associated_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> AssociatedItem {
L
ljedrz 已提交
3127 3128 3129 3130
    let id = tcx.hir().as_local_hir_id(def_id).unwrap();
    let parent_id = tcx.hir().get_parent_item(id);
    let parent_def_id = tcx.hir().local_def_id_from_hir_id(parent_id);
    let parent_item = tcx.hir().expect_item_by_hir_id(parent_id);
3131
    match parent_item.node {
C
csmoe 已提交
3132
        hir::ItemKind::Impl(.., ref impl_item_refs) => {
L
ljedrz 已提交
3133
            if let Some(impl_item_ref) = impl_item_refs.iter().find(|i| i.id.hir_id == id) {
3134 3135
                let assoc_item = tcx.associated_item_from_impl_item_ref(parent_def_id,
                                                                        impl_item_ref);
3136 3137
                debug_assert_eq!(assoc_item.def_id, def_id);
                return assoc_item;
3138 3139 3140
            }
        }

C
csmoe 已提交
3141
        hir::ItemKind::Trait(.., ref trait_item_refs) => {
L
ljedrz 已提交
3142
            if let Some(trait_item_ref) = trait_item_refs.iter().find(|i| i.id.hir_id == id) {
3143 3144 3145
                let assoc_item = tcx.associated_item_from_trait_item_ref(parent_def_id,
                                                                         &parent_item.vis,
                                                                         trait_item_ref);
3146 3147
                debug_assert_eq!(assoc_item.def_id, def_id);
                return assoc_item;
3148 3149 3150
            }
        }

3151
        _ => { }
3152
    }
3153 3154 3155 3156

    span_bug!(parent_item.span,
              "unexpected parent of trait or impl item or item not found: {:?}",
              parent_item.node)
3157 3158
}

3159
#[derive(Clone, HashStable)]
3160 3161
pub struct AdtSizedConstraint<'tcx>(pub &'tcx [Ty<'tcx>]);

A
Alexander Regueiro 已提交
3162
/// Calculates the `Sized` constraint.
3163
///
3164
/// In fact, there are only a few options for the types in the constraint:
3165 3166 3167 3168
///     - an obviously-unsized type
///     - a type parameter or projection whose Sizedness can't be known
///     - a tuple of type parameters or projections, if there are multiple
///       such.
V
varkor 已提交
3169
///     - a Error, if a type contained itself. The representability
3170 3171 3172
///       check should catch this case.
fn adt_sized_constraint<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                  def_id: DefId)
3173
                                  -> AdtSizedConstraint<'tcx> {
3174
    let def = tcx.adt_def(def_id);
3175

3176
    let result = tcx.mk_type_list(def.variants.iter().flat_map(|v| {
3177 3178
        v.fields.last()
    }).flat_map(|f| {
3179
        def.sized_constraint_for_ty(tcx, tcx.type_of(f.did))
3180
    }));
3181

3182
    debug!("adt_sized_constraint: {:?} => {:?}", def, result);
3183

3184
    AdtSizedConstraint(result)
3185 3186
}

3187 3188
fn associated_item_def_ids<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                     def_id: DefId)
3189
                                     -> Lrc<Vec<DefId>> {
L
ljedrz 已提交
3190 3191
    let id = tcx.hir().as_local_hir_id(def_id).unwrap();
    let item = tcx.hir().expect_item_by_hir_id(id);
3192
    let vec: Vec<_> = match item.node {
C
csmoe 已提交
3193
        hir::ItemKind::Trait(.., ref trait_item_refs) => {
3194 3195
            trait_item_refs.iter()
                           .map(|trait_item_ref| trait_item_ref.id)
L
ljedrz 已提交
3196
                           .map(|id| tcx.hir().local_def_id_from_hir_id(id.hir_id))
3197 3198
                           .collect()
        }
C
csmoe 已提交
3199
        hir::ItemKind::Impl(.., ref impl_item_refs) => {
3200 3201
            impl_item_refs.iter()
                          .map(|impl_item_ref| impl_item_ref.id)
L
ljedrz 已提交
3202
                          .map(|id| tcx.hir().local_def_id_from_hir_id(id.hir_id))
3203 3204
                          .collect()
        }
C
csmoe 已提交
3205
        hir::ItemKind::TraitAlias(..) => vec![],
3206 3207
        _ => span_bug!(item.span, "associated_item_def_ids: not impl or trait")
    };
3208
    Lrc::new(vec)
3209 3210
}

A
achernyak 已提交
3211
fn def_span<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Span {
3212
    tcx.hir().span_if_local(def_id).unwrap()
A
achernyak 已提交
3213 3214
}

A
Alexander Regueiro 已提交
3215 3216 3217
/// If the given `DefId` describes an item belonging to a trait,
/// returns the `DefId` of the trait that the trait item belongs to;
/// otherwise, returns `None`.
A
achernyak 已提交
3218 3219 3220 3221 3222 3223 3224 3225 3226 3227
fn trait_of_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Option<DefId> {
    tcx.opt_associated_item(def_id)
        .and_then(|associated_item| {
            match associated_item.container {
                TraitContainer(def_id) => Some(def_id),
                ImplContainer(_) => None
            }
        })
}

3228
/// Yields the parent function's `DefId` if `def_id` is an `impl Trait` definition.
3229
pub fn is_impl_trait_defn(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Option<DefId> {
3230 3231
    if let Some(hir_id) = tcx.hir().as_local_hir_id(def_id) {
        if let Node::Item(item) = tcx.hir().get_by_hir_id(hir_id) {
3232 3233 3234 3235 3236 3237 3238 3239
            if let hir::ItemKind::Existential(ref exist_ty) = item.node {
                return exist_ty.impl_trait_fn;
            }
        }
    }
    None
}

3240
/// See `ParamEnv` struct definition for details.
3241
fn param_env<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
3242
                       def_id: DefId)
L
ljedrz 已提交
3243 3244
                       -> ParamEnv<'tcx>
{
O
Oliver Schneider 已提交
3245
    // The param_env of an impl Trait type is its defining function's param_env
3246 3247
    if let Some(parent) = is_impl_trait_defn(tcx, def_id) {
        return param_env(tcx, parent);
3248
    }
3249 3250
    // Compute the bounds on Self and the type parameters.

N
Niko Matsakis 已提交
3251 3252
    let InstantiatedPredicates { predicates } =
        tcx.predicates_of(def_id).instantiate_identity(tcx);
3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265

    // Finally, we have to normalize the bounds in the environment, in
    // case they contain any associated type projections. This process
    // can yield errors if the put in illegal associated types, like
    // `<i32 as Foo>::Bar` where `i32` does not implement `Foo`. We
    // report these errors right here; this doesn't actually feel
    // right to me, because constructing the environment feels like a
    // kind of a "idempotent" action, but I'm not sure where would be
    // a better place. In practice, we construct environments for
    // every fn once during type checking, and we'll abort if there
    // are any errors at that point, so after type checking you can be
    // sure that this will succeed without errors anyway.

S
scalexm 已提交
3266 3267 3268
    let unnormalized_env = ty::ParamEnv::new(
        tcx.intern_predicates(&predicates),
        traits::Reveal::UserFacing,
3269
        if tcx.sess.opts.debugging_opts.chalk { Some(def_id) } else { None }
S
scalexm 已提交
3270
    );
3271

L
ljedrz 已提交
3272 3273
    let body_id = tcx.hir().as_local_hir_id(def_id).map_or(hir::DUMMY_HIR_ID, |id| {
        tcx.hir().maybe_body_owned_by_by_hir_id(id).map_or(id, |body| body.hir_id)
3274 3275 3276 3277
    });
    let cause = traits::ObligationCause::misc(tcx.def_span(def_id), body_id);
    traits::normalize_param_env_or_error(tcx, def_id, unnormalized_env, cause)
}
A
achernyak 已提交
3278

3279
fn crate_disambiguator<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
3280
                                 crate_num: CrateNum) -> CrateDisambiguator {
3281 3282 3283 3284
    assert_eq!(crate_num, LOCAL_CRATE);
    tcx.sess.local_crate_disambiguator()
}

3285 3286 3287 3288 3289 3290
fn original_crate_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                 crate_num: CrateNum) -> Symbol {
    assert_eq!(crate_num, LOCAL_CRATE);
    tcx.crate_name.clone()
}

3291 3292 3293 3294
fn crate_hash<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                        crate_num: CrateNum)
                        -> Svh {
    assert_eq!(crate_num, LOCAL_CRATE);
3295
    tcx.hir().crate_hash
3296 3297
}

V
varkor 已提交
3298 3299 3300 3301
fn instance_def_size_estimate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                        instance_def: InstanceDef<'tcx>)
                                        -> usize {
    match instance_def {
3302 3303 3304
        InstanceDef::Item(..) |
        InstanceDef::DropGlue(..) => {
            let mir = tcx.instance_mir(instance_def);
V
varkor 已提交
3305 3306
            mir.basic_blocks().iter().map(|bb| bb.statements.len()).sum()
        },
3307
        // Estimate the size of other compiler-generated shims to be 1.
V
varkor 已提交
3308 3309 3310 3311
        _ => 1
    }
}

A
Alexander Regueiro 已提交
3312
/// If `def_id` is an issue 33140 hack impl, returns its self type; otherwise, returns `None`.
3313
///
A
Alexander Regueiro 已提交
3314
/// See [`ImplOverlapKind::Issue33140`] for more details.
3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363
fn issue33140_self_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                def_id: DefId)
                                -> Option<Ty<'tcx>>
{
    debug!("issue33140_self_ty({:?})", def_id);

    let trait_ref = tcx.impl_trait_ref(def_id).unwrap_or_else(|| {
        bug!("issue33140_self_ty called on inherent impl {:?}", def_id)
    });

    debug!("issue33140_self_ty({:?}), trait-ref={:?}", def_id, trait_ref);

    let is_marker_like =
        tcx.impl_polarity(def_id) == hir::ImplPolarity::Positive &&
        tcx.associated_item_def_ids(trait_ref.def_id).is_empty();

    // Check whether these impls would be ok for a marker trait.
    if !is_marker_like {
        debug!("issue33140_self_ty - not marker-like!");
        return None;
    }

    // impl must be `impl Trait for dyn Marker1 + Marker2 + ...`
    if trait_ref.substs.len() != 1 {
        debug!("issue33140_self_ty - impl has substs!");
        return None;
    }

    let predicates = tcx.predicates_of(def_id);
    if predicates.parent.is_some() || !predicates.predicates.is_empty() {
        debug!("issue33140_self_ty - impl has predicates {:?}!", predicates);
        return None;
    }

    let self_ty = trait_ref.self_ty();
    let self_ty_matches = match self_ty.sty {
        ty::Dynamic(ref data, ty::ReStatic) => data.principal().is_none(),
        _ => false
    };

    if self_ty_matches {
        debug!("issue33140_self_ty - MATCHES!");
        Some(self_ty)
    } else {
        debug!("issue33140_self_ty - non-matching self type");
        None
    }
}

3364
pub fn provide(providers: &mut ty::query::Providers<'_>) {
3365
    context::provide(providers);
3366
    erase_regions::provide(providers);
3367 3368
    layout::provide(providers);
    util::provide(providers);
3369
    constness::provide(providers);
3370
    *providers = ty::query::Providers {
3371
        associated_item,
3372
        associated_item_def_ids,
3373
        adt_sized_constraint,
A
achernyak 已提交
3374
        def_span,
3375
        param_env,
A
achernyak 已提交
3376
        trait_of_item,
3377
        crate_disambiguator,
3378
        original_crate_name,
3379
        crate_hash,
3380
        trait_impls_of: trait_def::trait_impls_of_provider,
V
varkor 已提交
3381
        instance_def_size_estimate,
3382
        issue33140_self_ty,
3383 3384 3385 3386
        ..*providers
    };
}

3387 3388 3389
/// A map for the local crate mapping each type to a vector of its
/// inherent impls. This is not meant to be used outside of coherence;
/// rather, you should request the vector for a specific type via
3390 3391
/// `tcx.inherent_impls(def_id)` so as to minimize your dependencies
/// (constructing this map requires touching the entire crate).
3392
#[derive(Clone, Debug, Default, HashStable)]
3393
pub struct CrateInherentImpls {
3394
    pub inherent_impls: DefIdMap<Lrc<Vec<DefId>>>,
3395
}
A
Ariel Ben-Yehuda 已提交
3396

3397
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable)]
3398 3399 3400 3401 3402 3403
pub struct SymbolName {
    // FIXME: we don't rely on interning or equality here - better have
    // this be a `&'tcx str`.
    pub name: InternedString
}

3404 3405 3406 3407
impl_stable_hash_for!(struct self::SymbolName {
    name
});

3408 3409 3410
impl SymbolName {
    pub fn new(name: &str) -> SymbolName {
        SymbolName {
3411
            name: Symbol::intern(name).as_interned_str()
3412 3413
        }
    }
3414

3415 3416 3417
    pub fn as_str(&self) -> LocalInternedString {
        self.name.as_str()
    }
3418 3419 3420
}

impl fmt::Display for SymbolName {
3421
    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
3422 3423 3424
        fmt::Display::fmt(&self.name, fmt)
    }
}
3425 3426

impl fmt::Debug for SymbolName {
3427
    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
3428 3429 3430
        fmt::Display::fmt(&self.name, fmt)
    }
}