about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorSimon Sapin <simon.sapin@exyr.org>2018-03-23 10:57:28 +0100
committerSimon Sapin <simon.sapin@exyr.org>2018-03-23 11:37:07 +0100
commitee67e14034438972c5aae46f8773fe69f20f14aa (patch)
tree2e06620d77b1082d1a9098f4a0530cf2c758decd /src
parent52f7e8836cc2e6c0edfaf402ee40ca724a8c0989 (diff)
downloadrust-ee67e14034438972c5aae46f8773fe69f20f14aa.tar.gz
rust-ee67e14034438972c5aae46f8773fe69f20f14aa.zip
Stabilize the copy_closures and clone_closures features
In addition to the `Fn*` family of traits, closures now implement `Copy` (and similarly `Clone`) if all of the captures do.
Diffstat (limited to 'src')
-rw-r--r--src/librustc/dep_graph/dep_node.rs2
-rw-r--r--src/librustc/lib.rs2
-rw-r--r--src/librustc/traits/select.rs8
-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/ty/maps/plumbing.rs2
-rw-r--r--src/librustc_metadata/cstore.rs10
-rw-r--r--src/librustc_metadata/cstore_impl.rs3
-rw-r--r--src/librustc_typeck/lib.rs2
-rw-r--r--src/libsyntax/feature_gate.rs26
-rw-r--r--src/test/compile-fail/not-clone-closure.rs2
-rw-r--r--src/test/compile-fail/not-copy-closure.rs3
-rw-r--r--src/test/compile-fail/unboxed-closer-non-implicit-copyable.rs19
-rw-r--r--src/test/run-pass/clone-closure.rs2
-rw-r--r--src/test/run-pass/copy-closure.rs3
-rw-r--r--src/test/ui/feature-gate-clone-closures.rs21
-rw-r--r--src/test/ui/feature-gate-clone-closures.stderr11
-rw-r--r--src/test/ui/feature-gate-copy-closures.rs19
-rw-r--r--src/test/ui/feature-gate-copy-closures.stderr13
-rw-r--r--src/test/ui/span/borrowck-call-is-borrow-issue-12224.rs5
-rw-r--r--src/test/ui/span/borrowck-call-is-borrow-issue-12224.stderr8
22 files changed, 15 insertions, 169 deletions
diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs
index 1e2e4e5a69f..5421d2add25 100644
--- a/src/librustc/dep_graph/dep_node.rs
+++ b/src/librustc/dep_graph/dep_node.rs
@@ -616,8 +616,6 @@ define_dep_nodes!( <'tcx>
     [input] MissingExternCrateItem(CrateNum),
     [input] UsedCrateSource(CrateNum),
     [input] PostorderCnums,
-    [] HasCloneClosures(CrateNum),
-    [] HasCopyClosures(CrateNum),
 
     // This query is not expected to have inputs -- as a result, it's
     // not a good candidate for "replay" because it's essentially a
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index 22b07c8cc04..a759ce59cb6 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -45,7 +45,7 @@
 #![feature(box_syntax)]
 #![feature(conservative_impl_trait)]
 #![feature(const_fn)]
-#![feature(copy_closures, clone_closures)]
+#![cfg_attr(stage0, feature(copy_closures, clone_closures))]
 #![feature(core_intrinsics)]
 #![feature(drain_filter)]
 #![feature(dyn_trait)]
diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs
index 4db81cf1dec..f414374d008 100644
--- a/src/librustc/traits/select.rs
+++ b/src/librustc/traits/select.rs
@@ -2086,12 +2086,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
 
             ty::TyClosure(def_id, substs) => {
                 let trait_id = obligation.predicate.def_id();
-                let copy_closures =
-                    Some(trait_id) == self.tcx().lang_items().copy_trait() &&
-                    self.tcx().has_copy_closures(def_id.krate);
-                let clone_closures =
-                    Some(trait_id) == self.tcx().lang_items().clone_trait() &&
-                    self.tcx().has_clone_closures(def_id.krate);
+                let copy_closures = Some(trait_id) == self.tcx().lang_items().copy_trait();
+                let clone_closures = Some(trait_id) == self.tcx().lang_items().clone_trait();
 
                 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 fd3465f59eb..f56d866cba5 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -2520,14 +2520,6 @@ 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.features().copy_closures
-    };
-    providers.has_clone_closures = |tcx, cnum| {
-        assert_eq!(cnum, LOCAL_CRATE);
-        tcx.features().clone_closures
-    };
     providers.features_query = |tcx, cnum| {
         assert_eq!(cnum, LOCAL_CRATE);
         Lrc::new(tcx.sess.features_untracked().clone())
diff --git a/src/librustc/ty/maps/config.rs b/src/librustc/ty/maps/config.rs
index 117d9219312..400bc6ba415 100644
--- a/src/librustc/ty/maps/config.rs
+++ b/src/librustc/ty/maps/config.rs
@@ -604,24 +604,12 @@ impl<'tcx> QueryDescription<'tcx> for queries::output_filenames<'tcx> {
     }
 }
 
