Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Methods Fn(Mut,Once)::call(mut,once) are gated with two feature gates, remove one of them #34802

Merged
merged 1 commit into from
Aug 1, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion src/libcollections/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@
#![feature(specialization)]
#![feature(staged_api)]
#![feature(step_by)]
#![feature(unboxed_closures)]
#![feature(unicode)]
#![feature(unique)]
#![feature(unsafe_no_drop_flag)]
Expand Down
1 change: 0 additions & 1 deletion src/libcoretest/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
#![feature(step_by)]
#![feature(test)]
#![feature(try_from)]
#![feature(unboxed_closures)]
#![feature(unicode)]
#![feature(unique)]

Expand Down
1 change: 0 additions & 1 deletion src/librustc_driver/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
#![feature(set_stdio)]
#![feature(staged_api)]
#![feature(question_mark)]
#![feature(unboxed_closures)]

extern crate arena;
extern crate flate;
Expand Down
29 changes: 2 additions & 27 deletions src/librustc_typeck/check/callee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,33 +27,8 @@ use rustc::hir;
/// to `trait_id` (this only cares about the trait, not the specific
/// method that is called)
pub fn check_legal_trait_for_method_call(ccx: &CrateCtxt, span: Span, trait_id: DefId) {
let tcx = ccx.tcx;
let did = Some(trait_id);
let li = &tcx.lang_items;

if did == li.drop_trait() {
span_err!(tcx.sess, span, E0040, "explicit use of destructor method");
} else if !tcx.sess.features.borrow().unboxed_closures {
// the #[feature(unboxed_closures)] feature isn't
// activated so we need to enforce the closure
// restrictions.

let method = if did == li.fn_trait() {
"call"
} else if did == li.fn_mut_trait() {
"call_mut"
} else if did == li.fn_once_trait() {
"call_once"
} else {
return // not a closure method, everything is OK.
};

struct_span_err!(tcx.sess, span, E0174,
"explicit use of unboxed closure method `{}` is experimental",
method)
.help("add `#![feature(unboxed_closures)]` to the crate \
attributes to enable")
.emit();
if ccx.tcx.lang_items.drop_trait() == Some(trait_id) {
span_err!(ccx.tcx.sess, span, E0040, "explicit use of destructor method");
}
}

Expand Down
84 changes: 1 addition & 83 deletions src/librustc_typeck/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1944,89 +1944,6 @@ To learn more about traits, take a look at the Book:
https://doc.rust-lang.org/book/traits.html
"##,

E0174: r##"
This error occurs because of the explicit use of unboxed closure methods
that are an experimental feature in current Rust version.

Example of erroneous code:

```compile_fail
fn foo<F: Fn(&str)>(mut f: F) {
f.call(("call",));
// error: explicit use of unboxed closure method `call`
f.call_mut(("call_mut",));
// error: explicit use of unboxed closure method `call_mut`
f.call_once(("call_once",));
// error: explicit use of unboxed closure method `call_once`
}

fn bar(text: &str) {
println!("Calling {} it works!", text);
}

fn main() {
foo(bar);
}
```

Rust's implementation of closures is a bit different than other languages.
They are effectively syntax sugar for traits `Fn`, `FnMut` and `FnOnce`.
To understand better how the closures are implemented see here:
https://doc.rust-lang.org/book/closures.html#closure-implementation

To fix this you can call them using parenthesis, like this: `foo()`.
When you execute the closure with parenthesis, under the hood you are executing
the method `call`, `call_mut` or `call_once`. However, using them explicitly is
currently an experimental feature.

Example of an implicit call:

```
fn foo<F: Fn(&str)>(f: F) {
f("using ()"); // Calling using () it works!
}

fn bar(text: &str) {
println!("Calling {} it works!", text);
}

fn main() {
foo(bar);
}
```

To enable the explicit calls you need to add `#![feature(unboxed_closures)]`.

This feature is still unstable so you will also need to add
`#![feature(fn_traits)]`.
More details about this issue here:
https://github.com/rust-lang/rust/issues/29625

Example of use:

```
#![feature(fn_traits)]
#![feature(unboxed_closures)]

fn foo<F: Fn(&str)>(mut f: F) {
f.call(("call",)); // Calling 'call' it works!
f.call_mut(("call_mut",)); // Calling 'call_mut' it works!
f.call_once(("call_once",)); // Calling 'call_once' it works!
}

fn bar(text: &str) {
println!("Calling '{}' it works!", text);
}

fn main() {
foo(bar);
}
```

To see more about closures take a look here:
https://doc.rust-lang.org/book/closures.html`
"##,

E0178: r##"
In types, the `+` type operator has low precedence, so it is often necessary
to use parentheses.
Expand Down Expand Up @@ -4049,6 +3966,7 @@ register_diagnostics! {
E0167,
// E0168,
// E0173, // manual implementations of unboxed closure traits are experimental
// E0174,
E0182,
E0183,
// E0187, // can't infer the kind of the closure
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@

#![allow(dead_code)]
#![feature(rustc_attrs)]
#![feature(unboxed_closures)]
#![deny(hr_lifetime_in_assoc_type)]

trait Foo<'a> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@

#![allow(dead_code, unused_variables)]
#![deny(hr_lifetime_in_assoc_type)]
#![feature(unboxed_closures)]

use std::str::Chars;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@

// Ensure that invoking a closure counts as a unique immutable borrow

#![feature(unboxed_closures)]

type Fn<'a> = Box<FnMut() + 'a>;

struct Test<'a> {
Expand Down
2 changes: 0 additions & 2 deletions src/test/compile-fail/borrowck/borrowck-unboxed-closures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(overloaded_calls, unboxed_closures)]

fn a<F:Fn(isize, isize) -> isize>(mut f: F) {
let g = &mut f;
f(1, 2); //~ ERROR cannot borrow `f` as immutable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
#![allow(dead_code)]

fn foo<F: Fn()>(mut f: F) {
f.call(()); //~ ERROR explicit use of unboxed closure method `call`
f.call_mut(()); //~ ERROR explicit use of unboxed closure method `call_mut`
f.call_once(()); //~ ERROR explicit use of unboxed closure method `call_once`
f.call(()); //~ ERROR use of unstable library feature 'fn_traits'
f.call_mut(()); //~ ERROR use of unstable library feature 'fn_traits'
f.call_once(()); //~ ERROR use of unstable library feature 'fn_traits'
}

fn main() {}
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@

#![allow(dead_code)]

fn foo<F: Fn()>(mut f: F, mut g: F) {
Fn::call(&g, ()); //~ ERROR explicit use of unboxed closure method `call`
FnMut::call_mut(&mut g, ()); //~ ERROR explicit use of unboxed closure method `call_mut`
FnOnce::call_once(g, ()); //~ ERROR explicit use of unboxed closure method `call_once`
fn foo<F: Fn()>(mut f: F) {
Fn::call(&f, ()); //~ ERROR use of unstable library feature 'fn_traits'
FnMut::call_mut(&mut f, ()); //~ ERROR use of unstable library feature 'fn_traits'
FnOnce::call_once(f, ()); //~ ERROR use of unstable library feature 'fn_traits'
}

fn main() {}
1 change: 0 additions & 1 deletion src/test/compile-fail/fn-trait-formatting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(unboxed_closures)]
#![feature(box_syntax)]

fn needs_fn<F>(x: F) where F: Fn(isize) -> isize {}
Expand Down
2 changes: 0 additions & 2 deletions src/test/compile-fail/issue-16939.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(overloaded_calls, unboxed_closures)]

// Make sure we don't ICE when making an overloaded call with the
// wrong arity.

Expand Down
2 changes: 0 additions & 2 deletions src/test/compile-fail/issue-17033.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(overloaded_calls)]

