Use closure parse code
This commit is contained in:
parent
05c516446a
commit
81a926cc2a
20 changed files with 137 additions and 68 deletions
|
@ -1762,6 +1762,11 @@ pub enum CaptureBy {
|
||||||
},
|
},
|
||||||
/// `move` keyword was not specified.
|
/// `move` keyword was not specified.
|
||||||
Ref,
|
Ref,
|
||||||
|
/// `use |x| y + x`.
|
||||||
|
Use {
|
||||||
|
/// The span of the `use` keyword.
|
||||||
|
use_kw: Span,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Closure lifetime binder, `for<'a, 'b>` in `for<'a, 'b> |_: &'a (), _: &'b ()|`.
|
/// Closure lifetime binder, `for<'a, 'b>` in `for<'a, 'b> |_: &'a (), _: &'b ()|`.
|
||||||
|
|
|
@ -1899,6 +1899,9 @@ fn walk_capture_by<T: MutVisitor>(vis: &mut T, capture_by: &mut CaptureBy) {
|
||||||
CaptureBy::Value { move_kw } => {
|
CaptureBy::Value { move_kw } => {
|
||||||
vis.visit_span(move_kw);
|
vis.visit_span(move_kw);
|
||||||
}
|
}
|
||||||
|
CaptureBy::Use { use_kw } => {
|
||||||
|
vis.visit_span(use_kw);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -893,6 +893,7 @@ impl<'a> State<'a> {
|
||||||
fn print_capture_clause(&mut self, capture_clause: ast::CaptureBy) {
|
fn print_capture_clause(&mut self, capture_clause: ast::CaptureBy) {
|
||||||
match capture_clause {
|
match capture_clause {
|
||||||
ast::CaptureBy::Value { .. } => self.word_space("move"),
|
ast::CaptureBy::Value { .. } => self.word_space("move"),
|
||||||
|
ast::CaptureBy::Use { .. } => self.word_space("use"),
|
||||||
ast::CaptureBy::Ref => {}
|
ast::CaptureBy::Ref => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -403,6 +403,7 @@ impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||||
.expect_closure();
|
.expect_closure();
|
||||||
let span = match capture_clause {
|
let span = match capture_clause {
|
||||||
rustc_hir::CaptureBy::Value { move_kw } => move_kw.shrink_to_lo(),
|
rustc_hir::CaptureBy::Value { move_kw } => move_kw.shrink_to_lo(),
|
||||||
|
rustc_hir::CaptureBy::Use { use_kw } => use_kw.shrink_to_lo(),
|
||||||
rustc_hir::CaptureBy::Ref => fn_decl_span.shrink_to_lo(),
|
rustc_hir::CaptureBy::Ref => fn_decl_span.shrink_to_lo(),
|
||||||
};
|
};
|
||||||
diag.span_suggestion_verbose(
|
diag.span_suggestion_verbose(
|
||||||
|
|
|
@ -2305,6 +2305,7 @@ impl<'a> State<'a> {
|
||||||
fn print_capture_clause(&mut self, capture_clause: hir::CaptureBy) {
|
fn print_capture_clause(&mut self, capture_clause: hir::CaptureBy) {
|
||||||
match capture_clause {
|
match capture_clause {
|
||||||
hir::CaptureBy::Value { .. } => self.word_space("move"),
|
hir::CaptureBy::Value { .. } => self.word_space("move"),
|
||||||
|
hir::CaptureBy::Use { .. } => self.word_space("use"),
|
||||||
hir::CaptureBy::Ref => {}
|
hir::CaptureBy::Ref => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -670,7 +670,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
origin = updated.1;
|
origin = updated.1;
|
||||||
|
|
||||||
let (place, capture_kind) = match capture_clause {
|
let (place, capture_kind) = match capture_clause {
|
||||||
hir::CaptureBy::Value { .. } => adjust_for_move_closure(place, capture_kind),
|
hir::CaptureBy::Value { .. } | hir::CaptureBy::Use { .. } => {
|
||||||
|
adjust_for_move_closure(place, capture_kind)
|
||||||
|
}
|
||||||
hir::CaptureBy::Ref => adjust_for_non_move_closure(place, capture_kind),
|
hir::CaptureBy::Ref => adjust_for_non_move_closure(place, capture_kind),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1165,7 +1167,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
let ty = match closure_clause {
|
let ty = match closure_clause {
|
||||||
hir::CaptureBy::Value { .. } => ty, // For move closure the capture kind should be by value
|
hir::CaptureBy::Value { .. } => ty, // For move closure the capture kind should be by value
|
||||||
hir::CaptureBy::Ref => {
|
hir::CaptureBy::Ref | hir::CaptureBy::Use { .. } => {
|
||||||
// For non move closure the capture kind is the max capture kind of all captures
|
// For non move closure the capture kind is the max capture kind of all captures
|
||||||
// according to the ordering ImmBorrow < UniqueImmBorrow < MutBorrow < ByValue
|
// according to the ordering ImmBorrow < UniqueImmBorrow < MutBorrow < ByValue
|
||||||
let mut max_capture_info = root_var_min_capture_list.first().unwrap().info;
|
let mut max_capture_info = root_var_min_capture_list.first().unwrap().info;
|
||||||
|
@ -1292,7 +1294,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
.insert(UpvarMigrationInfo::CapturingNothing { use_span: upvar.span });
|
.insert(UpvarMigrationInfo::CapturingNothing { use_span: upvar.span });
|
||||||
return Some(diagnostics_info);
|
return Some(diagnostics_info);
|
||||||
}
|
}
|
||||||
hir::CaptureBy::Ref => {}
|
hir::CaptureBy::Ref | hir::CaptureBy::Use { .. } => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
return None;
|
return None;
|
||||||
|
@ -1689,10 +1691,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
//
|
//
|
||||||
// If the data will be moved out of this place, then the place will be truncated
|
// If the data will be moved out of this place, then the place will be truncated
|
||||||
// at the first Deref in `adjust_for_move_closure` and then moved into the closure.
|
// at the first Deref in `adjust_for_move_closure` and then moved into the closure.
|
||||||
hir::CaptureBy::Value { .. } if !place.deref_tys().any(Ty::is_ref) => {
|
hir::CaptureBy::Value { .. } | hir::CaptureBy::Use { .. }
|
||||||
|
if !place.deref_tys().any(Ty::is_ref) =>
|
||||||
|
{
|
||||||
ty::UpvarCapture::ByValue
|
ty::UpvarCapture::ByValue
|
||||||
}
|
}
|
||||||
hir::CaptureBy::Value { .. } | hir::CaptureBy::Ref => {
|
hir::CaptureBy::Value { .. } | hir::CaptureBy::Use { .. } | hir::CaptureBy::Ref => {
|
||||||
ty::UpvarCapture::ByRef(BorrowKind::Immutable)
|
ty::UpvarCapture::ByRef(BorrowKind::Immutable)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,9 @@ parse_async_move_block_in_2015 = `async move` blocks are only allowed in Rust 20
|
||||||
parse_async_move_order_incorrect = the order of `move` and `async` is incorrect
|
parse_async_move_order_incorrect = the order of `move` and `async` is incorrect
|
||||||
.suggestion = try switching the order
|
.suggestion = try switching the order
|
||||||
|
|
||||||
|
parse_async_use_order_incorrect = the order of `use` and `async` is incorrect
|
||||||
|
.suggestion = try switching the order
|
||||||
|
|
||||||
parse_at_dot_dot_in_struct_pattern = `@ ..` is not supported in struct patterns
|
parse_at_dot_dot_in_struct_pattern = `@ ..` is not supported in struct patterns
|
||||||
.suggestion = bind to each field separately or, if you don't need them, just remove `{$ident} @`
|
.suggestion = bind to each field separately or, if you don't need them, just remove `{$ident} @`
|
||||||
|
|
||||||
|
|
|
@ -1512,6 +1512,14 @@ pub(crate) struct AsyncMoveOrderIncorrect {
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(parse_async_use_order_incorrect)]
|
||||||
|
pub(crate) struct AsyncUseOrderIncorrect {
|
||||||
|
#[primary_span]
|
||||||
|
#[suggestion(style = "verbose", code = "async use", applicability = "maybe-incorrect")]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(parse_double_colon_in_bound)]
|
#[diag(parse_double_colon_in_bound)]
|
||||||
pub(crate) struct DoubleColonInBound {
|
pub(crate) struct DoubleColonInBound {
|
||||||
|
|
|
@ -1404,6 +1404,7 @@ impl<'a> Parser<'a> {
|
||||||
} else if this.check_path() {
|
} else if this.check_path() {
|
||||||
this.parse_expr_path_start()
|
this.parse_expr_path_start()
|
||||||
} else if this.check_keyword(exp!(Move))
|
} else if this.check_keyword(exp!(Move))
|
||||||
|
|| this.check_keyword(exp!(Use))
|
||||||
|| this.check_keyword(exp!(Static))
|
|| this.check_keyword(exp!(Static))
|
||||||
|| this.check_const_closure()
|
|| this.check_const_closure()
|
||||||
{
|
{
|
||||||
|
@ -2395,7 +2396,7 @@ impl<'a> Parser<'a> {
|
||||||
Ok(closure)
|
Ok(closure)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses an optional `move` prefix to a closure-like construct.
|
/// Parses an optional `move` or `use` prefix to a closure-like construct.
|
||||||
fn parse_capture_clause(&mut self) -> PResult<'a, CaptureBy> {
|
fn parse_capture_clause(&mut self) -> PResult<'a, CaptureBy> {
|
||||||
if self.eat_keyword(exp!(Move)) {
|
if self.eat_keyword(exp!(Move)) {
|
||||||
let move_kw_span = self.prev_token.span;
|
let move_kw_span = self.prev_token.span;
|
||||||
|
@ -2408,6 +2409,16 @@ impl<'a> Parser<'a> {
|
||||||
} else {
|
} else {
|
||||||
Ok(CaptureBy::Value { move_kw: move_kw_span })
|
Ok(CaptureBy::Value { move_kw: move_kw_span })
|
||||||
}
|
}
|
||||||
|
} else if self.eat_keyword(exp!(Use)) {
|
||||||
|
let use_kw_span = self.prev_token.span;
|
||||||
|
self.psess.gated_spans.gate(sym::ergonomic_clones, use_kw_span);
|
||||||
|
// Check for `use async` and recover
|
||||||
|
if self.check_keyword(exp!(Async)) {
|
||||||
|
let use_async_span = self.token.span.with_lo(self.prev_token.span.data().lo);
|
||||||
|
Err(self.dcx().create_err(errors::AsyncUseOrderIncorrect { span: use_async_span }))
|
||||||
|
} else {
|
||||||
|
Ok(CaptureBy::Use { use_kw: use_kw_span })
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Ok(CaptureBy::Ref)
|
Ok(CaptureBy::Ref)
|
||||||
}
|
}
|
||||||
|
@ -3422,7 +3433,7 @@ impl<'a> Parser<'a> {
|
||||||
self.is_keyword_ahead(lookahead, &[kw])
|
self.is_keyword_ahead(lookahead, &[kw])
|
||||||
&& ((
|
&& ((
|
||||||
// `async move {`
|
// `async move {`
|
||||||
self.is_keyword_ahead(lookahead + 1, &[kw::Move])
|
self.is_keyword_ahead(lookahead + 1, &[kw::Move, kw::Use])
|
||||||
&& self.look_ahead(lookahead + 2, |t| {
|
&& self.look_ahead(lookahead + 2, |t| {
|
||||||
*t == token::OpenDelim(Delimiter::Brace) || t.is_whole_block()
|
*t == token::OpenDelim(Delimiter::Brace) || t.is_whole_block()
|
||||||
})
|
})
|
||||||
|
|
|
@ -1290,7 +1290,7 @@ impl<'a> Parser<'a> {
|
||||||
if self.check_keyword(exp!(Static)) {
|
if self.check_keyword(exp!(Static)) {
|
||||||
// Check if this could be a closure.
|
// Check if this could be a closure.
|
||||||
!self.look_ahead(1, |token| {
|
!self.look_ahead(1, |token| {
|
||||||
if token.is_keyword(kw::Move) {
|
if token.is_keyword(kw::Move) || token.is_keyword(kw::Use) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
matches!(token.kind, token::Or | token::OrOr)
|
matches!(token.kind, token::Or | token::OrOr)
|
||||||
|
|
|
@ -44,22 +44,22 @@ note: while trying to match `r#async`
|
||||||
LL | (r#async) => (1)
|
LL | (r#async) => (1)
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
|
|
||||||
error: macro expansion ends with an incomplete expression: expected one of `move`, `|`, or `||`
|
error: macro expansion ends with an incomplete expression: expected one of `move`, `use`, `|`, or `||`
|
||||||
--> $DIR/auxiliary/edition-kw-macro-2015.rs:27:23
|
--> $DIR/auxiliary/edition-kw-macro-2015.rs:27:23
|
||||||
|
|
|
|
||||||
LL | ($i: ident) => ($i)
|
LL | ($i: ident) => ($i)
|
||||||
| ^ expected one of `move`, `|`, or `||`
|
| ^ expected one of `move`, `use`, `|`, or `||`
|
||||||
|
|
|
|
||||||
::: $DIR/edition-keywords-2018-2015-parsing.rs:22:8
|
::: $DIR/edition-keywords-2018-2015-parsing.rs:22:8
|
||||||
|
|
|
|
||||||
LL | if passes_ident!(async) == 1 {} // FIXME: Edition hygiene bug, async here is 2018 and reserved
|
LL | if passes_ident!(async) == 1 {} // FIXME: Edition hygiene bug, async here is 2018 and reserved
|
||||||
| -------------------- in this macro invocation
|
| -------------------- in this macro invocation
|
||||||
|
|
||||||
error: macro expansion ends with an incomplete expression: expected one of `move`, `|`, or `||`
|
error: macro expansion ends with an incomplete expression: expected one of `move`, `use`, `|`, or `||`
|
||||||
--> $DIR/edition-keywords-2018-2015-parsing.rs:24:24
|
--> $DIR/edition-keywords-2018-2015-parsing.rs:24:24
|
||||||
|
|
|
|
||||||
LL | if passes_tt!(async) == 1 {}
|
LL | if passes_tt!(async) == 1 {}
|
||||||
| ^ expected one of `move`, `|`, or `||`
|
| ^ expected one of `move`, `use`, `|`, or `||`
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/edition-keywords-2018-2015-parsing.rs:29:33
|
--> $DIR/edition-keywords-2018-2015-parsing.rs:29:33
|
||||||
|
|
|
@ -44,34 +44,34 @@ note: while trying to match `r#async`
|
||||||
LL | (r#async) => (1)
|
LL | (r#async) => (1)
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
|
|
||||||
error: macro expansion ends with an incomplete expression: expected one of `move`, `|`, or `||`
|
error: macro expansion ends with an incomplete expression: expected one of `move`, `use`, `|`, or `||`
|
||||||
--> $DIR/auxiliary/edition-kw-macro-2018.rs:27:23
|
--> $DIR/auxiliary/edition-kw-macro-2018.rs:27:23
|
||||||
|
|
|
|
||||||
LL | ($i: ident) => ($i)
|
LL | ($i: ident) => ($i)
|
||||||
| ^ expected one of `move`, `|`, or `||`
|
| ^ expected one of `move`, `use`, `|`, or `||`
|
||||||
|
|
|
|
||||||
::: $DIR/edition-keywords-2018-2018-parsing.rs:29:8
|
::: $DIR/edition-keywords-2018-2018-parsing.rs:29:8
|
||||||
|
|
|
|
||||||
LL | if passes_ident!(async) == 1 {} // FIXME: Edition hygiene bug, async here is 2018 and reserved
|
LL | if passes_ident!(async) == 1 {} // FIXME: Edition hygiene bug, async here is 2018 and reserved
|
||||||
| -------------------- in this macro invocation
|
| -------------------- in this macro invocation
|
||||||
|
|
||||||
error: macro expansion ends with an incomplete expression: expected one of `move`, `|`, or `||`
|
error: macro expansion ends with an incomplete expression: expected one of `move`, `use`, `|`, or `||`
|
||||||
--> $DIR/edition-keywords-2018-2018-parsing.rs:31:24
|
--> $DIR/edition-keywords-2018-2018-parsing.rs:31:24
|
||||||
|
|
|
|
||||||
LL | if passes_tt!(async) == 1 {}
|
LL | if passes_tt!(async) == 1 {}
|
||||||
| ^ expected one of `move`, `|`, or `||`
|
| ^ expected one of `move`, `use`, `|`, or `||`
|
||||||
|
|
||||||
error: macro expansion ends with an incomplete expression: expected one of `move`, `|`, or `||`
|
error: macro expansion ends with an incomplete expression: expected one of `move`, `use`, `|`, or `||`
|
||||||
--> $DIR/edition-keywords-2018-2018-parsing.rs:14:23
|
--> $DIR/edition-keywords-2018-2018-parsing.rs:14:23
|
||||||
|
|
|
|
||||||
LL | ($i: ident) => ($i)
|
LL | ($i: ident) => ($i)
|
||||||
| ^ expected one of `move`, `|`, or `||`
|
| ^ expected one of `move`, `use`, `|`, or `||`
|
||||||
|
|
||||||
error: macro expansion ends with an incomplete expression: expected one of `move`, `|`, or `||`
|
error: macro expansion ends with an incomplete expression: expected one of `move`, `use`, `|`, or `||`
|
||||||
--> $DIR/edition-keywords-2018-2018-parsing.rs:35:30
|
--> $DIR/edition-keywords-2018-2018-parsing.rs:35:30
|
||||||
|
|
|
|
||||||
LL | if local_passes_tt!(async) == 1 {}
|
LL | if local_passes_tt!(async) == 1 {}
|
||||||
| ^ expected one of `move`, `|`, or `||`
|
| ^ expected one of `move`, `use`, `|`, or `||`
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/edition-keywords-2018-2018-parsing.rs:40:33
|
--> $DIR/edition-keywords-2018-2018-parsing.rs:40:33
|
||||||
|
|
23
tests/ui/ergonomic-clones/closure.rs
Normal file
23
tests/ui/ergonomic-clones/closure.rs
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
//@ check-pass
|
||||||
|
//@ edition:2018
|
||||||
|
|
||||||
|
#![feature(ergonomic_clones)]
|
||||||
|
|
||||||
|
fn ergonomic_clone_closure() -> i32 {
|
||||||
|
let cl = use || {
|
||||||
|
1
|
||||||
|
};
|
||||||
|
cl()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ergonomic_clone_async_closures() -> String {
|
||||||
|
let s = String::from("hi");
|
||||||
|
|
||||||
|
async use {
|
||||||
|
22
|
||||||
|
};
|
||||||
|
|
||||||
|
s
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -7,12 +7,13 @@ fn ergonomic_closure_clone() {
|
||||||
let s1 = String::from("hi!");
|
let s1 = String::from("hi!");
|
||||||
|
|
||||||
let s2 = use || {
|
let s2 = use || {
|
||||||
//~^ ERROR incorrect use of `use`
|
//~^ ERROR `.use` calls are experimental [E0658]
|
||||||
s1
|
s1
|
||||||
};
|
};
|
||||||
|
|
||||||
let s3 = use || {
|
let s3 = use || {
|
||||||
//~^ ERROR incorrect use of `use`
|
//~^ ERROR `.use` calls are experimental [E0658]
|
||||||
|
//~| ERROR use of moved value: `s1` [E0382]
|
||||||
s1
|
s1
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,39 +1,3 @@
|
||||||
error: incorrect use of `use`
|
|
||||||
--> $DIR/feature-gate-ergonomic-clones.rs:9:14
|
|
||||||
|
|
|
||||||
LL | let s2 = use || {
|
|
||||||
| ______________^
|
|
||||||
LL | |
|
|
||||||
LL | | s1
|
|
||||||
LL | | };
|
|
||||||
| |_____^
|
|
||||||
|
|
|
||||||
help: `use` is a postfix operation
|
|
||||||
|
|
|
||||||
LL ~ let s2 = || {
|
|
||||||
LL |
|
|
||||||
LL | s1
|
|
||||||
LL ~ }.use;
|
|
||||||
|
|
|
||||||
|
|
||||||
error: incorrect use of `use`
|
|
||||||
--> $DIR/feature-gate-ergonomic-clones.rs:14:14
|
|
||||||
|
|
|
||||||
LL | let s3 = use || {
|
|
||||||
| ______________^
|
|
||||||
LL | |
|
|
||||||
LL | | s1
|
|
||||||
LL | | };
|
|
||||||
| |_____^
|
|
||||||
|
|
|
||||||
help: `use` is a postfix operation
|
|
||||||
|
|
|
||||||
LL ~ let s3 = || {
|
|
||||||
LL |
|
|
||||||
LL | s1
|
|
||||||
LL ~ }.use;
|
|
||||||
|
|
|
||||||
|
|
||||||
error[E0658]: `.use` calls are experimental
|
error[E0658]: `.use` calls are experimental
|
||||||
--> $DIR/feature-gate-ergonomic-clones.rs:2:7
|
--> $DIR/feature-gate-ergonomic-clones.rs:2:7
|
||||||
|
|
|
|
||||||
|
@ -44,6 +8,50 @@ LL | x.use
|
||||||
= help: add `#![feature(ergonomic_clones)]` to the crate attributes to enable
|
= help: add `#![feature(ergonomic_clones)]` to the crate attributes to enable
|
||||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error[E0658]: `.use` calls are experimental
|
||||||
|
--> $DIR/feature-gate-ergonomic-clones.rs:9:14
|
||||||
|
|
|
||||||
|
LL | let s2 = use || {
|
||||||
|
| ^^^
|
||||||
|
|
|
||||||
|
= note: see issue #132290 <https://github.com/rust-lang/rust/issues/132290> for more information
|
||||||
|
= help: add `#![feature(ergonomic_clones)]` to the crate attributes to enable
|
||||||
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0658`.
|
error[E0658]: `.use` calls are experimental
|
||||||
|
--> $DIR/feature-gate-ergonomic-clones.rs:14:14
|
||||||
|
|
|
||||||
|
LL | let s3 = use || {
|
||||||
|
| ^^^
|
||||||
|
|
|
||||||
|
= note: see issue #132290 <https://github.com/rust-lang/rust/issues/132290> for more information
|
||||||
|
= help: add `#![feature(ergonomic_clones)]` to the crate attributes to enable
|
||||||
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
|
error[E0382]: use of moved value: `s1`
|
||||||
|
--> $DIR/feature-gate-ergonomic-clones.rs:14:14
|
||||||
|
|
|
||||||
|
LL | let s1 = String::from("hi!");
|
||||||
|
| -- move occurs because `s1` has type `String`, which does not implement the `Copy` trait
|
||||||
|
LL |
|
||||||
|
LL | let s2 = use || {
|
||||||
|
| ------ value moved into closure here
|
||||||
|
LL |
|
||||||
|
LL | s1
|
||||||
|
| -- variable moved due to use in closure
|
||||||
|
...
|
||||||
|
LL | let s3 = use || {
|
||||||
|
| ^^^^^^ value used here after move
|
||||||
|
...
|
||||||
|
LL | s1
|
||||||
|
| -- use occurs due to use in closure
|
||||||
|
|
|
||||||
|
help: consider cloning the value if the performance cost is acceptable
|
||||||
|
|
|
||||||
|
LL | s1.clone()
|
||||||
|
| ++++++++
|
||||||
|
|
||||||
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0382, E0658.
|
||||||
|
For more information about an error, try `rustc --explain E0382`.
|
||||||
|
|
|
@ -30,7 +30,7 @@ fn in_try() {
|
||||||
// FIXME(#80931)
|
// FIXME(#80931)
|
||||||
fn in_async() {
|
fn in_async() {
|
||||||
async
|
async
|
||||||
let x = 0; //~ ERROR expected one of `move`, `|`, or `||`, found keyword `let`
|
let x = 0; //~ ERROR expected one of `move`, `use`, `|`, or `||`, found keyword `let`
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME(#78168)
|
// FIXME(#78168)
|
||||||
|
|
|
@ -43,11 +43,11 @@ error: expected expression, found reserved keyword `try`
|
||||||
LL | try
|
LL | try
|
||||||
| ^^^ expected expression
|
| ^^^ expected expression
|
||||||
|
|
||||||
error: expected one of `move`, `|`, or `||`, found keyword `let`
|
error: expected one of `move`, `use`, `|`, or `||`, found keyword `let`
|
||||||
--> $DIR/block-no-opening-brace.rs:33:9
|
--> $DIR/block-no-opening-brace.rs:33:9
|
||||||
|
|
|
|
||||||
LL | async
|
LL | async
|
||||||
| - expected one of `move`, `|`, or `||`
|
| - expected one of `move`, `use`, `|`, or `||`
|
||||||
LL | let x = 0;
|
LL | let x = 0;
|
||||||
| ^^^ unexpected token
|
| ^^^ unexpected token
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: expected one of `move`, `|`, or `||`, found `Move`
|
error: expected one of `move`, `use`, `|`, or `||`, found `Move`
|
||||||
--> $DIR/async-move.rs:4:11
|
--> $DIR/async-move.rs:4:11
|
||||||
|
|
|
|
||||||
LL | async Move {}
|
LL | async Move {}
|
||||||
| ^^^^ expected one of `move`, `|`, or `||`
|
| ^^^^ expected one of `move`, `use`, `|`, or `||`
|
||||||
|
|
|
|
||||||
help: write keyword `move` in lowercase
|
help: write keyword `move` in lowercase
|
||||||
|
|
|
|
||||||
|
|
|
@ -7,6 +7,6 @@ fn main() {
|
||||||
enum Foo { Bar }
|
enum Foo { Bar }
|
||||||
fn foo(x: impl Iterator<Item = Foo>) {
|
fn foo(x: impl Iterator<Item = Foo>) {
|
||||||
for <Foo>::Bar in x {}
|
for <Foo>::Bar in x {}
|
||||||
//~^ ERROR expected one of `move`, `static`, `|`
|
//~^ ERROR expected one of `move`, `static`, `use`, `|`
|
||||||
//~^^ ERROR `for<...>` binders for closures are experimental
|
//~^^ ERROR `for<...>` binders for closures are experimental
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: expected one of `move`, `static`, `|`, or `||`, found `::`
|
error: expected one of `move`, `static`, `use`, `|`, or `||`, found `::`
|
||||||
--> $DIR/recover-quantified-closure.rs:9:14
|
--> $DIR/recover-quantified-closure.rs:9:14
|
||||||
|
|
|
|
||||||
LL | for <Foo>::Bar in x {}
|
LL | for <Foo>::Bar in x {}
|
||||||
| ^^ expected one of `move`, `static`, `|`, or `||`
|
| ^^ expected one of `move`, `static`, `use`, `|`, or `||`
|
||||||
|
|
||||||
error[E0658]: `for<...>` binders for closures are experimental
|
error[E0658]: `for<...>` binders for closures are experimental
|
||||||
--> $DIR/recover-quantified-closure.rs:2:5
|
--> $DIR/recover-quantified-closure.rs:2:5
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue