diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index a5d07f02197a..9d29a1037b60 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -250,10 +250,7 @@ pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'hir> { ExprKind::Await(expr, await_kw_span) => self.lower_expr_await(*await_kw_span, expr), ExprKind::Move(_, move_kw_span) => { if !self.tcx.features().move_expr() { - return self.expr_err( - *move_kw_span, - self.dcx().span_delayed_bug(*move_kw_span, "invalid move(expr)"), - ); + return self.expr_err(*move_kw_span, self.dcx().has_errors().unwrap()); } if let Some((ident, binding)) = self .move_expr_bindings @@ -276,10 +273,10 @@ pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'hir> { }), )) } else { - self.dcx().emit_err(MoveExprOnlyInPlainClosures { span: *move_kw_span }); - hir::ExprKind::Err( - self.dcx().span_delayed_bug(*move_kw_span, "invalid move(expr)"), - ) + let guar = self + .dcx() + .emit_err(MoveExprOnlyInPlainClosures { span: *move_kw_span }); + hir::ExprKind::Err(guar) } } ExprKind::Use(expr, use_kw_span) => self.lower_expr_use(*use_kw_span, expr), @@ -1087,6 +1084,8 @@ fn lower_expr_closure_expr(&mut self, e: &Expr, closure: &Closure) -> hir::Expr< let attrs = self.lower_attrs(expr_hir_id, &e.attrs, e.span, Target::from_expr(e)); match closure.coroutine_kind { + // FIXME(TaKO8Ki): Support `move(expr)` in coroutine closures too. + // For the first step, we only support plain closures. Some(coroutine_kind) => hir::Expr { hir_id: expr_hir_id, kind: self.lower_expr_coroutine_closure( @@ -1179,12 +1178,11 @@ fn lower_expr_plain_closure_with_move_exprs( )); } - let explicit_captures = self.arena.alloc_from_iter(lowered_occurrences.iter().map( - |(occurrence, _, binding)| hir::ExplicitCapture { - var_hir_id: *binding, - origin_span: self.lower_span(occurrence.move_kw_span), - }, - )); + let explicit_captures = self.arena.alloc_from_iter( + lowered_occurrences + .iter() + .map(|(_, _, binding)| hir::ExplicitCapture { var_hir_id: *binding }), + ); let closure_expr = self.arena.alloc(hir::Expr { hir_id: expr_hir_id, @@ -1380,9 +1378,10 @@ fn lower_expr_coroutine_closure( // knows that a `FnDecl` output type like `-> &str` actually means // "coroutine that returns &str", rather than directly returning a `&str`. kind: hir::ClosureKind::CoroutineClosure(coroutine_desugaring), - constness: hir::Constness::NotConst, + constness: self.lower_constness(constness), explicit_captures: &[], }); + hir::ExprKind::Closure(c) } diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 93fc3e0478b6..17f84154b9ff 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -638,6 +638,8 @@ pub fn internal(&self, feature: Symbol) -> bool { (unstable, mips_target_feature, "1.27.0", Some(150253)), /// Allows qualified paths in struct expressions, struct patterns and tuple struct patterns. (unstable, more_qualified_paths, "1.54.0", Some(86935)), + /// Allows `move(expr)` in closures. + (incomplete, move_expr, "CURRENT_RUSTC_VERSION", Some(155050)), /// The `movrs` target feature on x86. (unstable, movrs_target_feature, "1.88.0", Some(137976)), /// Allows the `multiple_supertrait_upcastable` lint. @@ -646,8 +648,6 @@ pub fn internal(&self, feature: Symbol) -> bool { (unstable, must_not_suspend, "1.57.0", Some(83310)), /// Allows `mut ref` and `mut ref mut` identifier patterns. (incomplete, mut_ref, "1.79.0", Some(123076)), - /// Allows `move(expr)` in closures. - (incomplete, move_expr, "CURRENT_RUSTC_VERSION", None), /// Allows using `#[naked]` on `extern "Rust"` functions. (unstable, naked_functions_rustic_abi, "1.88.0", Some(138997)), /// Allows using `#[target_feature(enable = "...")]` on `#[naked]` on functions. diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 668367e066a4..1c1a26846283 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1688,7 +1688,6 @@ pub struct Closure<'hir> { #[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct ExplicitCapture { pub var_hir_id: HirId, - pub origin_span: Span, } #[derive(Clone, PartialEq, Eq, Debug, Copy, Hash, StableHash, Encodable, Decodable)] diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index 1d57a71b104d..15af428d8ec4 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -217,8 +217,8 @@ fn analyze_closure( delegate.capture_information.push(( place, ty::CaptureInfo { - capture_kind_expr_id: Some(capture.var_hir_id), - path_expr_id: Some(capture.var_hir_id), + capture_kind_expr_id: Some(closure_hir_id), + path_expr_id: Some(closure_hir_id), capture_kind: UpvarCapture::ByValue, }, )); diff --git a/src/tools/rustfmt/src/expr.rs b/src/tools/rustfmt/src/expr.rs index daffc215c621..8a3674bff1ca 100644 --- a/src/tools/rustfmt/src/expr.rs +++ b/src/tools/rustfmt/src/expr.rs @@ -127,7 +127,13 @@ pub(crate) fn format_expr( } ast::ExprKind::Move(ref subexpr, move_kw_span) => { let inner_span = mk_sp(move_kw_span.hi(), expr.span.hi()); - rewrite_call(context, "move", std::slice::from_ref(subexpr), inner_span, shape) + rewrite_call( + context, + "move", + std::slice::from_ref(subexpr), + inner_span, + shape, + ) } ast::ExprKind::Paren(ref subexpr) => rewrite_paren(context, subexpr, shape, expr.span), ast::ExprKind::Binary(op, ref lhs, ref rhs) => { diff --git a/tests/ui/README.md b/tests/ui/README.md index 2fe1657e7ecf..1ab22a65ce50 100644 --- a/tests/ui/README.md +++ b/tests/ui/README.md @@ -927,6 +927,10 @@ Tests on the module system. **FIXME**: `tests/ui/imports/` should probably be merged with this. +## `tests/ui/move-expr/` + +Tests for `#![feature(move_expr)]`. + ## `tests/ui/moves` Tests on moves (destructive moves). diff --git a/tests/ui/feature-gates/feature-gate-move_expr.stderr b/tests/ui/feature-gates/feature-gate-move_expr.stderr index 28ab95ababc1..8b1da2c06893 100644 --- a/tests/ui/feature-gates/feature-gate-move_expr.stderr +++ b/tests/ui/feature-gates/feature-gate-move_expr.stderr @@ -4,6 +4,7 @@ error[E0658]: `move(expr)` syntax is experimental LL | let _ = || move(2); | ^^^^ | + = note: see issue #155050 for more information = help: add `#![feature(move_expr)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date