mod.rs 122.5 KB
Newer Older
S
Steven Fackler 已提交
1
pub use self::Variance::*;
2
pub use self::AssociatedItemContainer::*;
S
Steven Fackler 已提交
3 4
pub use self::BorrowKind::*;
pub use self::IntVarValue::*;
5
pub use self::fold::TypeFoldable;
S
Steven Fackler 已提交
6

M
Mark Mansi 已提交
7
use crate::hir::{map as hir_map, FreevarMap, GlobMap, TraitMap};
8
use crate::hir::{HirId, Node};
M
Mark Mansi 已提交
9 10
use crate::hir::def::{Def, CtorKind, ExportMap};
use crate::hir::def_id::{CrateNum, DefId, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
11
use rustc_data_structures::svh::Svh;
12
use rustc_macros::HashStable;
M
Mark Mansi 已提交
13 14 15 16 17 18 19 20 21 22 23 24
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 已提交
25
use crate::ty::subst::{Subst, InternalSubsts, SubstsRef};
M
Mark Mansi 已提交
26 27 28 29
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 已提交
30
use arena::SyncDroplessArena;
M
Mark Mansi 已提交
31
use crate::session::DataTypeKind;
32

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

48
use smallvec;
49
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
50 51
use rustc_data_structures::stable_hasher::{StableHasher, StableHasherResult,
                                           HashStable};
O
Oliver Schneider 已提交
52

M
Mark Mansi 已提交
53
use crate::hir;
54

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

70 71 72
pub use self::binding::BindingMode;
pub use self::binding::BindingMode::*;

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

80 81
pub use self::instance::{Instance, InstanceDef};

82
pub use self::trait_def::TraitDef;
83

84
pub use self::query::queries;
85

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

110 111
mod context;
mod flags;
112
mod instance;
113 114 115
mod structural_impls;
mod sty;

116
// Data types
117

118 119 120 121 122
#[derive(Clone)]
pub struct Resolutions {
    pub freevars: FreevarMap,
    pub trait_map: TraitMap,
    pub maybe_unused_trait_imports: NodeSet,
123
    pub maybe_unused_extern_crates: Vec<(NodeId, Span)>,
N
Niko Matsakis 已提交
124
    pub export_map: ExportMap,
125
    pub glob_map: GlobMap,
V
Vadim Petrochenkov 已提交
126 127 128
    /// 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>,
129 130
}

131
#[derive(Clone, Copy, PartialEq, Eq, Debug, HashStable)]
132
pub enum AssociatedItemContainer {
N
Niko Matsakis 已提交
133 134
    TraitContainer(DefId),
    ImplContainer(DefId),
135 136
}

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

N
Niko Matsakis 已提交
147
    pub fn id(&self) -> DefId {
148 149 150 151 152 153 154
        match *self {
            TraitContainer(id) => id,
            ImplContainer(id) => id,
        }
    }
}

A
Aaron Turon 已提交
155 156
/// 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 已提交
157
/// bounds / where-clauses).
A
Aaron Turon 已提交
158 159 160 161 162 163 164 165
#[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>>,
}

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

176 177 178 179
    /// Whether this is a method with an explicit self
    /// as its first argument, allowing method calls.
    pub method_has_self_argument: bool,
}
180

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

189 190 191 192 193 194
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 已提交
195
            AssociatedKind::Existential => Def::AssociatedExistential(self.def_id),
196 197
        }
    }
A
Andrew Cann 已提交
198 199 200 201 202

    /// 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 已提交
203 204
            AssociatedKind::Existential |
            AssociatedKind::Const |
A
Andrew Cann 已提交
205
            AssociatedKind::Type => true,
A
Andrew Cann 已提交
206
            // FIXME(canndrew): Be more thorough here, check if any argument is uninhabited.
A
Andrew Cann 已提交
207 208 209
            AssociatedKind::Method => !self.method_has_self_argument,
        }
    }
210 211 212 213 214 215 216 217

    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 已提交
218
                tcx.fn_sig(self.def_id).skip_binder().to_string()
219
            }
220
            ty::AssociatedKind::Type => format!("type {};", self.ident),
O
Oliver Schneider 已提交
221
            ty::AssociatedKind::Existential => format!("existential type {};", self.ident),
222
            ty::AssociatedKind::Const => {
223
                format!("const {}: {:?};", self.ident, tcx.type_of(self.def_id))
224 225 226
            }
        }
    }
227 228
}

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

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

    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
    }
255 256
}

257 258 259
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 })
260 261 262
    }
}

263
impl Visibility {
L
ljedrz 已提交
264
    pub fn from_hir(visibility: &hir::Visibility, id: hir::HirId, tcx: TyCtxt<'_, '_, '_>) -> Self {
265
        match visibility.node {
266 267 268
            hir::VisibilityKind::Public => Visibility::Public,
            hir::VisibilityKind::Crate(_) => Visibility::Restricted(DefId::local(CRATE_DEF_INDEX)),
            hir::VisibilityKind::Restricted { ref path, .. } => match path.def {
269 270
                // 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.
271
                Def::Err => Visibility::Public,
272
                def => Visibility::Restricted(def.def_id()),
273
            },
274
            hir::VisibilityKind::Inherited => {
L
ljedrz 已提交
275
                Visibility::Restricted(tcx.hir().get_module_parent_by_hir_id(id))
276
            }
277 278
        }
    }
279

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

A
Andrew Cann 已提交
292
        tree.is_descendant_of(module, restriction)
293
    }
294

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

303
        self.is_accessible_from(vis_restriction, tree)
304
    }
305

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

316
#[derive(Copy, Clone, PartialEq, Eq, RustcDecodable, RustcEncodable, Hash, HashStable)]
317
pub enum Variance {
318 319 320 321
    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
322
}
323

324 325 326 327
/// 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
328
/// `tcx.variances_of()` to get the variance for a *particular*
329
/// item.
330
#[derive(HashStable)]
331 332
pub struct CrateVariancesMap {
    /// For each item with generics, maps to a vector of the variance
A
Alexander Regueiro 已提交
333
    /// of its generics. If an item has no generics, it will have no
334
    /// entry.
335
    pub variances: FxHashMap<DefId, Lrc<Vec<ty::Variance>>>,
336 337

    /// An empty vector, useful for cloning.
338
    #[stable_hasher(ignore)]
339
    pub empty_variance: Lrc<Vec<ty::Variance>>,
340 341
}

342 343
impl Variance {
    /// `a.xform(b)` combines the variance of a context with the
A
Alexander Regueiro 已提交
344
    /// variance of a type with the following meaning. If we are in a
345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367
    /// 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 已提交
368
    /// `Covariant.xform(Contravariant)`, or `Contravariant`. `*const
369 370
    /// T` is covariant with respect to `T`, so the variance within
    /// which the first `Vec<i32>` appears is
A
Alexander Regueiro 已提交
371
    /// `Contravariant.xform(Covariant)` or `Contravariant`. The same
372 373 374 375 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
    /// 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,
        }
    }
}

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

410 411 412 413
// 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.
414
bitflags! {
415 416 417 418 419
    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;
420
        const HAS_RE_PLACEHOLDER = 1 << 4;
421 422 423 424 425

        /// 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.
426
        const HAS_RE_EARLY_BOUND = 1 << 5;
427 428 429

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

        /// Is an error type reachable?
433 434
        const HAS_TY_ERR         = 1 << 7;
        const HAS_PROJECTION     = 1 << 8;
J
John Kåre Alsaker 已提交
435 436

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

439
        // `true` if there are "names" of types and regions and so forth
440
        // that are local to a particular fn
441
        const HAS_FREE_LOCAL_NAMES    = 1 << 10;
442

443
        // Present if the type belongs in a local type context.
V
varkor 已提交
444
        // Only set for Infer other than Fresh.
445
        const KEEP_IN_LOCAL_TCX  = 1 << 11;
446

447 448
        // Is there a projection that does not involve a bound region?
        // Currently we can't normalize projections w/ bound regions.
449
        const HAS_NORMALIZABLE_PROJECTION = 1 << 12;
450

451 452
        /// Does this have any `ReLateBound` regions? Used to check
        /// if a global bound is safe to evaluate.
453
        const HAS_RE_LATE_BOUND = 1 << 13;
454

S
scalexm 已提交
455 456
        const HAS_TY_PLACEHOLDER = 1 << 14;

V
varkor 已提交
457 458
        const HAS_CT_INFER = 1 << 15;

459 460
        const NEEDS_SUBST        = TypeFlags::HAS_PARAMS.bits |
                                   TypeFlags::HAS_SELF.bits |
461
                                   TypeFlags::HAS_RE_EARLY_BOUND.bits;
462 463

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

484
pub struct TyS<'tcx> {
V
varkor 已提交
485
    pub sty: TyKind<'tcx>,
486
    pub flags: TypeFlags,
487

488 489 490 491 492 493 494 495
    /// 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
496
    /// will be *innermost*, because that is the innermost binder that
497
    /// captures nothing. But for a type `&'D u32`, where `'D` is a
A
Alexander Regueiro 已提交
498
    /// late-bound region with De Bruijn index `D`, this would be `D + 1`
499 500
    /// -- the binder itself does not capture `D`, but `D` is captured
    /// by an inner binder.
501
    ///
502
    /// We call this concept an "exclusive" binder `D` because all
A
Alexander Regueiro 已提交
503
    /// De Bruijn indices within the type are contained within `0..D`
504
    /// (exclusive).
505
    outer_exclusive_binder: ty::DebruijnIndex,
506 507
}

508 509 510 511
// `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);

512 513 514 515 516 517 518 519 520 521 522 523
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))
    }
}

524
impl<'tcx> PartialEq for TyS<'tcx> {
525
    #[inline]
526
    fn eq(&self, other: &TyS<'tcx>) -> bool {
527
        ptr::eq(self, other)
528 529
    }
}
530
impl<'tcx> Eq for TyS<'tcx> {}
531

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

G
Guillaume Gomez 已提交
538 539 540
impl<'tcx> TyS<'tcx> {
    pub fn is_primitive_ty(&self) -> bool {
        match self.sty {
541
            TyKind::Bool |
542 543 544 545 546 547 548 549
            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 已提交
550
            TyKind::Ref(_, x, _) => x.is_primitive_ty(),
G
Guillaume Gomez 已提交
551 552 553
            _ => false,
        }
    }
554 555 556

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

569
impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for ty::TyS<'gcx> {
570
    fn hash_stable<W: StableHasherResult>(&self,
571
                                          hcx: &mut StableHashingContext<'a>,
572 573 574 575 576 577 578
                                          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: _,
579 580

            outer_exclusive_binder: _,
581 582 583 584 585 586
        } = *self;

        sty.hash_stable(hcx, hasher);
    }
}

587
pub type Ty<'tcx> = &'tcx TyS<'tcx>;
588

589 590
impl<'tcx> serialize::UseSpecializedEncodable for Ty<'tcx> {}
impl<'tcx> serialize::UseSpecializedDecodable for Ty<'tcx> {}
591

592 593
pub type CanonicalTy<'gcx> = Canonical<'gcx, Ty<'gcx>>;

J
John Kåre Alsaker 已提交
594
extern {
V
varkor 已提交
595 596
    /// A dummy type used to force List to by unsized without requiring fat pointers
    type OpaqueListContents;
J
John Kåre Alsaker 已提交
597 598
}

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

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

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

J
John Kåre Alsaker 已提交
621 622 623 624 625 626
        // 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 已提交
627 628
        let size = offset + slice.len() * mem::size_of::<T>();

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

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

J
John Kåre Alsaker 已提交
641
            result
