diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 7c21bba49f81..b4cb39a034b4 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -570,6 +570,8 @@ define_dep_nodes!( <'tcx> [] MissingExternCrateItem(CrateNum), [] UsedCrateSource(CrateNum), [] PostorderCnums, + [] HasCloneClosures(CrateNum), + [] HasCopyClosures(CrateNum), [] Freevars(DefId), [] MaybeUnusedTraitImport(DefId), diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index e8a6c5a03474..00f0672822fc 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -2087,10 +2087,10 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { let trait_id = obligation.predicate.def_id(); let copy_closures = Some(trait_id) == self.tcx().lang_items().copy_trait() && - self.tcx().sess.features.borrow().copy_closures; + self.tcx().has_copy_closures(def_id.krate); let clone_closures = Some(trait_id) == self.tcx().lang_items().clone_trait() && - self.tcx().sess.features.borrow().clone_closures; + self.tcx().has_clone_closures(def_id.krate); if copy_closures || clone_closures { Where(ty::Binder(substs.upvar_tys(def_id, self.tcx()).collect())) diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 874bb426dc50..4a309ee0eb02 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -2247,4 +2247,12 @@ pub fn provide(providers: &mut ty::maps::Providers) { assert_eq!(cnum, LOCAL_CRATE); tcx.output_filenames.clone() }; + providers.has_copy_closures = |tcx, cnum| { + assert_eq!(cnum, LOCAL_CRATE); + tcx.sess.features.borrow().copy_closures + }; + providers.has_clone_closures = |tcx, cnum| { + assert_eq!(cnum, LOCAL_CRATE); + tcx.sess.features.borrow().clone_closures + }; } diff --git a/src/librustc/ty/maps/config.rs b/src/librustc/ty/maps/config.rs index 461b81a5c055..c8520c5be2df 100644 --- a/src/librustc/ty/maps/config.rs +++ b/src/librustc/ty/maps/config.rs @@ -490,3 +490,15 @@ impl<'tcx> QueryDescription for queries::output_filenames<'tcx> { format!("output_filenames") } } + +impl<'tcx> QueryDescription for queries::has_clone_closures<'tcx> { + fn describe(_tcx: TyCtxt, _: CrateNum) -> String { + format!("seeing if the crate has enabled `Clone` closures") + } +} + +impl<'tcx> QueryDescription for queries::has_copy_closures<'tcx> { + fn describe(_tcx: TyCtxt, _: CrateNum) -> String { + format!("seeing if the crate has enabled `Copy` closures") + } +} diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs index c08ad68eddd0..313a831f6b0e 100644 --- a/src/librustc/ty/maps/mod.rs +++ b/src/librustc/ty/maps/mod.rs @@ -326,6 +326,9 @@ define_maps! { <'tcx> [] fn compile_codegen_unit: CompileCodegenUnit(InternedString) -> Stats, [] fn output_filenames: output_filenames_node(CrateNum) -> Arc, + + [] fn has_copy_closures: HasCopyClosures(CrateNum) -> bool, + [] fn has_clone_closures: HasCloneClosures(CrateNum) -> bool, } ////////////////////////////////////////////////////////////////////// diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index 83a468171ccf..9e47e96aee4e 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -218,6 +218,16 @@ impl CrateMetadata { attr::contains_name(&attrs, "no_builtins") } + pub fn has_copy_closures(&self) -> bool { + let attrs = self.get_item_attrs(CRATE_DEF_INDEX); + attr::contains_feature_attr(&attrs, "copy_closures") + } + + pub fn has_clone_closures(&self) -> bool { + let attrs = self.get_item_attrs(CRATE_DEF_INDEX); + attr::contains_feature_attr(&attrs, "clone_closures") + } + pub fn panic_strategy(&self) -> PanicStrategy { self.root.panic_strategy.clone() } diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 78c44c7e45cd..f785d7bd4076 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -231,6 +231,9 @@ provide! { <'tcx> tcx, def_id, other, cdata, } used_crate_source => { Rc::new(cdata.source.clone()) } + + has_copy_closures => { cdata.has_copy_closures() } + has_clone_closures => { cdata.has_clone_closures() } } pub fn provide_local<'tcx>(providers: &mut Providers<'tcx>) { diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index 36ab3737f380..b1f796084df8 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -500,6 +500,20 @@ pub fn first_attr_value_str_by_name(attrs: &[Attribute], name: &str) -> Option bool { + attrs.iter().any(|item| { + item.check_name("feature") && + item.meta_item_list().map(|list| { + list.iter().any(|mi| { + mi.word().map(|w| w.name() == feature_name) + .unwrap_or(false) + }) + }).unwrap_or(false) + }) +} + /* Higher-level applications */ pub fn find_crate_name(attrs: &[Attribute]) -> Option {