-impl<'tcx> QueryDescription<'tcx> for queries::has_clone_closures<'tcx> {
-    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
-        format!("seeing if the crate has enabled `Clone` closures")
-    }
-}
-
 impl<'tcx> QueryDescription<'tcx> for queries::vtable_methods<'tcx> {
     fn describe(tcx: TyCtxt, key: ty::PolyTraitRef<'tcx> ) -> String {
         format!("finding all methods for trait {}", tcx.item_path_str(key.def_id()))
     }
 }
 
-impl<'tcx> QueryDescription<'tcx> for queries::has_copy_closures<'tcx> {
-    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
-        format!("seeing if the crate has enabled `Copy` closures")
-    }
-}
-
 impl<'tcx> QueryDescription<'tcx> for queries::features_query<'tcx> {
     fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
         format!("looking up enabled feature gates")
diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs
index 6c3b4efb932..95e00418658 100644
--- a/src/librustc/ty/maps/mod.rs
+++ b/src/librustc/ty/maps/mod.rs
@@ -382,9 +382,6 @@ define_maps! { <'tcx>
     [] fn output_filenames: output_filenames_node(CrateNum)
         -> Arc<OutputFilenames>,
 
-    [] fn has_copy_closures: HasCopyClosures(CrateNum) -> bool,
-    [] fn has_clone_closures: HasCloneClosures(CrateNum) -> bool,
-
     // Erases regions from `ty` to yield a new type.
     // Normally you would just use `tcx.erase_regions(&value)`,
     // however, which uses this query as a kind of cache.
diff --git a/src/librustc/ty/maps/plumbing.rs b/src/librustc/ty/maps/plumbing.rs
index 4170fa76797..d9caf94ed7f 100644
--- a/src/librustc/ty/maps/plumbing.rs
+++ b/src/librustc/ty/maps/plumbing.rs
@@ -917,8 +917,6 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
         }
         DepKind::UsedCrateSource => { force!(used_crate_source, krate!()); }
         DepKind::PostorderCnums => { force!(postorder_cnums, LOCAL_CRATE); }
