Skip to content

Commit 8289e5a

Browse files
committed
introduce is_foreign_item query
This may seem like overkill, but it's exactly what we want/need for incremental compilation I think. In particular, while generating code for some codegen unit X, we can wind up querying about any number of external items, and we only want to be forced to rebuild X is some of those changed from a foreign item to otherwise. Factoring this into a query means we would re-run only if some `false` became `true` (or vice versa).
1 parent 1785bca commit 8289e5a

File tree

5 files changed

+30
-10
lines changed

5 files changed

+30
-10
lines changed

src/librustc/dep_graph/dep_node.rs

+3
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ pub enum DepNode<D: Clone + Debug> {
8888
// predicates for an item wind up in `ItemSignature`).
8989
AssociatedItems(D),
9090
ItemSignature(D),
91+
IsForeignItem(D),
9192
TypeParamPredicates((D, D)),
9293
SizedConstraint(D),
9394
AdtDestructor(D),
@@ -171,6 +172,7 @@ impl<D: Clone + Debug> DepNode<D> {
171172
TransCrateItem,
172173
AssociatedItems,
173174
ItemSignature,
175+
IsForeignItem,
174176
AssociatedItemDefIds,
175177
InherentImpls,
176178
TypeckTables,
@@ -221,6 +223,7 @@ impl<D: Clone + Debug> DepNode<D> {
221223
TransInlinedItem(ref d) => op(d).map(TransInlinedItem),
222224
AssociatedItems(ref d) => op(d).map(AssociatedItems),
223225
ItemSignature(ref d) => op(d).map(ItemSignature),
226+
IsForeignItem(ref d) => op(d).map(IsForeignItem),
224227
TypeParamPredicates((ref item, ref param)) => {
225228
Some(TypeParamPredicates((try_opt!(op(item)), try_opt!(op(param)))))
226229
}

src/librustc/ty/maps.rs

+3
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,9 @@ define_maps! { <'tcx>
380380
pub adt_destructor: AdtDestructor(DefId) -> Option<ty::Destructor>,
381381
pub adt_sized_constraint: SizedConstraint(DefId) -> Ty<'tcx>,
382382

383+
/// True if this is a foreign item (i.e., linked via `extern { ... }`).
384+
pub is_foreign_item: IsForeignItem(DefId) -> bool,
385+
383386
/// Maps from def-id of a type or region parameter to its
384387
/// (inferred) variance.
385388
pub variances: ItemSignature(DefId) -> Rc<Vec<ty::Variance>>,

src/librustc_metadata/cstore_impl.rs

+1
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ provide! { <'tcx> tcx, def_id, cdata
111111
closure_kind => { cdata.closure_kind(def_id.index) }
112112
closure_type => { cdata.closure_ty(def_id.index, tcx) }
113113
inherent_impls => { Rc::new(cdata.get_inherent_implementations_for_type(def_id.index)) }
114+
is_foreign_item => { cdata.is_foreign_item(def_id.index) }
114115
}
115116

116117
impl CrateStore for cstore::CStore {

src/librustc_trans/callee.rs

+12-10
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,18 @@
1414
//! and methods are represented as just a fn ptr and not a full
1515
//! closure.
1616
17-
use llvm::{self, ValueRef};
18-
use rustc::hir::def_id::DefId;
19-
use rustc::ty::subst::Substs;
2017
use attributes;
2118
use common::{self, CrateContext};
22-
use monomorphize;
2319
use consts;
2420
use declare;
25-
use monomorphize::Instance;
21+
use llvm::{self, ValueRef};
22+
use monomorphize::{self, Instance};
23+
use rustc::hir::def_id::DefId;
24+
use rustc::ty::{self, TypeFoldable};
25+
use rustc::ty::subst::Substs;
26+
use syntax_pos::DUMMY_SP;
2627
use trans_item::TransItem;
2728
use type_of;
28-
use rustc::ty::TypeFoldable;
2929

3030
/// Translates a reference to a fn/method item, monomorphizing and
3131
/// inlining as it goes.
@@ -102,15 +102,17 @@ pub fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
102102
let attrs = instance.def.attrs(ccx.tcx());
103103
attributes::from_fn_attrs(ccx, &attrs, llfn);
104104

105-
let is_local_def = ccx.shared().translation_items().borrow()
106-
.contains(&TransItem::Fn(instance));
107-
if is_local_def {
108-
// FIXME(eddyb) Doubt all extern fn should allow unwinding.
105+
// Perhaps questionable, but we assume that anything defined
106+
// *in Rust code* may unwind. Foreign items like `extern "C" {
107+
// fn foo(); }` are assumed not to unwind **unless** they have
108+
// a `#[unwind]` attribute.
109+
if !ty::queries::is_foreign_item::get(tcx, DUMMY_SP, instance.def_id()) {
109110
attributes::unwind(llfn, true);
110111
unsafe {
111112
llvm::LLVMRustSetLinkage(llfn, llvm::Linkage::ExternalLinkage);
112113
}
113114
}
115+
114116
if ccx.use_dll_storage_attrs() &&
115117
ccx.sess().cstore.is_dllimport_foreign_item(instance.def_id())
116118
{

src/librustc_typeck/collect.rs

+11
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ pub fn provide(providers: &mut Providers) {
9999
trait_def,
100100
adt_def,
101101
impl_trait_ref,
102+
is_foreign_item,
102103
..*providers
103104
};
104105
}
@@ -1530,3 +1531,13 @@ fn compute_type_of_foreign_fn_decl<'a, 'tcx>(
15301531
let substs = Substs::identity_for_item(tcx, def_id);
15311532
tcx.mk_fn_def(def_id, substs, fty)
15321533
}
1534+
1535+
fn is_foreign_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1536+
def_id: DefId)
1537+
-> bool {
1538+
match tcx.hir.get_if_local(def_id) {
1539+
Some(hir_map::NodeForeignItem(..)) => true,
1540+
Some(_) => false,
1541+
_ => bug!("is_foreign_item applied to non-local def-id {:?}", def_id)
1542+
}
1543+
}

0 commit comments

Comments
 (0)