diff options
| author | mejrs <59372212+mejrs@users.noreply.github.com> | 2025-07-08 22:37:12 +0200 |
|---|---|---|
| committer | mejrs <59372212+mejrs@users.noreply.github.com> | 2025-07-08 22:37:12 +0200 |
| commit | 25eb3829e5661ab85067188ca9e6586c29aed6e9 (patch) | |
| tree | 3ccb9a062c06d5e90c134b08b76b32082518b0e6 /compiler | |
| parent | 49421d1fa382fba84792e5d5dd7721c1c3e0e46e (diff) | |
| download | rust-25eb3829e5661ab85067188ca9e6586c29aed6e9.tar.gz rust-25eb3829e5661ab85067188ca9e6586c29aed6e9.zip | |
Error on moving unsized values rather than ICE'ing
Diffstat (limited to 'compiler')
4 files changed, 35 insertions, 2 deletions
diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index 4e35b143173..fa69820d5d2 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs @@ -141,7 +141,12 @@ enum LocalRef<'tcx, V> { /// `UnsizedPlace(p)`: `p` itself is a thin pointer (indirect place). /// `*p` is the wide pointer that references the actual unsized place. /// - /// Rust has no alloca and thus no ability to move the unsized place. + /// MIR only supports unsized args, not dynamically-sized locals, so + /// new unsized temps don't exist and we must reuse the referred-to place. + /// + /// FIXME: Since the removal of unsized locals in <https://github.com/rust-lang/rust/pull/142911>, + /// can we maybe use `Place` here? Or refactor it in another way? There are quite a few + /// `UnsizedPlace => bug` branches now. UnsizedPlace(PlaceRef<'tcx, V>), /// The backend [`OperandValue`] has already been generated. Operand(OperandRef<'tcx, V>), diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index eeb8d33ef65..eb8d671c939 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -241,6 +241,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { arg_expr.span, ObligationCauseCode::WellFormed(None), ); + + self.check_place_expr_if_unsized(fn_input_ty, arg_expr); } // First, let's unify the formal method signature with the expectation eagerly. @@ -543,6 +545,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } + /// If `unsized_fn_params` is active, check that unsized values are place expressions. Since + /// the removal of `unsized_locals` in <https://github.com/rust-lang/rust/pull/142911> we can't + /// store them in MIR locals as temporaries. + /// + /// If `unsized_fn_params` is inactive, this will be checked in borrowck instead. + fn check_place_expr_if_unsized(&self, ty: Ty<'tcx>, expr: &'tcx hir::Expr<'tcx>) { + if self.tcx.features().unsized_fn_params() && !expr.is_syntactic_place_expr() { + self.require_type_is_sized( + ty, + expr.span, + ObligationCauseCode::UnsizedNonPlaceExpr(expr.span), + ); + } + } + fn report_arg_errors( &self, compatibility_diagonal: IndexVec<ProvidedIdx, Compatibility<'tcx>>, @@ -1873,7 +1890,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }); } hir::StmtKind::Semi(expr) => { - self.check_expr(expr); + let ty = self.check_expr(expr); + self.check_place_expr_if_unsized(ty, expr); } } diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 1a5a9765ce7..5bdde3a514e 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -412,6 +412,10 @@ pub enum ObligationCauseCode<'tcx> { /// Obligations emitted during the normalization of a free type alias. TypeAlias(ObligationCauseCodeHandle<'tcx>, Span, DefId), + + /// Only reachable if the `unsized_fn_params` feature is used. Unsized function arguments must + /// be place expressions because we can't store them in MIR locals as temporaries. + UnsizedNonPlaceExpr(Span), } /// Whether a value can be extracted into a const. diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 362052e9fdb..c5b85c95ba2 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -3624,6 +3624,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ); suggest_remove_deref(err, &expr); } + ObligationCauseCode::UnsizedNonPlaceExpr(span) => { + err.span_note( + span, + "unsized values must be place expressions and cannot be put in temporaries", + ); + } } } |
