]> git.proxmox.com Git - rustc.git/blame - src/librustc/ty/instance.rs
New upstream version 1.18.0+dfsg1
[rustc.git] / src / librustc / ty / instance.rs
CommitLineData
cc61c64b
XL
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
11use dep_graph::DepNode;
12use hir::def_id::DefId;
13use ty::{self, Ty, TypeFoldable, Substs};
14use util::ppaux;
15
16use std::fmt;
17
18#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
19pub struct Instance<'tcx> {
20 pub def: InstanceDef<'tcx>,
21 pub substs: &'tcx Substs<'tcx>,
22}
23
24#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
25pub 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
39impl<'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.item_type(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) fn dep_node(&self) -> DepNode<DefId> {
64 // HACK: def-id binning, project-style; someone replace this with
65 // real on-demand.
66 let ty = match self {
67 &InstanceDef::FnPtrShim(_, ty) => Some(ty),
68 &InstanceDef::DropGlue(_, ty) => ty,
69 _ => None
70 }.into_iter();
71
72 DepNode::MirShim(
73 Some(self.def_id()).into_iter().chain(
74 ty.flat_map(|t| t.walk()).flat_map(|t| match t.sty {
75 ty::TyAdt(adt_def, _) => Some(adt_def.did),
76 ty::TyProjection(ref proj) => Some(proj.trait_ref.def_id),
77 _ => None,
78 })
79 ).collect()
80 )
81 }
82}
83
84impl<'tcx> fmt::Display for Instance<'tcx> {
85 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
86 ppaux::parameterized(f, self.substs, self.def_id(), &[])?;
87 match self.def {
88 InstanceDef::Item(_) => Ok(()),
89 InstanceDef::Intrinsic(_) => {
90 write!(f, " - intrinsic")
91 }
92 InstanceDef::Virtual(_, num) => {
93 write!(f, " - shim(#{})", num)
94 }
95 InstanceDef::FnPtrShim(_, ty) => {
96 write!(f, " - shim({:?})", ty)
97 }
98 InstanceDef::ClosureOnceShim { .. } => {
99 write!(f, " - shim")
100 }
101 InstanceDef::DropGlue(_, ty) => {
102 write!(f, " - shim({:?})", ty)
103 }
104 }
105 }
106}
107
108impl<'a, 'b, 'tcx> Instance<'tcx> {
109 pub fn new(def_id: DefId, substs: &'tcx Substs<'tcx>)
110 -> Instance<'tcx> {
111 assert!(substs.is_normalized_for_trans() && !substs.has_escaping_regions(),
112 "substs of instance {:?} not normalized for trans: {:?}",
113 def_id, substs);
114 Instance { def: InstanceDef::Item(def_id), substs: substs }
115 }
116
117 pub fn mono(tcx: ty::TyCtxt<'a, 'tcx, 'b>, def_id: DefId) -> Instance<'tcx> {
118 Instance::new(def_id, tcx.global_tcx().empty_substs_for_def_id(def_id))
119 }
120
121 #[inline]
122 pub fn def_id(&self) -> DefId {
123 self.def.def_id()
124 }
125}