-        DepKind::HasCloneClosures => { force!(has_clone_closures, krate!()); }
-        DepKind::HasCopyClosures => { force!(has_copy_closures, krate!()); }
 
         DepKind::Freevars => { force!(freevars, def_id!()); }
         DepKind::MaybeUnusedTraitImport => {
diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs
index bd5ad93946e..b9623f28540 100644
--- a/src/librustc_metadata/cstore.rs
+++ b/src/librustc_metadata/cstore.rs
@@ -228,16 +228,6 @@ impl CrateMetadata {
         attr::contains_name(&attrs, "no_builtins")
     }
 
-     pub fn has_copy_closures(&self, sess: &Session) -> bool {
-        let attrs = self.get_item_attrs(CRATE_DEF_INDEX, sess);
-        attr::contains_feature_attr(&attrs, "copy_closures")
-    }
-
-    pub fn has_clone_closures(&self, sess: &Session) -> bool {
-        let attrs = self.get_item_attrs(CRATE_DEF_INDEX, sess);
-        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 2de27f3a1c3..f02a1831db2 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -256,9 +256,6 @@ provide! { <'tcx> tcx, def_id, other, cdata,
 
     used_crate_source => { Lrc::new(cdata.source.clone()) }
 
-    has_copy_closures => { cdata.has_copy_closures(tcx.sess) }
-    has_clone_closures => { cdata.has_clone_closures(tcx.sess) }
-
     exported_symbols => {
         let cnum = cdata.cnum;
         assert!(cnum != LOCAL_CRATE);
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index 9f98932f24b..8a1d87fe1ea 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -76,7 +76,7 @@ This API is completely unstable and subject to change.
 #![feature(box_patterns)]
 #![feature(box_syntax)]
 #![feature(conservative_impl_trait)]
-#![feature(copy_closures, clone_closures)]
+#![cfg_attr(stage0, feature(copy_closures, clone_closures))]
 #![feature(crate_visibility_modifier)]
 #![feature(from_ref)]
 #![feature(match_default_bindings)]
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 915396d29fe..73d088fb585 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -391,10 +391,6 @@ declare_features! (
     // Future-proofing enums/structs with #[non_exhaustive] attribute (RFC 2008)
     (active, non_exhaustive, "1.22.0", Some(44109), None),
 
-    // Copy/Clone closures (RFC 2132)
-    (active, clone_closures, "1.22.0", Some(44490), None),
-    (active, copy_closures, "1.22.0", Some(44490), None),
-
     // allow `'_` placeholder lifetimes
     (active, underscore_lifetimes, "1.22.0", Some(44524), None),
 
@@ -556,6 +552,9 @@ declare_features! (
     (accepted, inclusive_range_syntax, "1.26.0", Some(28237), None),
     // allow `..=` in patterns (RFC 1192)
     (accepted, dotdoteq_in_patterns, "1.26.0", Some(28237), None),
+    // Copy/Clone closures (RFC 2132)
+    (accepted, clone_closures, "1.26.0", Some(44490), None),
+    (accepted, copy_closures, "1.26.0", Some(44490), None),
 );
 
 // If you change this, please modify src/doc/unstable-book as well. You must
@@ -1867,8 +1866,6 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
 struct FeatureChecker {
     proc_macro: Option<Span>,
     custom_attribute: Option<Span>,
-    copy_closures: Option<Span>,
-    clone_closures: Option<Span>,
 }
 
 impl FeatureChecker {
@@ -1884,14 +1881,6 @@ impl FeatureChecker {
         if features.custom_attribute {
             self.custom_attribute = self.custom_attribute.or(Some(span));
         }
-
-        if features.copy_closures {
-            self.copy_closures = self.copy_closures.or(Some(span));
-        }
-
-        if features.clone_closures {
-            self.clone_closures = self.clone_closures.or(Some(span));
-        }
     }
 
     fn check(self, handler: &Handler) {
@@ -1903,15 +1892,6 @@ impl FeatureChecker {
 
             FatalError.raise();
         }
-
-        if let (Some(span), None) = (self.copy_closures, self.clone_closures) {
-            handler.struct_span_err(span, "`#![feature(copy_closures)]` can only be used with \
-                                           `#![feature(clone_closures)]`")
-                  .span_note(span, "`#![feature(copy_closures)]` declared here")
-                  .emit();
-
-            FatalError.raise();
-        }
     }
 }
 
diff --git a/src/test/compile-fail/not-clone-closure.rs b/src/test/compile-fail/not-clone-closure.rs
index 2a30dc4fdd4..967cb3610ca 100644
--- a/src/test/compile-fail/not-clone-closure.rs
+++ b/src/test/compile-fail/not-clone-closure.rs
@@ -10,8 +10,6 @@
 
 // Check that closures do not implement `Clone` if their environment is not `Clone`.
 
-#![feature(clone_closures)]
-
 struct S(i32);
 
 fn main() {
diff --git a/src/test/compile-fail/not-copy-closure.rs b/src/test/compile-fail/not-copy-closure.rs
index 271e6d5fc90..10567c5c961 100644
--- a/src/test/compile-fail/not-copy-closure.rs
+++ b/src/test/compile-fail/not-copy-closure.rs
@@ -10,9 +10,6 @@
 
 // Check that closures do not implement `Copy` if their environment is not `Copy`.
 
-#![feature(copy_closures)]
-#![feature(clone_closures)]
-
 fn main() {
     let mut a = 5;
     let hello = || {
diff --git a/src/test/compile-fail/unboxed-closer-non-implicit-copyable.rs b/src/test/compile-fail/unboxed-closer-non-implicit-copyable.rs
deleted file mode 100644
index 2d559794919..00000000000
--- a/src/test/compile-fail/unboxed-closer-non-implicit-copyable.rs
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![feature(unboxed_closures)]
-
-fn to_fn_once<A,F:FnOnce<A>>(f: F) -> F { f }
-
-fn main() {
-    let f = to_fn_once(move|| ());
-    f();
-    f(); //~ ERROR use of moved value
-}
diff --git a/src/test/run-pass/clone-closure.rs b/src/test/run-pass/clone-closure.rs
index 7f554c77fc4..0fe3711d8d3 100644
--- a/src/test/run-pass/clone-closure.rs
+++ b/src/test/run-pass/clone-closure.rs
@@ -10,8 +10,6 @@
 
 // Check that closures implement `Clone`.
 
-#![feature(clone_closures)]
-
 #[derive(Clone)]
 struct S(i32);
 
diff --git a/src/test/run-pass/copy-closure.rs b/src/test/run-pass/copy-closure.rs
index 309c83ebd99..a211d6fc3a3 100644
--- a/src/test/run-pass/copy-closure.rs
+++ b/src/test/run-pass/copy-closure.rs
@@ -10,9 +10,6 @@
 
 // Check that closures implement `Copy`.
 
-#![feature(copy_closures)]
-#![feature(clone_closures)]
-
 fn call<T, F: FnOnce() -> T>(f: F) -> T { f() }
 
 fn main() {
diff --git a/src/test/ui/feature-gate-clone-closures.rs b/src/test/ui/feature-gate-clone-closures.rs
deleted file mode 100644
index a15153ea7bf..00000000000
--- a/src/test/ui/feature-gate-clone-closures.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#[derive(Clone)]
-struct S(i32);
-
-fn main() {
-    let a = S(5);
-    let hello = move || {
-        println!("Hello {}", a.0);
-    };
-
-    let hello = hello.clone(); //~ ERROR no method named `clone` found for type
-}
diff --git a/src/test/ui/feature-gate-clone-closures.stderr b/src/test/ui/feature-gate-clone-closures.stderr
deleted file mode 100644
index 7038a76380d..00000000000
--- a/src/test/ui/feature-gate-clone-closures.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0599]: no method named `clone` found for type `[closure@$DIR/feature-gate-clone-closures.rs:16:17: 18:6 a:_]` in the current scope
-  --> $DIR/feature-gate-clone-closures.rs:20:23
-   |
-LL |     let hello = hello.clone(); //~ ERROR no method named `clone` found for type
-   |                       ^^^^^
-   |
-   = note: hello is a function, perhaps you wish to call it
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/feature-gate-copy-closures.rs b/src/test/ui/feature-gate-copy-closures.rs
deleted file mode 100644
index b11b09eb9fd..00000000000
--- a/src/test/ui/feature-gate-copy-closures.rs
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn main() {
-    let a = 5;
-    let hello = || {
-        println!("Hello {}", a);
-    };
-
-    let b = hello;
-    let c = hello; //~ ERROR use of moved value: `hello` [E0382]
-}
diff --git a/src/test/ui/feature-gate-copy-closures.stderr b/src/test/ui/feature-gate-copy-closures.stderr
deleted file mode 100644
index e72680b69ea..00000000000
--- a/src/test/ui/feature-gate-copy-closures.stderr
+++ /dev/null
@@ -1,13 +0,0 @@
-error[E0382]: use of moved value: `hello`
-  --> $DIR/feature-gate-copy-closures.rs:18:9
-   |
-LL |     let b = hello;
-   |         - value moved here
-LL |     let c = hello; //~ ERROR use of moved value: `hello` [E0382]
-   |         ^ value used here after move
-   |
-   = note: move occurs because `hello` has type `[closure@$DIR/feature-gate-copy-closures.rs:13:17: 15:6 a:&i32]`, which does not implement the `Copy` trait
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0382`.
diff --git a/src/test/ui/span/borrowck-call-is-borrow-issue-12224.rs b/src/test/ui/span/borrowck-call-is-borrow-issue-12224.rs
index 8e03c303e54..e8227971691 100644
--- a/src/test/ui/span/borrowck-call-is-borrow-issue-12224.rs
+++ b/src/test/ui/span/borrowck-call-is-borrow-issue-12224.rs
@@ -58,7 +58,10 @@ fn test6() {
 
 fn test7() {
     fn foo<F>(_: F) where F: FnMut(Box<FnMut(isize)>, isize) {}
-    let mut f = |g: Box<FnMut(isize)>, b: isize| {};
+    let s = String::new();  // Capture to make f !Copy
+    let mut f = move |g: Box<FnMut(isize)>, b: isize| {
+        let _ = s.len();
+    };
     f(Box::new(|a| {
         foo(f);
         //~^ ERROR cannot move `f` into closure because it is borrowed
diff --git a/src/test/ui/span/borrowck-call-is-borrow-issue-12224.stderr b/src/test/ui/span/borrowck-call-is-borrow-issue-12224.stderr
index 318b77dedcb..2e7e1e07441 100644
--- a/src/test/ui/span/borrowck-call-is-borrow-issue-12224.stderr
+++ b/src/test/ui/span/borrowck-call-is-borrow-issue-12224.stderr
@@ -28,7 +28,7 @@ LL |     f.f.call_mut(())
    |     ^^^ cannot borrow as mutable
 
 error[E0504]: cannot move `f` into closure because it is borrowed
-  --> $DIR/borrowck-call-is-borrow-issue-12224.rs:63:13
+  --> $DIR/borrowck-call-is-borrow-issue-12224.rs:66:13
    |
 LL |     f(Box::new(|a| {
    |     - borrow of `f` occurs here
@@ -36,11 +36,11 @@ LL |         foo(f);
    |             ^ move into closure occurs here
 
 error[E0507]: cannot move out of captured outer variable in an `FnMut` closure
-  --> $DIR/borrowck-call-is-borrow-issue-12224.rs:63:13
+  --> $DIR/borrowck-call-is-borrow-issue-12224.rs:66:13
    |
-LL |     let mut f = |g: Box<FnMut(isize)>, b: isize| {};
+LL |     let mut f = move |g: Box<FnMut(isize)>, b: isize| {
    |         ----- captured outer variable
-LL |     f(Box::new(|a| {
+...
 LL |         foo(f);
    |             ^ cannot move out of captured outer variable in an `FnMut` closure