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::DepConstructor;
12 use hir::def_id::DefId;
13 use ty::{self, Ty, TypeFoldable, Substs};
18 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
19 pub struct Instance<'tcx> {
20 pub def: InstanceDef<'tcx>,
21 pub substs: &'tcx Substs<'tcx>,
24 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
25 pub enum InstanceDef<'tcx> {
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>>),
39 impl<'tcx> InstanceDef<'tcx> {
41 pub fn def_id(&self) -> DefId {
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 }
49 InstanceDef::DropGlue(def_id, _) => def_id
54 pub fn def_ty<'a>(&self, tcx: ty::TyCtxt<'a, 'tcx, 'tcx>) -> Ty<'tcx> {
55 tcx.type_of(self.def_id())
59 pub fn attrs<'a>(&self, tcx: ty::TyCtxt<'a, 'tcx, 'tcx>) -> ty::Attributes<'tcx> {
60 tcx.get_attrs(self.def_id())
64 fn dep_node(&self) -> DepConstructor {
65 // HACK: def-id binning, project-style; someone replace this with
68 &InstanceDef::FnPtrShim(_, ty) => Some(ty),
69 &InstanceDef::DropGlue(_, ty) => ty,
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),
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(), &[])?;
89 InstanceDef::Item(_) => Ok(()),
90 InstanceDef::Intrinsic(_) => {
91 write!(f, " - intrinsic")
93 InstanceDef::Virtual(_, num) => {
94 write!(f, " - shim(#{})", num)
96 InstanceDef::FnPtrShim(_, ty) => {
97 write!(f, " - shim({:?})", ty)
99 InstanceDef::ClosureOnceShim { .. } => {
102 InstanceDef::DropGlue(_, ty) => {
103 write!(f, " - shim({:?})", ty)
109 impl<'a, 'b, 'tcx> Instance<'tcx> {
110 pub fn new(def_id: DefId, substs: &'tcx Substs<'tcx>)
112 assert!(substs.is_normalized_for_trans() && !substs.has_escaping_regions(),
113 "substs of instance {:?} not normalized for trans: {:?}",
115 Instance { def: InstanceDef::Item(def_id), substs: substs }
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))
123 pub fn def_id(&self) -> DefId {