fn f<'r>(p: &'r mut fn(p: &mut ())) {
(*p)(()) //~ ERROR mismatched types
//~| expected type `&mut ()`
Expand Down
2 changes: 0 additions & 2 deletions src/test/compile-fail/issue-17545.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(unboxed_closures)]

pub fn foo<'a, F: Fn(&'a ())>(bar: F) {
bar.call((
&(), //~ ERROR borrowed value does not live long enough
Expand Down
2 changes: 0 additions & 2 deletions src/test/compile-fail/issue-17551.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(unboxed_closures)]

use std::marker;

struct B<T>(marker::PhantomData<T>);
Expand Down
2 changes: 0 additions & 2 deletions src/test/compile-fail/issue-18532.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@
// when a type error or unconstrained type variable propagates
// into it.

#![feature(unboxed_closures)]

fn main() {
(return)((),());
//~^ ERROR the type of this value must be known
Expand Down
2 changes: 0 additions & 2 deletions src/test/compile-fail/issue-19521.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(unboxed_closures)]

fn main() {
"".homura()(); //~ ERROR no method named `homura` found
}
1 change: 0 additions & 1 deletion src/test/compile-fail/issue-19707.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(unboxed_closures)]
#![allow(dead_code)]

type foo = fn(&u8, &u8) -> &u8; //~ ERROR missing lifetime specifier
Expand Down
2 changes: 0 additions & 2 deletions src/test/compile-fail/issue-4335.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(unboxed_closures)]