J
John Kåre Alsaker 已提交
642 643 644 645
        }
    }
}

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

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

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

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

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

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

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

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

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

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

724
#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
725 726 727 728
pub struct UpvarPath {
    pub hir_id: hir::HirId,
}

A
Alexander Regueiro 已提交
729 730 731
/// 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.
732
#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
733
pub struct UpvarId {
734
    pub var_path: UpvarPath,
735
    pub closure_expr_id: LocalDefId,
736 737
}

738
#[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable, Copy, HashStable)]
739 740 741 742
pub enum BorrowKind {
    /// Data must be immutable and is aliasable.
    ImmBorrow,

A
Alexander Regueiro 已提交
743
    /// Data must be immutable but not aliasable. This kind of borrow
744
    /// cannot currently be expressed by the user and is used only in
K
king6cong 已提交
745
    /// implicit closure bindings. It is needed when the closure
746 747
    /// is borrowing or mutating a mutable referent, e.g.:
    ///
748
    ///    let x: &mut isize = ...;
749 750 751 752 753
    ///    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:
    ///
754 755
    ///    struct Env { x: & &mut isize }
    ///    let x: &mut isize = ...;
756 757 758 759 760 761 762
    ///    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:
    ///
763 764
    ///    struct Env { x: & &mut isize }
    ///    let x: &mut isize = ...;
765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783
    ///    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
}

784 785
/// Information describing the capture of an upvar. This is computed
/// during `typeck`, specifically by `regionck`.
786
#[derive(PartialEq, Clone, Debug, Copy, RustcEncodable, RustcDecodable, HashStable)]
787
pub enum UpvarCapture<'tcx> {
788 789 790 791 792 793
    /// 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.
794
    ByRef(UpvarBorrow<'tcx>),
795 796
}

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

    /// Region of the resulting reference.
N
Niko Matsakis 已提交
805
    pub region: ty::Region<'tcx>,
806 807
}

808
pub type UpvarListMap = FxHashMap<DefId, Vec<UpvarId>>;
809
pub type UpvarCaptureMap<'tcx> = FxHashMap<UpvarId, UpvarCapture<'tcx>>;
810

811 812
#[derive(Copy, Clone)]
pub struct ClosureUpvar<'tcx> {
813
    pub def: Def,
814 815 816 817
    pub span: Span,
    pub ty: Ty<'tcx>,
}

818
#[derive(Clone, Copy, PartialEq, Eq)]
819
pub enum IntVarValue {
820 821
    IntType(ast::IntTy),
    UintType(ast::UintTy),
822 823
}

824 825 826
#[derive(Clone, Copy, PartialEq, Eq)]
pub struct FloatVarValue(pub ast::FloatTy);

827
impl ty::EarlyBoundRegion {
828
    pub fn to_bound_region(&self) -> ty::BoundRegion {
829
        ty::BoundRegion::BrNamed(self.def_id, self.name)
830
    }
831 832 833 834 835 836

    /// 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()
    }
837 838
}

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

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

    /// `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,

861 862 863
    pub kind: GenericParamDefKind,
}

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

    pub fn to_bound_region(&self) -> ty::BoundRegion {
L
ljedrz 已提交
878 879 880 881
        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 已提交
882 883 884 885
        }
    }
}

V
varkor 已提交
886
#[derive(Default)]
887 888 889
pub struct GenericParamCount {
    pub lifetimes: usize,
    pub types: usize,
V
varkor 已提交
890
    pub consts: usize,
891 892
}

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

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

908
    pub has_self: bool,
909
    pub has_late_bound_regions: Option<Span>,
910 911
}

912
impl<'a, 'gcx, 'tcx> Generics {
913
    pub fn count(&self) -> usize {
V
varkor 已提交
914
        self.parent_count + self.params.len()
915
    }
916

V
varkor 已提交
917
    pub fn own_counts(&self) -> GenericParamCount {
918 919 920
        // 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 已提交
921
        let mut own_counts: GenericParamCount = Default::default();
922

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

V
varkor 已提交
931
        own_counts
932 933
    }

934
    pub fn requires_monomorphization(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> bool {
V
varkor 已提交
935
        for param in &self.params {
936
            match param.kind {
V
varkor 已提交
937
                GenericParamDefKind::Type { .. } | GenericParamDefKind::Const => return true,
V
varkor 已提交
938
                GenericParamDefKind::Lifetime => {}
V
varkor 已提交
939
            }
V
varkor 已提交
940 941 942
        }
        if let Some(parent_def_id) = self.parent {
            let parent = tcx.generics_of(parent_def_id);
943
            parent.requires_monomorphization(tcx)
V
varkor 已提交
944 945 946
        } else {
            false
        }
V
varkor 已提交
947 948
    }

949 950 951
    pub fn region_param(&'tcx self,
                        param: &EarlyBoundRegion,
                        tcx: TyCtxt<'a, 'gcx, 'tcx>)
952
                        -> &'tcx GenericParamDef
953
    {
V
varkor 已提交
954
        if let Some(index) = param.index.checked_sub(self.parent_count as u32) {
V
varkor 已提交
955
            let param = &self.params[index as usize];
956
            match param.kind {
V
varkor 已提交
957
                GenericParamDefKind::Lifetime => param,
V
varkor 已提交
958
                _ => bug!("expected lifetime parameter, but found another generic parameter")
V
varkor 已提交
959
            }
960
        } else {
961
            tcx.generics_of(self.parent.expect("parent_count > 0 but no parent?"))
L
ljedrz 已提交
962
               .region_param(param, tcx)
963
        }
964 965
    }

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

    /// 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)
        }
    }
999 1000
}

1001
/// Bounds on generics.
1002
#[derive(Clone, Default, Debug, HashStable)]
1003
pub struct GenericPredicates<'tcx> {
1004
    pub parent: Option<DefId>,
1005
    pub predicates: Vec<(Predicate<'tcx>, Span)>,
1006 1007
}

1008 1009 1010
impl<'tcx> serialize::UseSpecializedEncodable for GenericPredicates<'tcx> {}
impl<'tcx> serialize::UseSpecializedDecodable for GenericPredicates<'tcx> {}

1011
impl<'a, 'gcx, 'tcx> GenericPredicates<'tcx> {
C
csmoe 已提交
1012
    pub fn instantiate(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, substs: SubstsRef<'tcx>)
1013
                       -> InstantiatedPredicates<'tcx> {
1014 1015 1016 1017
        let mut instantiated = InstantiatedPredicates::empty();
        self.instantiate_into(tcx, &mut instantiated, substs);
        instantiated
    }
1018

C
csmoe 已提交
1019
    pub fn instantiate_own(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, substs: SubstsRef<'tcx>)
1020
                           -> InstantiatedPredicates<'tcx> {
1021
        InstantiatedPredicates {
1022
            predicates: self.predicates.iter().map(|(p, _)| p.subst(tcx, substs)).collect(),
1023 1024 1025 1026 1027
        }
    }

    fn instantiate_into(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
                        instantiated: &mut InstantiatedPredicates<'tcx>,
C
csmoe 已提交
1028
                        substs: SubstsRef<'tcx>) {
1029
        if let Some(def_id) = self.parent {
1030
            tcx.predicates_of(def_id).instantiate_into(tcx, instantiated, substs);
1031
        }
1032 1033 1034
        instantiated.predicates.extend(
            self.predicates.iter().map(|(p, _)| p.subst(tcx, substs)),
        );
1035
    }
1036

1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048
    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);
        }
1049
        instantiated.predicates.extend(self.predicates.iter().map(|&(p, _)| p))
1050 1051
    }

1052
    pub fn instantiate_supertrait(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
1053 1054 1055
                                  poly_trait_ref: &ty::PolyTraitRef<'tcx>)
                                  -> InstantiatedPredicates<'tcx>
    {
1056
        assert_eq!(self.parent, None);
1057
        InstantiatedPredicates {
1058
            predicates: self.predicates.iter().map(|(pred, _)| {
1059
                pred.subst_supertrait(tcx, poly_trait_ref)
1060
            }).collect()
1061 1062
        }
    }
1063 1064
}

1065
#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
1066
pub enum Predicate<'tcx> {
1067
    /// Corresponds to `where Foo: Bar<A,B,C>`. `Foo` here would be
N
Niko Matsakis 已提交
1068
    /// the `Self` type of the trait reference and `A`, `B`, and `C`
1069
    /// would be the type parameters.
1070
    Trait(PolyTraitPredicate<'tcx>),
1071

1072
    /// where `'a: 'b`
1073
    RegionOutlives(PolyRegionOutlivesPredicate<'tcx>),
1074

1075
    /// where `T: 'a`
1076
    TypeOutlives(PolyTypeOutlivesPredicate<'tcx>),
1077

1078 1079
    /// where `<T as TraitRef>::Name == X`, approximately.
    /// See the `ProjectionPredicate` struct for details.
1080
    Projection(PolyProjectionPredicate<'tcx>),
1081

1082
    /// no syntax: `T` well-formed
1083 1084 1085
    WellFormed(Ty<'tcx>),

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

1088
    /// No direct syntax. May be thought of as `where T: FnFoo<...>`
1089
    /// for some substitutions `...` and `T` being a closure type.
1090
    /// Satisfied (or refuted) once we know the closure's kind.
1091
    ClosureKind(DefId, ClosureSubsts<'tcx>, ClosureKind),
N
Niko Matsakis 已提交
1092 1093 1094

    /// `T1 <: T2`
    Subtype(PolySubtypePredicate<'tcx>),
1095 1096

    /// Constant initializer must evaluate successfully.
C
csmoe 已提交
1097
    ConstEvaluatable(DefId, SubstsRef<'tcx>),
1098 1099
}

1100 1101 1102 1103 1104 1105
/// 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.
1106
#[derive(HashStable)]
1107 1108 1109 1110 1111 1112 1113
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.
    pub predicates: FxHashMap<DefId, Lrc<Vec<ty::Predicate<'tcx>>>>,

    /// An empty vector, useful for cloning.
1114
    #[stable_hasher(ignore)]
1115 1116 1117
    pub empty_predicate: Lrc<Vec<ty::Predicate<'tcx>>>,
}

1118 1119 1120 1121 1122 1123
impl<'tcx> AsRef<Predicate<'tcx>> for Predicate<'tcx> {
    fn as_ref(&self) -> &Predicate<'tcx> {
        self
    }
}

1124
impl<'a, 'gcx, 'tcx> Predicate<'tcx> {
1125
    /// Performs a substitution suitable for going from a
1126 1127
    /// poly-trait-ref to supertraits that must hold if that
    /// poly-trait-ref holds. This is slightly different from a normal
A
Alexander Regueiro 已提交
1128
    /// substitution in terms of what happens with bound regions. See
1129
    /// lengthy comment below for details.
1130
    pub fn subst_supertrait(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
1131 1132 1133 1134 1135 1136 1137 1138
                            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:
        //
1139
        //     trait Foo<'a>: Bar<'a,'a> { }
1140 1141
        //     trait Bar<'b,'c> { }
        //
1142 1143
        // 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
1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155
        // 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:
        //
1156
        //     trait Foo1<'a>: for<'b> Bar1<'a,'b> { }
1157 1158
        //     trait Bar1<'b,'c> { }
        //
1159 1160
        // 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
1161
        // reason is similar to the previous example: any impl of
1162
        // `T:Foo1<'x>` must show that `for<'b> T: Bar1<'x, 'b>`.  So
1163 1164 1165 1166 1167 1168
        // 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:
        //
1169 1170
        // - 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>`,
1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193
        //   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).

1194
        let substs = &trait_ref.skip_binder().substs;
1195
        match *self {
1196 1197 1198 1199 1200 1201 1202 1203 1204 1205
            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))),
1206 1207 1208 1209
            Predicate::WellFormed(data) =>
                Predicate::WellFormed(data.subst(tcx, substs)),
            Predicate::ObjectSafe(trait_def_id) =>
                Predicate::ObjectSafe(trait_def_id),
1210 1211
            Predicate::ClosureKind(closure_def_id, closure_substs, kind) =>
                Predicate::ClosureKind(closure_def_id, closure_substs.subst(tcx, substs), kind),
1212 1213
            Predicate::ConstEvaluatable(def_id, const_substs) =>
                Predicate::ConstEvaluatable(def_id, const_substs.subst(tcx, substs)),
1214 1215 1216 1217
        }
    }
}

1218
#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
1219
pub struct TraitPredicate<'tcx> {
1220
    pub trait_ref: TraitRef<'tcx>
1221
}
1222

