mod.rs 108.0 KB
Newer Older
1
// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
2 3 4 5 6 7 8 9 10
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

S
Steven Fackler 已提交
11 12 13 14 15 16
pub use self::Variance::*;
pub use self::DtorKind::*;
pub use self::ImplOrTraitItemContainer::*;
pub use self::BorrowKind::*;
pub use self::ImplOrTraitItem::*;
pub use self::IntVarValue::*;
17
pub use self::LvaluePreference::*;
18
pub use self::fold::TypeFoldable;
S
Steven Fackler 已提交
19

20
use dep_graph::{self, DepNode};
21
use hir::map as ast_map;
22
use middle;
23
use hir::def::{Def, CtorKind, PathResolution, ExportMap};
24
use hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
25
use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem};
26
use middle::region::{CodeExtent, ROOT_CODE_EXTENT};
27 28
use traits;
use ty;
29
use ty::subst::{Subst, Substs};
30
use ty::walk::TypeWalker;
31
use util::common::MemoizationMap;
32
use util::nodemap::NodeSet;
33
use util::nodemap::FnvHashMap;
34

35
use serialize::{self, Encodable, Encoder};
S
Seo Sanghyeon 已提交
36
use std::borrow::Cow;
37
use std::cell::{Cell, RefCell};
38
use std::hash::{Hash, Hasher};
39
use std::iter;
40
use std::ops::Deref;
H
Huon Wilson 已提交
41
use std::rc::Rc;
42
use std::slice;
43
use std::vec::IntoIter;
44
use syntax::ast::{self, Name, NodeId};
45
use syntax::attr;
46
use syntax::parse::token::{self, InternedString};
47
use syntax_pos::{DUMMY_SP, Span};
48

49
use rustc_const_math::ConstInt;
O
Oliver Schneider 已提交
50

51 52
use hir;
use hir::intravisit::Visitor;
53

54
pub use self::sty::{Binder, DebruijnIndex};
55
pub use self::sty::{BuiltinBound, BuiltinBounds};
56
pub use self::sty::{BareFnTy, FnSig, PolyFnSig};
57
pub use self::sty::{ClosureTy, InferTy, ParamTy, ProjectionTy, TraitObject};
58 59
pub use self::sty::{ClosureSubsts, TypeAndMut};
pub use self::sty::{TraitRef, TypeVariants, PolyTraitRef};
60 61
pub use self::sty::{ExistentialTraitRef, PolyExistentialTraitRef};
pub use self::sty::{ExistentialProjection, PolyExistentialProjection};
62
pub use self::sty::{BoundRegion, EarlyBoundRegion, FreeRegion, Region};
63
pub use self::sty::Issue32330;
64 65 66 67 68 69 70 71 72 73 74 75
pub use self::sty::{TyVid, IntVid, FloatVid, RegionVid, SkolemizedRegionVid};
pub use self::sty::BoundRegion::*;
pub use self::sty::InferTy::*;
pub use self::sty::Region::*;
pub use self::sty::TypeVariants::*;

pub use self::sty::BuiltinBound::Send as BoundSend;
pub use self::sty::BuiltinBound::Sized as BoundSized;
pub use self::sty::BuiltinBound::Copy as BoundCopy;
pub use self::sty::BuiltinBound::Sync as BoundSync;

pub use self::contents::TypeContents;
76
pub use self::context::{TyCtxt, tls};
77 78
pub use self::context::{CtxtArenas, Lift, Tables};

79 80
pub use self::trait_def::{TraitDef, TraitFlags};

81
pub mod adjustment;
82
pub mod cast;
83
pub mod error;
84 85
pub mod fast_reject;
pub mod fold;
86
pub mod item_path;
87
pub mod layout;
88
pub mod _match;
89
pub mod maps;
90 91
pub mod outlives;
pub mod relate;
92
pub mod subst;
93
pub mod trait_def;
94 95
pub mod walk;
pub mod wf;
96
pub mod util;
97

98 99 100 101 102 103 104
mod contents;
mod context;
mod flags;
mod ivar;
mod structural_impls;
mod sty;

O
Oliver Schneider 已提交
105
pub type Disr = ConstInt;
106

107
// Data types
108

109 110
/// The complete set of all analyses described in this module. This is
/// produced by the driver and fed to trans and later passes.
J
Jeffrey Seyfried 已提交
111
#[derive(Clone)]
112
pub struct CrateAnalysis<'a> {
113
    pub export_map: ExportMap,
114
    pub access_levels: middle::privacy::AccessLevels,
115
    pub reachable: NodeSet,
116
    pub name: &'a str,
117
    pub glob_map: Option<hir::GlobMap>,
118 119
}

120 121 122
#[derive(Copy, Clone)]
pub enum DtorKind {
    NoDtor,
123
    TraitDtor
124 125 126 127 128
}

impl DtorKind {
    pub fn is_present(&self) -> bool {
        match *self {
129
            TraitDtor => true,
130 131 132 133 134
            _ => false
        }
    }
}

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

141
impl ImplOrTraitItemContainer {
N
Niko Matsakis 已提交
142
    pub fn id(&self) -> DefId {
143 144 145 146 147 148 149
        match *self {
            TraitContainer(id) => id,
            ImplContainer(id) => id,
        }
    }
}

A
Aaron Turon 已提交
150 151 152 153 154 155 156 157 158 159 160
/// The "header" of an impl is everything outside the body: a Self type, a trait
/// ref (in the case of a trait impl), and a set of predicates (from the
/// bounds/where clauses).
#[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>>,
}

161 162
impl<'a, 'gcx, 'tcx> ImplHeader<'tcx> {
    pub fn with_fresh_ty_vars(selcx: &mut traits::SelectionContext<'a, 'gcx, 'tcx>,
163 164
                              impl_def_id: DefId)
                              -> ImplHeader<'tcx>
A
Aaron Turon 已提交
165 166
    {
        let tcx = selcx.tcx();
167
        let impl_substs = selcx.infcx().fresh_substs_for_item(DUMMY_SP, impl_def_id);
A
Aaron Turon 已提交
168 169 170

        let header = ImplHeader {
            impl_def_id: impl_def_id,
171
            self_ty: tcx.lookup_item_type(impl_def_id).ty,
A
Aaron Turon 已提交
172
            trait_ref: tcx.impl_trait_ref(impl_def_id),
173
            predicates: tcx.lookup_predicates(impl_def_id).predicates
174
        }.subst(tcx, impl_substs);
A
Aaron Turon 已提交
175

176 177
        let traits::Normalized { value: mut header, obligations } =
            traits::normalize(selcx, traits::ObligationCause::dummy(), &header);
A
Aaron Turon 已提交
178 179 180 181 182 183

        header.predicates.extend(obligations.into_iter().map(|o| o.predicate));
        header
    }
}

184
#[derive(Clone)]
185
pub enum ImplOrTraitItem<'tcx> {
186
    ConstTraitItem(Rc<AssociatedConst<'tcx>>),
187
    MethodTraitItem(Rc<Method<'tcx>>),
188
    TypeTraitItem(Rc<AssociatedType<'tcx>>),
189 190
}

191
impl<'tcx> ImplOrTraitItem<'tcx> {
192 193 194 195
    pub fn def(&self) -> Def {
        match *self {
            ConstTraitItem(ref associated_const) => Def::AssociatedConst(associated_const.def_id),
            MethodTraitItem(ref method) => Def::Method(method.def_id),
196
            TypeTraitItem(ref ty) => Def::AssociatedTy(ty.def_id),
197 198 199
        }
    }

N
Niko Matsakis 已提交
200
    pub fn def_id(&self) -> DefId {
201
        match *self {
202
            ConstTraitItem(ref associated_const) => associated_const.def_id,
203
            MethodTraitItem(ref method) => method.def_id,
204
            TypeTraitItem(ref associated_type) => associated_type.def_id,
205 206 207
        }
    }

208
    pub fn name(&self) -> Name {
209
        match *self {
210
            ConstTraitItem(ref associated_const) => associated_const.name,
211 212
            MethodTraitItem(ref method) => method.name,
            TypeTraitItem(ref associated_type) => associated_type.name,
213 214 215
        }
    }

216
    pub fn vis(&self) -> Visibility {
217 218 219 220 221 222 223
        match *self {
            ConstTraitItem(ref associated_const) => associated_const.vis,
            MethodTraitItem(ref method) => method.vis,
            TypeTraitItem(ref associated_type) => associated_type.vis,
        }
    }

224 225
    pub fn container(&self) -> ImplOrTraitItemContainer {
        match *self {
226
            ConstTraitItem(ref associated_const) => associated_const.container,
227
            MethodTraitItem(ref method) => method.container,
228
            TypeTraitItem(ref associated_type) => associated_type.container,
229 230
        }
    }
231

232
    pub fn as_opt_method(&self) -> Option<Rc<Method<'tcx>>> {
233 234
        match *self {
            MethodTraitItem(ref m) => Some((*m).clone()),
235
            _ => None,
236 237
        }
    }
238 239
}

240
#[derive(Clone, Debug, PartialEq, Eq, Copy, RustcEncodable, RustcDecodable)]
241 242 243 244 245 246 247 248 249
pub enum Visibility {
    /// Visible everywhere (including in other crates).
    Public,
    /// Visible only in the given crate-local module.
    Restricted(NodeId),
    /// Not visible anywhere in the local crate. This is the visibility of private external items.
    PrivateExternal,
}

250 251 252 253 254 255 256
pub trait NodeIdTree {
    fn is_descendant_of(&self, node: NodeId, ancestor: NodeId) -> bool;
}

impl<'a> NodeIdTree for ast_map::Map<'a> {
    fn is_descendant_of(&self, node: NodeId, ancestor: NodeId) -> bool {
        let mut node_ancestor = node;
J
Jeffrey Seyfried 已提交
257
        while node_ancestor != ancestor {
258
            let node_ancestor_parent = self.get_module_parent(node_ancestor);
J
Jeffrey Seyfried 已提交
259 260 261
            if node_ancestor_parent == node_ancestor {
                return false;
            }
262 263
            node_ancestor = node_ancestor_parent;
        }
J
Jeffrey Seyfried 已提交
264
        true
265 266 267
    }
}

268
impl Visibility {
269
    pub fn from_hir(visibility: &hir::Visibility, id: NodeId, tcx: TyCtxt) -> Self {
270 271
        match *visibility {
            hir::Public => Visibility::Public,
272
            hir::Visibility::Crate => Visibility::Restricted(ast::CRATE_NODE_ID),
273
            hir::Visibility::Restricted { id, .. } => match tcx.expect_def(id) {
274 275
                // 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.
276 277
                Def::Err => Visibility::Public,
                def => Visibility::Restricted(tcx.map.as_local_node_id(def.def_id()).unwrap()),
278
            },
279 280 281
            hir::Inherited => Visibility::Restricted(tcx.map.get_module_parent(id)),
        }
    }
282 283

    /// Returns true if an item with this visibility is accessible from the given block.
284
    pub fn is_accessible_from<T: NodeIdTree>(self, block: NodeId, tree: &T) -> bool {
285 286 287 288 289 290 291 292 293
        let restriction = match self {
            // Public items are visible everywhere.
            Visibility::Public => return true,
            // Private items from other crates are visible nowhere.
            Visibility::PrivateExternal => return false,
            // Restricted items are visible in an arbitrary local module.
            Visibility::Restricted(module) => module,
        };

294
        tree.is_descendant_of(block, restriction)
295
    }
296 297

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

305
        self.is_accessible_from(vis_restriction, tree)
306
    }
307 308
}

J
Jorge Aparicio 已提交
309
#[derive(Clone, Debug)]
310
pub struct Method<'tcx> {
311
    pub name: Name,
312
    pub generics: &'tcx Generics<'tcx>,
313
    pub predicates: GenericPredicates<'tcx>,
314
    pub fty: &'tcx BareFnTy<'tcx>,
315
    pub explicit_self: ExplicitSelfCategory<'tcx>,
316
    pub vis: Visibility,
317
    pub defaultness: hir::Defaultness,
318
    pub has_body: bool,
N
Niko Matsakis 已提交
319
    pub def_id: DefId,
320
    pub container: ImplOrTraitItemContainer,
321
}
322

323
impl<'tcx> Method<'tcx> {
N
Niko Matsakis 已提交
324
    pub fn container_id(&self) -> DefId {
325 326 327 328 329
        match self.container {
            TraitContainer(id) => id,
            ImplContainer(id) => id,
        }
    }
330 331
}

332 333 334 335 336 337 338 339 340 341 342 343 344 345
impl<'tcx> PartialEq for Method<'tcx> {
    #[inline]
    fn eq(&self, other: &Self) -> bool { self.def_id == other.def_id }
}

impl<'tcx> Eq for Method<'tcx> {}

impl<'tcx> Hash for Method<'tcx> {
    #[inline]
    fn hash<H: Hasher>(&self, s: &mut H) {
        self.def_id.hash(s)
    }
}

346 347
#[derive(Clone, Copy, Debug)]
pub struct AssociatedConst<'tcx> {
348
    pub name: Name,
349
    pub ty: Ty<'tcx>,
350
    pub vis: Visibility,
351
    pub defaultness: hir::Defaultness,
N
Niko Matsakis 已提交
352
    pub def_id: DefId,
353
    pub container: ImplOrTraitItemContainer,
354
    pub has_value: bool
355 356
}

J
Jorge Aparicio 已提交
357
#[derive(Clone, Copy, Debug)]
358
pub struct AssociatedType<'tcx> {
359
    pub name: Name,
360
    pub ty: Option<Ty<'tcx>>,
361
    pub vis: Visibility,
362
    pub defaultness: hir::Defaultness,
N
Niko Matsakis 已提交
363
    pub def_id: DefId,
364 365 366
    pub container: ImplOrTraitItemContainer,
}

367
#[derive(Clone, PartialEq, RustcDecodable, RustcEncodable, Copy)]
368
pub enum Variance {
369 370 371 372
    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
373
}
374

375
#[derive(Clone, Copy, Debug, RustcDecodable, RustcEncodable)]
376
pub struct MethodCallee<'tcx> {
377
    /// Impl method ID, for inherent methods, or trait method ID, otherwise.
N
Niko Matsakis 已提交
378
    pub def_id: DefId,
379
    pub ty: Ty<'tcx>,
380
    pub substs: &'tcx Substs<'tcx>
381 382 383 384 385 386 387 388 389 390 391 392 393 394
}

/// With method calls, we store some extra information in
/// side tables (i.e method_map). We use
/// MethodCall as a key to index into these tables instead of
/// just directly using the expression's NodeId. The reason
/// for this being that we may apply adjustments (coercions)
/// with the resulting expression also needing to use the
/// side tables. The problem with this is that we don't
/// assign a separate NodeId to this new expression
/// and so it would clash with the base expression if both
/// needed to add to the side tables. Thus to disambiguate
/// we also keep track of whether there's an adjustment in
/// our key.
J
Jorge Aparicio 已提交
395
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
396
pub struct MethodCall {
397
    pub expr_id: NodeId,
398
    pub autoderef: u32
399 400 401
}

