about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorscalexm <martin.alex32@hotmail.fr>2017-09-20 20:42:49 +0200
committerscalexm <martin.alex32@hotmail.fr>2017-09-20 20:48:06 +0200
commit3fa3fe01b65ec4dde20c66c6bedcd28e2f83f8b6 (patch)
tree1eb75438d9833dee61d34237ae7c25e9758f7891 /src
parentf7964aebe516bc7e4f06f7128ebb39ad5576a1a7 (diff)
downloadrust-3fa3fe01b65ec4dde20c66c6bedcd28e2f83f8b6.tar.gz
rust-3fa3fe01b65ec4dde20c66c6bedcd28e2f83f8b6.zip
Fix ICE
Diffstat (limited to 'src')
-rw-r--r--src/librustc/dep_graph/dep_node.rs2
-rw-r--r--src/librustc/traits/select.rs4
-rw-r--r--src/librustc/ty/context.rs8
-rw-r--r--src/librustc/ty/maps/config.rs12
-rw-r--r--src/librustc/ty/maps/mod.rs3
-rw-r--r--src/librustc_metadata/cstore.rs10
-rw-r--r--src/librustc_metadata/cstore_impl.rs3
-rw-r--r--src/libsyntax/attr.rs14
8 files changed, 54 insertions, 2 deletions
diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs
index 7c21bba49f8..b4cb39a034b 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 e8a6c5a0347..00f0672822f 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 874bb426dc5..4a309ee0eb0 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 461b81a5c05..c8520c5be2d 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 c08ad68eddd..313a831f6b0 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<OutputFilenames>,
+
+    [] 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 83a468171cc..9e47e96aee4 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 78c44c7e45c..f785d7bd407 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 36ab3737f38..b1f796084df 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<S
         .and_then(|at| at.value_str())
 }
 
+/// Check if `attrs` contains an attribute like `#![feature(feature_name)]`.
+/// This will not perform any "sanity checks" on the form of the attributes.
+pub fn contains_feature_attr(attrs: &[Attribute], feature_name: &str) -> 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<Symbol> {