1223 1224 1225
pub type PolyTraitPredicate<'tcx> = ty::Binder<TraitPredicate<'tcx>>;

impl<'tcx> TraitPredicate<'tcx> {
N
Niko Matsakis 已提交
1226
    pub fn def_id(&self) -> DefId {
1227 1228 1229
        self.trait_ref.def_id
    }

1230
    pub fn input_types<'a>(&'a self) -> impl DoubleEndedIterator<Item=Ty<'tcx>> + 'a {
1231
        self.trait_ref.input_types()
1232 1233 1234 1235 1236 1237 1238 1239
    }

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

impl<'tcx> PolyTraitPredicate<'tcx> {
N
Niko Matsakis 已提交
1240
    pub fn def_id(&self) -> DefId {
1241
        // ok to skip binder since trait def-id does not care about regions
1242
        self.skip_binder().def_id()
1243
    }
1244 1245
}

1246 1247
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord,
         Hash, Debug, RustcEncodable, RustcDecodable, HashStable)]
1248
pub struct OutlivesPredicate<A,B>(pub A, pub B); // `A: B`
1249
pub type PolyOutlivesPredicate<A,B> = ty::Binder<OutlivesPredicate<A,B>>;
S
scalexm 已提交
1250 1251 1252 1253 1254 1255
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>>;
1256

1257
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable, HashStable)]
N
Niko Matsakis 已提交
1258 1259 1260 1261 1262 1263 1264
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>>;

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

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

1285
impl<'tcx> PolyProjectionPredicate<'tcx> {
1286
    /// Returns the `DefId` of the associated item being projected.
1287 1288 1289 1290
    pub fn item_def_id(&self) -> DefId {
        self.skip_binder().projection_ty.item_def_id
    }

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

    pub fn ty(&self) -> Binder<Ty<'tcx>> {
1302 1303 1304
        self.map_bound(|predicate| predicate.ty)
    }

1305
    /// The `DefId` of the `TraitItem` for the associated type.
1306
    ///
1307 1308
    /// Note that this is not the `DefId` of the `TraitRef` containing this
    /// associated type, which is in `tcx.associated_item(projection_def_id()).container`.
1309
    pub fn projection_def_id(&self) -> DefId {
1310
        // okay to skip binder since trait def-id does not care about regions
1311
        self.skip_binder().projection_ty.item_def_id
1312
    }
1313 1314
}

1315 1316 1317 1318
pub trait ToPolyTraitRef<'tcx> {
    fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx>;
}

1319
impl<'tcx> ToPolyTraitRef<'tcx> for TraitRef<'tcx> {
1320
    fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> {
1321
        ty::Binder::dummy(self.clone())
1322 1323 1324 1325 1326
    }
}

impl<'tcx> ToPolyTraitRef<'tcx> for PolyTraitPredicate<'tcx> {
    fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> {
1327
        self.map_bound_ref(|trait_pred| trait_pred.trait_ref)
1328 1329 1330
    }
}

1331 1332
pub trait ToPredicate<'tcx> {
    fn to_predicate(&self) -> Predicate<'tcx>;
1333 1334
}

1335 1336
impl<'tcx> ToPredicate<'tcx> for TraitRef<'tcx> {
    fn to_predicate(&self) -> Predicate<'tcx> {
1337
        ty::Predicate::Trait(ty::Binder::dummy(ty::TraitPredicate {
1338 1339 1340 1341 1342
            trait_ref: self.clone()
        }))
    }
}

1343 1344
impl<'tcx> ToPredicate<'tcx> for PolyTraitRef<'tcx> {
    fn to_predicate(&self) -> Predicate<'tcx> {
1345
        ty::Predicate::Trait(self.to_poly_trait_predicate())
1346 1347 1348
    }
}

1349
impl<'tcx> ToPredicate<'tcx> for PolyRegionOutlivesPredicate<'tcx> {
1350
    fn to_predicate(&self) -> Predicate<'tcx> {
1351 1352 1353 1354
        Predicate::RegionOutlives(self.clone())
    }
}

1355 1356
impl<'tcx> ToPredicate<'tcx> for PolyTypeOutlivesPredicate<'tcx> {
    fn to_predicate(&self) -> Predicate<'tcx> {
1357 1358
        Predicate::TypeOutlives(self.clone())
    }
1359 1360
}

1361 1362
impl<'tcx> ToPredicate<'tcx> for PolyProjectionPredicate<'tcx> {
    fn to_predicate(&self) -> Predicate<'tcx> {
1363 1364 1365 1366
        Predicate::Projection(self.clone())
    }
}

1367 1368 1369 1370 1371 1372 1373 1374 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
// 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()
            }
        }
    }
}

1412
impl<'tcx> Predicate<'tcx> {
1413 1414 1415
    /// 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.
1416 1417
    pub fn walk_tys(&'a self) -> impl Iterator<Item = Ty<'tcx>> + 'a {
        match *self {
1418
            ty::Predicate::Trait(ref data) => {
1419
                WalkTysIter::InputTypes(data.skip_binder().input_types())
1420
            }
1421 1422
            ty::Predicate::Subtype(binder) => {
                let SubtypePredicate { a, b, a_is_expected: _ } = binder.skip_binder();
1423
                WalkTysIter::Two(a, b)
N
Niko Matsakis 已提交
1424
            }
1425
            ty::Predicate::TypeOutlives(binder) => {
1426
                WalkTysIter::One(binder.skip_binder().0)
1427 1428
            }
            ty::Predicate::RegionOutlives(..) => {
1429
                WalkTysIter::None
1430 1431
            }
            ty::Predicate::Projection(ref data) => {
1432
                let inner = data.skip_binder();
1433 1434
                WalkTysIter::ProjectionTypes(
                    inner.projection_ty.substs.types().chain(Some(inner.ty)))
1435
            }
1436
            ty::Predicate::WellFormed(data) => {
1437
                WalkTysIter::One(data)
1438 1439
            }
            ty::Predicate::ObjectSafe(_trait_def_id) => {
1440
                WalkTysIter::None
1441
            }
1442
            ty::Predicate::ClosureKind(_closure_def_id, closure_substs, _kind) => {
1443
                WalkTysIter::Types(closure_substs.substs.types())
1444
            }
1445
            ty::Predicate::ConstEvaluatable(_, substs) => {
1446
                WalkTysIter::Types(substs.types())
1447
            }
1448
        }
1449 1450
    }

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

    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
            }
        }
    }
1486 1487
}

S
Steve Klabnik 已提交
1488
/// Represents the bounds declared on a particular set of type
A
Alexander Regueiro 已提交
1489 1490
/// parameters. Should eventually be generalized into a flag list of
/// where-clauses. You can obtain a `InstantiatedPredicates` list from a
1491 1492 1493 1494
/// `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 已提交
1495 1496 1497 1498 1499 1500 1501 1502
/// 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>> { ... }
///
1503
/// Here, the `GenericPredicates` for `Foo` would contain a list of bounds like
A
Alexander Regueiro 已提交
1504
/// `[[], [U:Bar<T>]]`. Now if there were some particular reference
1505 1506
/// like `Foo<isize,usize>`, then the `InstantiatedPredicates` would be `[[],
/// [usize:Bar<isize>]]`.
1507
#[derive(Clone, Debug)]
1508
pub struct InstantiatedPredicates<'tcx> {
1509
    pub predicates: Vec<Predicate<'tcx>>,
1510 1511
}

1512 1513
impl<'tcx> InstantiatedPredicates<'tcx> {
    pub fn empty() -> InstantiatedPredicates<'tcx> {
1514
        InstantiatedPredicates { predicates: vec![] }
1515 1516
    }

1517 1518
    pub fn is_empty(&self) -> bool {
        self.predicates.is_empty()
1519
    }
1520 1521
}

1522
newtype_index! {
1523 1524 1525 1526 1527 1528 1529 1530 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
    /// "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.
1558 1559 1560 1561
    pub struct UniverseIndex {
        DEBUG_FORMAT = "U{}",
    }
}
1562 1563

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

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

1568 1569
    /// Returns the "next" universe index in order -- this new index
    /// is considered to extend all previous universes. This
A
Alexander Regueiro 已提交
1570
    /// corresponds to entering a `forall` quantifier. So, for
1571
    /// example, suppose we have this type in universe `U`:
N
Niko Matsakis 已提交
1572 1573 1574 1575 1576 1577
    ///
    /// ```
    /// for<'a> fn(&'a u32)
    /// ```
    ///
    /// Once we "enter" into this `for<'a>` quantifier, we are in a
1578 1579 1580 1581
    /// 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 {
1582
        UniverseIndex::from_u32(self.private.checked_add(1).unwrap())
1583 1584
    }

1585
    /// Returns `true` if `self` can name a name from `other` -- in other words,
1586
    /// if the set of names in `self` is a superset of those in
N
Niko Matsakis 已提交
1587
    /// `other` (`self >= other`).
1588 1589
    pub fn can_name(self, other: UniverseIndex) -> bool {
        self.private >= other.private
N
Niko Matsakis 已提交
1590
    }
N
Niko Matsakis 已提交
1591

1592
    /// Returns `true` if `self` cannot name some names from `other` -- in other
N
Niko Matsakis 已提交
1593 1594 1595 1596 1597
    /// 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 已提交
1598 1599
}

1600 1601 1602 1603 1604 1605 1606
/// 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 已提交
1607
pub struct Placeholder<T> {
1608
    pub universe: UniverseIndex,
S
scalexm 已提交
1609
    pub name: T,
1610 1611
}

S
scalexm 已提交
1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627
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>;
1628

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

I
Irina Popa 已提交
1639
    /// Typically, this is `Reveal::UserFacing`, but during codegen we
1640 1641 1642
    /// 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 已提交
1643 1644 1645 1646 1647

    /// 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>,
1648
}
1649

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

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

    /// Construct a trait environment with the given set of predicates.
1673
    #[inline]
S
scalexm 已提交
1674 1675 1676 1677 1678 1679
    pub fn new(
        caller_bounds: &'tcx List<ty::Predicate<'tcx>>,
        reveal: Reveal,
        def_id: Option<DefId>
    ) -> Self {
        ty::ParamEnv { caller_bounds, reveal, def_id }
1680 1681 1682 1683
    }

    /// Returns a new parameter environment with the same clauses, but
    /// which "reveals" the true results of projections in all cases
A
Alexander Regueiro 已提交
1684
    /// (even for associated types that are specializable). This is
I
Irina Popa 已提交
1685
    /// the desired behavior during codegen and certain other special
1686 1687 1688 1689 1690 1691 1692 1693
    /// 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 已提交
1694
        ty::ParamEnv { caller_bounds: List::empty(), ..self }
1695 1696
    }

1697
    /// Creates a suitable environment in which to perform trait
1698 1699 1700 1701 1702
    /// 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.
1703
    ///
1704
    /// N.B., we preserve the environment when type-checking because it
1705
    /// is possible for the user to have wacky where-clauses like
1706
    /// `where Box<u32>: Copy`, which are clearly never
1707 1708
    /// satisfiable. We generally want to behave as if they were true,
    /// although the surrounding function is never reachable.
1709
    pub fn and<T: TypeFoldable<'tcx>>(self, value: T) -> ParamEnvAnd<'tcx, T> {
1710 1711 1712 1713 1714 1715
        match self.reveal {
            Reveal::UserFacing => {
                ParamEnvAnd {
                    param_env: self,
                    value,
                }
1716
            }
1717 1718

            Reveal::All => {
1719
                if value.has_placeholders()
1720 1721 1722 1723
                    || value.needs_infer()
                    || value.has_param_types()
                    || value.has_self_ty()
                {
1724 1725 1726 1727 1728 1729 1730 1731 1732 1733
                    ParamEnvAnd {
                        param_env: self,
                        value,
                    }
                } else {
                    ParamEnvAnd {
                        param_env: self.without_caller_bounds(),
                        value,
                    }
                }
1734
            }
1735 1736 1737
        }
    }
}
1738

1739
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1740 1741
pub struct ParamEnvAnd<'tcx, T> {
    pub param_env: ParamEnv<'tcx>,
1742
    pub value: T,
1743 1744
}

1745 1746
impl<'tcx, T> ParamEnvAnd<'tcx, T> {
    pub fn into_parts(self) -> (ParamEnv<'tcx>, T) {
1747
        (self.param_env, self.value)
1748
    }
1749 1750
}

1751 1752
impl<'a, 'gcx, T> HashStable<StableHashingContext<'a>> for ParamEnvAnd<'gcx, T>
    where T: HashStable<StableHashingContext<'a>>
1753 1754
{
    fn hash_stable<W: StableHasherResult>(&self,
1755
                                          hcx: &mut StableHashingContext<'a>,
1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766
                                          hasher: &mut StableHasher<W>) {
        let ParamEnvAnd {
            ref param_env,
            ref value
        } = *self;

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

1767
#[derive(Copy, Clone, Debug, HashStable)]
1768
pub struct Destructor {
A
Alexander Regueiro 已提交
1769
    /// The `DefId` of the destructor method
1770 1771 1772
    pub did: DefId,
}

1773
bitflags! {
1774
    #[derive(HashStable)]
1775 1776
    pub struct AdtFlags: u32 {
        const NO_ADT_FLAGS        = 0;
1777
        /// Indicates whether the ADT is an enum.
1778
        const IS_ENUM             = 1 << 0;
1779
        /// Indicates whether the ADT is a union.
A
Alexander Regueiro 已提交
1780
        const IS_UNION            = 1 << 1;
1781
        /// Indicates whether the ADT is a struct.
A
Alexander Regueiro 已提交
1782
        const IS_STRUCT           = 1 << 2;
1783
        /// Indicates whether the ADT is a struct and has a constructor.
1784
        const HAS_CTOR            = 1 << 3;
1785
        /// Indicates whether the type is a `PhantomData`.
A
Alexander Regueiro 已提交
1786
        const IS_PHANTOM_DATA     = 1 << 4;
1787
        /// Indicates whether the type has a `#[fundamental]` attribute.
A
Alexander Regueiro 已提交
1788
        const IS_FUNDAMENTAL      = 1 << 5;
1789
        /// Indicates whether the type is a `Box`.
A
Alexander Regueiro 已提交
1790
        const IS_BOX              = 1 << 6;
1791
        /// Indicates whether the type is an `Arc`.
A
Alexander Regueiro 已提交
1792
        const IS_ARC              = 1 << 7;
1793
        /// Indicates whether the type is an `Rc`.
A
Alexander Regueiro 已提交
1794
        const IS_RC               = 1 << 8;
1795 1796
        /// 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 已提交
1797
        const IS_VARIANT_LIST_NON_EXHAUSTIVE = 1 << 9;
1798 1799 1800 1801
    }
}

bitflags! {
1802
    #[derive(HashStable)]
1803 1804 1805 1806
    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;
1807 1808 1809
    }
}

1810
/// Definition of a variant -- a struct's fields or a enum variant.
1811
#[derive(Debug)]
1812
pub struct VariantDef {
1813 1814 1815 1816 1817 1818
    /// `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>,
1819 1820 1821
    /// Variant or struct name.
    pub ident: Ident,
    /// Discriminant of this variant.
1822
    pub discr: VariantDiscr,
1823
    /// Fields of this variant.
1824
    pub fields: Vec<FieldDef>,
1825
    /// Type of constructor of variant.
1826
    pub ctor_kind: CtorKind,
1827
    /// Flags of the variant (e.g. is field list non-exhaustive)?
1828
    flags: VariantFlags,
1829
    /// Recovered?
1830
    pub recovered: bool,
1831 1832
}

1833
impl<'a, 'gcx, 'tcx> VariantDef {
A
Alexander Regueiro 已提交
1834
    /// Creates a new `VariantDef`.
1835
    ///
1836 1837
    /// `variant_did` is the `DefId` that identifies the enum variant (if this `VariantDef`
    /// represents an enum variant).
1838
    ///
1839 1840 1841 1842 1843 1844 1845
    /// `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
1846 1847 1848
    /// 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 已提交
1849
    /// remove this hack and use the constructor `DefId` everywhere.
1850 1851 1852
    pub fn new(
        tcx: TyCtxt<'a, 'gcx, 'tcx>,
        ident: Ident,
1853
        variant_did: Option<DefId>,
1854
        ctor_def_id: Option<DefId>,
1855 1856 1857
        discr: VariantDiscr,
        fields: Vec<FieldDef>,
        ctor_kind: CtorKind,
1858 1859
        adt_kind: AdtKind,
        parent_did: DefId,
1860 1861
        recovered: bool,
    ) -> Self {
1862
        debug!(
1863
            "VariantDef::new(ident = {:?}, variant_did = {:?}, ctor_def_id = {:?}, discr = {:?},
1864
             fields = {:?}, ctor_kind = {:?}, adt_kind = {:?}, parent_did = {:?})",
1865
             ident, variant_did, ctor_def_id, discr, fields, ctor_kind, adt_kind, parent_did,
1866 1867
        );

1868
        let mut flags = VariantFlags::NO_VARIANT_FLAGS;
1869 1870
        if adt_kind == AdtKind::Struct && tcx.has_attr(parent_did, "non_exhaustive") {
            debug!("found non-exhaustive field list for {:?}", parent_did);
1871 1872
            flags = flags | VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE;
        }
1873

1874
        VariantDef {
1875 1876
            def_id: variant_did.unwrap_or(parent_did),
            ctor_def_id,
1877
            ident,
1878 1879 1880
            discr,
            fields,
            ctor_kind,
1881 1882
            flags,
            recovered,
1883 1884 1885
        }
    }

1886
    /// Is this field list non-exhaustive?
1887 1888 1889 1890
    #[inline]
    pub fn is_field_list_non_exhaustive(&self) -> bool {
        self.flags.intersects(VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE)
    }
1891 1892
}

1893
impl_stable_hash_for!(struct VariantDef {
1894 1895
    def_id,
    ctor_def_id,
1896
    ident -> (ident.name),
1897 1898 1899
    discr,
    fields,
    ctor_kind,
1900 1901
    flags,
    recovered
1902 1903
});

1904
#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
1905
pub enum VariantDiscr {
1906
    /// Explicit value for this variant, i.e., `X = 123`.
1907 1908 1909 1910 1911 1912 1913
    /// 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.
1914
    Relative(u32),
1915 1916
}

1917
#[derive(Debug, HashStable)]
1918
pub struct FieldDef {
1919
    pub did: DefId,
1920
    #[stable_hasher(project(name))]
1921
    pub ident: Ident,
1922
    pub vis: Visibility,
1923 1924
}

1925
/// The definition of an abstract data type -- a struct or enum.
A
Ariel Ben-Yehuda 已提交
1926
///
1927
/// These are all interned (by `intern_adt_def`) into the `adt_defs` table.
1928
pub struct AdtDef {
1929
    /// `DefId` of the struct, enum or union item.
1930
    pub did: DefId,
1931
    /// Variants of the ADT. If this is a struct or enum, then there will be a single variant.
1932
    pub variants: IndexVec<self::layout::VariantIdx, VariantDef>,
1933
    /// Flags of the ADT (e.g. is this a struct? is this non-exhaustive?)
1934
    flags: AdtFlags,
1935
    /// Repr options provided by the user.
1936
    pub repr: ReprOptions,
1937 1938
}

1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952
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)
    }
}

1953 1954
impl PartialEq for AdtDef {
    // AdtDef are always interned and this is part of TyS equality
1955
    #[inline]
1956
    fn eq(&self, other: &Self) -> bool { ptr::eq(self, other) }
1957 1958
}

1959
impl Eq for AdtDef {}
1960

1961
impl Hash for AdtDef {
1962 1963
    #[inline]
    fn hash<H: Hasher>(&self, s: &mut H) {
1964
        (self as *const AdtDef).hash(s)
1965 1966 1967
    }
}

1968
impl<'tcx> serialize::UseSpecializedEncodable for &'tcx AdtDef {
1969
    fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
1970 1971 1972 1973
        self.did.encode(s)
    }
}

1974
impl<'tcx> serialize::UseSpecializedDecodable for &'tcx AdtDef {}
1975

1976

1977
impl<'a> HashStable<StableHashingContext<'a>> for AdtDef {
1978
    fn hash_stable<W: StableHasherResult>(&self,
1979
                                          hcx: &mut StableHashingContext<'a>,
1980
                                          hasher: &mut StableHasher<W>) {
W
Wesley Wiser 已提交
1981
        thread_local! {
1982
            static CACHE: RefCell<FxHashMap<usize, Fingerprint>> = Default::default();
W
Wesley Wiser 已提交
1983
        }
1984

W
Wesley Wiser 已提交
1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005
        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);
2006 2007 2008
    }
}

2009
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
2010
pub enum AdtKind { Struct, Union, Enum }
2011

2012 2013 2014 2015 2016 2017 2018 2019 2020 2021
impl Into<DataTypeKind> for AdtKind {
    fn into(self) -> DataTypeKind {
        match self {
            AdtKind::Struct => DataTypeKind::Struct,
            AdtKind::Union => DataTypeKind::Union,
            AdtKind::Enum => DataTypeKind::Enum,
        }
    }
}

2022 2023
bitflags! {
    #[derive(RustcEncodable, RustcDecodable, Default)]
2024 2025
    pub struct ReprFlags: u8 {
        const IS_C               = 1 << 0;
2026 2027
        const IS_SIMD            = 1 << 1;
        const IS_TRANSPARENT     = 1 << 2;
2028
        // Internal only for now. If true, don't reorder fields.
2029
        const IS_LINEAR          = 1 << 3;
2030 2031 2032 2033

        // Any of these flags being set prevent field reordering optimisation.
        const IS_UNOPTIMISABLE   = ReprFlags::IS_C.bits |
                                   ReprFlags::IS_SIMD.bits |
2034
                                   ReprFlags::IS_LINEAR.bits;
2035 2036 2037 2038 2039 2040 2041
    }
}

impl_stable_hash_for!(struct ReprFlags {
    bits
});

