]> git.lizzy.rs Git - rust.git/blob - src/librustc/ty/instance.rs
Auto merge of #43028 - michaelwoerister:dedup-dep-nodes, r=nikomatsakis
[rust.git] / src / librustc / ty / instance.rs
1 // Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 use hir::def_id::DefId;
12 use ty::{self, Ty, TypeFoldable, Substs};
13 use util::ppaux;
14
15 use std::fmt;
16
17 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
18 pub struct Instance<'tcx> {
19     pub def: InstanceDef<'tcx>,
20     pub substs: &'tcx Substs<'tcx>,
21 }
22
23 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
24 pub enum InstanceDef<'tcx> {
25     Item(DefId),
26     Intrinsic(DefId),
27     // <fn() as FnTrait>::call_*
28     // def-id is FnTrait::call_*
29     FnPtrShim(DefId, Ty<'tcx>),
30     // <Trait as Trait>::fn
31     Virtual(DefId, usize),
32     // <[mut closure] as FnOnce>::call_once
33     ClosureOnceShim { call_once: DefId },
34     // drop_in_place::<T>; None for empty drop glue.
35     DropGlue(DefId, Option<Ty<'tcx>>),
36 }
37
38 impl<'tcx> InstanceDef<'tcx> {
39     #[inline]
40     pub fn def_id(&self) -> DefId {
41         match *self {
42             InstanceDef::Item(def_id) |
43             InstanceDef::FnPtrShim(def_id, _) |
44             InstanceDef::Virtual(def_id, _) |
45             InstanceDef::Intrinsic(def_id, ) |
46             InstanceDef::ClosureOnceShim { call_once: def_id }
47                 => def_id,
48             InstanceDef::DropGlue(def_id, _) => def_id
49         }
50     }
51
52     #[inline]
53     pub fn def_ty<'a>(&self, tcx: ty::TyCtxt<'a, 'tcx, 'tcx>) -> Ty<'tcx> {
54         tcx.type_of(self.def_id())
55     }
56
57     #[inline]
58     pub fn attrs<'a>(&self, tcx: ty::TyCtxt<'a, 'tcx, 'tcx>) -> ty::Attributes<'tcx> {
59         tcx.get_attrs(self.def_id())
60     }
61 }
62
63 impl<'tcx> fmt::Display for Instance<'tcx> {
64     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
65         ppaux::parameterized(f, self.substs, self.def_id(), &[])?;
66         match self.def {
67             InstanceDef::Item(_) => Ok(()),
68             InstanceDef::Intrinsic(_) => {
69                 write!(f, " - intrinsic")
70             }
71             InstanceDef::Virtual(_, num) => {
72                 write!(f, " - shim(#{})", num)
73             }
74             InstanceDef::FnPtrShim(_, ty) => {
75                 write!(f, " - shim({:?})", ty)
76             }
77             InstanceDef::ClosureOnceShim { .. } => {
78                 write!(f, " - shim")
79             }
80             InstanceDef::DropGlue(_, ty) => {
81                 write!(f, " - shim({:?})", ty)
82             }
83         }
84     }
85 }
86
87 impl<'a, 'b, 'tcx> Instance<'tcx> {
88     pub fn new(def_id: DefId, substs: &'tcx Substs<'tcx>)
89                -> Instance<'tcx> {
90         assert!(substs.is_normalized_for_trans() && !substs.has_escaping_regions(),
91                 "substs of instance {:?} not normalized for trans: {:?}",
92                 def_id, substs);
93         Instance { def: InstanceDef::Item(def_id), substs: substs }
94     }
95
96     pub fn mono(tcx: ty::TyCtxt<'a, 'tcx, 'b>, def_id: DefId) -> Instance<'tcx> {
97         Instance::new(def_id, tcx.global_tcx().empty_substs_for_def_id(def_id))
98     }
99
100     #[inline]
101     pub fn def_id(&self) -> DefId {
102         self.def.def_id()
103     }
104 }