impl MethodCall {
402
    pub fn expr(id: NodeId) -> MethodCall {
403 404
        MethodCall {
            expr_id: id,
405
            autoderef: 0
406 407 408
        }
    }

409
    pub fn autoderef(expr_id: NodeId, autoderef: u32) -> MethodCall {
410 411
        MethodCall {
            expr_id: expr_id,
412
            autoderef: 1 + autoderef
413 414 415 416 417 418
        }
    }
}

// maps from an expression id that corresponds to a method call to the details
// of the method to be invoked
419
pub type MethodMap<'tcx> = FnvHashMap<MethodCall, MethodCallee<'tcx>>;
420

421 422 423
// Contains information needed to resolve types and (in the future) look up
// the types of AST nodes.
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
424
pub struct CReaderCacheKey {
425 426 427 428
    pub cnum: CrateNum,
    pub pos: usize,
}

429 430 431 432 433 434 435 436 437
/// Describes the fragment-state associated with a NodeId.
///
/// Currently only unfragmented paths have entries in the table,
/// but longer-term this enum is expected to expand to also
/// include data for fragmented paths.
#[derive(Copy, Clone, Debug)]
pub enum FragmentInfo {
    Moved { var: NodeId, move_expr: NodeId },
    Assigned { var: NodeId, assign_expr: NodeId, assignee_id: NodeId },
438
}
439

440 441 442 443
// 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.
444 445
bitflags! {
    flags TypeFlags: u32 {
446 447 448 449
        const HAS_PARAMS         = 1 << 0,
        const HAS_SELF           = 1 << 1,
        const HAS_TY_INFER       = 1 << 2,
        const HAS_RE_INFER       = 1 << 3,
N
Niko Matsakis 已提交
450 451 452 453 454 455
        const HAS_RE_SKOL        = 1 << 4,
        const HAS_RE_EARLY_BOUND = 1 << 5,
        const HAS_FREE_REGIONS   = 1 << 6,
        const HAS_TY_ERR         = 1 << 7,
        const HAS_PROJECTION     = 1 << 8,
        const HAS_TY_CLOSURE     = 1 << 9,
456 457 458

        // true if there are "names" of types and regions and so forth
        // that are local to a particular fn
N
Niko Matsakis 已提交
459
        const HAS_LOCAL_NAMES    = 1 << 10,
460

461 462
        // Present if the type belongs in a local type context.
        // Only set for TyInfer other than Fresh.
463
        const KEEP_IN_LOCAL_TCX  = 1 << 11,
464

465 466 467 468
        // Is there a projection that does not involve a bound region?
        // Currently we can't normalize projections w/ bound regions.
        const HAS_NORMALIZABLE_PROJECTION = 1 << 12,

469 470 471
        const NEEDS_SUBST        = TypeFlags::HAS_PARAMS.bits |
                                   TypeFlags::HAS_SELF.bits |
                                   TypeFlags::HAS_RE_EARLY_BOUND.bits,
472 473

        // Flags representing the nominal content of a type,
474 475
        // computed by FlagsComputation. If you add a new nominal
        // flag, it should be added here too.
476 477 478 479
        const NOMINAL_FLAGS     = TypeFlags::HAS_PARAMS.bits |
                                  TypeFlags::HAS_SELF.bits |
                                  TypeFlags::HAS_TY_INFER.bits |
                                  TypeFlags::HAS_RE_INFER.bits |
480 481
                                  TypeFlags::HAS_RE_EARLY_BOUND.bits |
                                  TypeFlags::HAS_FREE_REGIONS.bits |
482
                                  TypeFlags::HAS_TY_ERR.bits |
483
                                  TypeFlags::HAS_PROJECTION.bits |
484
                                  TypeFlags::HAS_TY_CLOSURE.bits |
485 486
                                  TypeFlags::HAS_LOCAL_NAMES.bits |
                                  TypeFlags::KEEP_IN_LOCAL_TCX.bits,
487 488 489 490 491 492

        // Caches for type_is_sized, type_moves_by_default
        const SIZEDNESS_CACHED  = 1 << 16,
        const IS_SIZED          = 1 << 17,
        const MOVENESS_CACHED   = 1 << 18,
        const MOVES_BY_DEFAULT  = 1 << 19,
493
    }
494 495
}

496
pub struct TyS<'tcx> {
497
    pub sty: TypeVariants<'tcx>,
498
    pub flags: Cell<TypeFlags>,
499 500

    // the maximal depth of any bound regions appearing in this type.
501
    region_depth: u32,
502 503
}

504
impl<'tcx> PartialEq for TyS<'tcx> {
505
    #[inline]
506 507 508 509 510
    fn eq(&self, other: &TyS<'tcx>) -> bool {
        // (self as *const _) == (other as *const _)
        (self as *const TyS<'tcx>) == (other as *const TyS<'tcx>)
    }
}
511
impl<'tcx> Eq for TyS<'tcx> {}
512

A
Alex Crichton 已提交
513 514
impl<'tcx> Hash for TyS<'tcx> {
    fn hash<H: Hasher>(&self, s: &mut H) {
N
Nick Cameron 已提交
515
        (self as *const TyS).hash(s)
A
Alex Crichton 已提交
516 517
    }
}
518

519
pub type Ty<'tcx> = &'tcx TyS<'tcx>;
520

521 522
impl<'tcx> serialize::UseSpecializedEncodable for Ty<'tcx> {}
impl<'tcx> serialize::UseSpecializedDecodable for Ty<'tcx> {}
523

A
Adam Perry 已提交
524
/// A wrapper for slices with the additional invariant
525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562
/// that the slice is interned and no other slice with
/// the same contents can exist in the same context.
/// This means we can use pointer + length for both
/// equality comparisons and hashing.
#[derive(Debug, RustcEncodable)]
pub struct Slice<T>([T]);

impl<T> PartialEq for Slice<T> {
    #[inline]
    fn eq(&self, other: &Slice<T>) -> bool {
        (&self.0 as *const [T]) == (&other.0 as *const [T])
    }
}
impl<T> Eq for Slice<T> {}

impl<T> Hash for Slice<T> {
    fn hash<H: Hasher>(&self, s: &mut H) {
        (self.as_ptr(), self.len()).hash(s)
    }
}

impl<T> Deref for Slice<T> {
    type Target = [T];
    fn deref(&self) -> &[T] {
        &self.0
    }
}

impl<'a, T> IntoIterator for &'a Slice<T> {
    type Item = &'a T;
    type IntoIter = <&'a [T] as IntoIterator>::IntoIter;
    fn into_iter(self) -> Self::IntoIter {
        self[..].iter()
    }
}

impl<'tcx> serialize::UseSpecializedDecodable for &'tcx Slice<Ty<'tcx>> {}

S
Steve Klabnik 已提交
563 564 565
/// Upvars do not get their own node-id. 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.
566
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
567
pub struct UpvarId {
568 569
    pub var_id: NodeId,
    pub closure_expr_id: NodeId,
570 571
}

J
Jorge Aparicio 已提交
572
#[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable, Copy)]
573 574 575 576 577 578 579 580 581
pub enum BorrowKind {
    /// Data must be immutable and is aliasable.
    ImmBorrow,

    /// Data must be immutable but not aliasable.  This kind of borrow
    /// cannot currently be expressed by the user and is used only in
    /// implicit closure bindings. It is needed when you the closure
    /// is borrowing or mutating a mutable referent, e.g.:
    ///
582
    ///    let x: &mut isize = ...;
583 584 585 586 587
    ///    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:
    ///
588 589
    ///    struct Env { x: & &mut isize }
    ///    let x: &mut isize = ...;
590 591 592 593 594 595 596
    ///    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:
    ///
597 598
    ///    struct Env { x: & &mut isize }
    ///    let x: &mut isize = ...;
599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617
    ///    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
}

618 619
/// Information describing the capture of an upvar. This is computed
/// during `typeck`, specifically by `regionck`.
620
#[derive(PartialEq, Clone, Debug, Copy, RustcEncodable, RustcDecodable)]
621
pub enum UpvarCapture<'tcx> {
622 623 624 625 626 627
    /// 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.
628
    ByRef(UpvarBorrow<'tcx>),
629 630
}

631
#[derive(PartialEq, Clone, Copy, RustcEncodable, RustcDecodable)]
632
pub struct UpvarBorrow<'tcx> {
633 634 635
    /// The kind of borrow: by-ref upvars have access to shared
    /// immutable borrows, which are not part of the normal language
    /// syntax.
636
    pub kind: BorrowKind,
637 638

    /// Region of the resulting reference.
639
    pub region: &'tcx ty::Region,
640 641
}

642
pub type UpvarCaptureMap<'tcx> = FnvHashMap<UpvarId, UpvarCapture<'tcx>>;
643

644 645
#[derive(Copy, Clone)]
pub struct ClosureUpvar<'tcx> {
646
    pub def: Def,
647 648 649 650
    pub span: Span,
    pub ty: Ty<'tcx>,
}

651
#[derive(Clone, Copy, PartialEq)]
652
pub enum IntVarValue {
653 654
    IntType(ast::IntTy),
    UintType(ast::UintTy),
655 656
}

657 658 659 660 661
/// Default region to use for the bound of objects that are
/// supplied as the value for this type parameter. This is derived
/// from `T:'a` annotations appearing in the type definition.  If
/// this is `None`, then the default is inherited from the
/// surrounding context. See RFC #599 for details.
662
#[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
663
pub enum ObjectLifetimeDefault<'tcx> {
664 665 666 667
    /// Require an explicit annotation. Occurs when multiple
    /// `T:'a` constraints are found.
    Ambiguous,

668 669 670
    /// Use the base default, typically 'static, but in a fn body it is a fresh variable
    BaseDefault,

671
    /// Use the given region as the default.
672
    Specific(&'tcx Region),
673 674
}

675
#[derive(Clone, RustcEncodable, RustcDecodable)]
676
pub struct TypeParameterDef<'tcx> {
677
    pub name: Name,
N
Niko Matsakis 已提交
678
    pub def_id: DefId,
679
    pub index: u32,
J
Jared Roesch 已提交
680
    pub default_def_id: DefId, // for use in error reporing about defaults
681
    pub default: Option<Ty<'tcx>>,
682
    pub object_lifetime_default: ObjectLifetimeDefault<'tcx>,
683 684 685 686 687

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

690
#[derive(Clone, RustcEncodable, RustcDecodable)]
691
pub struct RegionParameterDef<'tcx> {
692
    pub name: Name,
N
Niko Matsakis 已提交
693
    pub def_id: DefId,
694
    pub index: u32,
695
    pub bounds: Vec<&'tcx ty::Region>,
696 697 698 699 700

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

703
impl<'tcx> RegionParameterDef<'tcx> {
704
    pub fn to_early_bound_region(&self) -> ty::Region {
705 706 707 708 709
        ty::ReEarlyBound(self.to_early_bound_region_data())
    }

    pub fn to_early_bound_region_data(&self) -> ty::EarlyBoundRegion {
        ty::EarlyBoundRegion {
710 711
            index: self.index,
            name: self.name,
712
        }
713
    }
714

715
    pub fn to_bound_region(&self) -> ty::BoundRegion {
716 717
        // this is an early bound region, so unaffected by #32330
        ty::BoundRegion::BrNamed(self.def_id, self.name, Issue32330::WontChange)
718
    }
719 720 721
}

/// Information about the formal type/lifetime parameters associated
722
/// with an item or method. Analogous to hir::Generics.
723
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
724
pub struct Generics<'tcx> {
725 726 727
    pub parent: Option<DefId>,
    pub parent_regions: u32,
    pub parent_types: u32,
728
    pub regions: Vec<RegionParameterDef<'tcx>>,
729
    pub types: Vec<TypeParameterDef<'tcx>>,
730
    pub has_self: bool,
731 732
}

733 734 735 736 737 738 739 740 741 742 743 744
impl<'tcx> Generics<'tcx> {
    pub fn parent_count(&self) -> usize {
        self.parent_regions as usize + self.parent_types as usize
    }

    pub fn own_count(&self) -> usize {
        self.regions.len() + self.types.len()
    }

    pub fn count(&self) -> usize {
        self.parent_count() + self.own_count()
    }
745 746 747 748 749 750 751 752

    pub fn region_param(&self, param: &EarlyBoundRegion) -> &RegionParameterDef<'tcx> {
        &self.regions[param.index as usize - self.has_self as usize]
    }

    pub fn type_param(&self, param: &ParamTy) -> &TypeParameterDef<'tcx> {
        &self.types[param.idx as usize - self.has_self as usize - self.regions.len()]
    }
753 754
}

755
/// Bounds on generics.
756
#[derive(Clone)]
757
pub struct GenericPredicates<'tcx> {
758
    pub parent: Option<DefId>,
759
    pub predicates: Vec<Predicate<'tcx>>,
760 761
}

762 763 764
impl<'tcx> serialize::UseSpecializedEncodable for GenericPredicates<'tcx> {}
impl<'tcx> serialize::UseSpecializedDecodable for GenericPredicates<'tcx> {}

765 766
impl<'a, 'gcx, 'tcx> GenericPredicates<'tcx> {
    pub fn instantiate(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, substs: &Substs<'tcx>)
767
                       -> InstantiatedPredicates<'tcx> {
768 769 770 771 772 773
        let mut instantiated = InstantiatedPredicates::empty();
        self.instantiate_into(tcx, &mut instantiated, substs);
        instantiated
    }
    pub fn instantiate_own(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, substs: &Substs<'tcx>)
                           -> InstantiatedPredicates<'tcx> {
774
        InstantiatedPredicates {
775 776 777 778 779 780 781 782 783
            predicates: self.predicates.subst(tcx, substs)
        }
    }

