Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit ffee956

Browse files
committed
move Instance to rustc and use it in the collector
1 parent 0af3775 commit ffee956

24 files changed

+522
-432
lines changed

src/librustc/dep_graph/dep_node.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ pub enum DepNode<D: Clone + Debug> {
8989
// things read/modify that MIR.
9090
MirKrate,
9191
Mir(D),
92+
MirShim(Vec<D>),
9293

9394
BorrowCheckKrate,
9495
BorrowCheck(D),
@@ -258,6 +259,10 @@ impl<D: Clone + Debug> DepNode<D> {
258259
IntrinsicCheck(ref d) => op(d).map(IntrinsicCheck),
259260
MatchCheck(ref d) => op(d).map(MatchCheck),
260261
Mir(ref d) => op(d).map(Mir),
262+
MirShim(ref def_ids) => {
263+
let def_ids: Option<Vec<E>> = def_ids.iter().map(op).collect();
264+
def_ids.map(MirShim)
265+
}
261266
BorrowCheck(ref d) => op(d).map(BorrowCheck),
262267
RvalueCheck(ref d) => op(d).map(RvalueCheck),
263268
StabilityCheck(ref d) => op(d).map(StabilityCheck),

src/librustc/ty/instance.rs

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
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+
// <fn() as FnTrait>::call_*
31+
FnPtrShim(DefId, Ty<'tcx>),
32+
}
33+
34+
impl<'tcx> InstanceDef<'tcx> {
35+
#[inline]
36+
pub fn def_id(&self) -> DefId {
37+
match *self {
38+
InstanceDef::Item(def_id) |
39+
InstanceDef::FnPtrShim(def_id, _)
40+
=> def_id
41+
}
42+
}
43+
44+
#[inline]
45+
pub fn def_ty<'a>(&self, tcx: ty::TyCtxt<'a, 'tcx, 'tcx>) -> Ty<'tcx> {
46+
tcx.item_type(self.def_id())
47+
}
48+
49+
#[inline]
50+
pub fn attrs<'a>(&self, tcx: ty::TyCtxt<'a, 'tcx, 'tcx>) -> Cow<'tcx, [ast::Attribute]> {
51+
tcx.get_attrs(self.def_id())
52+
}
53+
54+
pub(crate) fn dep_node(&self) -> DepNode<DefId> {
55+
// HACK: def-id binning, project-style; someone replace this with
56+
// real on-demand.
57+
let ty = match self {
58+
&InstanceDef::FnPtrShim(_, ty) => Some(ty),
59+
_ => None
60+
}.into_iter();
61+
62+
DepNode::MirShim(
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),
67+
_ => None,
68+
})
69+
).collect()
70+
)
71+
}
72+
}
73+
74+
impl<'tcx> fmt::Display for Instance<'tcx> {
75+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
76+
match self.def {
77+
InstanceDef::Item(def) => {
78+
ppaux::parameterized(f, self.substs, def, &[])
79+
}
80+
InstanceDef::FnPtrShim(def, ty) => {
81+
ppaux::parameterized(f, self.substs, def, &[])?;
82+
write!(f, " - shim({:?})", ty)
83+
}
84+
}
85+
}
86+
}
87+
88+
impl<'a, 'b, 'tcx> Instance<'tcx> {
89+
pub fn new(def_id: DefId, substs: &'tcx Substs<'tcx>)
90+
-> Instance<'tcx> {
91+
assert!(substs.is_normalized_for_trans() && !substs.has_escaping_regions(),
92+
"substs of instance {:?} not normalized for trans: {:?}",
93+
def_id, substs);
94+
Instance { def: InstanceDef::Item(def_id), substs: substs }
95+
}
96+
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))
99+
}
100+
101+
#[inline]
102+
pub fn def_id(&self) -> DefId {
103+
self.def.def_id()
104+
}
105+
}

src/librustc/ty/maps.rs

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
// except according to those terms.
1010

1111
use dep_graph::{DepGraph, DepNode, DepTrackingMap, DepTrackingMapConfig};
12-
use hir::def_id::{CrateNum, DefId};
12+
use hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
1313
use middle::const_val::ConstVal;
1414
use mir;
1515
use ty::{self, Ty, TyCtxt};
@@ -24,6 +24,16 @@ trait Key {
2424
fn default_span(&self, tcx: TyCtxt) -> Span;
2525
}
2626

27+
impl<'tcx> Key for ty::InstanceDef<'tcx> {
28+
fn map_crate(&self) -> CrateNum {
29+
LOCAL_CRATE
30+
}
31+
32+
fn default_span(&self, tcx: TyCtxt) -> Span {
33+
tcx.def_span(self.def_id())
34+
}
35+
}
36+
2737
impl Key for CrateNum {
2838
fn map_crate(&self) -> CrateNum {
2939
*self
@@ -83,9 +93,9 @@ impl<'tcx> Value<'tcx> for Ty<'tcx> {
8393
}
8494
}
8595

86-
pub struct CycleError<'a> {
96+
pub struct CycleError<'a, 'tcx: 'a> {
8797
span: Span,
88-
cycle: RefMut<'a, [(Span, Query)]>,
98+
cycle: RefMut<'a, [(Span, Query<'tcx>)]>,
8999
}
90100

91101
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
@@ -110,8 +120,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
110120
err.emit();
111121
}
112122

113-
fn cycle_check<F, R>(self, span: Span, query: Query, compute: F)
114-
-> Result<R, CycleError<'a>>
123+
fn cycle_check<F, R>(self, span: Span, query: Query<'gcx>, compute: F)
124+
-> Result<R, CycleError<'a, 'gcx>>
115125
where F: FnOnce() -> R
116126
{
117127
{
@@ -172,13 +182,20 @@ impl<'tcx> QueryDescription for queries::coherent_inherent_impls<'tcx> {
172182
}
173183
}
174184

185+
impl<'tcx> QueryDescription for queries::mir_shims<'tcx> {
186+
fn describe(tcx: TyCtxt, def: ty::InstanceDef<'tcx>) -> String {
187+
format!("generating MIR shim for `{}`",
188+
tcx.item_path_str(def.def_id()))
189+
}
190+
}
191+
175192
macro_rules! define_maps {
176193
(<$tcx:tt>
177194
$($(#[$attr:meta])*
178195
pub $name:ident: $node:ident($K:ty) -> $V:ty),*) => {
179196
pub struct Maps<$tcx> {
180197
providers: IndexVec<CrateNum, Providers<$tcx>>,
181-
query_stack: RefCell<Vec<(Span, Query)>>,
198+
query_stack: RefCell<Vec<(Span, Query<$tcx>)>>,
182199
$($(#[$attr])* pub $name: RefCell<DepTrackingMap<queries::$name<$tcx>>>),*
183200
}
184201

@@ -196,11 +213,11 @@ macro_rules! define_maps {
196213

197214
#[allow(bad_style)]
198215
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
199-
pub enum Query {
216+
pub enum Query<$tcx> {
200217
$($(#[$attr])* $name($K)),*
201218
}
202219

203-
impl Query {
220+
impl<$tcx> Query<$tcx> {
204221
pub fn describe(&self, tcx: TyCtxt) -> String {
205222
match *self {
206223
$(Query::$name(key) => queries::$name::describe(tcx, key)),*
@@ -233,7 +250,7 @@ macro_rules! define_maps {
233250
mut span: Span,
234251
key: $K,
235252
f: F)
236-
-> Result<R, CycleError<'a>>
253+
-> Result<R, CycleError<'a, $tcx>>
237254
where F: FnOnce(&$V) -> R
238255
{
239256
if let Some(result) = tcx.maps.$name.borrow().get(&key) {
@@ -256,7 +273,7 @@ macro_rules! define_maps {
256273
}
257274

258275
pub fn try_get(tcx: TyCtxt<'a, $tcx, 'lcx>, span: Span, key: $K)
259-
-> Result<$V, CycleError<'a>> {
276+
-> Result<$V, CycleError<'a, $tcx>> {
260277
Self::try_get_with(tcx, span, key, Clone::clone)
261278
}
262279

@@ -387,7 +404,9 @@ define_maps! { <'tcx>
387404

388405
/// Results of evaluating monomorphic constants embedded in
389406
/// other items, such as enum variant explicit discriminants.
390-
pub monomorphic_const_eval: MonomorphicConstEval(DefId) -> Result<ConstVal<'tcx>, ()>
407+
pub monomorphic_const_eval: MonomorphicConstEval(DefId) -> Result<ConstVal<'tcx>, ()>,
408+
409+
pub mir_shims: mir_shim(ty::InstanceDef<'tcx>) -> &'tcx RefCell<mir::Mir<'tcx>>
391410
}
392411

393412
fn coherent_trait_dep_node((_, def_id): (CrateNum, DefId)) -> DepNode<DefId> {
@@ -397,3 +416,7 @@ fn coherent_trait_dep_node((_, def_id): (CrateNum, DefId)) -> DepNode<DefId> {
397416
fn coherent_inherent_impls_dep_node(_: CrateNum) -> DepNode<DefId> {
398417
DepNode::Coherence
399418
}
419+
420+
fn mir_shim(instance: ty::InstanceDef) -> DepNode<DefId> {
421+
instance.dep_node()
422+
}

src/librustc/ty/mod.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ pub use self::contents::TypeContents;
7373
pub use self::context::{TyCtxt, GlobalArenas, tls};
7474
pub use self::context::{Lift, TypeckTables};
7575

76+
pub use self::instance::{Instance, InstanceDef};
77+
7678
pub use self::trait_def::{TraitDef, TraitFlags};
7779

7880
pub use self::maps::queries;
@@ -98,6 +100,7 @@ pub mod util;
98100
mod contents;
99101
mod context;
100102
mod flags;
103+
mod instance;
101104
mod structural_impls;
102105
mod sty;
103106

@@ -2309,6 +2312,16 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
23092312
queries::mir::get(self, DUMMY_SP, did).borrow()
23102313
}
23112314

2315+
/// Return the possibly-auto-generated MIR of a (DefId, Subst) pair.
2316+
pub fn instance_mir(self, instance: ty::InstanceDef<'gcx>)
2317+
-> Ref<'gcx, Mir<'gcx>>
2318+
{
2319+
match instance {
2320+
ty::InstanceDef::Item(did) if true => self.item_mir(did),
2321+
_ => queries::mir_shims::get(self, DUMMY_SP, instance).borrow(),
2322+
}
2323+
}
2324+
23122325
/// Given the DefId of an item, returns its MIR, borrowed immutably.
23132326
/// Returns None if there is no MIR for the DefId
23142327
pub fn maybe_item_mir(self, did: DefId) -> Option<Ref<'gcx, Mir<'gcx>>> {

src/librustc/ty/util.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,18 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
398398
}
399399
def_id
400400
}
401+
402+
/// Given the def-id of some item that has no type parameters, make
403+
/// a suitable "empty substs" for it.
404+
pub fn empty_substs_for_def_id(self, item_def_id: DefId) -> &'tcx ty::Substs<'tcx> {
405+
ty::Substs::for_item(self, item_def_id,
406+
|_, _| self.mk_region(ty::ReErased),
407+
|_, _| {
408+
bug!("empty_substs_for_def_id: {:?} has type parameters", item_def_id)
409+
})
410+
}
411+
412+
401413
}
402414

403415
pub struct TypeIdHasher<'a, 'gcx: 'a+'tcx, 'tcx: 'a, W> {

src/librustc_mir/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,5 +60,6 @@ use rustc::ty::maps::Providers;
6060

6161
pub fn provide(providers: &mut Providers) {
6262
mir_map::provide(providers);
63+
shim::provide(providers);
6364
transform::qualify_consts::provide(providers);
6465
}

src/librustc_mir/shim.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,31 @@ use rustc::infer;
1313
use rustc::mir::*;
1414
use rustc::mir::transform::MirSource;
1515
use rustc::ty;
16+
use rustc::ty::maps::Providers;
1617

1718
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
1819

1920
use syntax::ast;
2021
use syntax_pos::Span;
2122

23+
use std::cell::RefCell;
2224
use std::iter;
2325

26+
pub fn provide(providers: &mut Providers) {
27+
providers.mir_shims = make_shim;
28+
}
29+
30+
fn make_shim<'a, 'tcx>(_tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
31+
instance: ty::InstanceDef<'tcx>)
32+
-> &'tcx RefCell<Mir<'tcx>>
33+
{
34+
match instance {
35+
ty::InstanceDef::Item(..) =>
36+
bug!("item {:?} passed to make_shim", instance),
37+
ty::InstanceDef::FnPtrShim(..) => unimplemented!()
38+
}
39+
}
40+
2441
fn local_decls_for_sig<'tcx>(sig: &ty::FnSig<'tcx>)
2542
-> IndexVec<Local, LocalDecl<'tcx>>
2643
{

src/librustc_trans/back/symbol_export.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use context::SharedCrateContext;
1212
use monomorphize::Instance;
1313
use symbol_map::SymbolMap;
14+
use back::symbol_names::symbol_name;
1415
use util::nodemap::FxHashMap;
1516
use rustc::hir::def_id::{DefId, CrateNum, LOCAL_CRATE};
1617
use rustc::session::config;
@@ -106,7 +107,7 @@ impl ExportedSymbols {
106107
.exported_symbols(cnum)
107108
.iter()
108109
.map(|&def_id| {
109-
let name = Instance::mono(scx, def_id).symbol_name(scx);
110+
let name = symbol_name(Instance::mono(scx.tcx(), def_id), scx);
110111
let export_level = if special_runtime_crate {
111112
// We can probably do better here by just ensuring that
112113
// it has hidden visibility rather than public
@@ -218,9 +219,9 @@ fn symbol_for_def_id<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
218219
}
219220
}
220221

221-
let instance = Instance::mono(scx, def_id);
222+
let instance = Instance::mono(scx.tcx(), def_id);
222223

223224
symbol_map.get(TransItem::Fn(instance))
224225
.map(str::to_owned)
225-
.unwrap_or_else(|| instance.symbol_name(scx))
226+
.unwrap_or_else(|| symbol_name(instance, scx))
226227
}

0 commit comments

Comments
 (0)