diff --git a/compiler/rustc_borrowck/messages.ftl b/compiler/rustc_borrowck/messages.ftl index 8c5a1d89709..bf14d5eb9a0 100644 --- a/compiler/rustc_borrowck/messages.ftl +++ b/compiler/rustc_borrowck/messages.ftl @@ -163,7 +163,13 @@ borrowck_returned_lifetime_wrong = borrowck_returned_ref_escaped = returns a reference to a captured variable which escapes the closure body -borrowck_simd_shuffle_last_const = last argument of `simd_shuffle` is required to be a `const` item +borrowck_simd_intrinsic_arg_const = + {$arg -> + [1] 1st + [2] 2nd + [3] 3rd + *[other] {$arg}th + } argument of `{$intrinsic}` is required to be a `const` item borrowck_suggest_create_freash_reborrow = consider reborrowing the `Pin` instead of moving it diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs index 1685624f247..a055ce95e8e 100644 --- a/compiler/rustc_borrowck/src/session_diagnostics.rs +++ b/compiler/rustc_borrowck/src/session_diagnostics.rs @@ -454,8 +454,10 @@ pub(crate) enum TypeNoCopy<'a, 'tcx> { } #[derive(Diagnostic)] -#[diag(borrowck_simd_shuffle_last_const)] -pub(crate) struct SimdShuffleLastConst { +#[diag(borrowck_simd_intrinsic_arg_const)] +pub(crate) struct SimdIntrinsicArgConst { #[primary_span] pub span: Span, + pub arg: usize, + pub intrinsic: String, } diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 64469727d0d..5d5ed62e731 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -49,7 +49,7 @@ use rustc_mir_dataflow::move_paths::MoveData; use rustc_mir_dataflow::ResultsCursor; -use crate::session_diagnostics::{MoveUnsized, SimdShuffleLastConst}; +use crate::session_diagnostics::{MoveUnsized, SimdIntrinsicArgConst}; use crate::{ borrow_set::BorrowSet, constraints::{OutlivesConstraint, OutlivesConstraintSet}, @@ -1666,9 +1666,22 @@ fn check_call_inputs( let func_ty = func.ty(body, self.infcx.tcx); if let ty::FnDef(def_id, _) = *func_ty.kind() { - if let Some(sym::simd_shuffle) = self.tcx().intrinsic(def_id) { - if !matches!(args[2], Spanned { node: Operand::Constant(_), .. }) { - self.tcx().dcx().emit_err(SimdShuffleLastConst { span: term.source_info.span }); + // Some of the SIMD intrinsics are special: they need a particular argument to be a constant. + // (Eventually this should use const-generics, but those are not up for the task yet: + // https://github.com/rust-lang/rust/issues/85229.) + if let Some(name @ (sym::simd_shuffle | sym::simd_insert | sym::simd_extract)) = + self.tcx().intrinsic(def_id) + { + let idx = match name { + sym::simd_shuffle => 2, + _ => 1, + }; + if !matches!(args[idx], Spanned { node: Operand::Constant(_), .. }) { + self.tcx().dcx().emit_err(SimdIntrinsicArgConst { + span: term.source_info.span, + arg: idx + 1, + intrinsic: name.to_string(), + }); } } } diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 75d413dedad..00007110938 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -864,8 +864,7 @@ fn codegen_call_terminator( .map(|(i, arg)| { // The indices passed to simd_shuffle in the // third argument must be constant. This is - // checked by const-qualification, which also - // promotes any complex rvalues to constants. + // checked by the type-checker. if i == 2 && intrinsic == sym::simd_shuffle { if let mir::Operand::Constant(constant) = &arg.node { let (llval, ty) = self.simd_shuffle_indices(bx, constant);