2042
/// Represents the repr options provided by the user,
2043
#[derive(Copy, Clone, Debug, Eq, PartialEq, RustcEncodable, RustcDecodable, Default)]
2044 2045
pub struct ReprOptions {
    pub int: Option<attr::IntType>,
2046
    pub align: u32,
2047
    pub pack: u32,
2048
    pub flags: ReprFlags,
2049 2050
}

2051
impl_stable_hash_for!(struct ReprOptions {
2052
    align,
2053
    pack,
2054
    int,
2055
    flags
2056 2057
});

2058
impl ReprOptions {
2059
    pub fn new(tcx: TyCtxt<'_, '_, '_>, did: DefId) -> ReprOptions {
2060 2061
        let mut flags = ReprFlags::empty();
        let mut size = None;
2062
        let mut max_align = 0;
2063
        let mut min_pack = 0;
2064
        for attr in tcx.get_attrs(did).iter() {
C
csmoe 已提交
2065
            for r in attr::find_repr_attrs(&tcx.sess.parse_sess, attr) {
2066
                flags.insert(match r {
2067
                    attr::ReprC => ReprFlags::IS_C,
2068 2069 2070 2071 2072 2073 2074 2075
                    attr::ReprPacked(pack) => {
                        min_pack = if min_pack > 0 {
                            cmp::min(pack, min_pack)
                        } else {
                            pack
                        };
                        ReprFlags::empty()
                    },
R
Robin Kruppe 已提交
2076
                    attr::ReprTransparent => ReprFlags::IS_TRANSPARENT,
2077 2078 2079 2080 2081
                    attr::ReprSimd => ReprFlags::IS_SIMD,
                    attr::ReprInt(i) => {
                        size = Some(i);
                        ReprFlags::empty()
                    },
2082 2083 2084 2085
                    attr::ReprAlign(align) => {
                        max_align = cmp::max(align, max_align);
                        ReprFlags::empty()
                    },
2086
                });
2087 2088
            }
        }
2089

2090
        // This is here instead of layout because the choice must make it into metadata.
2091
        if !tcx.consider_optimizing(|| format!("Reorder fields of {:?}", tcx.def_path_str(did))) {
2092 2093
            flags.insert(ReprFlags::IS_LINEAR);
        }
2094
        ReprOptions { int: size, align: max_align, pack: min_pack, flags: flags }
2095
    }
2096

2097 2098 2099 2100 2101
    #[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]
2102
    pub fn packed(&self) -> bool { self.pack > 0 }
2103
    #[inline]
R
Robin Kruppe 已提交
2104 2105
    pub fn transparent(&self) -> bool { self.flags.contains(ReprFlags::IS_TRANSPARENT) }
    #[inline]
2106 2107
    pub fn linear(&self) -> bool { self.flags.contains(ReprFlags::IS_LINEAR) }

2108
    pub fn discr_type(&self) -> attr::IntType {
2109
        self.int.unwrap_or(attr::SignedInt(ast::IntTy::Isize))
2110
    }
2111

2112
    /// Returns `true` if this `#[repr()]` should inhabit "smart enum
2113 2114 2115
    /// layout" optimizations, such as representing `Foo<&T>` as a
    /// single pointer.
    pub fn inhibit_enum_layout_opt(&self) -> bool {
2116
        self.c() || self.int.is_some()
2117
    }
2118

2119
    /// Returns `true` if this `#[repr()]` should inhibit struct field reordering
A
Alexander Regueiro 已提交
2120
    /// optimizations, such as with `repr(C)`, `repr(packed(1))`, or `repr(<int>)`.
2121
    pub fn inhibit_struct_field_reordering_opt(&self) -> bool {
2122 2123
        self.flags.intersects(ReprFlags::IS_UNOPTIMISABLE) || self.pack == 1 ||
            self.int.is_some()
2124
    }
2125

A
Alexander Regueiro 已提交
2126
    /// Returns `true` if this `#[repr()]` should inhibit union ABI optimisations.
2127 2128 2129 2130
    pub fn inhibit_union_abi_opt(&self) -> bool {
        self.c()
    }

2131 2132
}

2133
impl<'a, 'gcx, 'tcx> AdtDef {
2134 2135 2136 2137 2138 2139 2140 2141
    /// Creates a new `AdtDef`.
    fn new(
        tcx: TyCtxt<'_, '_, '_>,
        did: DefId,
        kind: AdtKind,
        variants: IndexVec<VariantIdx, VariantDef>,
        repr: ReprOptions
    ) -> Self {
2142
        debug!("AdtDef::new({:?}, {:?}, {:?}, {:?})", did, kind, variants, repr);
A
Ariel Ben-Yehuda 已提交
2143
        let mut flags = AdtFlags::NO_ADT_FLAGS;
A
Alexander Regueiro 已提交
2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154

        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;
        }
        flags |= match kind {
            AdtKind::Enum => AdtFlags::IS_ENUM,
            AdtKind::Union => AdtFlags::IS_UNION,
            AdtKind::Struct => AdtFlags::IS_STRUCT,
        };

2155
        if kind == AdtKind::Struct && variants[VariantIdx::new(0)].ctor_def_id.is_some() {
2156
            flags |= AdtFlags::HAS_CTOR;
A
Alexander Regueiro 已提交
2157 2158
        }

A
Ariel Ben-Yehuda 已提交
2159
        let attrs = tcx.get_attrs(did);
2160
        if attr::contains_name(&attrs, "fundamental") {
A
Alexander Regueiro 已提交
2161
            flags |= AdtFlags::IS_FUNDAMENTAL;
2162
        }
2163
        if Some(did) == tcx.lang_items().phantom_data() {
A
Alexander Regueiro 已提交
2164
            flags |= AdtFlags::IS_PHANTOM_DATA;
2165
        }
2166
        if Some(did) == tcx.lang_items().owned_box() {
A
Alexander Regueiro 已提交
2167
            flags |= AdtFlags::IS_BOX;
2168
        }
2169
        if Some(did) == tcx.lang_items().arc() {
A
Alexander Regueiro 已提交
2170
            flags |= AdtFlags::IS_ARC;
2171 2172
        }
        if Some(did) == tcx.lang_items().rc() {
A
Alexander Regueiro 已提交
2173
            flags |= AdtFlags::IS_RC;
2174
        }
A
Alexander Regueiro 已提交
2175

2176
        AdtDef {
2177 2178 2179 2180
            did,
            variants,
            flags,
            repr,
2181 2182 2183
        }
    }

2184
    /// Returns `true` if this is a struct.
2185 2186
    #[inline]
    pub fn is_struct(&self) -> bool {
A
Alexander Regueiro 已提交
2187 2188 2189
        self.flags.contains(AdtFlags::IS_STRUCT)
    }

2190
    /// Returns `true` if this is a union.
2191 2192
    #[inline]
    pub fn is_union(&self) -> bool {
A
Alexander Regueiro 已提交
2193
        self.flags.contains(AdtFlags::IS_UNION)
2194 2195
    }

2196
    /// Returns `true` if this is a enum.
2197 2198
    #[inline]
    pub fn is_enum(&self) -> bool {
A
Alexander Regueiro 已提交
2199
        self.flags.contains(AdtFlags::IS_ENUM)
2200 2201
    }

2202
    /// Returns `true` if the variant list of this ADT is `#[non_exhaustive]`.
2203
    #[inline]
2204
    pub fn is_variant_list_non_exhaustive(&self) -> bool {
A
Alexander Regueiro 已提交
2205
        self.flags.contains(AdtFlags::IS_VARIANT_LIST_NON_EXHAUSTIVE)
2206 2207
    }

A
Alexander Regueiro 已提交
2208
    /// Returns the kind of the ADT.
2209
    #[inline]
A
Ariel Ben-Yehuda 已提交
2210
    pub fn adt_kind(&self) -> AdtKind {
2211
        if self.is_enum() {
A
Ariel Ben-Yehuda 已提交
2212
            AdtKind::Enum
2213
        } else if self.is_union() {
2214
            AdtKind::Union
2215
        } else {
A
Ariel Ben-Yehuda 已提交
2216
            AdtKind::Struct
2217 2218 2219
        }
    }

2220
    /// Returns a description of this abstract data type.
2221 2222 2223 2224 2225 2226 2227 2228
    pub fn descr(&self) -> &'static str {
        match self.adt_kind() {
            AdtKind::Struct => "struct",
            AdtKind::Union => "union",
            AdtKind::Enum => "enum",
        }
    }

2229
    /// Returns a description of a variant of this abstract data type.
2230
    #[inline]
2231 2232 2233 2234 2235 2236 2237 2238
    pub fn variant_descr(&self) -> &'static str {
        match self.adt_kind() {
            AdtKind::Struct => "struct",
            AdtKind::Union => "union",
            AdtKind::Enum => "variant",
        }
    }

2239 2240 2241 2242 2243 2244
    /// 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 已提交
2245
    /// Returns `true` if this type is `#[fundamental]` for the purposes
A
Ariel Ben-Yehuda 已提交
2246
    /// of coherence checking.
2247 2248
    #[inline]
    pub fn is_fundamental(&self) -> bool {
A
Alexander Regueiro 已提交
2249
        self.flags.contains(AdtFlags::IS_FUNDAMENTAL)
2250 2251
    }

A
Alexander Regueiro 已提交
2252
    /// Returns `true` if this is `PhantomData<T>`.
2253 2254
    #[inline]
    pub fn is_phantom_data(&self) -> bool {
A
Alexander Regueiro 已提交
2255
        self.flags.contains(AdtFlags::IS_PHANTOM_DATA)
2256 2257
    }

2258 2259
    /// Returns `true` if this is `Arc<T>`.
    pub fn is_arc(&self) -> bool {
A
Alexander Regueiro 已提交
2260
        self.flags.contains(AdtFlags::IS_ARC)
2261 2262 2263 2264
    }

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

2268
    /// Returns `true` if this is Box<T>.
2269 2270
    #[inline]
    pub fn is_box(&self) -> bool {
A
Alexander Regueiro 已提交
2271
        self.flags.contains(AdtFlags::IS_BOX)
2272 2273
    }

A
Alexander Regueiro 已提交
2274
    /// Returns `true` if this type has a destructor.
2275 2276
    pub fn has_dtor(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> bool {
        self.destructor(tcx).is_some()
2277 2278
    }

2279 2280 2281
    /// 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());
2282
        &self.variants[VariantIdx::new(0)]
2283 2284 2285
    }

    #[inline]
2286
    pub fn predicates(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Lrc<GenericPredicates<'gcx>> {
2287
        tcx.predicates_of(self.did)
2288
    }
2289

A
Ariel Ben-Yehuda 已提交
2290 2291
    /// Returns an iterator over all fields contained
    /// by this ADT.
2292
    #[inline]
2293 2294
    pub fn all_fields<'s>(&'s self) -> impl Iterator<Item = &'s FieldDef> {
        self.variants.iter().flat_map(|v| v.fields.iter())
2295 2296 2297 2298 2299 2300 2301
    }

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

2302 2303 2304
    pub fn variant_with_id(&self, vid: DefId) -> &VariantDef {
        self.variants.iter().find(|v| v.def_id == vid)
            .expect("variant_with_id: unknown variant")
2305 2306
    }

2307
    pub fn variant_with_ctor_id(&self, cid: DefId) -> &VariantDef {
2308
        self.variants.iter().find(|v| v.ctor_def_id == Some(cid))
2309 2310 2311
            .expect("variant_with_ctor_id: unknown variant")
    }

2312 2313 2314
    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
