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.
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.
11 use dep_graph::DepNode;
12 use hir::def_id::DefId;
13 use ty::{self, Ty, TypeFoldable, Substs};
21 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
22 pub struct Instance<'tcx> {
23 pub def: InstanceDef<'tcx>,
24 pub substs: &'tcx Substs<'tcx>,
27 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
28 pub enum InstanceDef<'tcx> {
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>>),
42 impl<'tcx> InstanceDef<'tcx> {
44 pub fn def_id(&self) -> DefId {
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 }
52 InstanceDef::DropGlue(def_id, _) => def_id
57 pub fn def_ty<'a>(&self, tcx: ty::TyCtxt<'a, 'tcx, 'tcx>) -> Ty<'tcx> {
58 tcx.item_type(self.def_id())
62 pub fn attrs<'a>(&self, tcx: ty::TyCtxt<'a, 'tcx, 'tcx>) -> Cow<'tcx, [ast::Attribute]> {
63 tcx.get_attrs(self.def_id())
66 pub(crate) fn dep_node(&self) -> DepNode<DefId> {
67 // HACK: def-id binning, project-style; someone replace this with
70 &InstanceDef::FnPtrShim(_, ty) => Some(ty),
71 &InstanceDef::DropGlue(_, ty) => ty,
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),
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(), &[])?;
91 InstanceDef::Item(_) => Ok(()),
92 InstanceDef::Intrinsic(_) => {
93 write!(f, " - intrinsic")
95 InstanceDef::Virtual(_, num) => {
96 write!(f, " - shim(#{})", num)
98 InstanceDef::FnPtrShim(_, ty) => {
99 write!(f, " - shim({:?})", ty)
101 InstanceDef::ClosureOnceShim { .. } => {
104 InstanceDef::DropGlue(_, ty) => {
105 write!(f, " - shim({:?})", ty)
111 impl<'a, 'b, 'tcx> Instance<'tcx> {
112 pub fn new(def_id: DefId, substs: &'tcx Substs<'tcx>)
114 assert!(substs.is_normalized_for_trans() && !substs.has_escaping_regions(),
115 "substs of instance {:?} not normalized for trans: {:?}",
117 Instance { def: InstanceDef::Item(def_id), substs: substs }
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))
125 pub fn def_id(&self) -> DefId {