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> {
30 // <fn() as FnTrait>::call_*
31 FnPtrShim(DefId, Ty<'tcx>),
34 impl<'tcx> InstanceDef<'tcx> {
36 pub fn def_id(&self) -> DefId {
38 InstanceDef::Item(def_id) |
39 InstanceDef::FnPtrShim(def_id, _)
45 pub fn def_ty<'a>(&self, tcx: ty::TyCtxt<'a, 'tcx, 'tcx>) -> Ty<'tcx> {
46 tcx.item_type(self.def_id())
50 pub fn attrs<'a>(&self, tcx: ty::TyCtxt<'a, 'tcx, 'tcx>) -> Cow<'tcx, [ast::Attribute]> {
51 tcx.get_attrs(self.def_id())
54 pub(crate) fn dep_node(&self) -> DepNode<DefId> {
55 // HACK: def-id binning, project-style; someone replace this with
58 &InstanceDef::FnPtrShim(_, ty) => Some(ty),
63 Some(self.def_id()).into_iter().chain(
64 ty.flat_map(|t| t.walk()).flat_map(|t| match t.sty {
65 ty::TyAdt(adt_def, _) => Some(adt_def.did),
66 ty::TyProjection(ref proj) => Some(proj.trait_ref.def_id),
74 impl<'tcx> fmt::Display for Instance<'tcx> {
75 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
77 InstanceDef::Item(def) => {
78 ppaux::parameterized(f, self.substs, def, &[])
80 InstanceDef::FnPtrShim(def, ty) => {
81 ppaux::parameterized(f, self.substs, def, &[])?;
82 write!(f, " - shim({:?})", ty)
88 impl<'a, 'b, 'tcx> Instance<'tcx> {
89 pub fn new(def_id: DefId, substs: &'tcx Substs<'tcx>)
91 assert!(substs.is_normalized_for_trans() && !substs.has_escaping_regions(),
92 "substs of instance {:?} not normalized for trans: {:?}",
94 Instance { def: InstanceDef::Item(def_id), substs: substs }
97 pub fn mono(tcx: ty::TyCtxt<'a, 'tcx, 'b>, def_id: DefId) -> Instance<'tcx> {
98 Instance::new(def_id, tcx.global_tcx().empty_substs_for_def_id(def_id))
102 pub fn def_id(&self) -> DefId {