2315 2316 2317
    }

    pub fn variant_index_with_ctor_id(&self, cid: DefId) -> VariantIdx {
2318 2319
        self.variants.iter_enumerated().find(|(_, v)| v.ctor_def_id == Some(cid))
            .expect("variant_index_with_ctor_id: unknown variant").0
N
Niko Matsakis 已提交
2320 2321
    }

2322
    pub fn variant_of_def(&self, def: Def) -> &VariantDef {
2323
        match def {
2324
            Def::Variant(vid) => self.variant_with_id(vid),
2325 2326
            Def::Ctor(hir::CtorOf::Variant, cid, ..) => self.variant_with_ctor_id(cid),
            Def::Struct(..) | Def::Ctor(..) | Def::Union(..) |
F
F001 已提交
2327 2328
            Def::TyAlias(..) | Def::AssociatedTy(..) | Def::SelfTy(..) |
            Def::SelfCtor(..) => self.non_enum_variant(),
2329
            _ => bug!("unexpected def {:?} in variant_of_def", def)
2330 2331
        }
    }
2332

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

2380
    #[inline]
2381 2382 2383
    pub fn discriminants(
        &'a self,
        tcx: TyCtxt<'a, 'gcx, 'tcx>,
2384
    ) -> impl Iterator<Item=(VariantIdx, Discr<'tcx>)> + Captures<'gcx> + 'a {
2385
        let repr_type = self.repr.discr_type();
2386
        let initial = repr_type.initial_discriminant(tcx.global_tcx());
O
Oliver Schneider 已提交
2387
        let mut prev_discr = None::<Discr<'tcx>>;
2388
        self.variants.iter_enumerated().map(move |(i, v)| {
O
Oliver Schneider 已提交
2389
            let mut discr = prev_discr.map_or(initial, |d| d.wrap_incr(tcx));
2390
            if let VariantDiscr::Explicit(expr_did) = v.discr {
O
Oliver Schneider 已提交
2391 2392
                if let Some(new_discr) = self.eval_explicit_discr(tcx, expr_did) {
                    discr = new_discr;
2393 2394 2395 2396
                }
            }
            prev_discr = Some(discr);

2397
            (i, discr)
2398 2399 2400
        })
    }

A
Alexander Regueiro 已提交
2401
    /// Computes the discriminant value used by a specific variant.
2402 2403 2404 2405 2406 2407
    /// 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>,
2408
                                    variant_index: VariantIdx)
O
Oliver Schneider 已提交
2409
                                    -> Discr<'tcx> {
2410 2411 2412 2413 2414 2415 2416
        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 已提交
2417
    /// Yields a `DefId` for the discriminant and an offset to add to it
2418
    /// Alternatively, if there is no explicit discriminant, returns the
A
Alexander Regueiro 已提交
2419
    /// inferred discriminant directly.
2420 2421
    pub fn discriminant_def_for_variant(
        &self,
2422 2423 2424
        variant_index: VariantIdx,
    ) -> (Option<DefId>, u32) {
        let mut explicit_index = variant_index.as_u32();
2425
        let expr_did;
2426
        loop {
2427
            match self.variants[VariantIdx::from_u32(explicit_index)].discr {
2428 2429 2430 2431
                ty::VariantDiscr::Relative(0) => {
                    expr_did = None;
                    break;
                },
2432 2433 2434
                ty::VariantDiscr::Relative(distance) => {
                    explicit_index -= distance;
                }
2435 2436 2437
                ty::VariantDiscr::Explicit(did) => {
                    expr_did = Some(did);
                    break;
2438 2439 2440
                }
            }
        }
2441
        (expr_did, variant_index.as_u32() - explicit_index)
2442 2443
    }

2444
    pub fn destructor(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Destructor> {
2445
        tcx.adt_destructor(self.did)
2446 2447
    }

2448
    /// Returns a list of types such that `Self: Sized` if and only
A
Alexander Regueiro 已提交
2449
    /// if that type is `Sized`, or `TyErr` if this type is recursive.
A
Ariel Ben-Yehuda 已提交
2450
    ///
A
Alexander Regueiro 已提交
2451
    /// Oddly enough, checking that the sized-constraint is `Sized` is
A
Ariel Ben-Yehuda 已提交
2452
    /// actually more expressive than checking all members:
A
Alexander Regueiro 已提交
2453 2454
    /// the `Sized` trait is inductive, so an associated type that references
    /// `Self` would prevent its containing ADT from being `Sized`.
A
Ariel Ben-Yehuda 已提交
2455 2456
    ///
    /// Due to normalization being eager, this applies even if
A
Alexander Regueiro 已提交
2457
    /// the associated type is behind a pointer (e.g., issue #31299).
2458
    pub fn sized_constraint(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> &'tcx [Ty<'tcx>] {
2459
        tcx.adt_sized_constraint(self.did).0
2460
    }
2461

2462 2463 2464 2465
    fn sized_constraint_for_ty(&self,
                               tcx: TyCtxt<'a, 'tcx, 'tcx>,
                               ty: Ty<'tcx>)
                               -> Vec<Ty<'tcx>> {
2466
        let result = match ty.sty {
2467
            Bool | Char | Int(..) | Uint(..) | Float(..) |
V
varkor 已提交
2468 2469
            RawPtr(..) | Ref(..) | FnDef(..) | FnPtr(_) |
            Array(..) | Closure(..) | Generator(..) | Never => {
A
Ariel Ben-Yehuda 已提交
2470
                vec![]
2471 2472
            }

2473
            Str |
V
varkor 已提交
2474 2475
            Dynamic(..) |
            Slice(_) |
V
varkor 已提交
2476
            Foreign(..) |
V
varkor 已提交
2477 2478
            Error |
            GeneratorWitness(..) => {
2479
                // these are never sized - return the target type
A
Ariel Ben-Yehuda 已提交
2480
                vec![ty]
2481 2482
            }

V
varkor 已提交
2483
            Tuple(ref tys) => {
2484 2485
                match tys.last() {
                    None => vec![],
2486
                    Some(ty) => self.sized_constraint_for_ty(tcx, ty)
2487
                }
2488 2489
            }

V
varkor 已提交
2490
            Adt(adt, substs) => {
2491
                // recursive case
2492
                let adt_tys = adt.sized_constraint(tcx);
2493
                debug!("sized_constraint_for_ty({:?}) intermediate = {:?}",
2494 2495
                       ty, adt_tys);
                adt_tys.iter()
L
ljedrz 已提交
2496 2497 2498
                       .map(|ty| ty.subst(tcx, substs))
                       .flat_map(|ty| self.sized_constraint_for_ty(tcx, ty))
                       .collect()
2499 2500
            }

2501
            Projection(..) | Opaque(..) => {
2502 2503
                // must calculate explicitly.
                // FIXME: consider special-casing always-Sized projections
A
Ariel Ben-Yehuda 已提交
2504
                vec![ty]
2505 2506
            }

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

V
varkor 已提交
2509
            Param(..) => {
A
Ariel Ben-Yehuda 已提交
2510 2511 2512 2513
                // 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.

2514
                let sized_trait = match tcx.lang_items().sized_trait() {
2515
                    Some(x) => x,
A
Ariel Ben-Yehuda 已提交
2516
                    _ => return vec![ty]
2517
                };
2518
                let sized_predicate = Binder::dummy(TraitRef {
2519
                    def_id: sized_trait,
2520
                    substs: tcx.mk_substs_trait(ty, &[])
2521
                }).to_predicate();
2522 2523
                let predicates = &tcx.predicates_of(self.did).predicates;
                if predicates.iter().any(|(p, _)| *p == sized_predicate) {
A
Ariel Ben-Yehuda 已提交
2524
                    vec![]
2525
                } else {
A
Ariel Ben-Yehuda 已提交
2526
                    vec![ty]
2527 2528 2529
                }
            }

S
scalexm 已提交
2530
            Placeholder(..) |
S
scalexm 已提交
2531
            Bound(..) |
V
varkor 已提交
2532
            Infer(..) => {
2533 2534 2535 2536 2537 2538 2539
                bug!("unexpected type `{:?}` in sized_constraint_for_ty",
                     ty)
            }
        };
        debug!("sized_constraint_for_ty({:?}) = {:?}", ty, result);
        result
    }
2540 2541
}

2542
impl<'a, 'gcx, 'tcx> FieldDef {
C
csmoe 已提交
2543
    pub fn ty(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, subst: SubstsRef<'tcx>) -> Ty<'tcx> {
2544
        tcx.type_of(self.did).subst(tcx, subst)
2545
    }
2546 2547
}

A
Alexander Regueiro 已提交
2548
/// Represents the various closure traits in the language. This
2549
/// will determine the type of the environment (`self`, in the
A
Andy Russell 已提交
2550
/// desugaring) argument that the closure expects.
2551 2552 2553
///
/// You can get the environment type of a closure using
/// `tcx.closure_env_ty()`.
2554 2555
#[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash, Debug,
         RustcEncodable, RustcDecodable, HashStable)]
2556
pub enum ClosureKind {
2557 2558 2559
    // 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.
2560 2561 2562
    Fn,
    FnMut,
    FnOnce,
2563 2564
}

2565
impl<'a, 'tcx> ClosureKind {
2566 2567 2568
    // This is the initial value used when doing upvar inference.
    pub const LATTICE_BOTTOM: ClosureKind = ClosureKind::Fn;

2569
    pub fn trait_did(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> DefId {
2570 2571
        match *self {
            ClosureKind::Fn => tcx.require_lang_item(FnTraitLangItem),
2572
            ClosureKind::FnMut => {
2573
                tcx.require_lang_item(FnMutTraitLangItem)
2574
            }
2575
            ClosureKind::FnOnce => {
2576
                tcx.require_lang_item(FnOnceTraitLangItem)
2577 2578 2579
            }
        }
    }
2580

2581
    /// Returns `true` if this a type that impls this closure kind
2582 2583 2584
    /// must also implement `other`.
    pub fn extends(self, other: ty::ClosureKind) -> bool {
        match (self, other) {
2585 2586 2587 2588 2589 2590
            (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,
2591 2592 2593
            _ => false,
        }
    }
2594 2595 2596 2597 2598 2599 2600 2601 2602

    /// 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,
        }
2603
    }
2604 2605
}

2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618
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)
2619 2620
    }

A
Alexander Regueiro 已提交
2621
    /// Iterator that walks the immediate children of `self`. Hence
2622 2623
    /// `Foo<Bar<i32>, u32>` yields the sequence `[Bar<i32>, u32]`
    /// (but not `i32`, like `walk`).
2624
    pub fn walk_shallow(&'tcx self) -> smallvec::IntoIter<walk::TypeWalkerArray<'tcx>> {
2625
        walk::walk_shallow(self)
2626 2627
    }

2628
    /// Walks `ty` and any types appearing within `ty`, invoking the
A
Alexander Regueiro 已提交
2629
    /// callback `f` on each type. If the callback returns `false`, then the
2630 2631 2632 2633
    /// children of the current type are ignored.
    ///
    /// Note: prefer `ty.walk()` where possible.
    pub fn maybe_walk<F>(&'tcx self, mut f: F)
2634
        where F: FnMut(Ty<'tcx>) -> bool
2635 2636 2637 2638 2639 2640 2641
    {
        let mut walker = self.walk();
        while let Some(ty) = walker.next() {
            if !f(ty) {
                walker.skip_current_subtree();
            }
        }
2642
    }
2643
}
2644

2645
impl BorrowKind {
2646
    pub fn from_mutbl(m: hir::Mutability) -> BorrowKind {
2647
        match m {
2648 2649
            hir::MutMutable => MutBorrow,
            hir::MutImmutable => ImmBorrow,
2650 2651
        }
    }
2652

2653 2654 2655 2656
    /// 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.
2657
    pub fn to_mutbl_lossy(self) -> hir::Mutability {
2658
        match self {
2659 2660
            MutBorrow => hir::MutMutable,
            ImmBorrow => hir::MutImmutable,
2661 2662 2663 2664

            // 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".
2665
            UniqueImmBorrow => hir::MutMutable,
2666
        }
2667
    }
2668

2669 2670 2671 2672 2673 2674
    pub fn to_user_str(&self) -> &'static str {
        match *self {
            MutBorrow => "mutable",
            ImmBorrow => "immutable",
            UniqueImmBorrow => "uniquely immutable",
        }
2675 2676 2677
    }
}

2678 2679
#[derive(Debug, Clone)]
pub enum Attributes<'gcx> {
2680
    Owned(Lrc<[ast::Attribute]>),
2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694
    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
        }
    }
}