    fn instantiate_into(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
                        instantiated: &mut InstantiatedPredicates<'tcx>,
                        substs: &Substs<'tcx>) {
        if let Some(def_id) = self.parent {
            tcx.lookup_predicates(def_id).instantiate_into(tcx, instantiated, substs);
784
        }
785
        instantiated.predicates.extend(self.predicates.iter().map(|p| p.subst(tcx, substs)))
786
    }
787

788
    pub fn instantiate_supertrait(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
789 790 791
                                  poly_trait_ref: &ty::PolyTraitRef<'tcx>)
                                  -> InstantiatedPredicates<'tcx>
    {
792
        assert_eq!(self.parent, None);
793
        InstantiatedPredicates {
794
            predicates: self.predicates.iter().map(|pred| {
795
                pred.subst_supertrait(tcx, poly_trait_ref)
796
            }).collect()
797 798
        }
    }
799 800
}

801
#[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
802
pub enum Predicate<'tcx> {
N
Niko Matsakis 已提交
803 804
    /// Corresponds to `where Foo : Bar<A,B,C>`. `Foo` here would be
    /// the `Self` type of the trait reference and `A`, `B`, and `C`
805
    /// would be the type parameters.
806
    Trait(PolyTraitPredicate<'tcx>),
807

N
Niko Matsakis 已提交
808
    /// where `T1 == T2`.
809
    Equate(PolyEquatePredicate<'tcx>),
810 811

    /// where 'a : 'b
812
    RegionOutlives(PolyRegionOutlivesPredicate<'tcx>),
813 814

    /// where T : 'a
815
    TypeOutlives(PolyTypeOutlivesPredicate<'tcx>),
816

N
Niko Matsakis 已提交
817 818
    /// where <T as TraitRef>::Name == X, approximately.
    /// See `ProjectionPredicate` struct for details.
819
    Projection(PolyProjectionPredicate<'tcx>),
820 821 822 823 824

    /// no syntax: T WF
    WellFormed(Ty<'tcx>),

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

827 828 829
    /// No direct syntax. May be thought of as `where T : FnFoo<...>`
    /// for some substitutions `...` and T being a closure type.
    /// Satisfied (or refuted) once we know the closure's kind.
830
    ClosureKind(DefId, ClosureKind),
831 832
}

833
impl<'a, 'gcx, 'tcx> Predicate<'tcx> {
834
    /// Performs a substitution suitable for going from a
835 836 837 838
    /// poly-trait-ref to supertraits that must hold if that
    /// poly-trait-ref holds. This is slightly different from a normal
    /// substitution in terms of what happens with bound regions.  See
    /// lengthy comment below for details.
839
    pub fn subst_supertrait(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914
                            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:
        //
        //     trait Foo<'a> : Bar<'a,'a> { }
        //     trait Bar<'b,'c> { }
        //
        // 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
        // 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:
        //
        //     trait Foo1<'a> : for<'b> Bar1<'a,'b> { }
        //     trait Bar1<'b,'c> { }
        //
        // 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
        // reason is similar to the previous example: any impl of
        // `T:Foo1<'x>` must show that `for<'b> T : Bar1<'x, 'b>`.  So
        // 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:
        //
        // - 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>`,
        //   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).

        let substs = &trait_ref.0.substs;
        match *self {
            Predicate::Trait(ty::Binder(ref data)) =>
                Predicate::Trait(ty::Binder(data.subst(tcx, substs))),
            Predicate::Equate(ty::Binder(ref data)) =>
                Predicate::Equate(ty::Binder(data.subst(tcx, substs))),
            Predicate::RegionOutlives(ty::Binder(ref data)) =>
                Predicate::RegionOutlives(ty::Binder(data.subst(tcx, substs))),
            Predicate::TypeOutlives(ty::Binder(ref data)) =>
                Predicate::TypeOutlives(ty::Binder(data.subst(tcx, substs))),
            Predicate::Projection(ty::Binder(ref data)) =>
                Predicate::Projection(ty::Binder(data.subst(tcx, substs))),
915 916 917 918
            Predicate::WellFormed(data) =>
                Predicate::WellFormed(data.subst(tcx, substs)),
            Predicate::ObjectSafe(trait_def_id) =>
                Predicate::ObjectSafe(trait_def_id),
919 920
            Predicate::ClosureKind(closure_def_id, kind) =>
                Predicate::ClosureKind(closure_def_id, kind),
921 922 923 924
        }
    }
}

925
#[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
926
pub struct TraitPredicate<'tcx> {
927
    pub trait_ref: TraitRef<'tcx>
928 929 930 931
}
pub type PolyTraitPredicate<'tcx> = ty::Binder<TraitPredicate<'tcx>>;

impl<'tcx> TraitPredicate<'tcx> {
N
Niko Matsakis 已提交
932
    pub fn def_id(&self) -> DefId {
933 934 935
        self.trait_ref.def_id
    }

936
    /// Creates the dep-node for selecting/evaluating this trait reference.
937
    fn dep_node(&self) -> DepNode<DefId> {
938 939 940 941 942 943 944
        // Ideally, the dep-node would just have all the input types
        // in it.  But they are limited to including def-ids. So as an
        // approximation we include the def-ids for all nominal types
        // found somewhere. This means that we will e.g. conflate the
        // dep-nodes for `u32: SomeTrait` and `u64: SomeTrait`, but we
        // would have distinct dep-nodes for `Vec<u32>: SomeTrait`,
        // `Rc<u32>: SomeTrait`, and `(Vec<u32>, Rc<u32>): SomeTrait`.
N
Niko Matsakis 已提交
945
        // Note that it's always sound to conflate dep-nodes, it just
946 947 948 949 950
        // leads to more recompilation.
        let def_ids: Vec<_> =
            self.input_types()
                .flat_map(|t| t.walk())
                .filter_map(|t| match t.sty {
951
                    ty::TyAdt(adt_def, _) =>
952 953 954 955
                        Some(adt_def.did),
                    _ =>
                        None
                })
956
                .chain(iter::once(self.def_id()))
957
                .collect();
958
        DepNode::TraitSelect(def_ids)
959 960
    }

961
    pub fn input_types<'a>(&'a self) -> impl DoubleEndedIterator<Item=Ty<'tcx>> + 'a {
962
        self.trait_ref.input_types()
963 964 965 966 967 968 969 970
    }

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

impl<'tcx> PolyTraitPredicate<'tcx> {
N
Niko Matsakis 已提交
971
    pub fn def_id(&self) -> DefId {
972
        // ok to skip binder since trait def-id does not care about regions
973 974
        self.0.def_id()
    }
975

976
    pub fn dep_node(&self) -> DepNode<DefId> {
977 978 979
        // ok to skip binder since depnode does not care about regions
        self.0.dep_node()
    }
980 981
}

982
#[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
983 984 985
pub struct EquatePredicate<'tcx>(pub Ty<'tcx>, pub Ty<'tcx>); // `0 == 1`
pub type PolyEquatePredicate<'tcx> = ty::Binder<EquatePredicate<'tcx>>;

986
#[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
987 988
pub struct OutlivesPredicate<A,B>(pub A, pub B); // `A : B`
pub type PolyOutlivesPredicate<A,B> = ty::Binder<OutlivesPredicate<A,B>>;
989 990 991
pub type PolyRegionOutlivesPredicate<'tcx> = PolyOutlivesPredicate<&'tcx ty::Region,
                                                                   &'tcx ty::Region>;
pub type PolyTypeOutlivesPredicate<'tcx> = PolyOutlivesPredicate<Ty<'tcx>, &'tcx ty::Region>;
992

993 994 995 996 997 998 999 1000 1001 1002
/// This kind of predicate has no *direct* correspondent in the
/// syntax, but it roughly corresponds to the syntactic forms:
///
/// 1. `T : TraitRef<..., Item=Type>`
/// 2. `<T as TraitRef<...>>::Item == Type` (NYI)
///
/// In particular, form #1 is "desugared" to the combination of a
/// normal trait predicate (`T : TraitRef<...>`) and one of these
/// predicates. Form #2 is a broader form in that it also permits
/// equality between arbitrary types. Processing an instance of Form
F
Flavio Percoco 已提交
1003
/// #2 eventually yields one of these `ProjectionPredicate`
1004
/// instances to normalize the LHS.
1005
#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
1006 1007 1008 1009 1010 1011 1012
pub struct ProjectionPredicate<'tcx> {
    pub projection_ty: ProjectionTy<'tcx>,
    pub ty: Ty<'tcx>,
}

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

1013
impl<'tcx> PolyProjectionPredicate<'tcx> {
1014
    pub fn item_name(&self) -> Name {
1015 1016
        self.0.projection_ty.item_name // safe to skip the binder to access a name
    }
1017 1018
}

1019 1020 1021 1022
pub trait ToPolyTraitRef<'tcx> {
    fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx>;
}

1023
impl<'tcx> ToPolyTraitRef<'tcx> for TraitRef<'tcx> {
1024 1025 1026 1027 1028 1029 1030 1031
    fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> {
        assert!(!self.has_escaping_regions());
        ty::Binder(self.clone())
    }
}

impl<'tcx> ToPolyTraitRef<'tcx> for PolyTraitPredicate<'tcx> {
    fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> {
1032
        self.map_bound_ref(|trait_pred| trait_pred.trait_ref)
1033 1034 1035 1036 1037 1038 1039 1040 1041 1042
    }
}

impl<'tcx> ToPolyTraitRef<'tcx> for PolyProjectionPredicate<'tcx> {
    fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> {
        // Note: unlike with TraitRef::to_poly_trait_ref(),
        // self.0.trait_ref is permitted to have escaping regions.
        // This is because here `self` has a `Binder` and so does our
        // return value, so we are preserving the number of binding
        // levels.
1043
        ty::Binder(self.0.projection_ty.trait_ref)
1044 1045 1046
    }
}

1047 1048
pub trait ToPredicate<'tcx> {
    fn to_predicate(&self) -> Predicate<'tcx>;
1049 1050
}

1051 1052
impl<'tcx> ToPredicate<'tcx> for TraitRef<'tcx> {
    fn to_predicate(&self) -> Predicate<'tcx> {
1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063
        // we're about to add a binder, so let's check that we don't
        // accidentally capture anything, or else that might be some
        // weird debruijn accounting.
        assert!(!self.has_escaping_regions());

        ty::Predicate::Trait(ty::Binder(ty::TraitPredicate {
            trait_ref: self.clone()
        }))
    }
}

1064 1065
impl<'tcx> ToPredicate<'tcx> for PolyTraitRef<'tcx> {
    fn to_predicate(&self) -> Predicate<'tcx> {
1066
        ty::Predicate::Trait(self.to_poly_trait_predicate())
1067 1068 1069
    }
}

1070 1071
impl<'tcx> ToPredicate<'tcx> for PolyEquatePredicate<'tcx> {
    fn to_predicate(&self) -> Predicate<'tcx> {
1072 1073 1074 1075
        Predicate::Equate(self.clone())
    }
}

1076
impl<'tcx> ToPredicate<'tcx> for PolyRegionOutlivesPredicate<'tcx> {
1077
    fn to_predicate(&self) -> Predicate<'tcx> {
1078 1079 1080 1081
        Predicate::RegionOutlives(self.clone())
    }
}

1082 1083
impl<'tcx> ToPredicate<'tcx> for PolyTypeOutlivesPredicate<'tcx> {
    fn to_predicate(&self) -> Predicate<'tcx> {
1084 1085
        Predicate::TypeOutlives(self.clone())
    }
1086 1087
}

1088 1089
impl<'tcx> ToPredicate<'tcx> for PolyProjectionPredicate<'tcx> {
    fn to_predicate(&self) -> Predicate<'tcx> {
1090 1091 1092 1093
        Predicate::Projection(self.clone())
    }
}

1094
impl<'tcx> Predicate<'tcx> {
1095 1096 1097 1098 1099 1100
    /// 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.
    pub fn walk_tys(&self) -> IntoIter<Ty<'tcx>> {
        let vec: Vec<_> = match *self {
            ty::Predicate::Trait(ref data) => {
1101
                data.skip_binder().input_types().collect()
1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112
            }
            ty::Predicate::Equate(ty::Binder(ref data)) => {
                vec![data.0, data.1]
            }
            ty::Predicate::TypeOutlives(ty::Binder(ref data)) => {
                vec![data.0]
            }
            ty::Predicate::RegionOutlives(..) => {
                vec![]
            }
            ty::Predicate::Projection(ref data) => {
1113
                let trait_inputs = data.0.projection_ty.trait_ref.input_types();
1114
                trait_inputs.chain(Some(data.0.ty)).collect()
1115
            }
1116 1117 1118 1119 1120 1121
            ty::Predicate::WellFormed(data) => {
                vec![data]
            }
            ty::Predicate::ObjectSafe(_trait_def_id) => {
                vec![]
            }
1122 1123 1124
            ty::Predicate::ClosureKind(_closure_def_id, _kind) => {
                vec![]
            }
1125 1126 1127 1128 1129 1130 1131 1132 1133 1134
        };

        // The only reason to collect into a vector here is that I was
        // too lazy to make the full (somewhat complicated) iterator
        // type that would be needed here. But I wanted this fn to
        // return an iterator conceptually, rather than a `Vec`, so as
        // to be closer to `Ty::walk`.
        vec.into_iter()
    }

1135
    pub fn to_opt_poly_trait_ref(&self) -> Option<PolyTraitRef<'tcx>> {
1136 1137
        match *self {
            Predicate::Trait(ref t) => {
1138
                Some(t.to_poly_trait_ref())
1139
            }
1140
            Predicate::Projection(..) |
1141 1142
            Predicate::Equate(..) |
            Predicate::RegionOutlives(..) |
1143 1144
            Predicate::WellFormed(..) |
            Predicate::ObjectSafe(..) |
1145
            Predicate::ClosureKind(..) |
1146 1147 1148
            Predicate::TypeOutlives(..) => {
                None
            }
1149 1150 1151 1152
        }
    }
}

S
Steve Klabnik 已提交
1153 1154
/// Represents the bounds declared on a particular set of type
/// parameters.  Should eventually be generalized into a flag list of
1155 1156 1157 1158 1159
/// where clauses.  You can obtain a `InstantiatedPredicates` list from a
/// `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 已提交
1160 1161 1162 1163 1164 1165 1166 1167
/// 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>> { ... }
///
1168
/// Here, the `GenericPredicates` for `Foo` would contain a list of bounds like
J
Jorge Aparicio 已提交
1169
/// `[[], [U:Bar<T>]]`.  Now if there were some particular reference
1170 1171
/// like `Foo<isize,usize>`, then the `InstantiatedPredicates` would be `[[],
/// [usize:Bar<isize>]]`.
1172
#[derive(Clone)]
1173
pub struct InstantiatedPredicates<'tcx> {
1174
    pub predicates: Vec<Predicate<'tcx>>,
1175 1176
}

1177 1178
impl<'tcx> InstantiatedPredicates<'tcx> {
    pub fn empty() -> InstantiatedPredicates<'tcx> {
1179
        InstantiatedPredicates { predicates: vec![] }
1180 1181
    }

1182 1183
    pub fn is_empty(&self) -> bool {
        self.predicates.is_empty()
1184
    }
1185 1186
}

1187
impl<'tcx> TraitRef<'tcx> {
N
Niko Matsakis 已提交
1188
    pub fn new(def_id: DefId, substs: &'tcx Substs<'tcx>) -> TraitRef<'tcx> {
1189 1190 1191
        TraitRef { def_id: def_id, substs: substs }
    }

1192
    pub fn self_ty(&self) -> Ty<'tcx> {
1193
        self.substs.type_at(0)
1194
    }
N
Niko Matsakis 已提交
1195

1196
    pub fn input_types<'a>(&'a self) -> impl DoubleEndedIterator<Item=Ty<'tcx>> + 'a {
N
Niko Matsakis 已提交
1197 1198 1199 1200
        // Select only the "input types" from a trait-reference. For
        // now this is all the types that appear in the
        // trait-reference, but it should eventually exclude
        // associated types.
1201
        self.substs.types()
N
Niko Matsakis 已提交
1202
    }
1203 1204
}

1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216
/// When type checking, we use the `ParameterEnvironment` to track
/// details about the type/lifetime parameters that are in scope.
/// It primarily stores the bounds information.
///
/// Note: This information might seem to be redundant with the data in
/// `tcx.ty_param_defs`, but it is not. That table contains the
/// parameter definitions from an "outside" perspective, but this
/// struct will contain the bounds for a parameter as seen from inside
/// the function body. Currently the only real distinction is that
/// bound lifetime parameters are replaced with free ones, but in the
/// future I hope to refine the representation of types so as to make
/// more distinctions clearer.
1217
#[derive(Clone)]
1218
pub struct ParameterEnvironment<'tcx> {
1219
    /// See `construct_free_substs` for details.
1220
    pub free_substs: &'tcx Substs<'tcx>,
1221

1222 1223 1224 1225
    /// Each type parameter has an implicit region bound that
    /// indicates it must outlive at least the function body (the user
    /// may specify stronger requirements). This field indicates the
    /// region of the callee.
