diff --git a/compiler/rustc_borrowck/messages.ftl b/compiler/rustc_borrowck/messages.ftl index 67fdb671742..d8ca62565fa 100644 --- a/compiler/rustc_borrowck/messages.ftl +++ b/compiler/rustc_borrowck/messages.ftl @@ -166,6 +166,8 @@ 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_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 d1d8cfa74aa..ca3ccf439f2 100644 --- a/compiler/rustc_borrowck/src/session_diagnostics.rs +++ b/compiler/rustc_borrowck/src/session_diagnostics.rs @@ -452,3 +452,10 @@ pub(crate) enum TypeNoCopy<'a, 'tcx> { #[note(borrowck_ty_no_impl_copy)] Note { is_partial_move: bool, ty: Ty<'tcx>, place: &'a str }, } + +#[derive(Diagnostic)] +#[diag(borrowck_simd_shuffle_last_const)] +pub(crate) struct SimdShuffleLastConst { + #[primary_span] + pub span: Span, +} diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 28286243e82..0f661421cdc 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -50,7 +50,7 @@ use rustc_mir_dataflow::move_paths::MoveData; use rustc_mir_dataflow::ResultsCursor; -use crate::session_diagnostics::MoveUnsized; +use crate::session_diagnostics::{MoveUnsized, SimdShuffleLastConst}; use crate::{ borrow_set::BorrowSet, constraints::{OutlivesConstraint, OutlivesConstraintSet}, @@ -1426,7 +1426,7 @@ fn check_terminator( .add_element(region_vid, term_location); } - self.check_call_inputs(body, term, &sig, args, term_location, *call_source); + self.check_call_inputs(body, term, func, &sig, args, term_location, *call_source); } TerminatorKind::Assert { cond, msg, .. } => { self.check_operand(cond, term_location); @@ -1546,25 +1546,36 @@ fn check_call_dest( } } + #[instrument(level = "debug", skip(self, body, term, func, term_location, call_source))] fn check_call_inputs( &mut self, body: &Body<'tcx>, term: &Terminator<'tcx>, + func: &Operand<'tcx>, sig: &ty::FnSig<'tcx>, args: &[Operand<'tcx>], term_location: Location, call_source: CallSource, ) { - debug!("check_call_inputs({:?}, {:?})", sig, args); if args.len() < sig.inputs().len() || (args.len() > sig.inputs().len() && !sig.c_variadic) { span_mirbug!(self, term, "call to {:?} with wrong # of args", sig); } - let func_ty = if let TerminatorKind::Call { func, .. } = &term.kind { - Some(func.ty(body, self.infcx.tcx)) - } else { - None - }; + let func_ty = func.ty(body, self.infcx.tcx); + if let ty::FnDef(def_id, _) = *func_ty.kind() { + if self.tcx().is_intrinsic(def_id) { + match self.tcx().item_name(def_id) { + sym::simd_shuffle => { + if !matches!(args[2], Operand::Constant(_)) { + self.tcx() + .sess + .emit_err(SimdShuffleLastConst { span: term.source_info.span }); + } + } + _ => {} + } + } + } debug!(?func_ty); for (n, (fn_arg, op_arg)) in iter::zip(sig.inputs(), args).enumerate() { @@ -1572,7 +1583,7 @@ fn check_call_inputs( let op_arg_ty = self.normalize(op_arg_ty, term_location); let category = if call_source.from_hir_call() { - ConstraintCategory::CallArgument(self.infcx.tcx.erase_regions(func_ty)) + ConstraintCategory::CallArgument(Some(self.infcx.tcx.erase_regions(func_ty))) } else { ConstraintCategory::Boring }; diff --git a/compiler/rustc_mir_transform/messages.ftl b/compiler/rustc_mir_transform/messages.ftl index 2598eb2ed09..5a99afc45b0 100644 --- a/compiler/rustc_mir_transform/messages.ftl +++ b/compiler/rustc_mir_transform/messages.ftl @@ -42,8 +42,6 @@ mir_transform_requires_unsafe = {$details} is unsafe and requires unsafe {$op_in } .not_inherited = items do not inherit unsafety from separate enclosing items -mir_transform_simd_shuffle_last_const = last argument of `simd_shuffle` is required to be a `const` item - mir_transform_target_feature_call_label = call to function with `#[target_feature]` mir_transform_target_feature_call_note = can only be called if the required target features are available diff --git a/compiler/rustc_mir_transform/src/errors.rs b/compiler/rustc_mir_transform/src/errors.rs index 4b796d79ef6..35373bcaa41 100644 --- a/compiler/rustc_mir_transform/src/errors.rs +++ b/compiler/rustc_mir_transform/src/errors.rs @@ -258,10 +258,3 @@ pub(crate) struct MustNotSuspendReason { pub span: Span, pub reason: String, } - -#[derive(Diagnostic)] -#[diag(mir_transform_simd_shuffle_last_const)] -pub(crate) struct SimdShuffleLastConst { - #[primary_span] - pub span: Span, -} diff --git a/compiler/rustc_mir_transform/src/lower_intrinsics.rs b/compiler/rustc_mir_transform/src/lower_intrinsics.rs index a8dc91ca439..13277d62bf4 100644 --- a/compiler/rustc_mir_transform/src/lower_intrinsics.rs +++ b/compiler/rustc_mir_transform/src/lower_intrinsics.rs @@ -1,11 +1,10 @@ //! Lowers intrinsic calls -use crate::{errors, MirPass}; +use crate::MirPass; use rustc_middle::mir::*; use rustc_middle::ty::GenericArgsRef; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::symbol::{sym, Symbol}; -use rustc_span::Span; use rustc_target::abi::{FieldIdx, VariantIdx}; pub struct LowerIntrinsics; @@ -304,9 +303,6 @@ fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { terminator.kind = TerminatorKind::Unreachable; } } - sym::simd_shuffle => { - validate_simd_shuffle(tcx, args, terminator.source_info.span); - } _ => {} } } @@ -325,9 +321,3 @@ fn resolve_rust_intrinsic<'tcx>( } None } - -fn validate_simd_shuffle<'tcx>(tcx: TyCtxt<'tcx>, args: &[Operand<'tcx>], span: Span) { - if !matches!(args[2], Operand::Constant(_)) { - tcx.sess.emit_err(errors::SimdShuffleLastConst { span }); - } -}