fn id<T>(t: T) -> T { t }

fn f<'r, T>(v: &'r T) -> Box<FnMut() -> T + 'r> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@
// bound must be noncopyable. For details see
// http://smallcultfollowing.com/babysteps/blog/2013/04/30/the-case-of-the-recurring-closure/

#![feature(unboxed_closures)]

struct R<'a> {
// This struct is needed to create the
// otherwise infinite type of a fn that
Expand Down
2 changes: 0 additions & 2 deletions src/test/compile-fail/regionck-unboxed-closure-lifetimes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(unboxed_closures, overloaded_calls)]

use std::ops::FnMut;

fn main() {
Expand Down
2 changes: 0 additions & 2 deletions src/test/compile-fail/regions-escape-unboxed-closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(unboxed_closures)]

fn with_int(f: &mut FnMut(&isize)) {
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@

// Test that closures cannot subvert aliasing restrictions

#![feature(overloaded_calls, unboxed_closures)]

fn main() {
// Unboxed closure case
{
Expand Down
2 changes: 0 additions & 2 deletions src/test/compile-fail/regions-steal-closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(unboxed_closures)]

struct closure_box<'a> {
cl: Box<FnMut() + 'a>,
}
Expand Down
2 changes: 0 additions & 2 deletions src/test/compile-fail/unboxed-closure-immutable-capture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(unboxed_closures)]

// Test that even unboxed closures that are capable of mutating their
// environment cannot mutate captured variables that have not been
// declared mutable (#18335)
Expand Down
2 changes: 0 additions & 2 deletions src/test/compile-fail/unboxed-closure-region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(unboxed_closures)]

// Test that an unboxed closure that captures a free variable by
// reference cannot escape the region of that variable.
fn main() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(unboxed_closures)]

fn f<F:Nonexist(isize) -> isize>(x: F) {} //~ ERROR trait `Nonexist` is not in scope

type Typedef = isize;
Expand Down
2 changes: 0 additions & 2 deletions src/test/compile-fail/unboxed-closures-borrow-conflict.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(unboxed_closures)]

// Test that an unboxed closure that mutates a free variable will
// cause borrow conflicts.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
// That a closure whose expected argument types include two distinct
// bound regions.

#![feature(unboxed_closures)]

use std::cell::Cell;

fn doit<T,F>(val: T, f: &F)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(unboxed_closures)]

fn main() {
let mut zero = || {};
let () = zero.call_mut(());
Expand Down
Loading