2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733
#[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
}

2734
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
2735
    pub fn body_tables(self, body: hir::BodyId) -> &'gcx TypeckTables<'gcx> {
2736
        self.typeck_tables_of(self.hir().body_owner_def_id(body))
2737 2738
    }

A
Alexander Regueiro 已提交
2739
    /// Returns an iterator of the `DefId`s for all body-owners in this
N
Niko Matsakis 已提交
2740
    /// crate. If you would prefer to iterate over the bodies
2741
    /// themselves, you can do `self.hir().krate().body_ids.iter()`.
2742 2743 2744
    pub fn body_owners(
        self,
    ) -> impl Iterator<Item = DefId> + Captures<'tcx> + Captures<'gcx> + 'a {
2745 2746 2747 2748
        self.hir().krate()
                  .body_ids
                  .iter()
                  .map(move |&body_id| self.hir().body_owner_def_id(body_id))
N
Niko Matsakis 已提交
2749 2750
    }

J
John Kåre Alsaker 已提交
2751
    pub fn par_body_owners<F: Fn(DefId) + sync::Sync + sync::Send>(self, f: F) {
2752 2753
        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 已提交
2754 2755 2756
        });
    }

2757
    pub fn expr_span(self, id: NodeId) -> Span {
2758
        match self.hir().find(id) {
V
varkor 已提交
2759
            Some(Node::Expr(e)) => {
2760 2761 2762
                e.span
            }
            Some(f) => {
2763
                bug!("Node id {} is not an expr: {:?}", id, f);
2764 2765
            }
            None => {
2766
                bug!("Node id {} is not present in the node map", id);
2767
            }
2768
        }
2769 2770
    }

2771 2772
    pub fn provided_trait_methods(self, id: DefId) -> Vec<AssociatedItem> {
        self.associated_items(id)
2773
            .filter(|item| item.kind == AssociatedKind::Method && item.defaultness.has_value())
2774
            .collect()
2775 2776
    }

A
Andrew Cann 已提交
2777 2778 2779 2780 2781 2782
    pub fn trait_relevant_for_never(self, did: DefId) -> bool {
        self.associated_items(did).any(|item| {
            item.relevant_for_never()
        })
    }

2783
    pub fn opt_associated_item(self, def_id: DefId) -> Option<AssociatedItem> {
2784 2785
        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 已提交
2786
                Node::TraitItem(_) | Node::ImplItem(_) => true,
2787 2788 2789
                _ => false,
            }
        } else {
2790
            match self.describe_def(def_id).expect("no def for def-id") {
2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802
                Def::AssociatedConst(_) | Def::Method(_) | Def::AssociatedTy(_) => true,
                _ => false,
            }
        };

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

2803 2804
    fn associated_item_from_trait_item_ref(self,
                                           parent_def_id: DefId,
2805
                                           parent_vis: &hir::Visibility,
2806
                                           trait_item_ref: &hir::TraitItemRef)
2807
                                           -> AssociatedItem {
L
ljedrz 已提交
2808
        let def_id = self.hir().local_def_id_from_hir_id(trait_item_ref.id.hir_id);
2809 2810 2811 2812
        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)
2813
            }
2814
            hir::AssociatedItemKind::Type => (ty::AssociatedKind::Type, false),
O
Oliver Schneider 已提交
2815
            hir::AssociatedItemKind::Existential => bug!("only impls can have existentials"),
2816 2817 2818
        };

        AssociatedItem {
2819
            ident: trait_item_ref.ident,
2820
            kind,
2821
            // Visibility of trait items is inherited from their traits.
L
ljedrz 已提交
2822
            vis: Visibility::from_hir(parent_vis, trait_item_ref.id.hir_id, self),
2823
            defaultness: trait_item_ref.defaultness,
2824
            def_id,
2825 2826 2827 2828 2829 2830 2831 2832 2833
            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 已提交
2834
        let def_id = self.hir().local_def_id_from_hir_id(impl_item_ref.id.hir_id);
2835 2836 2837 2838 2839 2840
        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 已提交
2841
            hir::AssociatedItemKind::Existential => (ty::AssociatedKind::Existential, false),
2842 2843
        };

2844 2845
        AssociatedItem {
            ident: impl_item_ref.ident,
2846
            kind,
2847
            // Visibility of trait impl items doesn't matter.
L
ljedrz 已提交
2848
            vis: ty::Visibility::from_hir(&impl_item_ref.vis, impl_item_ref.id.hir_id, self),
2849
            defaultness: impl_item_ref.defaultness,
2850
            def_id,
2851 2852 2853 2854 2855
            container: ImplContainer(parent_def_id),
            method_has_self_argument: has_self
        }
    }

L
ljedrz 已提交
2856
    pub fn field_index(self, hir_id: hir::HirId, tables: &TypeckTables<'_>) -> usize {
2857 2858 2859 2860 2861
        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| {
2862
            self.adjust_ident(ident, variant.def_id, hir::DUMMY_HIR_ID).0 == field.ident.modern()
2863 2864 2865
        })
    }

2866 2867 2868
    pub fn associated_items(
        self,
        def_id: DefId,
2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879
    ) -> 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,
        }
2880 2881
    }

2882
    /// Returns `true` if the impls are the same polarity and the trait either
2883
    /// has no items or is annotated #[marker] and prevents item overrides.
2884 2885 2886 2887
    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 {
2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898
            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
2899
        } else {
2900 2901 2902 2903 2904 2905 2906
            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)
2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929
        };

        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
2930
        }
S
Sean Griffin 已提交
2931 2932
    }

2933 2934
    // Returns `ty::VariantDef` if `def` refers to a struct,
    // or variant or their constructors, panics otherwise.
2935
    pub fn expect_variant_def(self, def: Def) -> &'tcx VariantDef {
2936
        match def {
2937
            Def::Variant(did) => {
2938
                let enum_did = self.parent(did).unwrap();
2939
                self.adt_def(enum_did).variant_with_id(did)
2940
            }
2941
            Def::Struct(did) | Def::Union(did) => {
2942
                self.adt_def(did).non_enum_variant()
2943
            }
2944 2945 2946 2947 2948 2949 2950 2951
            Def::Ctor(hir::CtorOf::Variant, variant_ctor_did, ..) => {
                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)
            }
            Def::Ctor(hir::CtorOf::Struct, ctor_did, ..) => {
                let struct_did = self.parent(ctor_did).expect("struct ctor has no parent");
                self.adt_def(struct_did).non_enum_variant()
2952 2953 2954 2955 2956
            }
            _ => bug!("expect_variant_def used with unexpected def {:?}", def)
        }
    }

2957
    pub fn item_name(self, id: DefId) -> InternedString {
2958
        if id.index == CRATE_DEF_INDEX {
2959
            self.original_crate_name(id.krate).as_interned_str()
2960
        } else {
2961
            let def_key = self.def_key(id);
2962 2963 2964 2965 2966 2967 2968 2969
            match def_key.disambiguated_data.data {
                // The name of a `StructCtor` or `VariantCtor` is that of its parent.
                hir_map::DefPathData::StructCtor | hir_map::DefPathData::VariantCtor =>
                    self.item_name(DefId {
                        krate: id.krate,
                        index: def_key.parent.unwrap()
                    }),
                _ => def_key.disambiguated_data.data.get_opt_name().unwrap_or_else(|| {
2970
                    bug!("item_name: no name for {:?}", self.def_path(id));
2971
                }),
2972
            }
2973 2974 2975
        }
    }

A
Alexander Regueiro 已提交
2976
    /// Returns the possibly-auto-generated MIR of a `(DefId, Subst)` pair.
2977
    pub fn instance_mir(self, instance: ty::InstanceDef<'gcx>)
2978
                        -> &'gcx Mir<'gcx>
2979 2980
    {
        match instance {
N
Niko Matsakis 已提交
2981
            ty::InstanceDef::Item(did) => {
2982
                self.optimized_mir(did)
N
Niko Matsakis 已提交
2983
            }
M
Masaki Hara 已提交
2984
            ty::InstanceDef::VtableShim(..) |
N
Niko Matsakis 已提交
2985 2986 2987 2988
            ty::InstanceDef::Intrinsic(..) |
            ty::InstanceDef::FnPtrShim(..) |
            ty::InstanceDef::Virtual(..) |
            ty::InstanceDef::ClosureOnceShim { .. } |
2989
            ty::InstanceDef::DropGlue(..) |
S
scalexm 已提交
2990
            ty::InstanceDef::CloneShim(..) => {
2991
                self.mir_shims(instance)
N
Niko Matsakis 已提交
2992
            }
2993 2994 2995
        }
    }

A
Alexander Regueiro 已提交
2996
    /// Gets the attributes of a definition.
2997
    pub fn get_attrs(self, did: DefId) -> Attributes<'gcx> {
L
ljedrz 已提交
2998 2999
        if let Some(id) = self.hir().as_local_hir_id(did) {
            Attributes::Borrowed(self.hir().attrs_by_hir_id(id))
3000
        } else {
A
achernyak 已提交
3001
            Attributes::Owned(self.item_attrs(did))
3002
        }
3003 3004
    }

A
Alexander Regueiro 已提交
3005
    /// Determines whether an item is annotated with an attribute.
3006
    pub fn has_attr(self, did: DefId, attr: &str) -> bool {
3007
        attr::contains_name(&self.get_attrs(did), attr)
3008
    }
3009

3010
    /// Returns `true` if this is an `auto trait`.
3011
    pub fn trait_is_auto(self, trait_def_id: DefId) -> bool {
3012
        self.trait_def(trait_def_id).has_auto_impl
3013
    }
3014

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

A
Alexander Regueiro 已提交
3019 3020
    /// Given the `DefId` of an impl, returns the `DefId` of the trait it implements.
    /// If it implements no trait, returns `None`.
3021
    pub fn trait_id_of_impl(self, def_id: DefId) -> Option<DefId> {
3022
        self.impl_trait_ref(def_id).map(|tr| tr.def_id)
3023
    }
3024

A
Alexander Regueiro 已提交
3025 3026
    /// 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`.
3027
    pub fn impl_of_method(self, def_id: DefId) -> Option<DefId> {
3028
        let item = if def_id.krate != LOCAL_CRATE {
A
achernyak 已提交
3029
            if let Some(Def::Method(_)) = self.describe_def(def_id) {
3030 3031 3032 3033 3034
                Some(self.associated_item(def_id))
            } else {
                None
            }
        } else {
3035
            self.opt_associated_item(def_id)
3036 3037
        };

3038 3039 3040 3041
        item.and_then(|trait_item|
            match trait_item.container {
                TraitContainer(_) => None,
                ImplContainer(def_id) => Some(def_id),
3042
            }
3043
        )
3044 3045
    }