1226
    pub implicit_region_bound: &'tcx ty::Region,
1227 1228 1229

    /// Obligations that the caller must satisfy. This is basically
    /// the set of bounds on the in-scope type parameters, translated
1230
    /// into Obligations, and elaborated and normalized.
1231
    pub caller_bounds: Vec<ty::Predicate<'tcx>>,
1232

1233 1234 1235 1236 1237 1238 1239
    /// Scope that is attached to free regions for this scope. This
    /// is usually the id of the fn body, but for more abstract scopes
    /// like structs we often use the node-id of the struct.
    ///
    /// FIXME(#3696). It would be nice to refactor so that free
    /// regions don't have this implicit scope and instead introduce
    /// relationships in the environment.
1240
    pub free_id_outlive: CodeExtent,
1241 1242 1243 1244 1245 1246

    /// A cache for `moves_by_default`.
    pub is_copy_cache: RefCell<FnvHashMap<Ty<'tcx>, bool>>,

    /// A cache for `type_is_sized`
    pub is_sized_cache: RefCell<FnvHashMap<Ty<'tcx>, bool>>,
1247 1248
}

1249
impl<'a, 'tcx> ParameterEnvironment<'tcx> {
1250 1251
    pub fn with_caller_bounds(&self,
                              caller_bounds: Vec<ty::Predicate<'tcx>>)
1252
                              -> ParameterEnvironment<'tcx>
1253 1254
    {
        ParameterEnvironment {
1255
            free_substs: self.free_substs,
1256 1257
            implicit_region_bound: self.implicit_region_bound,
            caller_bounds: caller_bounds,
1258
            free_id_outlive: self.free_id_outlive,
1259 1260
            is_copy_cache: RefCell::new(FnvHashMap()),
            is_sized_cache: RefCell::new(FnvHashMap()),
1261 1262 1263
        }
    }

1264
    /// Construct a parameter environment given an item, impl item, or trait item
1265 1266
    pub fn for_item(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: NodeId)
                    -> ParameterEnvironment<'tcx> {
1267
        match tcx.map.find(id) {
1268
            Some(ast_map::NodeImplItem(ref impl_item)) => {
1269
                match impl_item.node {
V
Vadim Petrochenkov 已提交
1270
                    hir::ImplItemKind::Type(_) | hir::ImplItemKind::Const(..) => {
1271 1272
                        // associated types don't have their own entry (for some reason),
                        // so for now just grab environment for the impl
1273 1274 1275
                        let impl_id = tcx.map.get_parent(id);
                        let impl_def_id = tcx.map.local_def_id(impl_id);
                        tcx.construct_parameter_environment(impl_item.span,
1276
                                                            impl_def_id,
1277
                                                            tcx.region_maps.item_extent(id))
1278
                    }
1279
                    hir::ImplItemKind::Method(_, ref body) => {
1280 1281
                        let method_def_id = tcx.map.local_def_id(id);
                        match tcx.impl_or_trait_item(method_def_id) {
1282
                            MethodTraitItem(ref method_ty) => {
1283
                                tcx.construct_parameter_environment(
1284
                                    impl_item.span,
1285
                                    method_ty.def_id,
1286
                                    tcx.region_maps.call_site_extent(id, body.id))
1287
                            }
1288
                            _ => {
1289 1290
                                bug!("ParameterEnvironment::for_item(): \
                                      got non-method item from impl method?!")
1291
                            }
1292 1293 1294 1295
                        }
                    }
                }
            }
1296 1297
            Some(ast_map::NodeTraitItem(trait_item)) => {
                match trait_item.node {
1298
                    hir::TypeTraitItem(..) | hir::ConstTraitItem(..) => {
1299 1300
                        // associated types don't have their own entry (for some reason),
                        // so for now just grab environment for the trait
1301 1302 1303
                        let trait_id = tcx.map.get_parent(id);
                        let trait_def_id = tcx.map.local_def_id(trait_id);
                        tcx.construct_parameter_environment(trait_item.span,
1304
                                                            trait_def_id,
1305
                                                            tcx.region_maps.item_extent(id))
1306
                    }
1307
                    hir::MethodTraitItem(_, ref body) => {
1308 1309 1310
                        // Use call-site for extent (unless this is a
                        // trait method with no default; then fallback
                        // to the method id).
1311 1312
                        let method_def_id = tcx.map.local_def_id(id);
                        match tcx.impl_or_trait_item(method_def_id) {
1313
                            MethodTraitItem(ref method_ty) => {
1314 1315
                                let extent = if let Some(ref body) = *body {
                                    // default impl: use call_site extent as free_id_outlive bound.
1316
                                    tcx.region_maps.call_site_extent(id, body.id)
1317 1318
                                } else {
                                    // no default impl: use item extent as free_id_outlive bound.
1319
                                    tcx.region_maps.item_extent(id)
1320
                                };
1321
                                tcx.construct_parameter_environment(
1322
                                    trait_item.span,
1323
                                    method_ty.def_id,
1324
                                    extent)
1325
                            }
1326
                            _ => {
1327 1328 1329
                                bug!("ParameterEnvironment::for_item(): \
                                      got non-method item from provided \
                                      method?!")
1330
                            }
1331 1332 1333 1334 1335 1336
                        }
                    }
                }
            }
            Some(ast_map::NodeItem(item)) => {
                match item.node {
V
Vadim Petrochenkov 已提交
1337
                    hir::ItemFn(.., ref body) => {
1338
                        // We assume this is a function.
1339 1340 1341 1342
                        let fn_def_id = tcx.map.local_def_id(id);

                        tcx.construct_parameter_environment(
                            item.span,
1343
                            fn_def_id,
1344
                            tcx.region_maps.call_site_extent(id, body.id))
1345
                    }
1346 1347
                    hir::ItemEnum(..) |
                    hir::ItemStruct(..) |
1348
                    hir::ItemUnion(..) |
1349
                    hir::ItemTy(..) |
1350 1351 1352
                    hir::ItemImpl(..) |
                    hir::ItemConst(..) |
                    hir::ItemStatic(..) => {
1353 1354
                        let def_id = tcx.map.local_def_id(id);
                        tcx.construct_parameter_environment(item.span,
1355
                                                            def_id,
1356
                                                            tcx.region_maps.item_extent(id))
1357
                    }
1358
                    hir::ItemTrait(..) => {
1359 1360
                        let def_id = tcx.map.local_def_id(id);
                        tcx.construct_parameter_environment(item.span,
1361
                                                            def_id,
1362
                                                            tcx.region_maps.item_extent(id))
1363
                    }
1364
                    _ => {
1365 1366 1367 1368
                        span_bug!(item.span,
                                  "ParameterEnvironment::for_item():
                                   can't create a parameter \
                                   environment for this kind of item")
1369 1370 1371
                    }
                }
            }
1372
            Some(ast_map::NodeExpr(expr)) => {
N
Niko Matsakis 已提交
1373
                // This is a convenience to allow closures to work.
1374 1375 1376 1377 1378
                if let hir::ExprClosure(..) = expr.node {
                    ParameterEnvironment::for_item(tcx, tcx.map.get_parent(id))
                } else {
                    tcx.empty_parameter_environment()
                }
N
Niko Matsakis 已提交
1379
            }
1380
            Some(ast_map::NodeForeignItem(item)) => {
1381 1382
                let def_id = tcx.map.local_def_id(id);
                tcx.construct_parameter_environment(item.span,
1383
                                                    def_id,
1384
                                                    ROOT_CODE_EXTENT)
1385
            }
1386
            _ => {
1387 1388
                bug!("ParameterEnvironment::from_item(): \
                      `{}` is not an item",
1389
                     tcx.map.node_to_string(id))
1390 1391 1392 1393 1394
            }
        }
    }
}

1395 1396 1397 1398 1399 1400
/// A "type scheme", in ML terminology, is a type combined with some
/// set of generic types that the type is, well, generic over. In Rust
/// terms, it is the "type" of a fn item or struct -- this type will
/// include various generic parameters that must be substituted when
/// the item/struct is referenced. That is called converting the type
/// scheme to a monotype.
1401
///
1402 1403 1404
/// - `generics`: the set of type parameters and their bounds
/// - `ty`: the base types, which may reference the parameters defined
///   in `generics`
N
Niko Matsakis 已提交
1405 1406 1407 1408 1409 1410
///
/// Note that TypeSchemes are also sometimes called "polytypes" (and
/// in fact this struct used to carry that name, so you may find some
/// stray references in a comment or something). We try to reserve the
/// "poly" prefix to refer to higher-ranked things, as in
/// `PolyTraitRef`.
1411 1412 1413
///
/// Note that each item also comes with predicates, see
/// `lookup_predicates`.
J
Jorge Aparicio 已提交
1414
#[derive(Clone, Debug)]
1415
pub struct TypeScheme<'tcx> {
1416
    pub generics: &'tcx Generics<'tcx>,
1417
    pub ty: Ty<'tcx>,
1418
}
1419

1420
bitflags! {
A
Ariel Ben-Yehuda 已提交
1421
    flags AdtFlags: u32 {
1422
        const NO_ADT_FLAGS        = 0,
A
Ariel Ben-Yehuda 已提交
1423 1424 1425 1426 1427 1428
        const IS_ENUM             = 1 << 0,
        const IS_DTORCK           = 1 << 1, // is this a dtorck type?
        const IS_DTORCK_VALID     = 1 << 2,
        const IS_PHANTOM_DATA     = 1 << 3,
        const IS_SIMD             = 1 << 4,
        const IS_FUNDAMENTAL      = 1 << 5,
1429
        const IS_UNION            = 1 << 6,
1430 1431 1432
    }
}

A
Ariel Ben-Yehuda 已提交
1433 1434 1435
pub type AdtDef<'tcx> = &'tcx AdtDefData<'tcx, 'static>;
pub type VariantDef<'tcx> = &'tcx VariantDefData<'tcx, 'static>;
pub type FieldDef<'tcx> = &'tcx FieldDefData<'tcx, 'static>;
1436

A
Ariel Ben-Yehuda 已提交
1437 1438 1439 1440 1441 1442
// See comment on AdtDefData for explanation
pub type AdtDefMaster<'tcx> = &'tcx AdtDefData<'tcx, 'tcx>;
pub type VariantDefMaster<'tcx> = &'tcx VariantDefData<'tcx, 'tcx>;
pub type FieldDefMaster<'tcx> = &'tcx FieldDefData<'tcx, 'tcx>;

pub struct VariantDefData<'tcx, 'container: 'tcx> {
1443 1444
    /// The variant's DefId. If this is a tuple-like struct,
    /// this is the DefId of the struct's ctor.
1445 1446 1447
    pub did: DefId,
    pub name: Name, // struct's name if this is a struct
    pub disr_val: Disr,
1448
    pub fields: Vec<FieldDefData<'tcx, 'container>>,
1449
    pub ctor_kind: CtorKind,
1450 1451
}

A
Ariel Ben-Yehuda 已提交
1452
pub struct FieldDefData<'tcx, 'container: 'tcx> {
A
Ariel Ben-Yehuda 已提交
1453 1454
    /// The field's DefId. NOTE: the fields of tuple-like enum variants
    /// are not real items, and don't have entries in tcache etc.
1455
    pub did: DefId,
1456
    pub name: Name,
1457
    pub vis: Visibility,
A
Ariel Ben-Yehuda 已提交
1458
    /// TyIVar is used here to allow for variance (see the doc at
A
Ariel Ben-Yehuda 已提交
1459
    /// AdtDefData).
1460 1461
    ///
    /// Note: direct accesses to `ty` must also add dep edges.
1462
    ty: ivar::TyIVar<'tcx, 'container>
1463 1464
}

A
Ariel Ben-Yehuda 已提交
1465 1466 1467 1468 1469 1470 1471 1472 1473
/// The definition of an abstract data type - a struct or enum.
///
/// These are all interned (by intern_adt_def) into the adt_defs
/// table.
///
/// Because of the possibility of nested tcx-s, this type
/// needs 2 lifetimes: the traditional variant lifetime ('tcx)
/// bounding the lifetime of the inner types is of course necessary.
/// However, it is not sufficient - types from a child tcx must
A
Ariel Ben-Yehuda 已提交
1474
/// not be leaked into the master tcx by being stored in an AdtDefData.
A
Ariel Ben-Yehuda 已提交
1475 1476 1477 1478
///
/// The 'container lifetime ensures that by outliving the container
/// tcx and preventing shorter-lived types from being inserted. When
/// write access is not needed, the 'container lifetime can be
A
Ariel Ben-Yehuda 已提交
1479 1480
/// erased to 'static, which can be done by the AdtDef wrapper.
pub struct AdtDefData<'tcx, 'container: 'tcx> {
1481
    pub did: DefId,
A
Ariel Ben-Yehuda 已提交
1482
    pub variants: Vec<VariantDefData<'tcx, 'container>>,
1483
    destructor: Cell<Option<DefId>>,
A
Ariel Ben-Yehuda 已提交
1484
    flags: Cell<AdtFlags>,
1485
    sized_constraint: ivar::TyIVar<'tcx, 'container>,
1486 1487
}

A
Ariel Ben-Yehuda 已提交
1488 1489
impl<'tcx, 'container> PartialEq for AdtDefData<'tcx, 'container> {
    // AdtDefData are always interned and this is part of TyS equality
1490 1491 1492 1493
    #[inline]
    fn eq(&self, other: &Self) -> bool { self as *const _ == other as *const _ }
}

A
Ariel Ben-Yehuda 已提交
1494
impl<'tcx, 'container> Eq for AdtDefData<'tcx, 'container> {}
1495

A
Ariel Ben-Yehuda 已提交
1496
impl<'tcx, 'container> Hash for AdtDefData<'tcx, 'container> {
1497 1498
    #[inline]
    fn hash<H: Hasher>(&self, s: &mut H) {
A
Ariel Ben-Yehuda 已提交
1499
        (self as *const AdtDefData).hash(s)
1500 1501 1502
    }
}

1503 1504
impl<'tcx> serialize::UseSpecializedEncodable for AdtDef<'tcx> {
    fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
1505 1506 1507 1508
        self.did.encode(s)
    }
}

1509
impl<'tcx> serialize::UseSpecializedDecodable for AdtDef<'tcx> {}
1510 1511

#[derive(Copy, Clone, Debug, Eq, PartialEq)]
1512
pub enum AdtKind { Struct, Union, Enum }
1513

