require simd_insert, simd_extract indices to be constants

This commit is contained in:
Ralf Jung 2024-02-17 09:57:24 +01:00
parent 0b9f6ad994
commit 396cf1e1f5
4 changed files with 29 additions and 9 deletions

View File

@ -163,7 +163,13 @@ borrowck_returned_lifetime_wrong =
borrowck_returned_ref_escaped = borrowck_returned_ref_escaped =
returns a reference to a captured variable which escapes the closure body 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 = borrowck_suggest_create_freash_reborrow =
consider reborrowing the `Pin` instead of moving it consider reborrowing the `Pin` instead of moving it

View File

@ -454,8 +454,10 @@ pub(crate) enum TypeNoCopy<'a, 'tcx> {
} }
#[derive(Diagnostic)] #[derive(Diagnostic)]
#[diag(borrowck_simd_shuffle_last_const)] #[diag(borrowck_simd_intrinsic_arg_const)]
pub(crate) struct SimdShuffleLastConst { pub(crate) struct SimdIntrinsicArgConst {
#[primary_span] #[primary_span]
pub span: Span, pub span: Span,
pub arg: usize,
pub intrinsic: String,
} }

View File

@ -49,7 +49,7 @@
use rustc_mir_dataflow::move_paths::MoveData; use rustc_mir_dataflow::move_paths::MoveData;
use rustc_mir_dataflow::ResultsCursor; use rustc_mir_dataflow::ResultsCursor;
use crate::session_diagnostics::{MoveUnsized, SimdShuffleLastConst}; use crate::session_diagnostics::{MoveUnsized, SimdIntrinsicArgConst};
use crate::{ use crate::{
borrow_set::BorrowSet, borrow_set::BorrowSet,
constraints::{OutlivesConstraint, OutlivesConstraintSet}, constraints::{OutlivesConstraint, OutlivesConstraintSet},
@ -1666,9 +1666,22 @@ fn check_call_inputs(
let func_ty = func.ty(body, self.infcx.tcx); let func_ty = func.ty(body, self.infcx.tcx);
if let ty::FnDef(def_id, _) = *func_ty.kind() { if let ty::FnDef(def_id, _) = *func_ty.kind() {
if let Some(sym::simd_shuffle) = self.tcx().intrinsic(def_id) { // Some of the SIMD intrinsics are special: they need a particular argument to be a constant.
if !matches!(args[2], Spanned { node: Operand::Constant(_), .. }) { // (Eventually this should use const-generics, but those are not up for the task yet:
self.tcx().dcx().emit_err(SimdShuffleLastConst { span: term.source_info.span }); // 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(),
});
} }
} }
} }

View File

@ -864,8 +864,7 @@ fn codegen_call_terminator(
.map(|(i, arg)| { .map(|(i, arg)| {
// The indices passed to simd_shuffle in the // The indices passed to simd_shuffle in the
// third argument must be constant. This is // third argument must be constant. This is
// checked by const-qualification, which also // checked by the type-checker.
// promotes any complex rvalues to constants.
if i == 2 && intrinsic == sym::simd_shuffle { if i == 2 && intrinsic == sym::simd_shuffle {
if let mir::Operand::Constant(constant) = &arg.node { if let mir::Operand::Constant(constant) = &arg.node {
let (llval, ty) = self.simd_shuffle_indices(bx, constant); let (llval, ty) = self.simd_shuffle_indices(bx, constant);