]> git.lizzy.rs Git - rust.git/blob - src/librustc/ty/instance.rs
Rollup merge of #44606 - alexcrichton:update-cmake, r=Mark-Simulacrum
[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, TyCtxt};
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
28     /// <fn() as FnTrait>::call_*
29     /// def-id is FnTrait::call_*
30     FnPtrShim(DefId, Ty<'tcx>),
31
32     /// <Trait as Trait>::fn
33     Virtual(DefId, usize),
34
35     /// <[mut closure] as FnOnce>::call_once
36     ClosureOnceShim { call_once: DefId },
37
38     /// drop_in_place::<T>; None for empty drop glue.
39     DropGlue(DefId, Option<Ty<'tcx>>),
40
41     /// Builtin method implementation, e.g. `Clone::clone`.
42     CloneShim(DefId, Ty<'tcx>),
43 }
44
45 impl<'tcx> InstanceDef<'tcx> {
46     #[inline]
47     pub fn def_id(&self) -> DefId {
48         match *self {
49             InstanceDef::Item(def_id) |
50             InstanceDef::FnPtrShim(def_id, _) |
51             InstanceDef::Virtual(def_id, _) |
52             InstanceDef::Intrinsic(def_id, ) |
53             InstanceDef::ClosureOnceShim { call_once: def_id } |
54             InstanceDef::DropGlue(def_id, _) |
55             InstanceDef::CloneShim(def_id, _) => def_id
56         }
57     }
58
59     #[inline]
60     pub fn def_ty<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Ty<'tcx> {
61         tcx.type_of(self.def_id())
62     }
63
64     #[inline]
65     pub fn attrs<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> ty::Attributes<'tcx> {
66         tcx.get_attrs(self.def_id())
67     }
68 }
69
70 impl<'tcx> fmt::Display for Instance<'tcx> {
71     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
72         ppaux::parameterized(f, self.substs, self.def_id(), &[])?;
73         match self.def {
74             InstanceDef::Item(_) => Ok(()),
75             InstanceDef::Intrinsic(_) => {
76                 write!(f, " - intrinsic")
77             }
78             InstanceDef::Virtual(_, num) => {
79                 write!(f, " - shim(#{})", num)
80             }
81             InstanceDef::FnPtrShim(_, ty) => {
82                 write!(f, " - shim({:?})", ty)
83             }
84             InstanceDef::ClosureOnceShim { .. } => {
85                 write!(f, " - shim")
86             }
87             InstanceDef::DropGlue(_, ty) => {
88                 write!(f, " - shim({:?})", ty)
89             }
90             InstanceDef::CloneShim(_, ty) => {
91                 write!(f, " - shim({:?})", ty)
92             }
93         }
94     }
95 }
96
97 impl<'a, 'b, 'tcx> Instance<'tcx> {
98     pub fn new(def_id: DefId, substs: &'tcx Substs<'tcx>)
99                -> Instance<'tcx> {
100         assert!(substs.is_normalized_for_trans() && !substs.has_escaping_regions(),
101                 "substs of instance {:?} not normalized for trans: {:?}",
102                 def_id, substs);
103         Instance { def: InstanceDef::Item(def_id), substs: substs }
104     }
105
106     pub fn mono(tcx: TyCtxt<'a, 'tcx, 'b>, def_id: DefId) -> Instance<'tcx> {
107         Instance::new(def_id, tcx.global_tcx().empty_substs_for_def_id(def_id))
108     }
109
110     #[inline]
111     pub fn def_id(&self) -> DefId {
112         self.def.def_id()
113     }
114 }