1514 1515
impl<'a, 'gcx, 'tcx, 'container> AdtDefData<'gcx, 'container> {
    fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>,
1516
           did: DefId,
A
Ariel Ben-Yehuda 已提交
1517
           kind: AdtKind,
1518
           variants: Vec<VariantDefData<'gcx, 'container>>) -> Self {
A
Ariel Ben-Yehuda 已提交
1519
        let mut flags = AdtFlags::NO_ADT_FLAGS;
A
Ariel Ben-Yehuda 已提交
1520
        let attrs = tcx.get_attrs(did);
1521
        if attr::contains_name(&attrs, "fundamental") {
A
Ariel Ben-Yehuda 已提交
1522
            flags = flags | AdtFlags::IS_FUNDAMENTAL;
1523
        }
1524
        if tcx.lookup_simd(did) {
A
Ariel Ben-Yehuda 已提交
1525
            flags = flags | AdtFlags::IS_SIMD;
A
Ariel Ben-Yehuda 已提交
1526
        }
1527
        if Some(did) == tcx.lang_items.phantom_data() {
A
Ariel Ben-Yehuda 已提交
1528
            flags = flags | AdtFlags::IS_PHANTOM_DATA;
1529
        }
1530 1531 1532 1533
        match kind {
            AdtKind::Enum => flags = flags | AdtFlags::IS_ENUM,
            AdtKind::Union => flags = flags | AdtFlags::IS_UNION,
            AdtKind::Struct => {}
1534
        }
A
Ariel Ben-Yehuda 已提交
1535
        AdtDefData {
1536
            did: did,
1537
            variants: variants,
1538
            flags: Cell::new(flags),
1539 1540
            destructor: Cell::new(None),
            sized_constraint: ivar::TyIVar::new(),
1541 1542 1543
        }
    }

1544
    fn calculate_dtorck(&'gcx self, tcx: TyCtxt) {
1545
        if tcx.is_adt_dtorck(self) {
A
Ariel Ben-Yehuda 已提交
1546
            self.flags.set(self.flags.get() | AdtFlags::IS_DTORCK);
1547
        }
A
Ariel Ben-Yehuda 已提交
1548
        self.flags.set(self.flags.get() | AdtFlags::IS_DTORCK_VALID)
1549 1550
    }

1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565
    #[inline]
    pub fn is_struct(&self) -> bool {
        !self.is_union() && !self.is_enum()
    }

    #[inline]
    pub fn is_union(&self) -> bool {
        self.flags.get().intersects(AdtFlags::IS_UNION)
    }

    #[inline]
    pub fn is_enum(&self) -> bool {
        self.flags.get().intersects(AdtFlags::IS_ENUM)
    }

A
Ariel Ben-Yehuda 已提交
1566
    /// Returns the kind of the ADT - Struct or Enum.
1567
    #[inline]
A
Ariel Ben-Yehuda 已提交
1568
    pub fn adt_kind(&self) -> AdtKind {
1569
        if self.is_enum() {
A
Ariel Ben-Yehuda 已提交
1570
            AdtKind::Enum
1571
        } else if self.is_union() {
1572
            AdtKind::Union
1573
        } else {
A
Ariel Ben-Yehuda 已提交
1574
            AdtKind::Struct
1575 1576 1577
        }
    }

1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593
    pub fn descr(&self) -> &'static str {
        match self.adt_kind() {
            AdtKind::Struct => "struct",
            AdtKind::Union => "union",
            AdtKind::Enum => "enum",
        }
    }

    pub fn variant_descr(&self) -> &'static str {
        match self.adt_kind() {
            AdtKind::Struct => "struct",
            AdtKind::Union => "union",
            AdtKind::Enum => "variant",
        }
    }

A
Ariel Ben-Yehuda 已提交
1594 1595 1596
    /// Returns whether this is a dtorck type. If this returns
    /// true, this type being safe for destruction requires it to be
    /// alive; Otherwise, only the contents are required to be.
1597
    #[inline]
1598
    pub fn is_dtorck(&'gcx self, tcx: TyCtxt) -> bool {
A
Ariel Ben-Yehuda 已提交
1599
        if !self.flags.get().intersects(AdtFlags::IS_DTORCK_VALID) {
1600 1601
            self.calculate_dtorck(tcx)
        }
A
Ariel Ben-Yehuda 已提交
1602
        self.flags.get().intersects(AdtFlags::IS_DTORCK)
1603 1604
    }

A
Ariel Ben-Yehuda 已提交
1605 1606
    /// Returns whether this type is #[fundamental] for the purposes
    /// of coherence checking.
1607 1608
    #[inline]
    pub fn is_fundamental(&self) -> bool {
A
Ariel Ben-Yehuda 已提交
1609
        self.flags.get().intersects(AdtFlags::IS_FUNDAMENTAL)
1610 1611
    }

A
Ariel Ben-Yehuda 已提交
1612 1613
    #[inline]
    pub fn is_simd(&self) -> bool {
A
Ariel Ben-Yehuda 已提交
1614
        self.flags.get().intersects(AdtFlags::IS_SIMD)
A
Ariel Ben-Yehuda 已提交
1615 1616
    }

A
Ariel Ben-Yehuda 已提交
1617
    /// Returns true if this is PhantomData<T>.
1618 1619
    #[inline]
    pub fn is_phantom_data(&self) -> bool {
A
Ariel Ben-Yehuda 已提交
1620
        self.flags.get().intersects(AdtFlags::IS_PHANTOM_DATA)
1621 1622
    }

A
Ariel Ben-Yehuda 已提交
1623
    /// Returns whether this type has a destructor.
1624
    pub fn has_dtor(&self) -> bool {
1625
        self.dtor_kind().is_present()
1626 1627
    }

A
Ariel Ben-Yehuda 已提交
1628 1629
    /// Asserts this is a struct and returns the struct's unique
    /// variant.
1630
    pub fn struct_variant(&self) -> &VariantDefData<'gcx, 'container> {
1631
        assert!(!self.is_enum());
1632
        &self.variants[0]
1633 1634 1635
    }

    #[inline]
1636
    pub fn type_scheme(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> TypeScheme<'gcx> {
1637 1638 1639 1640
        tcx.lookup_item_type(self.did)
    }

    #[inline]
1641
    pub fn predicates(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> GenericPredicates<'gcx> {
1642 1643
        tcx.lookup_predicates(self.did)
    }
1644

A
Ariel Ben-Yehuda 已提交
1645 1646
    /// Returns an iterator over all fields contained
    /// by this ADT.
1647 1648 1649
    #[inline]
    pub fn all_fields(&self) ->
            iter::FlatMap<
1650 1651 1652 1653
                slice::Iter<VariantDefData<'gcx, 'container>>,
                slice::Iter<FieldDefData<'gcx, 'container>>,
                for<'s> fn(&'s VariantDefData<'gcx, 'container>)
                    -> slice::Iter<'s, FieldDefData<'gcx, 'container>>
1654
            > {
A
Ariel Ben-Yehuda 已提交
1655
        self.variants.iter().flat_map(VariantDefData::fields_iter)
1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672
    }

    #[inline]
    pub fn is_empty(&self) -> bool {
        self.variants.is_empty()
    }

    #[inline]
    pub fn is_univariant(&self) -> bool {
        self.variants.len() == 1
    }

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

1673
    pub fn variant_with_id(&self, vid: DefId) -> &VariantDefData<'gcx, 'container> {
1674 1675 1676 1677 1678 1679
        self.variants
            .iter()
            .find(|v| v.did == vid)
            .expect("variant_with_id: unknown variant")
    }

N
Niko Matsakis 已提交
1680 1681 1682 1683 1684 1685 1686
    pub fn variant_index_with_id(&self, vid: DefId) -> usize {
        self.variants
            .iter()
            .position(|v| v.did == vid)
            .expect("variant_index_with_id: unknown variant")
    }

1687
    pub fn variant_of_def(&self, def: Def) -> &VariantDefData<'gcx, 'container> {
1688
        match def {
1689 1690
            Def::Variant(vid) | Def::VariantCtor(vid, ..) => self.variant_with_id(vid),
            Def::Struct(..) | Def::StructCtor(..) | Def::Union(..) |
1691
            Def::TyAlias(..) | Def::AssociatedTy(..) => self.struct_variant(),
1692
            _ => bug!("unexpected def {:?} in variant_of_def", def)
1693 1694
        }
    }
1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705

    pub fn destructor(&self) -> Option<DefId> {
        self.destructor.get()
    }

    pub fn set_destructor(&self, dtor: DefId) {
        self.destructor.set(Some(dtor));
    }

    pub fn dtor_kind(&self) -> DtorKind {
        match self.destructor.get() {
1706
            Some(_) => TraitDtor,
1707 1708 1709
            None => NoDtor,
        }
    }
1710
}
1711

1712
impl<'a, 'gcx, 'tcx, 'container> AdtDefData<'tcx, 'container> {
1713 1714
    /// Returns a simpler type such that `Self: Sized` if and only
    /// if that type is Sized, or `TyErr` if this type is recursive.
A
Ariel Ben-Yehuda 已提交
1715
    ///
1716 1717 1718 1719
    /// HACK: instead of returning a list of types, this function can
    /// return a tuple. In that case, the result is Sized only if
    /// all elements of the tuple are Sized.
    ///
A
Ariel Ben-Yehuda 已提交
1720 1721 1722 1723 1724 1725 1726 1727 1728 1729
    /// This is generally the `struct_tail` if this is a struct, or a
    /// tuple of them if this is an enum.
    ///
    /// Oddly enough, checking that the sized-constraint is Sized is
    /// actually more expressive than checking all members:
    /// the Sized trait is inductive, so an associated type that references
    /// Self would prevent its containing ADT from being Sized.
    ///
    /// Due to normalization being eager, this applies even if
    /// the associated type is behind a pointer, e.g. issue #31299.
1730
    pub fn sized_constraint(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx> {
1731
        match self.sized_constraint.get(DepNode::SizedConstraint(self.did)) {
1732
            None => {
1733 1734 1735
                let global_tcx = tcx.global_tcx();
                let this = global_tcx.lookup_adt_def_master(self.did);
                this.calculate_sized_constraint_inner(global_tcx, &mut Vec::new());
1736
                self.sized_constraint(tcx)
1737 1738 1739 1740 1741 1742
            }
            Some(ty) => ty
        }
    }
}

1743
impl<'a, 'tcx> AdtDefData<'tcx, 'tcx> {
A
Ariel Ben-Yehuda 已提交
1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758
    /// Calculates the Sized-constraint.
    ///
    /// As the Sized-constraint of enums can be a *set* of types,
    /// the Sized-constraint may need to be a set also. Because introducing
    /// a new type of IVar is currently a complex affair, the Sized-constraint
    /// may be a tuple.
    ///
    /// In fact, there are only a few options for the constraint:
    ///     - `bool`, if the type is always Sized
    ///     - 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.
    ///     - a TyError, if a type contained itself. The representability
    ///       check should catch this case.
1759 1760
    fn calculate_sized_constraint_inner(&'tcx self,
                                        tcx: TyCtxt<'a, 'tcx, 'tcx>,
A
Ariel Ben-Yehuda 已提交
1761
                                        stack: &mut Vec<AdtDefMaster<'tcx>>)
1762
    {
1763
        let dep_node = || DepNode::SizedConstraint(self.did);
1764 1765 1766 1767 1768 1769 1770

        // Follow the memoization pattern: push the computation of
        // DepNode::SizedConstraint as our current task.
        let _task = tcx.dep_graph.in_task(dep_node());
        if self.sized_constraint.untracked_get().is_some() {
            //                   ---------------
            // can skip the dep-graph read since we just pushed the task
A
Ariel Ben-Yehuda 已提交
1771 1772 1773 1774 1775 1776 1777 1778 1779
            return;
        }

        if stack.contains(&self) {
            debug!("calculate_sized_constraint: {:?} is recursive", self);
            // This should be reported as an error by `check_representable`.
            //
            // Consider the type as Sized in the meanwhile to avoid
            // further errors.
1780
            self.sized_constraint.fulfill(dep_node(), tcx.types.err);
A
Ariel Ben-Yehuda 已提交
1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796
            return;
        }

        stack.push(self);

        let tys : Vec<_> =
            self.variants.iter().flat_map(|v| {
                v.fields.last()
            }).flat_map(|f| {
                self.sized_constraint_for_ty(tcx, stack, f.unsubst_ty())
            }).collect();

        let self_ = stack.pop().unwrap();
        assert_eq!(self_, self);

        let ty = match tys.len() {
A
Ariel Ben-Yehuda 已提交
1797
            _ if tys.references_error() => tcx.types.err,
1798 1799
            0 => tcx.types.bool,
            1 => tys[0],
1800
            _ => tcx.mk_tup(&tys)
A
Ariel Ben-Yehuda 已提交
1801 1802
        };

1803
        match self.sized_constraint.get(dep_node()) {
A
Ariel Ben-Yehuda 已提交
1804 1805 1806 1807 1808 1809
            Some(old_ty) => {
                debug!("calculate_sized_constraint: {:?} recurred", self);
                assert_eq!(old_ty, tcx.types.err)
            }
            None => {
                debug!("calculate_sized_constraint: {:?} => {:?}", self, ty);
1810
                self.sized_constraint.fulfill(dep_node(), ty)
A
Ariel Ben-Yehuda 已提交
1811
            }
1812 1813
        }
    }
1814

1815 1816
    fn sized_constraint_for_ty(
        &'tcx self,
1817
        tcx: TyCtxt<'a, 'tcx, 'tcx>,
1818 1819
        stack: &mut Vec<AdtDefMaster<'tcx>>,
        ty: Ty<'tcx>
A
Ariel Ben-Yehuda 已提交
1820
    ) -> Vec<Ty<'tcx>> {
1821 1822 1823
        let result = match ty.sty {
            TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) |
            TyBox(..) | TyRawPtr(..) | TyRef(..) | TyFnDef(..) | TyFnPtr(_) |
A
Andrew Cann 已提交
1824
            TyArray(..) | TyClosure(..) | TyNever => {
A
Ariel Ben-Yehuda 已提交
1825
                vec![]
1826 1827
            }

A
Ariel Ben-Yehuda 已提交
1828
            TyStr | TyTrait(..) | TySlice(_) | TyError => {
1829
                // these are never sized - return the target type
A
Ariel Ben-Yehuda 已提交
1830
                vec![ty]
1831 1832 1833
            }

            TyTuple(ref tys) => {
1834 1835 1836 1837
                match tys.last() {
                    None => vec![],
                    Some(ty) => self.sized_constraint_for_ty(tcx, stack, ty)
                }
1838 1839
            }

1840
            TyAdt(adt, substs) => {
1841 1842 1843 1844 1845 1846 1847 1848 1849
                // recursive case
                let adt = tcx.lookup_adt_def_master(adt.did);
                adt.calculate_sized_constraint_inner(tcx, stack);
                let adt_ty =
                    adt.sized_constraint
                    .unwrap(DepNode::SizedConstraint(adt.did))
                    .subst(tcx, substs);
                debug!("sized_constraint_for_ty({:?}) intermediate = {:?}",
                       ty, adt_ty);
A
Ariel Ben-Yehuda 已提交
1850 1851 1852 1853 1854 1855 1856
                if let ty::TyTuple(ref tys) = adt_ty.sty {
                    tys.iter().flat_map(|ty| {
                        self.sized_constraint_for_ty(tcx, stack, ty)
                    }).collect()
                } else {
                    self.sized_constraint_for_ty(tcx, stack, adt_ty)
                }
1857 1858
            }

1859
            TyProjection(..) | TyAnon(..) => {
1860 1861
                // must calculate explicitly.
                // FIXME: consider special-casing always-Sized projections
A
Ariel Ben-Yehuda 已提交
1862
                vec![ty]
1863 1864 1865
            }

            TyParam(..) => {
A
Ariel Ben-Yehuda 已提交
1866 1867 1868 1869
                // 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.

1870 1871
                let sized_trait = match tcx.lang_items.sized_trait() {
                    Some(x) => x,
A
Ariel Ben-Yehuda 已提交
1872
                    _ => return vec![ty]
1873 1874 1875
                };
                let sized_predicate = Binder(TraitRef {
                    def_id: sized_trait,
1876
                    substs: Substs::new_trait(tcx, ty, &[])
1877 1878 1879
                }).to_predicate();
                let predicates = tcx.lookup_predicates(self.did).predicates;
                if predicates.into_iter().any(|p| p == sized_predicate) {
A
Ariel Ben-Yehuda 已提交
1880
                    vec![]
1881
                } else {
A
Ariel Ben-Yehuda 已提交
1882
                    vec![ty]
1883 1884 1885
                }
            }

A
Ariel Ben-Yehuda 已提交
1886
            TyInfer(..) => {
1887 1888 1889 1890 1891 1892 1893
                bug!("unexpected type `{:?}` in sized_constraint_for_ty",
                     ty)
            }
        };
        debug!("sized_constraint_for_ty({:?}) = {:?}", ty, result);
        result
    }
1894 1895
}

