about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2024-02-17 09:57:24 +0100
committerRalf Jung <post@ralfj.de>2024-02-20 07:50:46 +0100
commit396cf1e1f51ed37e320f47e0c7ff0dc7ddcb288b (patch)
treedc5dd1871241c10dcb767adccac733e68d827443 /compiler
parent0b9f6ad99482c9fc35baa5f40cebf21be4fd98b3 (diff)
downloadrust-396cf1e1f51ed37e320f47e0c7ff0dc7ddcb288b.tar.gz
rust-396cf1e1f51ed37e320f47e0c7ff0dc7ddcb288b.zip
require simd_insert, simd_extract indices to be constants
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_borrowck/messages.ftl8
-rw-r--r--compiler/rustc_borrowck/src/session_diagnostics.rs6
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs21
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/block.rs3
4 files changed, 29 insertions, 9 deletions
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::impls::MaybeInitializedPlaces;
 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 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
 
         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 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     .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);