diff --git a/src/libstd/future.rs b/src/libstd/future.rs index f74c84e6dfd48..7b1beb1ecda80 100644 --- a/src/libstd/future.rs +++ b/src/libstd/future.rs @@ -16,9 +16,10 @@ pub use core::future::*; /// /// This function returns a `GenFuture` underneath, but hides it in `impl Trait` to give /// better error messages (`impl Future` rather than `GenFuture<[closure.....]>`). +// This is `const` to avoid extra errors after we recover from `const async fn` #[doc(hidden)] #[unstable(feature = "gen_future", issue = "50547")] -pub fn from_generator>(x: T) -> impl Future { +pub const fn from_generator>(x: T) -> impl Future { GenFuture(x) } diff --git a/src/test/ui/async-await/no-const-async.rs b/src/test/ui/async-await/no-const-async.rs index b3c59734e036f..57a9f175ca318 100644 --- a/src/test/ui/async-await/no-const-async.rs +++ b/src/test/ui/async-await/no-const-async.rs @@ -3,3 +3,4 @@ pub const async fn x() {} //~^ ERROR functions cannot be both `const` and `async` +//~| ERROR `impl Trait` in const fn is unstable diff --git a/src/test/ui/async-await/no-const-async.stderr b/src/test/ui/async-await/no-const-async.stderr index f6ae0f1447ced..07559cd240bb6 100644 --- a/src/test/ui/async-await/no-const-async.stderr +++ b/src/test/ui/async-await/no-const-async.stderr @@ -7,5 +7,15 @@ LL | pub const async fn x() {} | | `async` because of this | `const` because of this -error: aborting due to previous error +error[E0723]: `impl Trait` in const fn is unstable + --> $DIR/no-const-async.rs:4:24 + | +LL | pub const async fn x() {} + | ^ + | + = note: see issue #57563 for more information + = help: add `#![feature(const_fn)]` to the crate attributes to enable + +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0723`. diff --git a/src/test/ui/borrowck/borrow-immutable-upvar-mutation-impl-trait.rs b/src/test/ui/borrowck/borrow-immutable-upvar-mutation-impl-trait.rs new file mode 100644 index 0000000000000..57198cb95e770 --- /dev/null +++ b/src/test/ui/borrowck/borrow-immutable-upvar-mutation-impl-trait.rs @@ -0,0 +1,14 @@ +#![feature(unboxed_closures)] + +// Tests that we can't assign to or mutably borrow upvars from `Fn` +// closures (issue #17780) + +fn main() {} + +fn bar() -> impl Fn() -> usize { + let mut x = 0; + move || { + x += 1; //~ ERROR cannot assign + x + } +} diff --git a/src/test/ui/borrowck/borrow-immutable-upvar-mutation-impl-trait.stderr b/src/test/ui/borrowck/borrow-immutable-upvar-mutation-impl-trait.stderr new file mode 100644 index 0000000000000..003c40d27736d --- /dev/null +++ b/src/test/ui/borrowck/borrow-immutable-upvar-mutation-impl-trait.stderr @@ -0,0 +1,16 @@ +error[E0594]: cannot assign to `x`, as it is a captured variable in a `Fn` closure + --> $DIR/borrow-immutable-upvar-mutation-impl-trait.rs:11:9 + | +LL | fn bar() -> impl Fn() -> usize { + | --- ------------------ change this to return `FnMut` instead of `Fn` +LL | let mut x = 0; +LL | / move || { +LL | | x += 1; + | | ^^^^^^ cannot assign +LL | | x +LL | | } + | |_____- in this closure + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0594`. diff --git a/src/test/ui/borrowck/borrow-immutable-upvar-mutation.rs b/src/test/ui/borrowck/borrow-immutable-upvar-mutation.rs index 62e27bcf1643f..e2f016614bf86 100644 --- a/src/test/ui/borrowck/borrow-immutable-upvar-mutation.rs +++ b/src/test/ui/borrowck/borrow-immutable-upvar-mutation.rs @@ -3,10 +3,16 @@ // Tests that we can't assign to or mutably borrow upvars from `Fn` // closures (issue #17780) -fn set(x: &mut usize) { *x = 5; } +fn set(x: &mut usize) { + *x = 5; +} -fn to_fn>(f: F) -> F { f } -fn to_fn_mut>(f: F) -> F { f } +fn to_fn>(f: F) -> F { + f +} +fn to_fn_mut>(f: F) -> F { + f +} fn main() { // By-ref captures @@ -33,7 +39,11 @@ fn main() { let _g = to_fn(move || set(&mut y)); //~ ERROR cannot borrow let mut z = 0; - let _h = to_fn_mut(move || { set(&mut z); to_fn(move || z = 42); }); //~ ERROR cannot assign + let _h = to_fn_mut(move || { + set(&mut z); + to_fn(move || z = 42); + //~^ ERROR cannot assign + }); } } @@ -44,11 +54,3 @@ fn foo() -> Box usize> { x }) } - -fn bar() -> impl Fn() -> usize { - let mut x = 0; - move || { - x += 1; //~ ERROR cannot assign - x - } -} diff --git a/src/test/ui/borrowck/borrow-immutable-upvar-mutation.stderr b/src/test/ui/borrowck/borrow-immutable-upvar-mutation.stderr index 3046b047d00f6..a28cb7431e6a9 100644 --- a/src/test/ui/borrowck/borrow-immutable-upvar-mutation.stderr +++ b/src/test/ui/borrowck/borrow-immutable-upvar-mutation.stderr @@ -1,8 +1,8 @@ error[E0594]: cannot assign to `x`, as it is a captured variable in a `Fn` closure - --> $DIR/borrow-immutable-upvar-mutation.rs:15:27 + --> $DIR/borrow-immutable-upvar-mutation.rs:21:27 | -LL | fn to_fn>(f: F) -> F { f } - | - change this to accept `FnMut` instead of `Fn` +LL | fn to_fn>(f: F) -> F { + | - change this to accept `FnMut` instead of `Fn` ... LL | let _f = to_fn(|| x = 42); | ----- ^^^^^^ cannot assign @@ -10,10 +10,10 @@ LL | let _f = to_fn(|| x = 42); | expects `Fn` instead of `FnMut` error[E0596]: cannot borrow `y` as mutable, as it is a captured variable in a `Fn` closure - --> $DIR/borrow-immutable-upvar-mutation.rs:18:31 + --> $DIR/borrow-immutable-upvar-mutation.rs:24:31 | -LL | fn to_fn>(f: F) -> F { f } - | - change this to accept `FnMut` instead of `Fn` +LL | fn to_fn>(f: F) -> F { + | - change this to accept `FnMut` instead of `Fn` ... LL | let _g = to_fn(|| set(&mut y)); | ----- ^^^^^^ cannot borrow as mutable @@ -21,10 +21,10 @@ LL | let _g = to_fn(|| set(&mut y)); | expects `Fn` instead of `FnMut` error[E0594]: cannot assign to `z`, as it is a captured variable in a `Fn` closure - --> $DIR/borrow-immutable-upvar-mutation.rs:23:22 + --> $DIR/borrow-immutable-upvar-mutation.rs:29:22 | -LL | fn to_fn>(f: F) -> F { f } - | - change this to accept `FnMut` instead of `Fn` +LL | fn to_fn>(f: F) -> F { + | - change this to accept `FnMut` instead of `Fn` ... LL | to_fn(|| z = 42); | ----- ^^^^^^ cannot assign @@ -32,10 +32,10 @@ LL | to_fn(|| z = 42); | expects `Fn` instead of `FnMut` error[E0594]: cannot assign to `x`, as it is a captured variable in a `Fn` closure - --> $DIR/borrow-immutable-upvar-mutation.rs:30:32 + --> $DIR/borrow-immutable-upvar-mutation.rs:36:32 | -LL | fn to_fn>(f: F) -> F { f } - | - change this to accept `FnMut` instead of `Fn` +LL | fn to_fn>(f: F) -> F { + | - change this to accept `FnMut` instead of `Fn` ... LL | let _f = to_fn(move || x = 42); | ----- ^^^^^^ cannot assign @@ -43,10 +43,10 @@ LL | let _f = to_fn(move || x = 42); | expects `Fn` instead of `FnMut` error[E0596]: cannot borrow `y` as mutable, as it is a captured variable in a `Fn` closure - --> $DIR/borrow-immutable-upvar-mutation.rs:33:36 + --> $DIR/borrow-immutable-upvar-mutation.rs:39:36 | -LL | fn to_fn>(f: F) -> F { f } - | - change this to accept `FnMut` instead of `Fn` +LL | fn to_fn>(f: F) -> F { + | - change this to accept `FnMut` instead of `Fn` ... LL | let _g = to_fn(move || set(&mut y)); | ----- ^^^^^^ cannot borrow as mutable @@ -54,18 +54,18 @@ LL | let _g = to_fn(move || set(&mut y)); | expects `Fn` instead of `FnMut` error[E0594]: cannot assign to `z`, as it is a captured variable in a `Fn` closure - --> $DIR/borrow-immutable-upvar-mutation.rs:36:65 + --> $DIR/borrow-immutable-upvar-mutation.rs:44:27 | -LL | fn to_fn>(f: F) -> F { f } - | - change this to accept `FnMut` instead of `Fn` +LL | fn to_fn>(f: F) -> F { + | - change this to accept `FnMut` instead of `Fn` ... -LL | let _h = to_fn_mut(move || { set(&mut z); to_fn(move || z = 42); }); - | ----- ^^^^^^ cannot assign - | | - | expects `Fn` instead of `FnMut` +LL | to_fn(move || z = 42); + | ----- ^^^^^^ cannot assign + | | + | expects `Fn` instead of `FnMut` error[E0594]: cannot assign to `x`, as it is a captured variable in a `Fn` closure - --> $DIR/borrow-immutable-upvar-mutation.rs:43:9 + --> $DIR/borrow-immutable-upvar-mutation.rs:53:9 | LL | fn foo() -> Box usize> { | --- ---------------------- change this to return `FnMut` instead of `Fn` @@ -78,20 +78,7 @@ LL | | x LL | | }) | |_____- in this closure -error[E0594]: cannot assign to `x`, as it is a captured variable in a `Fn` closure - --> $DIR/borrow-immutable-upvar-mutation.rs:51:9 - | -LL | fn bar() -> impl Fn() -> usize { - | --- ------------------ change this to return `FnMut` instead of `Fn` -LL | let mut x = 0; -LL | / move || { -LL | | x += 1; - | | ^^^^^^ cannot assign -LL | | x -LL | | } - | |_____- in this closure - -error: aborting due to 8 previous errors +error: aborting due to 7 previous errors Some errors have detailed explanations: E0594, E0596. For more information about an error, try `rustc --explain E0594`.