A
Ariel Ben-Yehuda 已提交
1896
impl<'tcx, 'container> VariantDefData<'tcx, 'container> {
1897
    #[inline]
A
Ariel Ben-Yehuda 已提交
1898
    fn fields_iter(&self) -> slice::Iter<FieldDefData<'tcx, 'container>> {
1899 1900 1901 1902
        self.fields.iter()
    }

    #[inline]
A
Ariel Ben-Yehuda 已提交
1903 1904 1905
    pub fn find_field_named(&self,
                            name: ast::Name)
                            -> Option<&FieldDefData<'tcx, 'container>> {
1906 1907 1908
        self.fields.iter().find(|f| f.name == name)
    }

1909 1910 1911 1912 1913 1914 1915
    #[inline]
    pub fn index_of_field_named(&self,
                                name: ast::Name)
                                -> Option<usize> {
        self.fields.iter().position(|f| f.name == name)
    }

1916
    #[inline]
A
Ariel Ben-Yehuda 已提交
1917
    pub fn field_named(&self, name: ast::Name) -> &FieldDefData<'tcx, 'container> {
1918 1919 1920 1921
        self.find_field_named(name).unwrap()
    }
}

1922
impl<'a, 'gcx, 'tcx, 'container> FieldDefData<'tcx, 'container> {
1923 1924
    pub fn new(did: DefId,
               name: Name,
1925
               vis: Visibility) -> Self {
A
Ariel Ben-Yehuda 已提交
1926
        FieldDefData {
1927 1928 1929
            did: did,
            name: name,
            vis: vis,
1930
            ty: ivar::TyIVar::new()
1931 1932 1933
        }
    }

1934
    pub fn ty(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, subst: &Substs<'tcx>) -> Ty<'tcx> {
1935 1936 1937 1938
        self.unsubst_ty().subst(tcx, subst)
    }

    pub fn unsubst_ty(&self) -> Ty<'tcx> {
1939
        self.ty.unwrap(DepNode::FieldTy(self.did))
1940 1941
    }

A
Ariel Ben-Yehuda 已提交
1942
    pub fn fulfill_ty(&self, ty: Ty<'container>) {
1943
        self.ty.fulfill(DepNode::FieldTy(self.did), ty);
1944
    }
1945 1946
}

1947 1948
/// Records the substitutions used to translate the polytype for an
/// item into the monotype of an item reference.
1949
#[derive(Clone, RustcEncodable, RustcDecodable)]
1950
pub struct ItemSubsts<'tcx> {
1951
    pub substs: &'tcx Substs<'tcx>,
1952 1953
}

1954
#[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
1955
pub enum ClosureKind {
1956 1957 1958
    // 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.
1959 1960 1961
    Fn,
    FnMut,
    FnOnce,
1962 1963
}

1964 1965
impl<'a, 'tcx> ClosureKind {
    pub fn trait_did(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> DefId {
1966
        let result = match *self {
1967
            ClosureKind::Fn => tcx.lang_items.require(FnTraitLangItem),
1968
            ClosureKind::FnMut => {
1969
                tcx.lang_items.require(FnMutTraitLangItem)
1970
            }
1971
            ClosureKind::FnOnce => {
1972
                tcx.lang_items.require(FnOnceTraitLangItem)
1973 1974 1975 1976
            }
        };
        match result {
            Ok(trait_did) => trait_did,
1977
            Err(err) => tcx.sess.fatal(&err[..]),
1978 1979
        }
    }
1980 1981 1982 1983 1984

    /// True if this a type that impls this closure kind
    /// must also implement `other`.
    pub fn extends(self, other: ty::ClosureKind) -> bool {
        match (self, other) {
1985 1986 1987 1988 1989 1990
            (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,
1991 1992 1993
            _ => false,
        }
    }
1994 1995
}

1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008
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)
2009 2010
    }

2011 2012 2013 2014 2015
    /// Iterator that walks the immediate children of `self`.  Hence
    /// `Foo<Bar<i32>, u32>` yields the sequence `[Bar<i32>, u32]`
    /// (but not `i32`, like `walk`).
    pub fn walk_shallow(&'tcx self) -> IntoIter<Ty<'tcx>> {
        walk::walk_shallow(self)
2016 2017
    }

2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031
    /// Walks `ty` and any types appearing within `ty`, invoking the
    /// callback `f` on each type. If the callback returns false, then the
    /// children of the current type are ignored.
    ///
    /// Note: prefer `ty.walk()` where possible.
    pub fn maybe_walk<F>(&'tcx self, mut f: F)
        where F : FnMut(Ty<'tcx>) -> bool
    {
        let mut walker = self.walk();
        while let Some(ty) = walker.next() {
            if !f(ty) {
                walker.skip_current_subtree();
            }
        }
2032
    }
2033
}
2034

2035 2036 2037
impl<'tcx> ItemSubsts<'tcx> {
    pub fn is_noop(&self) -> bool {
        self.substs.is_noop()
A
Alex Crichton 已提交
2038
    }
2039
}
2040

2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum LvaluePreference {
    PreferMutLvalue,
    NoPreference
}

impl LvaluePreference {
    pub fn from_mutbl(m: hir::Mutability) -> Self {
        match m {
            hir::MutMutable => PreferMutLvalue,
            hir::MutImmutable => NoPreference,
        }
    }
}

2056
/// Helper for looking things up in the various maps that are populated during
2057
/// typeck::collect (e.g., `tcx.impl_or_trait_items`, `tcx.tcache`, etc).  All of
2058 2059 2060
/// these share the pattern that if the id is local, it should have been loaded
/// into the map by the `typeck::collect` phase.  If the def-id is external,
/// then we have to go consult the crate loading code (and cache the result for
S
Steve Klabnik 已提交
2061
/// the future).
2062
fn lookup_locally_or_in_crate_store<M, F>(descr: &str,
N
Niko Matsakis 已提交
2063
                                          def_id: DefId,
2064 2065 2066 2067 2068
                                          map: &M,
                                          load_external: F)
                                          -> M::Value where
    M: MemoizationMap<Key=DefId>,
    F: FnOnce() -> M::Value,
J
Jorge Aparicio 已提交
2069
{
2070 2071
    map.memoize(def_id, || {
        if def_id.is_local() {
2072
            bug!("No def'n found for {:?} in tcx.{}", def_id, descr);
2073 2074 2075
        }
        load_external()
    })
2076 2077
}

2078
impl BorrowKind {
2079
    pub fn from_mutbl(m: hir::Mutability) -> BorrowKind {
2080
        match m {
2081 2082
            hir::MutMutable => MutBorrow,
            hir::MutImmutable => ImmBorrow,
2083 2084
        }
    }
2085

2086 2087 2088 2089
    /// 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.
2090
    pub fn to_mutbl_lossy(self) -> hir::Mutability {
2091
        match self {
2092 2093
            MutBorrow => hir::MutMutable,
            ImmBorrow => hir::MutImmutable,
2094 2095 2096 2097

            // 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".
2098
            UniqueImmBorrow => hir::MutMutable,
2099
        }
2100
    }
2101

2102 2103 2104 2105 2106 2107
    pub fn to_user_str(&self) -> &'static str {
        match *self {
            MutBorrow => "mutable",
            ImmBorrow => "immutable",
            UniqueImmBorrow => "uniquely immutable",
        }
2108 2109 2110
    }
}

2111 2112
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
    pub fn node_id_to_type(self, id: NodeId) -> Ty<'gcx> {
2113 2114
        match self.node_id_to_type_opt(id) {
           Some(ty) => ty,
2115 2116
           None => bug!("node_id_to_type: no type for node `{}`",
                        self.map.node_to_string(id))
2117 2118
        }
    }
2119

2120
    pub fn node_id_to_type_opt(self, id: NodeId) -> Option<Ty<'gcx>> {
2121
        self.tables.borrow().node_types.get(&id).cloned()
2122
    }
2123

2124
    pub fn node_id_item_substs(self, id: NodeId) -> ItemSubsts<'gcx> {
2125
        match self.tables.borrow().item_substs.get(&id) {
2126
            None => ItemSubsts {
2127
                substs: Substs::empty(self.global_tcx())
2128
            },
2129 2130 2131
            Some(ts) => ts.clone(),
        }
    }
2132

2133 2134
    // Returns the type of a pattern as a monotype. Like @expr_ty, this function
    // doesn't provide type parameter substitutions.
2135
    pub fn pat_ty(self, pat: &hir::Pat) -> Ty<'gcx> {
2136 2137
        self.node_id_to_type(pat.id)
    }
2138
    pub fn pat_ty_opt(self, pat: &hir::Pat) -> Option<Ty<'gcx>> {
2139 2140
        self.node_id_to_type_opt(pat.id)
    }
2141

2142 2143 2144 2145 2146 2147 2148 2149 2150 2151
    // Returns the type of an expression as a monotype.
    //
    // NB (1): This is the PRE-ADJUSTMENT TYPE for the expression.  That is, in
    // some cases, we insert `AutoAdjustment` annotations such as auto-deref or
    // auto-ref.  The type returned by this function does not consider such
    // adjustments.  See `expr_ty_adjusted()` instead.
    //
    // NB (2): This type doesn't provide type parameter substitutions; e.g. if you
    // ask for the type of "id" in "id(3)", it will return "fn(&isize) -> isize"
    // instead of "fn(ty) -> T with T = isize".
2152
    pub fn expr_ty(self, expr: &hir::Expr) -> Ty<'gcx> {
2153
        self.node_id_to_type(expr.id)
2154
    }
2155

2156
    pub fn expr_ty_opt(self, expr: &hir::Expr) -> Option<Ty<'gcx>> {
2157
        self.node_id_to_type_opt(expr.id)
2158
    }
2159

2160 2161 2162 2163 2164 2165 2166 2167 2168
    /// Returns the type of `expr`, considering any `AutoAdjustment`
    /// entry recorded for that expression.
    ///
    /// It would almost certainly be better to store the adjusted ty in with
    /// the `AutoAdjustment`, but I opted not to do this because it would
    /// require serializing and deserializing the type and, although that's not
    /// hard to do, I just hate that code so much I didn't want to touch it
    /// unless it was to fix it properly, which seemed a distraction from the
    /// thread at hand! -nmatsakis
2169
    pub fn expr_ty_adjusted(self, expr: &hir::Expr) -> Ty<'gcx> {
2170
        self.expr_ty(expr)
2171
            .adjust(self.global_tcx(), expr.span, expr.id,
2172
                    self.tables.borrow().adjustments.get(&expr.id),
2173
                    |method_call| {
2174
            self.tables.borrow().method_map.get(&method_call).map(|method| method.ty)
2175 2176
        })
    }
2177

2178 2179
    pub fn expr_ty_adjusted_opt(self, expr: &hir::Expr) -> Option<Ty<'gcx>> {
        self.expr_ty_opt(expr).map(|t| t.adjust(self.global_tcx(),
2180 2181 2182 2183 2184 2185 2186 2187
                                                expr.span,
                                                expr.id,
                                                self.tables.borrow().adjustments.get(&expr.id),
                                                |method_call| {
            self.tables.borrow().method_map.get(&method_call).map(|method| method.ty)
        }))
    }

2188
    pub fn expr_span(self, id: NodeId) -> Span {
2189 2190 2191 2192 2193
        match self.map.find(id) {
            Some(ast_map::NodeExpr(e)) => {
                e.span
            }
            Some(f) => {
2194
                bug!("Node id {} is not an expr: {:?}", id, f);
2195 2196
            }
            None => {
2197
                bug!("Node id {} is not present in the node map", id);
2198
            }
2199
        }
2200 2201
    }

2202
    pub fn local_var_name_str(self, id: NodeId) -> InternedString {
2203 2204 2205
        match self.map.find(id) {
            Some(ast_map::NodeLocal(pat)) => {
                match pat.node {
2206
                    hir::PatKind::Binding(_, ref path1, _) => path1.node.as_str(),
2207
                    _ => {
2208
                        bug!("Variable id {} maps to {:?}, not local", id, pat);
2209
                    },
2210
                }
2211
            },
2212
            r => bug!("Variable id {} maps to {:?}, not local", id, r),
2213
        }
2214 2215
    }

2216
    pub fn expr_is_lval(self, expr: &hir::Expr) -> bool {
2217
         match expr.node {
2218
            hir::ExprPath(..) => {
2219 2220 2221 2222 2223 2224
                // This function can be used during type checking when not all paths are
                // fully resolved. Partially resolved paths in expressions can only legally
                // refer to associated items which are always rvalues.
                match self.expect_resolution(expr.id).base_def {
                    Def::Local(..) | Def::Upvar(..) | Def::Static(..) | Def::Err => true,
                    _ => false,
2225 2226
                }
            }
2227

2228 2229 2230 2231
            hir::ExprType(ref e, _) => {
                self.expr_is_lval(e)
            }

2232 2233 2234 2235
            hir::ExprUnary(hir::UnDeref, _) |
            hir::ExprField(..) |
            hir::ExprTupField(..) |
            hir::ExprIndex(..) => {
2236 2237 2238
                true
            }

2239 2240 2241 2242 2243 2244 2245 2246 2247
            hir::ExprCall(..) |
            hir::ExprMethodCall(..) |
            hir::ExprStruct(..) |
            hir::ExprTup(..) |
            hir::ExprIf(..) |
            hir::ExprMatch(..) |
            hir::ExprClosure(..) |
            hir::ExprBlock(..) |
            hir::ExprRepeat(..) |
2248
            hir::ExprArray(..) |
2249 2250 2251 2252 2253 2254 2255 2256 2257 2258
            hir::ExprBreak(..) |
            hir::ExprAgain(..) |
            hir::ExprRet(..) |
            hir::ExprWhile(..) |
            hir::ExprLoop(..) |
            hir::ExprAssign(..) |
            hir::ExprInlineAsm(..) |
            hir::ExprAssignOp(..) |
            hir::ExprLit(_) |
            hir::ExprUnary(..) |
2259 2260 2261 2262 2263
            hir::ExprBox(..) |
            hir::ExprAddrOf(..) |
            hir::ExprBinary(..) |
            hir::ExprCast(..) => {
                false
2264
            }
2265 2266 2267
        }
    }

2268
    pub fn provided_trait_methods(self, id: DefId) -> Vec<Rc<Method<'gcx>>> {