3046 3047
    /// Looks up the span of `impl_did` if the impl is local; otherwise returns `Err`
    /// with the name of the crate containing the impl.
3048
    pub fn span_of_impl(self, impl_did: DefId) -> Result<Span, Symbol> {
3049
        if impl_did.is_local() {
L
ljedrz 已提交
3050 3051
            let hir_id = self.hir().as_local_hir_id(impl_did).unwrap();
            Ok(self.hir().span_by_hir_id(hir_id))
3052
        } else {
3053
            Err(self.crate_name(impl_did.krate))
3054 3055
        }
    }
J
Jeffrey Seyfried 已提交
3056

A
Alexander Regueiro 已提交
3057 3058 3059
    /// 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.
3060
    pub fn hygienic_eq(self, use_name: Ident, def_name: Ident, def_parent_def_id: DefId) -> bool {
L
ljedrz 已提交
3061
        self.adjust_ident(use_name, def_parent_def_id, hir::DUMMY_HIR_ID).0 == def_name.modern()
J
Jeffrey Seyfried 已提交
3062 3063
    }

L
ljedrz 已提交
3064
    pub fn adjust_ident(self, mut ident: Ident, scope: DefId, block: hir::HirId) -> (Ident, DefId) {
3065 3066
        ident = ident.modern();
        let target_expansion = match scope.krate {
3067
            LOCAL_CRATE => self.hir().definitions().expansion_that_defined(scope.index),
J
Jeffrey Seyfried 已提交
3068 3069
            _ => Mark::root(),
        };
3070 3071
        let scope = match ident.span.adjust(target_expansion) {
            Some(actual_expansion) =>
3072
                self.hir().definitions().parent_module_of_macro_def(actual_expansion),
L
ljedrz 已提交
3073 3074
            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 已提交
3075 3076 3077
        };
        (ident, scope)
    }
3078
}
3079

3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095
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))
    }
}

3096
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
3097
    pub fn with_freevars<T, F>(self, fid: HirId, f: F) -> T where
3098
        F: FnOnce(&[hir::Freevar]) -> T,
3099
    {
3100
        let def_id = self.hir().local_def_id_from_hir_id(fid);
A
Alex Crichton 已提交
3101
        match self.freevars(def_id) {
3102
            None => f(&[]),
3103
            Some(d) => f(&d),
3104 3105
        }
    }
3106
}
3107

L
ljedrz 已提交
3108
fn associated_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> AssociatedItem {
L
ljedrz 已提交
3109 3110 3111 3112
    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);
3113
    match parent_item.node {
C
csmoe 已提交
3114
        hir::ItemKind::Impl(.., ref impl_item_refs) => {
L
ljedrz 已提交
3115
            if let Some(impl_item_ref) = impl_item_refs.iter().find(|i| i.id.hir_id == id) {
3116 3117
                let assoc_item = tcx.associated_item_from_impl_item_ref(parent_def_id,
                                                                        impl_item_ref);
3118 3119
                debug_assert_eq!(assoc_item.def_id, def_id);
                return assoc_item;
3120 3121 3122
            }
        }

C
csmoe 已提交
3123
        hir::ItemKind::Trait(.., ref trait_item_refs) => {
L
ljedrz 已提交
3124
            if let Some(trait_item_ref) = trait_item_refs.iter().find(|i| i.id.hir_id == id) {
3125 3126 3127
                let assoc_item = tcx.associated_item_from_trait_item_ref(parent_def_id,
                                                                         &parent_item.vis,
                                                                         trait_item_ref);
3128 3129
                debug_assert_eq!(assoc_item.def_id, def_id);
                return assoc_item;
3130 3131 3132
            }
        }

3133
        _ => { }
3134
    }
3135 3136 3137 3138

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

3141
#[derive(Clone, HashStable)]
3142 3143
pub struct AdtSizedConstraint<'tcx>(pub &'tcx [Ty<'tcx>]);

A
Alexander Regueiro 已提交
3144
/// Calculates the `Sized` constraint.
3145
///
3146
/// In fact, there are only a few options for the types in the constraint:
3147 3148 3149 3150
///     - 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 已提交
3151
///     - a Error, if a type contained itself. The representability
3152 3153 3154
///       check should catch this case.
fn adt_sized_constraint<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                  def_id: DefId)
3155
                                  -> AdtSizedConstraint<'tcx> {
3156
    let def = tcx.adt_def(def_id);
3157

3158
    let result = tcx.mk_type_list(def.variants.iter().flat_map(|v| {
3159 3160
        v.fields.last()
    }).flat_map(|f| {
3161
        def.sized_constraint_for_ty(tcx, tcx.type_of(f.did))
3162
    }));
3163

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

3166
    AdtSizedConstraint(result)
3167 3168
}

3169 3170
fn associated_item_def_ids<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                     def_id: DefId)
3171
                                     -> Lrc<Vec<DefId>> {
L
ljedrz 已提交
3172 3173
    let id = tcx.hir().as_local_hir_id(def_id).unwrap();
    let item = tcx.hir().expect_item_by_hir_id(id);
3174
    let vec: Vec<_> = match item.node {
C
csmoe 已提交
3175
        hir::ItemKind::Trait(.., ref trait_item_refs) => {
3176 3177
            trait_item_refs.iter()
                           .map(|trait_item_ref| trait_item_ref.id)
L
ljedrz 已提交
3178
                           .map(|id| tcx.hir().local_def_id_from_hir_id(id.hir_id))
3179 3180
                           .collect()
        }
C
csmoe 已提交
3181
        hir::ItemKind::Impl(.., ref impl_item_refs) => {
3182 3183
            impl_item_refs.iter()
                          .map(|impl_item_ref| impl_item_ref.id)
L
ljedrz 已提交
3184
                          .map(|id| tcx.hir().local_def_id_from_hir_id(id.hir_id))
3185 3186
                          .collect()
        }
C
csmoe 已提交
3187
        hir::ItemKind::TraitAlias(..) => vec![],
3188 3189
        _ => span_bug!(item.span, "associated_item_def_ids: not impl or trait")
    };
3190
    Lrc::new(vec)
3191 3192
}

A
achernyak 已提交
3193
fn def_span<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Span {
3194
    tcx.hir().span_if_local(def_id).unwrap()
A
achernyak 已提交
3195 3196
}

A
Alexander Regueiro 已提交
3197 3198 3199
/// 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 已提交
3200 3201 3202 3203 3204 3205 3206 3207 3208 3209
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
            }
        })
}

3210
/// Yields the parent function's `DefId` if `def_id` is an `impl Trait` definition.
3211
pub fn is_impl_trait_defn(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Option<DefId> {
3212 3213
    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) {
3214 3215 3216 3217 3218 3219 3220 3221
            if let hir::ItemKind::Existential(ref exist_ty) = item.node {
                return exist_ty.impl_trait_fn;
            }
        }
    }
    None
}

3222
/// See `ParamEnv` struct definition for details.
3223
fn param_env<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
3224
                       def_id: DefId)
L
ljedrz 已提交
3225 3226
                       -> ParamEnv<'tcx>
{
O
Oliver Schneider 已提交
3227
    // The param_env of an impl Trait type is its defining function's param_env
3228 3229
    if let Some(parent) = is_impl_trait_defn(tcx, def_id) {
        return param_env(tcx, parent);
3230
    }
3231 3232
    // Compute the bounds on Self and the type parameters.

N
Niko Matsakis 已提交
3233 3234
    let InstantiatedPredicates { predicates } =
        tcx.predicates_of(def_id).instantiate_identity(tcx);
3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247

    // 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 已提交
3248 3249 3250
    let unnormalized_env = ty::ParamEnv::new(
        tcx.intern_predicates(&predicates),
        traits::Reveal::UserFacing,
3251
        if tcx.sess.opts.debugging_opts.chalk { Some(def_id) } else { None }
S
scalexm 已提交
3252
    );
3253

L
ljedrz 已提交
3254 3255
    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)
3256 3257 3258 3259
    });
    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 已提交
3260

3261
fn crate_disambiguator<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
3262
                                 crate_num: CrateNum) -> CrateDisambiguator {
3263 3264 3265 3266
    assert_eq!(crate_num, LOCAL_CRATE);
    tcx.sess.local_crate_disambiguator()
}

3267 3268 3269 3270 3271 3272
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()
}

3273 3274 3275 3276
fn crate_hash<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                        crate_num: CrateNum)
                        -> Svh {
    assert_eq!(crate_num, LOCAL_CRATE);
3277
    tcx.hir().crate_hash
3278 3279
}

V
varkor 已提交
3280 3281 3282 3283
fn instance_def_size_estimate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                        instance_def: InstanceDef<'tcx>)
                                        -> usize {
    match instance_def {
3284 3285 3286
        InstanceDef::Item(..) |
        InstanceDef::DropGlue(..) => {
            let mir = tcx.instance_mir(instance_def);
V
varkor 已提交
3287 3288
            mir.basic_blocks().iter().map(|bb| bb.statements.len()).sum()
        },
3289
        // Estimate the size of other compiler-generated shims to be 1.
V
varkor 已提交
3290 3291 3292 3293
        _ => 1
    }
}

A
Alexander Regueiro 已提交
3294
/// If `def_id` is an issue 33140 hack impl, returns its self type; otherwise, returns `None`.
3295
///
A
Alexander Regueiro 已提交
3296
/// See [`ImplOverlapKind::Issue33140`] for more details.
3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 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
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
    }
}

3346
pub fn provide(providers: &mut ty::query::Providers<'_>) {
3347
    context::provide(providers);
3348
    erase_regions::provide(providers);
3349 3350
    layout::provide(providers);
    util::provide(providers);
3351
    constness::provide(providers);
3352
    *providers = ty::query::Providers {
3353
        associated_item,
3354
        associated_item_def_ids,
3355
        adt_sized_constraint,
A
achernyak 已提交
3356
        def_span,
3357
        param_env,
A
achernyak 已提交
3358
        trait_of_item,
3359
        crate_disambiguator,
3360
        original_crate_name,
3361
        crate_hash,
3362
        trait_impls_of: trait_def::trait_impls_of_provider,
V
varkor 已提交
3363
        instance_def_size_estimate,
3364
        issue33140_self_ty,
3365 3366 3367 3368
        ..*providers
    };
}

3369 3370 3371
/// 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
3372 3373
/// `tcx.inherent_impls(def_id)` so as to minimize your dependencies
/// (constructing this map requires touching the entire crate).
3374
#[derive(Clone, Debug, Default, HashStable)]
3375
pub struct CrateInherentImpls {
3376
    pub inherent_impls: DefIdMap<Lrc<Vec<DefId>>>,
3377
}
A
Ariel Ben-Yehuda 已提交
3378

3379
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable)]
3380 3381 3382 3383 3384 3385
pub struct SymbolName {
    // FIXME: we don't rely on interning or equality here - better have
    // this be a `&'tcx str`.
    pub name: InternedString
}

3386 3387 3388 3389
impl_stable_hash_for!(struct self::SymbolName {
    name
});

3390 3391 3392
impl SymbolName {
    pub fn new(name: &str) -> SymbolName {
        SymbolName {
3393
            name: Symbol::intern(name).as_interned_str()
3394 3395
        }
    }
3396

3397 3398 3399
    pub fn as_str(&self) -> LocalInternedString {
        self.name.as_str()
    }
3400 3401 3402
}

impl fmt::Display for SymbolName {
3403
    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
3404 3405 3406
        fmt::Display::fmt(&self.name, fmt)
    }
}
3407 3408

impl fmt::Debug for SymbolName {
3409
    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
3410 3411 3412
        fmt::Display::fmt(&self.name, fmt)
    }
}