]> git.lizzy.rs Git - rust.git/blob - src/librustc/ty/instance.rs
Auto merge of #42430 - nagisa:core-float, r=alexcrichton
[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 dep_graph::DepConstructor;
12 use hir::def_id::DefId;
13 use ty::{self, Ty, TypeFoldable, Substs};
14 use util::ppaux;
15
16 use std::fmt;
17
18 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
19 pub struct Instance<'tcx> {
20     pub def: InstanceDef<'tcx>,
21     pub substs: &'tcx Substs<'tcx>,
22 }
23
24 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
25 pub enum InstanceDef<'tcx> {
26     Item(DefId),
27     Intrinsic(DefId),
28     // <fn() as FnTrait>::call_*
29     // def-id is FnTrait::call_*
30     FnPtrShim(DefId, Ty<'tcx>),
31     // <Trait as Trait>::fn
32     Virtual(DefId, usize),
33     // <[mut closure] as FnOnce>::call_once
34     ClosureOnceShim { call_once: DefId },
35     // drop_in_place::<T>; None for empty drop glue.
36     DropGlue(DefId, Option<Ty<'tcx>>),
37 }
38
39 impl<'tcx> InstanceDef<'tcx> {
40     #[inline]
41     pub fn def_id(&self) -> DefId {
42         match *self {
43             InstanceDef::Item(def_id) |
44             InstanceDef::FnPtrShim(def_id, _) |
45             InstanceDef::Virtual(def_id, _) |
46             InstanceDef::Intrinsic(def_id, ) |
47             InstanceDef::ClosureOnceShim { call_once: def_id }
48                 => def_id,
49             InstanceDef::DropGlue(def_id, _) => def_id
50         }
51     }
52
53     #[inline]
54     pub fn def_ty<'a>(&self, tcx: ty::TyCtxt<'a, 'tcx, 'tcx>) -> Ty<'tcx> {
55         tcx.type_of(self.def_id())
56     }
57
58     #[inline]
59     pub fn attrs<'a>(&self, tcx: ty::TyCtxt<'a, 'tcx, 'tcx>) -> ty::Attributes<'tcx> {
60         tcx.get_attrs(self.def_id())
61     }
62
63     pub //(crate)
64      fn dep_node(&self) -> DepConstructor {
65         // HACK: def-id binning, project-style; someone replace this with
66         // real on-demand.
67         let ty = match self {
68             &InstanceDef::FnPtrShim(_, ty) => Some(ty),
69             &InstanceDef::DropGlue(_, ty) => ty,
70             _ => None
71         }.into_iter();
72
73         DepConstructor::MirShim(
74             Some(self.def_id()).into_iter().chain(
75                 ty.flat_map(|t| t.walk()).flat_map(|t| match t.sty {
76                    ty::TyAdt(adt_def, _) => Some(adt_def.did),
77                    ty::TyProjection(ref proj) => Some(proj.trait_ref.def_id),
78                    _ => None,
79                })
80             ).collect()
81         )
82     }
83 }
84
85 impl<'tcx> fmt::Display for Instance<'tcx> {
86     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
87         ppaux::parameterized(f, self.substs, self.def_id(), &[])?;
88         match self.def {
89             InstanceDef::Item(_) => Ok(()),
90             InstanceDef::Intrinsic(_) => {
91                 write!(f, " - intrinsic")
92             }
93             InstanceDef::Virtual(_, num) => {
94                 write!(f, " - shim(#{})", num)
95             }
96             InstanceDef::FnPtrShim(_, ty) => {
97                 write!(f, " - shim({:?})", ty)
98             }
99             InstanceDef::ClosureOnceShim { .. } => {
100                 write!(f, " - shim")
101             }
102             InstanceDef::DropGlue(_, ty) => {
103                 write!(f, " - shim({:?})", ty)
104             }
105         }
106     }
107 }
108
109 impl<'a, 'b, 'tcx> Instance<'tcx> {
110     pub fn new(def_id: DefId, substs: &'tcx Substs<'tcx>)
111                -> Instance<'tcx> {
112         assert!(substs.is_normalized_for_trans() && !substs.has_escaping_regions(),
113                 "substs of instance {:?} not normalized for trans: {:?}",
114                 def_id, substs);
115         Instance { def: InstanceDef::Item(def_id), substs: substs }
116     }
117
118     pub fn mono(tcx: ty::TyCtxt<'a, 'tcx, 'b>, def_id: DefId) -> Instance<'tcx> {
119         Instance::new(def_id, tcx.global_tcx().empty_substs_for_def_id(def_id))
120     }
121
122     #[inline]
123     pub fn def_id(&self) -> DefId {
124         self.def.def_id()
125     }
126 }