2269 2270
        self.impl_or_trait_items(id).iter().filter_map(|&def_id| {
            match self.impl_or_trait_item(def_id) {
2271 2272
                MethodTraitItem(ref m) if m.has_body => Some(m.clone()),
                _ => None
2273
            }
2274
        }).collect()
2275 2276
    }

2277
    pub fn trait_impl_polarity(self, id: DefId) -> hir::ImplPolarity {
2278 2279
        if let Some(id) = self.map.as_local_node_id(id) {
            match self.map.expect_item(id).node {
2280 2281
                hir::ItemImpl(_, polarity, ..) => polarity,
                ref item => bug!("trait_impl_polarity: {:?} not an impl", item)
2282 2283
            }
        } else {
2284
            self.sess.cstore.impl_polarity(id)
2285
        }
2286
    }
2287

2288
    pub fn custom_coerce_unsized_kind(self, did: DefId) -> adjustment::CustomCoerceUnsized {
2289
        self.custom_coerce_unsized_kinds.memoize(did, || {
N
Niko Matsakis 已提交
2290
            let (kind, src) = if did.krate != LOCAL_CRATE {
2291
                (self.sess.cstore.custom_coerce_unsized_kind(did), "external")
2292 2293 2294
            } else {
                (None, "local")
            };
2295

2296 2297 2298
            match kind {
                Some(kind) => kind,
                None => {
2299 2300 2301
                    bug!("custom_coerce_unsized_kind: \
                          {} impl `{}` is missing its kind",
                          src, self.item_path_str(did));
2302 2303 2304 2305 2306
                }
            }
        })
    }

2307
    pub fn impl_or_trait_item(self, id: DefId) -> ImplOrTraitItem<'gcx> {
2308 2309
        lookup_locally_or_in_crate_store(
            "impl_or_trait_items", id, &self.impl_or_trait_items,
2310
            || self.sess.cstore.impl_or_trait_item(self.global_tcx(), id)
2311
                   .expect("missing ImplOrTraitItem in metadata"))
2312 2313
    }

2314
    pub fn impl_or_trait_items(self, id: DefId) -> Rc<Vec<DefId>> {
2315
        lookup_locally_or_in_crate_store(
2316
            "impl_or_trait_items", id, &self.impl_or_trait_item_def_ids,
2317
            || Rc::new(self.sess.cstore.impl_or_trait_items(id)))
2318 2319 2320 2321
    }

    /// Returns the trait-ref corresponding to a given impl, or None if it is
    /// an inherent impl.
2322
    pub fn impl_trait_ref(self, id: DefId) -> Option<TraitRef<'gcx>> {
2323 2324
        lookup_locally_or_in_crate_store(
            "impl_trait_refs", id, &self.impl_trait_refs,
2325
            || self.sess.cstore.impl_trait_ref(self.global_tcx(), id))
2326 2327
    }

2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341
    /// Returns a path resolution for node id if it exists, panics otherwise.
    pub fn expect_resolution(self, id: NodeId) -> PathResolution {
        *self.def_map.borrow().get(&id).expect("no def-map entry for node id")
    }

    /// Returns a fully resolved definition for node id if it exists, panics otherwise.
    pub fn expect_def(self, id: NodeId) -> Def {
        self.expect_resolution(id).full_def()
    }

    /// Returns a fully resolved definition for node id if it exists, or none if no
    /// definition exists, panics on partial resolutions to catch errors.
    pub fn expect_def_or_none(self, id: NodeId) -> Option<Def> {
        self.def_map.borrow().get(&id).map(|resolution| resolution.full_def())
2342
    }
2343

2344 2345 2346 2347
    // Returns `ty::VariantDef` if `def` refers to a struct,
    // or variant or their constructors, panics otherwise.
    pub fn expect_variant_def(self, def: Def) -> VariantDef<'tcx> {
        match def {
2348
            Def::Variant(did) | Def::VariantCtor(did, ..) => {
2349
                let enum_did = self.parent_def_id(did).unwrap();
2350 2351
                self.lookup_adt_def(enum_did).variant_with_id(did)
            }
2352 2353 2354 2355 2356
            Def::Struct(did) | Def::Union(did) => {
                self.lookup_adt_def(did).struct_variant()
            }
            Def::StructCtor(ctor_did, ..) => {
                let did = self.parent_def_id(ctor_did).expect("struct ctor has no parent");
2357 2358 2359 2360 2361 2362
                self.lookup_adt_def(did).struct_variant()
            }
            _ => bug!("expect_variant_def used with unexpected def {:?}", def)
        }
    }

2363
    pub fn def_key(self, id: DefId) -> ast_map::DefKey {
2364 2365 2366 2367 2368
        if id.is_local() {
            self.map.def_key(id)
        } else {
            self.sess.cstore.def_key(id)
        }
2369 2370
    }

2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381
    /// Convert a `DefId` into its fully expanded `DefPath` (every
    /// `DefId` is really just an interned def-path).
    ///
    /// Note that if `id` is not local to this crate -- or is
    /// inlined into this crate -- the result will be a non-local
    /// `DefPath`.
    ///
    /// This function is only safe to use when you are sure that the
    /// full def-path is accessible. Examples that are known to be
    /// safe are local def-ids or items; see `opt_def_path` for more
    /// details.
2382
    pub fn def_path(self, id: DefId) -> ast_map::DefPath {
2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403
        self.opt_def_path(id).unwrap_or_else(|| {
            bug!("could not load def-path for {:?}", id)
        })
    }

    /// Convert a `DefId` into its fully expanded `DefPath` (every
    /// `DefId` is really just an interned def-path).
    ///
    /// When going across crates, we do not save the full info for
    /// every cross-crate def-id, and hence we may not always be able
    /// to create a def-path. Therefore, this returns
    /// `Option<DefPath>` to cover that possibility. It will always
    /// return `Some` for local def-ids, however, as well as for
    /// items. The problems arise with "minor" def-ids like those
    /// associated with a pattern, `impl Trait`, or other internal
    /// detail to a fn.
    ///
    /// Note that if `id` is not local to this crate -- or is
    /// inlined into this crate -- the result will be a non-local
    /// `DefPath`.
    pub fn opt_def_path(self, id: DefId) -> Option<ast_map::DefPath> {
2404
        if id.is_local() {
2405
            Some(self.map.def_path(id))
2406
        } else {
2407
            self.sess.cstore.relative_def_path(id)
2408 2409 2410
        }
    }

2411
    pub fn item_name(self, id: DefId) -> ast::Name {
2412
        if let Some(id) = self.map.as_local_node_id(id) {
2413
            self.map.name(id)
2414 2415
        } else if id.index == CRATE_DEF_INDEX {
            token::intern(&self.sess.cstore.original_crate_name(id.krate))
2416
        } else {
2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428
            let def_key = self.sess.cstore.def_key(id);
            // The name of a StructCtor is that of its struct parent.
            if let ast_map::DefPathData::StructCtor = def_key.disambiguated_data.data {
                self.item_name(DefId {
                    krate: id.krate,
                    index: def_key.parent.unwrap()
                })
            } else {
                def_key.disambiguated_data.data.get_opt_name().unwrap_or_else(|| {
                    bug!("item_name: no name for {:?}", self.def_path(id));
                })
            }
2429 2430 2431
        }
    }

2432
    // Register a given item type
2433 2434 2435
    pub fn register_item_type(self, did: DefId, scheme: TypeScheme<'gcx>) {
        self.tcache.borrow_mut().insert(did, scheme.ty);
        self.generics.borrow_mut().insert(did, scheme.generics);
2436
    }
2437

2438 2439
    // If the given item is in an external crate, looks up its type and adds it to
    // the type cache. Returns the type parameters and type.
2440
    pub fn lookup_item_type(self, did: DefId) -> TypeScheme<'gcx> {
2441
        let ty = lookup_locally_or_in_crate_store(
2442
            "tcache", did, &self.tcache,
2443 2444 2445 2446 2447 2448
            || self.sess.cstore.item_type(self.global_tcx(), did));

        TypeScheme {
            ty: ty,
            generics: self.lookup_generics(did)
        }
2449
    }
T
Tim Chevalier 已提交
2450

A
Ariel Ben-Yehuda 已提交
2451
    pub fn opt_lookup_item_type(self, did: DefId) -> Option<TypeScheme<'gcx>> {
2452 2453
        if did.krate != LOCAL_CRATE {
            return Some(self.lookup_item_type(did));
A
Ariel Ben-Yehuda 已提交
2454 2455
        }

2456 2457 2458 2459 2460
        if let Some(ty) = self.tcache.borrow().get(&did).cloned() {
            Some(TypeScheme {
                ty: ty,
                generics: self.lookup_generics(did)
            })
A
Ariel Ben-Yehuda 已提交
2461
        } else {
2462
            None
A
Ariel Ben-Yehuda 已提交
2463 2464 2465
        }
    }

2466
    /// Given the did of a trait, returns its canonical trait ref.
2467
    pub fn lookup_trait_def(self, did: DefId) -> &'gcx TraitDef<'gcx> {
2468 2469
        lookup_locally_or_in_crate_store(
            "trait_defs", did, &self.trait_defs,
2470
            || self.alloc_trait_def(self.sess.cstore.trait_def(self.global_tcx(), did))
2471 2472
        )
    }
2473

A
Ariel Ben-Yehuda 已提交
2474 2475 2476
    /// Given the did of an ADT, return a master reference to its
    /// definition. Unless you are planning on fulfilling the ADT's fields,
    /// use lookup_adt_def instead.
2477
    pub fn lookup_adt_def_master(self, did: DefId) -> AdtDefMaster<'gcx> {
2478 2479
        lookup_locally_or_in_crate_store(
            "adt_defs", did, &self.adt_defs,
2480
            || self.sess.cstore.adt_def(self.global_tcx(), did)
2481 2482 2483
        )
    }

A
Ariel Ben-Yehuda 已提交
2484
    /// Given the did of an ADT, return a reference to its definition.
2485
    pub fn lookup_adt_def(self, did: DefId) -> AdtDef<'gcx> {
A
Ariel Ben-Yehuda 已提交
2486
        // when reverse-variance goes away, a transmute::<AdtDefMaster,AdtDef>
C
Carlos E. Garcia 已提交
2487
        // would be needed here.
A
Ariel Ben-Yehuda 已提交
2488 2489 2490
        self.lookup_adt_def_master(did)
    }

2491 2492 2493 2494
    /// Given the did of an item, returns its generics.
    pub fn lookup_generics(self, did: DefId) -> &'gcx Generics<'gcx> {
        lookup_locally_or_in_crate_store(
            "generics", did, &self.generics,
2495
            || self.alloc_generics(self.sess.cstore.item_generics(self.global_tcx(), did)))
2496 2497
    }

2498
    /// Given the did of an item, returns its full set of predicates.
2499
    pub fn lookup_predicates(self, did: DefId) -> GenericPredicates<'gcx> {
2500 2501
        lookup_locally_or_in_crate_store(
            "predicates", did, &self.predicates,
2502
            || self.sess.cstore.item_predicates(self.global_tcx(), did))
2503
    }
2504

2505
    /// Given the did of a trait, returns its superpredicates.
2506
    pub fn lookup_super_predicates(self, did: DefId) -> GenericPredicates<'gcx> {
2507 2508
        lookup_locally_or_in_crate_store(
            "super_predicates", did, &self.super_predicates,
2509
            || self.sess.cstore.item_super_predicates(self.global_tcx(), did))
2510
    }
2511

2512 2513 2514 2515 2516 2517
    /// If `type_needs_drop` returns true, then `ty` is definitely
    /// non-copy and *might* have a destructor attached; if it returns
    /// false, then `ty` definitely has no destructor (i.e. no drop glue).
    ///
    /// (Note that this implies that if `ty` has a destructor attached,
    /// then `type_needs_drop` will definitely return `true` for `ty`.)
2518
    pub fn type_needs_drop_given_env(self,
2519 2520
                                     ty: Ty<'gcx>,
                                     param_env: &ty::ParameterEnvironment<'gcx>) -> bool {
2521 2522 2523 2524
        // Issue #22536: We first query type_moves_by_default.  It sees a
        // normalized version of the type, and therefore will definitely
        // know whether the type implements Copy (and thus needs no
        // cleanup/drop/zeroing) ...
2525 2526
        let tcx = self.global_tcx();
        let implements_copy = !ty.moves_by_default(tcx, param_env, DUMMY_SP);
2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540

        if implements_copy { return false; }

        // ... (issue #22536 continued) but as an optimization, still use
        // prior logic of asking if the `needs_drop` bit is set; we need
        // not zero non-Copy types if they have no destructor.

        // FIXME(#22815): Note that calling `ty::type_contents` is a
        // conservative heuristic; it may report that `needs_drop` is set
        // when actual type does not actually have a destructor associated
        // with it. But since `ty` absolutely did not have the `Copy`
        // bound attached (see above), it is sound to treat it as having a
        // destructor (e.g. zero its memory on move).

2541
        let contents = ty.type_contents(tcx);
2542
        debug!("type_needs_drop ty={:?} contents={:?}", ty, contents);
2543
        contents.needs_drop(tcx)
2544 2545
    }

2546
    /// Get the attributes of a definition.
2547
    pub fn get_attrs(self, did: DefId) -> Cow<'gcx, [ast::Attribute]> {
2548 2549
        if let Some(id) = self.map.as_local_node_id(did) {
            Cow::Borrowed(self.map.attrs(id))
2550
        } else {
2551
            Cow::Owned(self.sess.cstore.item_attrs(did))
2552
        }
2553 2554
    }

2555
    /// Determine whether an item is annotated with an attribute
2556
    pub fn has_attr(self, did: DefId, attr: &str) -> bool {
2557 2558
        self.get_attrs(did).iter().any(|item| item.check_name(attr))
    }
2559

2560
    /// Determine whether an item is annotated with `#[repr(packed)]`
2561
    pub fn lookup_packed(self, did: DefId) -> bool {
2562 2563
        self.lookup_repr_hints(did).contains(&attr::ReprPacked)
    }
2564

2565
    /// Determine whether an item is annotated with `#[simd]`
2566
    pub fn lookup_simd(self, did: DefId) -> bool {
2567
        self.has_attr(did, "simd")
2568
            || self.lookup_repr_hints(did).contains(&attr::ReprSimd)
2569
    }
S
Seo Sanghyeon 已提交
2570

2571
    pub fn item_variances(self, item_id: DefId) -> Rc<Vec<ty::Variance>> {
2572 2573
        lookup_locally_or_in_crate_store(
            "item_variance_map", item_id, &self.item_variance_map,
2574
            || Rc::new(self.sess.cstore.item_variances(item_id)))
2575
    }
2576

2577
    pub fn trait_has_default_impl(self, trait_def_id: DefId) -> bool {
2578
        self.populate_implementations_for_trait_if_necessary(trait_def_id);
2579

2580 2581
        let def = self.lookup_trait_def(trait_def_id);
        def.flags.get().intersects(TraitFlags::HAS_DEFAULT_IMPL)
2582
    }
2583

2584
    /// Records a trait-to-implementation mapping.
2585
    pub fn record_trait_has_default_impl(self, trait_def_id: DefId) {
2586 2587
        let def = self.lookup_trait_def(trait_def_id);
        def.flags.set(def.flags.get() | TraitFlags::HAS_DEFAULT_IMPL)
2588 2589
    }

