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