2590
    /// Load primitive inherent implementations if necessary
2591
    pub fn populate_implementations_for_primitive_if_necessary(self,
N
Niko Matsakis 已提交
2592
                                                               primitive_def_id: DefId) {
2593
        if primitive_def_id.is_local() {
2594 2595
            return
        }
2596

2597 2598 2599 2600
        // The primitive is not local, hence we are reading this out
        // of metadata.
        let _ignore = self.dep_graph.in_ignore();

2601 2602 2603
        if self.populated_external_primitive_impls.borrow().contains(&primitive_def_id) {
            return
        }
2604

2605 2606
        debug!("populate_implementations_for_primitive_if_necessary: searching for {:?}",
               primitive_def_id);
2607

2608
        let impl_items = self.sess.cstore.impl_or_trait_items(primitive_def_id);
2609

2610
        // Store the implementation info.
2611
        self.impl_or_trait_item_def_ids.borrow_mut().insert(primitive_def_id, Rc::new(impl_items));
2612
        self.populated_external_primitive_impls.borrow_mut().insert(primitive_def_id);
2613 2614
    }

2615 2616
    /// Populates the type context with all the inherent implementations for
    /// the given type if necessary.
2617
    pub fn populate_inherent_implementations_for_type_if_necessary(self,
N
Niko Matsakis 已提交
2618
                                                                   type_id: DefId) {
2619
        if type_id.is_local() {
2620 2621 2622
            return
        }

2623 2624 2625 2626
        // The type is not local, hence we are reading this out of
        // metadata and don't need to track edges.
        let _ignore = self.dep_graph.in_ignore();

2627 2628 2629
        if self.populated_external_types.borrow().contains(&type_id) {
            return
        }
2630

2631 2632
        debug!("populate_inherent_implementations_for_type_if_necessary: searching for {:?}",
               type_id);
2633

2634 2635
        let inherent_impls = self.sess.cstore.inherent_implementations_for_type(type_id);
        for &impl_def_id in &inherent_impls {
2636
            // Store the implementation info.
2637
            let impl_items = self.sess.cstore.impl_or_trait_items(impl_def_id);
2638
            self.impl_or_trait_item_def_ids.borrow_mut().insert(impl_def_id, Rc::new(impl_items));
2639
        }
2640

2641
        self.inherent_impls.borrow_mut().insert(type_id, inherent_impls);
2642
        self.populated_external_types.borrow_mut().insert(type_id);
2643
    }
2644

2645 2646
    /// Populates the type context with all the implementations for the given
    /// trait if necessary.
2647
    pub fn populate_implementations_for_trait_if_necessary(self, trait_id: DefId) {
2648
        if trait_id.is_local() {
2649 2650
            return
        }
2651

2652 2653 2654 2655
        // The type is not local, hence we are reading this out of
        // metadata and don't need to track edges.
        let _ignore = self.dep_graph.in_ignore();

2656 2657 2658 2659
        let def = self.lookup_trait_def(trait_id);
        if def.flags.get().intersects(TraitFlags::IMPLS_VALID) {
            return;
        }
2660

2661
        debug!("populate_implementations_for_trait_if_necessary: searching for {:?}", def);
2662

2663
        if self.sess.cstore.is_defaulted_trait(trait_id) {
2664 2665 2666
            self.record_trait_has_default_impl(trait_id);
        }

2667 2668
        for impl_def_id in self.sess.cstore.implementations_of_trait(Some(trait_id)) {
            let impl_items = self.sess.cstore.impl_or_trait_items(impl_def_id);
2669
            let trait_ref = self.impl_trait_ref(impl_def_id).unwrap();
2670

2671
            // Record the trait->implementation mapping.
2672 2673
            let parent = self.sess.cstore.impl_parent(impl_def_id).unwrap_or(trait_id);
            def.record_remote_impl(self, impl_def_id, trait_ref, parent);
2674

2675 2676
            // For any methods that use a default implementation, add them to
            // the map. This is a bit unfortunate.
2677
            for &impl_item_def_id in &impl_items {
2678 2679
                // load impl items eagerly for convenience
                // FIXME: we may want to load these lazily
2680
                self.impl_or_trait_item(impl_item_def_id);
2681 2682
            }

2683
            // Store the implementation info.
2684
            self.impl_or_trait_item_def_ids.borrow_mut().insert(impl_def_id, Rc::new(impl_items));
2685
        }
2686

2687 2688
        def.flags.set(def.flags.get() | TraitFlags::IMPLS_VALID);
    }
2689

2690
    pub fn closure_kind(self, def_id: DefId) -> ty::ClosureKind {
2691 2692 2693 2694 2695 2696 2697 2698 2699 2700
        // If this is a local def-id, it should be inserted into the
        // tables by typeck; else, it will be retreived from
        // the external crate metadata.
        if let Some(&kind) = self.tables.borrow().closure_kinds.get(&def_id) {
            return kind;
        }

        let kind = self.sess.cstore.closure_kind(def_id);
        self.tables.borrow_mut().closure_kinds.insert(def_id, kind);
        kind
2701 2702
    }

2703
    pub fn closure_type(self,
2704
                        def_id: DefId,
2705 2706
                        substs: ClosureSubsts<'tcx>)
                        -> ty::ClosureTy<'tcx>
2707
    {
2708 2709 2710 2711 2712 2713 2714 2715 2716 2717
        // If this is a local def-id, it should be inserted into the
        // tables by typeck; else, it will be retreived from
        // the external crate metadata.
        if let Some(ty) = self.tables.borrow().closure_tys.get(&def_id) {
            return ty.subst(self, substs.func_substs);
        }

        let ty = self.sess.cstore.closure_ty(self.global_tcx(), def_id);
        self.tables.borrow_mut().closure_tys.insert(def_id, ty.clone());
        ty.subst(self, substs.func_substs)
2718 2719
    }

2720 2721
    /// Given the def_id of an impl, return the def_id of the trait it implements.
    /// If it implements no trait, return `None`.
2722
    pub fn trait_id_of_impl(self, def_id: DefId) -> Option<DefId> {
2723
        self.impl_trait_ref(def_id).map(|tr| tr.def_id)
2724
    }
2725 2726 2727

    /// If the given def ID describes a method belonging to an impl, return the
    /// ID of the impl that the method belongs to. Otherwise, return `None`.
2728
    pub fn impl_of_method(self, def_id: DefId) -> Option<DefId> {
2729
        if def_id.krate != LOCAL_CRATE {
2730 2731
            return self.sess.cstore.impl_or_trait_item(self.global_tcx(), def_id)
                       .and_then(|item| {
2732 2733 2734 2735 2736
                match item.container() {
                    TraitContainer(_) => None,
                    ImplContainer(def_id) => Some(def_id),
                }
            });
2737
        }
2738 2739 2740 2741 2742 2743
        match self.impl_or_trait_items.borrow().get(&def_id).cloned() {
            Some(trait_item) => {
                match trait_item.container() {
                    TraitContainer(_) => None,
                    ImplContainer(def_id) => Some(def_id),
                }
2744
            }
2745
            None => None
2746 2747 2748
        }
    }

2749 2750 2751
    /// If the given def ID describes an item belonging to a trait,
    /// return the ID of the trait that the trait item belongs to.
    /// Otherwise, return `None`.
2752
    pub fn trait_of_item(self, def_id: DefId) -> Option<DefId> {
2753
        if def_id.krate != LOCAL_CRATE {
2754
            return self.sess.cstore.trait_of_item(def_id);
2755
        }
2756
        match self.impl_or_trait_items.borrow().get(&def_id) {
2757 2758 2759
            Some(impl_or_trait_item) => {
                match impl_or_trait_item.container() {
                    TraitContainer(def_id) => Some(def_id),
2760
                    ImplContainer(_) => None
2761
                }
A
Alex Crichton 已提交
2762
            }
2763 2764 2765 2766 2767 2768 2769 2770 2771 2772
            None => None
        }
    }

    /// If the given def ID describes an item belonging to a trait, (either a
    /// default method or an implementation of a trait method), return the ID of
    /// the method inside trait definition (this means that if the given def ID
    /// is already that of the original trait method, then the return value is
    /// the same).
    /// Otherwise, return `None`.
2773
    pub fn trait_item_of_item(self, def_id: DefId) -> Option<DefId> {
2774
        let impl_or_trait_item = match self.impl_or_trait_items.borrow().get(&def_id) {
2775 2776
            Some(m) => m.clone(),
            None => return None,
2777
        };
2778
        match impl_or_trait_item.container() {
2779
            TraitContainer(_) => Some(impl_or_trait_item.def_id()),
2780 2781 2782 2783 2784
            ImplContainer(def_id) => {
                self.trait_id_of_impl(def_id).and_then(|trait_did| {
                    let name = impl_or_trait_item.name();
                    self.trait_items(trait_did).iter()
                        .find(|item| item.name() == name)
2785
                        .map(|item| item.def_id())
2786
                })
2787 2788 2789 2790 2791 2792
            }
        }
    }

    /// Construct a parameter environment suitable for static contexts or other contexts where there
    /// are no free type/lifetime parameters in scope.
2793
    pub fn empty_parameter_environment(self) -> ParameterEnvironment<'tcx> {
2794 2795 2796 2797

        // for an empty parameter environment, there ARE no free
        // regions, so it shouldn't matter what we use for the free id
        let free_id_outlive = self.region_maps.node_extent(ast::DUMMY_NODE_ID);
2798
        ty::ParameterEnvironment {
2799
            free_substs: Substs::empty(self),
2800
            caller_bounds: Vec::new(),
2801
            implicit_region_bound: self.mk_region(ty::ReEmpty),
2802 2803 2804
            free_id_outlive: free_id_outlive,
            is_copy_cache: RefCell::new(FnvHashMap()),
            is_sized_cache: RefCell::new(FnvHashMap()),
2805
        }
2806 2807 2808 2809 2810 2811 2812
    }

    /// Constructs and returns a substitution that can be applied to move from
    /// the "outer" view of a type or method to the "inner" view.
    /// In general, this means converting from bound parameters to
    /// free parameters. Since we currently represent bound/free type
    /// parameters in the same way, this only has an effect on regions.
2813 2814 2815 2816 2817 2818
    pub fn construct_free_substs(self, def_id: DefId,
                                 free_id_outlive: CodeExtent)
                                 -> &'gcx Substs<'gcx> {

        let substs = Substs::for_item(self.global_tcx(), def_id, |def, _| {
            // map bound 'a => free 'a
2819 2820 2821 2822
            self.global_tcx().mk_region(ReFree(FreeRegion {
                scope: free_id_outlive,
                bound_region: def.to_bound_region()
            }))
2823 2824
        }, |def, _| {
            // map T => T
2825 2826
            self.global_tcx().mk_param_from_def(def)
        });
2827

2828 2829
        debug!("construct_parameter_environment: {:?}", substs);
        substs
2830
    }
2831

2832 2833
    /// See `ParameterEnvironment` struct def'n for details.
    /// If you were using `free_id: NodeId`, you might try `self.region_maps.item_extent(free_id)`
E
Eitan Adler 已提交
2834
    /// for the `free_id_outlive` parameter. (But note that this is not always quite right.)
2835 2836
    pub fn construct_parameter_environment(self,
                                           span: Span,
2837
                                           def_id: DefId,
2838
                                           free_id_outlive: CodeExtent)
2839
                                           -> ParameterEnvironment<'gcx>
2840 2841 2842 2843
    {
        //
        // Construct the free substs.
        //
2844

2845
        let free_substs = self.construct_free_substs(def_id, free_id_outlive);
2846

2847 2848 2849
        //
        // Compute the bounds on Self and the type parameters.
        //
2850

2851
        let tcx = self.global_tcx();
2852 2853
        let generic_predicates = tcx.lookup_predicates(def_id);
        let bounds = generic_predicates.instantiate(tcx, free_substs);
2854
        let bounds = tcx.liberate_late_bound_regions(free_id_outlive, &ty::Binder(bounds));
2855
        let predicates = bounds.predicates;
2856

2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868
        // 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.
        //
2869

2870
        let unnormalized_env = ty::ParameterEnvironment {
2871
            free_substs: free_substs,
2872
            implicit_region_bound: tcx.mk_region(ty::ReScope(free_id_outlive)),
2873
            caller_bounds: predicates,
2874
            free_id_outlive: free_id_outlive,
2875 2876
            is_copy_cache: RefCell::new(FnvHashMap()),
            is_sized_cache: RefCell::new(FnvHashMap()),
2877
        };
2878

2879
        let cause = traits::ObligationCause::misc(span, free_id_outlive.node_id(&self.region_maps));
2880
        traits::normalize_param_env_or_error(tcx, unnormalized_env, cause)
2881
    }
2882

2883 2884 2885 2886
    pub fn node_scope_region(self, id: NodeId) -> &'tcx Region {
        self.mk_region(ty::ReScope(self.region_maps.node_extent(id)))
    }

2887
    pub fn is_method_call(self, expr_id: NodeId) -> bool {
2888
        self.tables.borrow().method_map.contains_key(&MethodCall::expr(expr_id))
2889
    }
2890

2891
    pub fn is_overloaded_autoderef(self, expr_id: NodeId, autoderefs: u32) -> bool {
2892 2893 2894 2895
        self.tables.borrow().method_map.contains_key(&MethodCall::autoderef(expr_id,
                                                                            autoderefs))
    }

2896
    pub fn upvar_capture(self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture<'tcx>> {
2897
        Some(self.tables.borrow().upvar_capture_map.get(&upvar_id).unwrap().clone())
2898
    }
2899

2900
    pub fn visit_all_items_in_krate<V,F>(self,
2901 2902
                                         dep_node_fn: F,
                                         visitor: &mut V)
2903
        where F: FnMut(DefId) -> DepNode<DefId>, V: Visitor<'gcx>
2904
    {
2905
        dep_graph::visit_all_items_in_krate(self.global_tcx(), dep_node_fn, visitor);
2906
    }
2907

2908 2909
    /// Looks up the span of `impl_did` if the impl is local; otherwise returns `Err`
    /// with the name of the crate containing the impl.
2910
    pub fn span_of_impl(self, impl_did: DefId) -> Result<Span, InternedString> {
2911 2912 2913 2914
        if impl_did.is_local() {
            let node_id = self.map.as_local_node_id(impl_did).unwrap();
            Ok(self.map.span(node_id))
        } else {
2915
            Err(self.sess.cstore.crate_name(impl_did.krate))
2916 2917
        }
    }
2918
}
2919

2920
/// The category of explicit self.
2921
#[derive(Clone, Copy, Eq, PartialEq, Debug, RustcEncodable, RustcDecodable)]
2922
pub enum ExplicitSelfCategory<'tcx> {
2923 2924
    Static,
    ByValue,
2925
    ByReference(&'tcx Region, hir::Mutability),
2926
    ByBox,
2927 2928
}

2929
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
2930
    pub fn with_freevars<T, F>(self, fid: NodeId, f: F) -> T where
2931
        F: FnOnce(&[hir::Freevar]) -> T,
2932 2933 2934 2935 2936 2937
    {
        match self.freevars.borrow().get(&fid) {
            None => f(&[]),
            Some(d) => f(&d[..])
        }
    }
2938
}