From 06b2dc0de07fc7e1fffe20f3efbc941f8f81d183 Mon Sep 17 00:00:00 2001 From: George Wort Date: Thu, 7 Dec 2023 15:57:33 +0000 Subject: [PATCH 01/15] Add #[rustc_intrinsic_const_vector_arg] to allow vectors to be passed as constants This allows constant vectors using a repr(simd) type to be propagated through to the backend by reusing the functionality used to do a similar thing for the simd_shuffle intrinsic. fix #118209 --- Cargo.lock | 1 + compiler/rustc_borrowck/Cargo.toml | 1 + compiler/rustc_borrowck/messages.ftl | 2 + .../rustc_borrowck/src/session_diagnostics.rs | 8 ++ compiler/rustc_borrowck/src/type_check/mod.rs | 33 ++++++- compiler/rustc_codegen_gcc/src/common.rs | 5 + compiler/rustc_codegen_llvm/src/common.rs | 4 + compiler/rustc_codegen_ssa/messages.ftl | 2 + compiler/rustc_codegen_ssa/src/errors.rs | 7 ++ compiler/rustc_codegen_ssa/src/mir/block.rs | 56 ++++++++++- .../rustc_codegen_ssa/src/mir/constant.rs | 23 ++--- .../rustc_codegen_ssa/src/traits/consts.rs | 1 + compiler/rustc_feature/src/builtin_attrs.rs | 3 + compiler/rustc_passes/messages.ftl | 12 +++ compiler/rustc_passes/src/check_attr.rs | 94 ++++++++++++++++++- compiler/rustc_passes/src/errors.rs | 37 ++++++++ compiler/rustc_span/src/symbol.rs | 1 + .../crates/hir-expand/src/inert_attr_macro.rs | 1 + .../rustc_intrinsic_const_vector_arg.rs | 58 ++++++++++++ .../rustc_intrinsic_const_vector_arg.stderr | 68 ++++++++++++++ .../rustc_intrinsic_const_vector_arg_calls.rs | 34 +++++++ ...tc_intrinsic_const_vector_arg_calls.stderr | 20 ++++ .../simd/intrinsic/inlining-issue67557-ice.rs | 4 +- .../ui/simd/intrinsic/inlining-issue67557.rs | 4 +- 24 files changed, 455 insertions(+), 24 deletions(-) create mode 100644 tests/ui/internal-lints/rustc_intrinsic_const_vector_arg.rs create mode 100644 tests/ui/internal-lints/rustc_intrinsic_const_vector_arg.stderr create mode 100644 tests/ui/internal-lints/rustc_intrinsic_const_vector_arg_calls.rs create mode 100644 tests/ui/internal-lints/rustc_intrinsic_const_vector_arg_calls.stderr diff --git a/Cargo.lock b/Cargo.lock index 3355e1ddaef86..3d43e3929c11a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3779,6 +3779,7 @@ dependencies = [ "either", "itertools", "polonius-engine", + "rustc_ast", "rustc_data_structures", "rustc_errors", "rustc_fluent_macro", diff --git a/compiler/rustc_borrowck/Cargo.toml b/compiler/rustc_borrowck/Cargo.toml index bafc62c7318b4..a53267502f901 100644 --- a/compiler/rustc_borrowck/Cargo.toml +++ b/compiler/rustc_borrowck/Cargo.toml @@ -8,6 +8,7 @@ edition = "2021" either = "1.5.0" itertools = "0.12" polonius-engine = "0.13.0" +rustc_ast = { path = "../rustc_ast" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_fluent_macro = { path = "../rustc_fluent_macro" } diff --git a/compiler/rustc_borrowck/messages.ftl b/compiler/rustc_borrowck/messages.ftl index c14a617eb91fe..826cf2a83d10e 100644 --- a/compiler/rustc_borrowck/messages.ftl +++ b/compiler/rustc_borrowck/messages.ftl @@ -74,6 +74,8 @@ borrowck_higher_ranked_lifetime_error = borrowck_higher_ranked_subtype_error = higher-ranked subtype error +borrowck_intrinsic_const_vector_arg_non_const = argument at index {$index} must be a constant + borrowck_lifetime_constraints_error = lifetime may not live long enough diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs index 40c2ef1c91e14..b59e5f6c41d64 100644 --- a/compiler/rustc_borrowck/src/session_diagnostics.rs +++ b/compiler/rustc_borrowck/src/session_diagnostics.rs @@ -479,3 +479,11 @@ pub(crate) struct SimdIntrinsicArgConst { pub arg: usize, pub intrinsic: String, } + +#[derive(Diagnostic)] +#[diag(borrowck_intrinsic_const_vector_arg_non_const)] +pub(crate) struct IntrinsicConstVectorArgNonConst { + #[primary_span] + pub span: Span, + pub index: u128, +} diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index db4b5209145f0..eb2d2017f9e12 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -51,7 +51,9 @@ use rustc_mir_dataflow::move_paths::MoveData; use rustc_mir_dataflow::ResultsCursor; use crate::renumber::RegionCtxt; -use crate::session_diagnostics::{MoveUnsized, SimdIntrinsicArgConst}; +use crate::session_diagnostics::{ + IntrinsicConstVectorArgNonConst, MoveUnsized, SimdShuffleLastConst, +}; use crate::{ borrow_set::BorrowSet, constraints::{OutlivesConstraint, OutlivesConstraintSet}, @@ -1630,6 +1632,35 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { intrinsic: name.to_string(), }); } + } else if let Some(attr) = + self.tcx().get_attr(def_id, sym::rustc_intrinsic_const_vector_arg) + { + match attr.meta_item_list() { + Some(items) => { + items.into_iter().for_each(|item: rustc_ast::NestedMetaItem| match item { + rustc_ast::NestedMetaItem::Lit(rustc_ast::MetaItemLit { + kind: rustc_ast::LitKind::Int(index, _), + .. + }) => { + if index >= args.len() as u128 { + span_mirbug!(self, term, "index out of bounds"); + } else { + if !matches!(args[index as usize], Operand::Constant(_)) { + self.tcx().sess.emit_err(IntrinsicConstVectorArgNonConst { + span: term.source_info.span, + index, + }); + } + } + } + _ => { + span_mirbug!(self, term, "invalid index"); + } + }); + } + // Error is reported by `rustc_attr!` + None => (), + } } } debug!(?func_ty); diff --git a/compiler/rustc_codegen_gcc/src/common.rs b/compiler/rustc_codegen_gcc/src/common.rs index 70f0dc37e39da..aa02bf118e93d 100644 --- a/compiler/rustc_codegen_gcc/src/common.rs +++ b/compiler/rustc_codegen_gcc/src/common.rs @@ -161,6 +161,11 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> { self.context.new_struct_constructor(None, struct_type.as_type(), None, values) } + fn const_vector(&self, values: &[RValue<'gcc>]) -> RValue<'gcc> { + let typ = self.type_vector(values[0].get_type(), values.len() as u64); + self.context.new_rvalue_from_vector(None, typ, values) + } + fn const_to_opt_uint(&self, _v: RValue<'gcc>) -> Option { // TODO(antoyo) None diff --git a/compiler/rustc_codegen_llvm/src/common.rs b/compiler/rustc_codegen_llvm/src/common.rs index fe64649cf70fb..0ed12b60ad6d1 100644 --- a/compiler/rustc_codegen_llvm/src/common.rs +++ b/compiler/rustc_codegen_llvm/src/common.rs @@ -224,6 +224,10 @@ impl<'ll, 'tcx> ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> { struct_in_context(self.llcx, elts, packed) } + fn const_vector(&self, elts: &[&'ll Value]) -> &'ll Value { + unsafe { llvm::LLVMConstVector(elts.as_ptr(), elts.len() as c_uint) } + } + fn const_to_opt_uint(&self, v: &'ll Value) -> Option { try_as_const_integral(v).and_then(|v| unsafe { let mut i = 0u64; diff --git a/compiler/rustc_codegen_ssa/messages.ftl b/compiler/rustc_codegen_ssa/messages.ftl index 000fe2e3ce0f5..be8271229a72a 100644 --- a/compiler/rustc_codegen_ssa/messages.ftl +++ b/compiler/rustc_codegen_ssa/messages.ftl @@ -19,6 +19,8 @@ codegen_ssa_check_installed_visual_studio = please ensure that Visual Studio 201 codegen_ssa_compiler_builtins_cannot_call = `compiler_builtins` cannot call functions through upstream monomorphizations; encountered invalid call from `{$caller}` to `{$callee}` +codegen_ssa_const_vector_evaluation = could not evaluate constant vector at compile time + codegen_ssa_copy_path = could not copy {$from} to {$to}: {$error} codegen_ssa_copy_path_buf = unable to copy {$source_file} to {$output_path}: {$error} diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index e9d31db92541b..d9faac7358939 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -598,6 +598,13 @@ pub struct ShuffleIndicesEvaluation { pub span: Span, } +#[derive(Diagnostic)] +#[diag(codegen_ssa_const_vector_evaluation)] +pub struct ConstVectorEvaluation { + #[primary_span] + pub span: Span, +} + #[derive(Diagnostic)] #[diag(codegen_ssa_missing_memory_ordering)] pub struct MissingMemoryOrdering; diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index c9c8f02c491bd..f682145d7fc69 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -5,13 +5,13 @@ use super::{CachedLlbb, FunctionCx, LocalRef}; use crate::base::{self, is_call_from_compiler_builtins_to_upstream_monomorphization}; use crate::common::{self, IntPredicate}; -use crate::errors::CompilerBuiltinsCannotCall; +use crate::errors; use crate::meth; use crate::traits::*; use crate::MemFlags; use rustc_ast as ast; -use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; +use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece, LitKind, MetaItemLit, NestedMetaItem}; use rustc_hir::lang_items::LangItem; use rustc_middle::mir::{self, AssertKind, BasicBlock, SwitchTargets, UnwindTerminateReason}; use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, ValidityRequirement}; @@ -925,7 +925,15 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // checked by the type-checker. if i == 2 && intrinsic.name == sym::simd_shuffle { if let mir::Operand::Constant(constant) = &arg.node { - let (llval, ty) = self.simd_shuffle_indices(bx, constant); + let (llval, ty) = self.early_evaluate_const_vector(bx, constant); + let llval = llval.unwrap_or_else(|| { + bx.tcx().sess.emit_err(errors::ShuffleIndicesEvaluation { + span: constant.span, + }); + // We've errored, so we don't have to produce working code. + let llty = bx.backend_type(bx.layout_of(ty)); + bx.const_undef(llty) + }); return OperandRef { val: Immediate(llval), layout: bx.layout_of(ty), @@ -1003,9 +1011,49 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { (args, None) }; + let const_vec_arg_indexes = (|| { + if let Some(def) = def + && let Some(attr) = + bx.tcx().get_attr(def.def_id(), sym::rustc_intrinsic_const_vector_arg) + { + attr.meta_item_list() + .iter() + .flatten() + .map(|item: &NestedMetaItem| match item { + NestedMetaItem::Lit(MetaItemLit { + kind: LitKind::Int(index, _), .. + }) => *index as usize, + _ => span_bug!(item.span(), "attribute argument must be an integer"), + }) + .collect() + } else { + Vec::::new() + } + })(); + let mut copied_constant_arguments = vec![]; 'make_args: for (i, arg) in first_args.iter().enumerate() { - let mut op = self.codegen_operand(bx, &arg.node); + let mut op = if const_vec_arg_indexes.contains(&i) { + // Force the specified argument to be constant by using const-qualification to promote any complex rvalues to constant. + if let mir::Operand::Constant(constant) = &arg.node + && constant.ty().is_simd() + { + let (llval, ty) = self.early_evaluate_const_vector(bx, &constant); + let llval = llval.unwrap_or_else(|| { + bx.tcx() + .sess + .emit_err(errors::ConstVectorEvaluation { span: constant.span }); + // We've errored, so we don't have to produce working code. + let llty = bx.backend_type(bx.layout_of(ty)); + bx.const_undef(llty) + }); + OperandRef { val: Immediate(llval), layout: bx.layout_of(ty) } + } else { + span_bug!(span, "argument at {i} must be a constant vector"); + } + } else { + self.codegen_operand(bx, &arg.node) + }; if let (0, Some(ty::InstanceKind::Virtual(_, idx))) = (i, def) { match op.val { diff --git a/compiler/rustc_codegen_ssa/src/mir/constant.rs b/compiler/rustc_codegen_ssa/src/mir/constant.rs index 35e9a3b7dc206..5dcfbe68c7156 100644 --- a/compiler/rustc_codegen_ssa/src/mir/constant.rs +++ b/compiler/rustc_codegen_ssa/src/mir/constant.rs @@ -1,4 +1,3 @@ -use crate::errors; use crate::mir::operand::OperandRef; use crate::traits::*; use rustc_middle::mir; @@ -29,7 +28,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { .expect("erroneous constant missed by mono item collection") } - /// This is a convenience helper for `simd_shuffle_indices`. It has the precondition + /// This is a convenience helper for `early_evaluate_const_vector`. It has the precondition /// that the given `constant` is an `Const::Unevaluated` and must be convertible to /// a `ValTree`. If you want a more general version of this, talk to `wg-const-eval` on zulip. /// @@ -60,12 +59,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { self.cx.tcx().const_eval_resolve_for_typeck(ty::ParamEnv::reveal_all(), uv, constant.span) } - /// process constant containing SIMD shuffle indices - pub fn simd_shuffle_indices( + /// process constant SIMD vector or constant containing SIMD shuffle indices + pub fn early_evaluate_const_vector( &mut self, bx: &Bx, constant: &mir::ConstOperand<'tcx>, - ) -> (Bx::Value, Ty<'tcx>) { + ) -> (Option, Ty<'tcx>) { let ty = self.monomorphize(constant.ty()); let val = self .eval_unevaluated_mir_constant_to_valtree(constant) @@ -85,17 +84,15 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { }; bx.scalar_to_backend(prim, scalar, bx.immediate_backend_type(layout)) } else { - bug!("simd shuffle field {:?}", field) + bug!("field is not a scalar {:?}", field) } }) .collect(); - bx.const_struct(&values, false) - }) - .unwrap_or_else(|| { - bx.tcx().dcx().emit_err(errors::ShuffleIndicesEvaluation { span: constant.span }); - // We've errored, so we don't have to produce working code. - let llty = bx.backend_type(bx.layout_of(ty)); - bx.const_undef(llty) + if ty.is_simd() { + bx.const_vector(&values) + } else { + bx.const_struct(&values, false) + } }); (val, ty) } diff --git a/compiler/rustc_codegen_ssa/src/traits/consts.rs b/compiler/rustc_codegen_ssa/src/traits/consts.rs index 3da732602c520..e6539b075e3db 100644 --- a/compiler/rustc_codegen_ssa/src/traits/consts.rs +++ b/compiler/rustc_codegen_ssa/src/traits/consts.rs @@ -29,6 +29,7 @@ pub trait ConstMethods<'tcx>: BackendTypes { fn const_str(&self, s: &str) -> (Self::Value, Self::Value); fn const_struct(&self, elts: &[Self::Value], packed: bool) -> Self::Value; + fn const_vector(&self, elts: &[Self::Value]) -> Self::Value; fn const_to_opt_uint(&self, v: Self::Value) -> Option; fn const_to_opt_u128(&self, v: Self::Value, sign_ext: bool) -> Option; diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 7b27049a579a1..8e452c36669b0 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -837,6 +837,9 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ rustc_runtime, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No, INTERNAL_UNSTABLE ), + rustc_attr!( + rustc_intrinsic_const_vector_arg, Normal, template!(List: "arg1_index, arg2_index, ..."), ErrorFollowing, INTERNAL_UNSTABLE + ), // ========================================================================== // Internal attributes, Layout related: diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 1d93cbaddd6fe..bc0df031fe441 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -601,6 +601,18 @@ passes_rustc_allow_const_fn_unstable = passes_rustc_dirty_clean = attribute requires -Z query-dep-graph to be enabled +passes_rustc_intrinsic_const_vector_arg = + attribute should be applied to functions in `extern "unadjusted"` modules + .label = not a function in an `extern "unadjusted"` module + +passes_rustc_intrinsic_const_vector_arg_invalid = attribute requires a parameter index + +passes_rustc_intrinsic_const_vector_arg_non_vector = parameter at index {$index} must be a simd type + .label = parameter is a non-simd type + +passes_rustc_intrinsic_const_vector_arg_out_of_bounds = function does not have a parameter at index {$index} + .label = function has {$arg_count} arguments + passes_rustc_layout_scalar_valid_range_arg = expected exactly one integer literal argument diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index ce2fa83810fe8..8008df486e09f 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -11,11 +11,15 @@ use rustc_data_structures::fx::FxHashMap; use rustc_errors::{Applicability, IntoDiagArg, MultiSpan}; use rustc_errors::{DiagCtxtHandle, StashKey}; use rustc_feature::{AttributeDuplicates, AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP}; -use rustc_hir::def_id::LocalModDefId; +use rustc_hir as hir; +use rustc_hir::def::Res; +use rustc_hir::def_id::{DefId, LocalModDefId}; + use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{self as hir}; use rustc_hir::{ - self, FnSig, ForeignItem, HirId, Item, ItemKind, TraitItem, CRATE_HIR_ID, CRATE_OWNER_ID, + self, FnSig, ForeignItem, HirId, Item, ItemKind, Path, PathSegment, QPath, TraitItem, TyKind, + CRATE_HIR_ID, CRATE_OWNER_ID, }; use rustc_hir::{MethodKind, Safety, Target}; use rustc_macros::LintDiagnostic; @@ -206,6 +210,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { [sym::rustc_safe_intrinsic] => { self.check_rustc_safe_intrinsic(hir_id, attr, span, target) } + sym::rustc_intrinsic_const_vector_arg => { + self.check_rustc_intrinsic_const_vector_arg(hir_id, attr, span, target) + } _ => true, }; @@ -2084,6 +2091,89 @@ impl<'tcx> CheckAttrVisitor<'tcx> { false } + fn check_rustc_intrinsic_const_vector_arg( + &self, + hir_id: HirId, + attr: &Attribute, + span: Span, + target: Target, + ) -> bool { + let hir = self.tcx.hir(); + + if let Target::ForeignFn = target + && let Some(parent) = hir.opt_parent_id(hir_id) + && let hir::Node::Item(Item { + kind: ItemKind::ForeignMod { abi: Abi::Unadjusted, .. }, + .. + }) = self.tcx.hir_node(parent) + { + let Some(list) = attr.meta_item_list() else { + // The attribute form is validated on AST. + return false; + }; + + let Some(decl) = self.tcx.hir_node(hir_id).fn_decl() else { + bug!("should be a function declaration"); + }; + + let arg_count = decl.inputs.len() as u128; + for meta in list { + if let Some(LitKind::Int(val, _)) = meta.lit().map(|lit| &lit.kind) { + if *val >= arg_count { + self.tcx.sess.emit_err(errors::RustcIntrinsicConstVectorArgOutOfBounds { + attr_span: attr.span, + span: span, + index: *val, + arg_count: decl.inputs.len(), + }); + return false; + } + + let param_ty = decl.inputs[*val as usize]; + let type_id: Option = match param_ty.kind { + TyKind::Path(path) => match path { + QPath::Resolved(_, Path { res: Res::Def(_, id), .. }) => Some(*id), + QPath::TypeRelative(_, PathSegment { res: Res::Def(_, id), .. }) => { + Some(*id) + } + _ => None, + }, + _ => None, + }; + + let is_simd = if let Some(type_id) = type_id { + self.tcx + .get_attrs(type_id, sym::repr) + .filter_map(|attr| attr.meta_item_list()) + .flatten() + .any(|hint: NestedMetaItem| hint.name_or_empty() == sym::simd) + } else { + false + }; + if !is_simd { + self.tcx.sess.emit_err(errors::RustcIntrinsicConstVectorArgNonVector { + attr_span: attr.span, + param_span: param_ty.span, + index: *val, + }); + return false; + } + } else { + self.tcx.sess.emit_err(errors::RustcIntrinsicConstVectorArgInvalid { + span: meta.span(), + }); + return false; + } + } + } else { + self.tcx + .sess + .emit_err(errors::RustcIntrinsicConstVectorArg { attr_span: attr.span, span }); + return false; + } + true + } + fn check_rustc_std_internal_symbol( &self, attr: &Attribute, diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 58d27d5b4bbaa..5e2b3b30a8ce3 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -617,6 +617,43 @@ pub struct RustcSafeIntrinsic { pub span: Span, } +#[derive(Diagnostic)] +#[diag(passes_rustc_intrinsic_const_vector_arg_out_of_bounds)] +pub(crate) struct RustcIntrinsicConstVectorArgOutOfBounds { + #[primary_span] + pub attr_span: Span, + #[label] + pub span: Span, + pub index: u128, + pub arg_count: usize, +} + +#[derive(Diagnostic)] +#[diag(passes_rustc_intrinsic_const_vector_arg_non_vector)] +pub(crate) struct RustcIntrinsicConstVectorArgNonVector { + #[primary_span] + pub attr_span: Span, + #[label] + pub param_span: Span, + pub index: u128, +} + +#[derive(Diagnostic)] +#[diag(passes_rustc_intrinsic_const_vector_arg_invalid)] +pub(crate) struct RustcIntrinsicConstVectorArgInvalid { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(passes_rustc_intrinsic_const_vector_arg)] +pub struct RustcIntrinsicConstVectorArg { + #[primary_span] + pub attr_span: Span, + #[label] + pub span: Span, +} + #[derive(Diagnostic)] #[diag(passes_rustc_std_internal_symbol)] pub struct RustcStdInternalSymbol { diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 5ae0138911673..79b0f82a15a66 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1633,6 +1633,7 @@ symbols! { rustc_insignificant_dtor, rustc_intrinsic, rustc_intrinsic_must_be_overridden, + rustc_intrinsic_const_vector_arg, rustc_layout, rustc_layout_scalar_valid_range_end, rustc_layout_scalar_valid_range_start, diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs index 7ead7e9390152..0675b37abc594 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs @@ -485,6 +485,7 @@ pub const INERT_ATTRIBUTES: &[BuiltinAttribute] = &[ rustc_attr!( rustc_const_panic_str, Normal, template!(Word), WarnFollowing, INTERNAL_UNSTABLE ), + rustc_attr!(rustc_intrinsic_const_vector_arg, Normal, template!(List: "arg_index1, arg_index2, ..."), ErrorFollowing, INTERNAL_UNSTABLE), // ========================================================================== // Internal attributes, Layout related: diff --git a/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg.rs b/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg.rs new file mode 100644 index 0000000000000..2d4bbd470372d --- /dev/null +++ b/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg.rs @@ -0,0 +1,58 @@ +// compile-flags: -Z unstable-options +#![feature(abi_unadjusted)] +#![feature(inline_const)] +#![feature(intrinsics)] +#![allow(non_camel_case_types)] +#![feature(repr_simd)] +#![feature(rustc_attrs)] +#![feature(simd_ffi)] +#![allow(unused)] + +#[repr(simd)] +#[derive(Clone)] +pub struct i8x2(i8, i8); + +extern "unadjusted" { + #[rustc_intrinsic_const_vector_arg] //~ ERROR malformed `rustc_intrinsic_const_vector_arg` attribute input + fn foo1(a: i8x2, b: i8); +} + +extern "unadjusted" { + #[rustc_intrinsic_const_vector_arg = "1"] //~ ERROR malformed `rustc_intrinsic_const_vector_arg` attribute input + fn foo2(a: i8x2, b: i8); +} + +#[rustc_intrinsic_const_vector_arg(0)] //~ ERROR attribute should be applied to functions in `extern "unadjusted"` modules +pub struct foo3(i8x2); + +extern "C" { + #[rustc_intrinsic_const_vector_arg(0)] //~ ERROR attribute should be applied to functions in `extern "unadjusted"` modules + fn foo4(a: i8x2); +} + +extern "unadjusted" { + #[rustc_intrinsic_const_vector_arg(0)] //~ ERROR function does not have a parameter at index 0 + fn foo5(); +} + +extern "unadjusted" { + #[rustc_intrinsic_const_vector_arg(1)] //~ ERROR function does not have a parameter at index 1 + fn foo6(a: i8x2); +} + +extern "unadjusted" { + #[rustc_intrinsic_const_vector_arg("bar")] //~ ERROR attribute requires a parameter index + fn foo7(a: i8x2); +} + +extern "unadjusted" { + #[rustc_intrinsic_const_vector_arg(0,2)] //~ ERROR function does not have a parameter at index 2 + fn foo8(a: i8x2, b: i8); +} + +extern "unadjusted" { + #[rustc_intrinsic_const_vector_arg(0)] //~ ERROR parameter at index 0 must be a simd type + fn foo9(a: i8); +} + +fn main() {} diff --git a/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg.stderr b/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg.stderr new file mode 100644 index 0000000000000..3182a9151d8c9 --- /dev/null +++ b/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg.stderr @@ -0,0 +1,68 @@ +error: malformed `rustc_intrinsic_const_vector_arg` attribute input + --> $DIR/rustc_intrinsic_const_vector_arg.rs:16:5 + | +LL | #[rustc_intrinsic_const_vector_arg] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_intrinsic_const_vector_arg(arg1_index, arg2_index, ...)]` + +error: malformed `rustc_intrinsic_const_vector_arg` attribute input + --> $DIR/rustc_intrinsic_const_vector_arg.rs:21:5 + | +LL | #[rustc_intrinsic_const_vector_arg = "1"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_intrinsic_const_vector_arg(arg1_index, arg2_index, ...)]` + +error: attribute should be applied to functions in `extern "unadjusted"` modules + --> $DIR/rustc_intrinsic_const_vector_arg.rs:25:1 + | +LL | #[rustc_intrinsic_const_vector_arg(0)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | pub struct foo3(i8x2); + | ---------------------- not a function in an `extern "unadjusted"` module + +error: attribute should be applied to functions in `extern "unadjusted"` modules + --> $DIR/rustc_intrinsic_const_vector_arg.rs:29:5 + | +LL | #[rustc_intrinsic_const_vector_arg(0)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn foo4(a: i8x2); + | ----------------- not a function in an `extern "unadjusted"` module + +error: function does not have a parameter at index 0 + --> $DIR/rustc_intrinsic_const_vector_arg.rs:34:5 + | +LL | #[rustc_intrinsic_const_vector_arg(0)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn foo5(); + | ---------- function has 0 arguments + +error: function does not have a parameter at index 1 + --> $DIR/rustc_intrinsic_const_vector_arg.rs:39:5 + | +LL | #[rustc_intrinsic_const_vector_arg(1)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn foo6(a: i8x2); + | ----------------- function has 1 arguments + +error: attribute requires a parameter index + --> $DIR/rustc_intrinsic_const_vector_arg.rs:44:40 + | +LL | #[rustc_intrinsic_const_vector_arg("bar")] + | ^^^^^ + +error: function does not have a parameter at index 2 + --> $DIR/rustc_intrinsic_const_vector_arg.rs:49:5 + | +LL | #[rustc_intrinsic_const_vector_arg(0,2)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn foo8(a: i8x2, b: i8); + | ------------------------ function has 2 arguments + +error: parameter at index 0 must be a simd type + --> $DIR/rustc_intrinsic_const_vector_arg.rs:54:5 + | +LL | #[rustc_intrinsic_const_vector_arg(0)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn foo9(a: i8); + | -- parameter is a non-simd type + +error: aborting due to 9 previous errors + diff --git a/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg_calls.rs b/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg_calls.rs new file mode 100644 index 0000000000000..00c341ff4f423 --- /dev/null +++ b/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg_calls.rs @@ -0,0 +1,34 @@ +// compile-flags: -Z unstable-options +#![feature(abi_unadjusted)] +#![feature(inline_const)] +#![feature(intrinsics)] +#![allow(non_camel_case_types)] +#![feature(repr_simd)] +#![feature(rustc_attrs)] +#![feature(simd_ffi)] +#![allow(unused)] + +#[repr(simd)] +#[derive(Clone)] +pub struct i8x2(i8, i8); + +extern "unadjusted" { + #[rustc_intrinsic_const_vector_arg(0)] // OK + fn foo1(a: i8x2); +} + +extern "unadjusted" { + #[rustc_intrinsic_const_vector_arg(0,1)] // OK + fn foo2(a: i8x2, b: i8x2); +} + +fn main() { + unsafe { + foo1(i8x2(0,1)); //~ ERROR argument at index 0 must be a constant + foo1({ i8x2(0,1) }); //~ ERROR argument at index 0 must be a constant + foo1(const { i8x2(0,1) }); // OK + + foo2(const { i8x2(0,1) }, { i8x2(2,3) }); //~ ERROR argument at index 1 must be a constant + foo2(const { i8x2(0,1) }, const { i8x2(2,3) }); // OK + } +} diff --git a/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg_calls.stderr b/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg_calls.stderr new file mode 100644 index 0000000000000..43a7d73efa5c3 --- /dev/null +++ b/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg_calls.stderr @@ -0,0 +1,20 @@ +error: argument at index 0 must be a constant + --> $DIR/rustc_intrinsic_const_vector_arg_calls.rs:27:9 + | +LL | foo1(i8x2(0,1)); + | ^^^^^^^^^^^^^^^ + +error: argument at index 0 must be a constant + --> $DIR/rustc_intrinsic_const_vector_arg_calls.rs:28:9 + | +LL | foo1({ i8x2(0,1) }); + | ^^^^^^^^^^^^^^^^^^^ + +error: argument at index 1 must be a constant + --> $DIR/rustc_intrinsic_const_vector_arg_calls.rs:31:9 + | +LL | foo2(const { i8x2(0,1) }, { i8x2(2,3) }); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/tests/ui/simd/intrinsic/inlining-issue67557-ice.rs b/tests/ui/simd/intrinsic/inlining-issue67557-ice.rs index 928d3824703e7..630af4da539b5 100644 --- a/tests/ui/simd/intrinsic/inlining-issue67557-ice.rs +++ b/tests/ui/simd/intrinsic/inlining-issue67557-ice.rs @@ -1,5 +1,5 @@ -// This used to cause an ICE for an internal index out of range due to simd_shuffle_indices being -// passed the wrong Instance, causing issues with inlining. See #67557. +// This used to cause an ICE for an internal index out of range due to early_evaluate_const_vector +// being passed the wrong Instance, causing issues with inlining. See #67557. // //@ run-pass //@ compile-flags: -Zmir-opt-level=4 diff --git a/tests/ui/simd/intrinsic/inlining-issue67557.rs b/tests/ui/simd/intrinsic/inlining-issue67557.rs index b8b8dbba547d1..f3896b36e412b 100644 --- a/tests/ui/simd/intrinsic/inlining-issue67557.rs +++ b/tests/ui/simd/intrinsic/inlining-issue67557.rs @@ -1,5 +1,5 @@ -// This used to cause assert_10_13 to unexpectingly fail, due to simd_shuffle_indices being passed -// the wrong Instance, causing issues with inlining. See #67557. +// This used to cause assert_10_13 to unexpectingly fail, due to early_evaluate_const_vector +// being passed the wrong Instance, causing issues with inlining. See #67557. // //@ run-pass //@ compile-flags: -Zmir-opt-level=4 From ca26d33132deec53d888dd5b2ea8bbd8cee7e1c7 Mon Sep 17 00:00:00 2001 From: George Wort Date: Mon, 18 Dec 2023 14:30:41 +0000 Subject: [PATCH 02/15] Add float testing and testing for wrapped arrays --- compiler/rustc_passes/messages.ftl | 4 +- compiler/rustc_passes/src/check_attr.rs | 46 ++++++++++++++---- .../rustc_intrinsic_const_vector_arg.rs | 12 ++++- .../rustc_intrinsic_const_vector_arg.stderr | 36 ++++++++------ .../rustc_intrinsic_const_vector_arg_calls.rs | 48 ++++++++++++++++--- ...tc_intrinsic_const_vector_arg_calls.stderr | 38 +++++++++++---- 6 files changed, 140 insertions(+), 44 deletions(-) diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index bc0df031fe441..506b239c29bf1 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -607,8 +607,8 @@ passes_rustc_intrinsic_const_vector_arg = passes_rustc_intrinsic_const_vector_arg_invalid = attribute requires a parameter index -passes_rustc_intrinsic_const_vector_arg_non_vector = parameter at index {$index} must be a simd type - .label = parameter is a non-simd type +passes_rustc_intrinsic_const_vector_arg_non_vector = parameter at index {$index} must be a simd type defined in the local crate + .label = parameter is a non-simd type or is not defined locally passes_rustc_intrinsic_const_vector_arg_out_of_bounds = function does not have a parameter at index {$index} .label = function has {$arg_count} arguments diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 8008df486e09f..d0815ee480bf7 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -2129,18 +2129,44 @@ impl<'tcx> CheckAttrVisitor<'tcx> { return false; } - let param_ty = decl.inputs[*val as usize]; - let type_id: Option = match param_ty.kind { - TyKind::Path(path) => match path { - QPath::Resolved(_, Path { res: Res::Def(_, id), .. }) => Some(*id), - QPath::TypeRelative(_, PathSegment { res: Res::Def(_, id), .. }) => { - Some(*id) - } + fn get_type_def(tcx: TyCtxt<'_>, param_ty: rustc_hir::Ty<'_>) -> Option { + let type_id: Option = match param_ty.kind { + TyKind::Path(path) => match path { + QPath::Resolved(_, Path { res: Res::Def(_, id), .. }) + | QPath::TypeRelative( + _, + PathSegment { res: Res::Def(_, id), .. }, + ) + | QPath::Resolved( + _, + Path { res: Res::SelfTyAlias { alias_to: id, .. }, .. }, + ) + | QPath::TypeRelative( + _, + PathSegment { + res: Res::SelfTyAlias { alias_to: id, .. }, .. + }, + ) => Some(*id), + _ => None, + }, _ => None, - }, - _ => None, - }; + }; + if let Some(type_id) = type_id + && let Some(did) = type_id.as_local() + { + if let Some(param_ty) = + tcx.hir_node(tcx.local_def_id_to_hir_id(did)).ty() + { + return get_type_def(tcx, *param_ty); + } else { + return Some(type_id); + } + } + None + } + let param_ty = decl.inputs[*val as usize]; + let type_id = get_type_def(self.tcx, param_ty); let is_simd = if let Some(type_id) = type_id { self.tcx .get_attrs(type_id, sym::repr) diff --git a/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg.rs b/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg.rs index 2d4bbd470372d..d8f45e9b13994 100644 --- a/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg.rs +++ b/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg.rs @@ -3,11 +3,14 @@ #![feature(inline_const)] #![feature(intrinsics)] #![allow(non_camel_case_types)] +#![feature(portable_simd)] #![feature(repr_simd)] #![feature(rustc_attrs)] #![feature(simd_ffi)] #![allow(unused)] +use std::simd::prelude::Simd; + #[repr(simd)] #[derive(Clone)] pub struct i8x2(i8, i8); @@ -46,13 +49,18 @@ extern "unadjusted" { } extern "unadjusted" { - #[rustc_intrinsic_const_vector_arg(0,2)] //~ ERROR function does not have a parameter at index 2 + #[rustc_intrinsic_const_vector_arg(0, 2)] //~ ERROR function does not have a parameter at index 2 fn foo8(a: i8x2, b: i8); } extern "unadjusted" { - #[rustc_intrinsic_const_vector_arg(0)] //~ ERROR parameter at index 0 must be a simd type + #[rustc_intrinsic_const_vector_arg(0)] //~ ERROR parameter at index 0 must be a simd type defined in the local crate fn foo9(a: i8); } +extern "unadjusted" { + #[rustc_intrinsic_const_vector_arg(0)] //~ ERROR parameter at index 0 must be a simd type defined in the local crate + fn foo10(a: Simd); +} + fn main() {} diff --git a/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg.stderr b/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg.stderr index 3182a9151d8c9..7ea9483da25dd 100644 --- a/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg.stderr +++ b/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg.stderr @@ -1,17 +1,17 @@ error: malformed `rustc_intrinsic_const_vector_arg` attribute input - --> $DIR/rustc_intrinsic_const_vector_arg.rs:16:5 + --> $DIR/rustc_intrinsic_const_vector_arg.rs:19:5 | LL | #[rustc_intrinsic_const_vector_arg] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_intrinsic_const_vector_arg(arg1_index, arg2_index, ...)]` error: malformed `rustc_intrinsic_const_vector_arg` attribute input - --> $DIR/rustc_intrinsic_const_vector_arg.rs:21:5 + --> $DIR/rustc_intrinsic_const_vector_arg.rs:24:5 | LL | #[rustc_intrinsic_const_vector_arg = "1"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_intrinsic_const_vector_arg(arg1_index, arg2_index, ...)]` error: attribute should be applied to functions in `extern "unadjusted"` modules - --> $DIR/rustc_intrinsic_const_vector_arg.rs:25:1 + --> $DIR/rustc_intrinsic_const_vector_arg.rs:28:1 | LL | #[rustc_intrinsic_const_vector_arg(0)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -19,7 +19,7 @@ LL | pub struct foo3(i8x2); | ---------------------- not a function in an `extern "unadjusted"` module error: attribute should be applied to functions in `extern "unadjusted"` modules - --> $DIR/rustc_intrinsic_const_vector_arg.rs:29:5 + --> $DIR/rustc_intrinsic_const_vector_arg.rs:32:5 | LL | #[rustc_intrinsic_const_vector_arg(0)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -27,7 +27,7 @@ LL | fn foo4(a: i8x2); | ----------------- not a function in an `extern "unadjusted"` module error: function does not have a parameter at index 0 - --> $DIR/rustc_intrinsic_const_vector_arg.rs:34:5 + --> $DIR/rustc_intrinsic_const_vector_arg.rs:37:5 | LL | #[rustc_intrinsic_const_vector_arg(0)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -35,7 +35,7 @@ LL | fn foo5(); | ---------- function has 0 arguments error: function does not have a parameter at index 1 - --> $DIR/rustc_intrinsic_const_vector_arg.rs:39:5 + --> $DIR/rustc_intrinsic_const_vector_arg.rs:42:5 | LL | #[rustc_intrinsic_const_vector_arg(1)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -43,26 +43,34 @@ LL | fn foo6(a: i8x2); | ----------------- function has 1 arguments error: attribute requires a parameter index - --> $DIR/rustc_intrinsic_const_vector_arg.rs:44:40 + --> $DIR/rustc_intrinsic_const_vector_arg.rs:47:40 | LL | #[rustc_intrinsic_const_vector_arg("bar")] | ^^^^^ error: function does not have a parameter at index 2 - --> $DIR/rustc_intrinsic_const_vector_arg.rs:49:5 + --> $DIR/rustc_intrinsic_const_vector_arg.rs:52:5 | -LL | #[rustc_intrinsic_const_vector_arg(0,2)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[rustc_intrinsic_const_vector_arg(0, 2)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ LL | fn foo8(a: i8x2, b: i8); | ------------------------ function has 2 arguments -error: parameter at index 0 must be a simd type - --> $DIR/rustc_intrinsic_const_vector_arg.rs:54:5 +error: parameter at index 0 must be a simd type defined in the local crate + --> $DIR/rustc_intrinsic_const_vector_arg.rs:57:5 | LL | #[rustc_intrinsic_const_vector_arg(0)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ LL | fn foo9(a: i8); - | -- parameter is a non-simd type + | -- parameter is a non-simd type or is not defined locally -error: aborting due to 9 previous errors +error: parameter at index 0 must be a simd type defined in the local crate + --> $DIR/rustc_intrinsic_const_vector_arg.rs:62:5 + | +LL | #[rustc_intrinsic_const_vector_arg(0)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn foo10(a: Simd); + | ----------- parameter is a non-simd type or is not defined locally + +error: aborting due to 10 previous errors diff --git a/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg_calls.rs b/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg_calls.rs index 00c341ff4f423..0d6501341fdb9 100644 --- a/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg_calls.rs +++ b/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg_calls.rs @@ -12,23 +12,59 @@ #[derive(Clone)] pub struct i8x2(i8, i8); +#[repr(simd)] +#[derive(Clone)] +pub struct f32x2(f32, f32); + +#[repr(simd)] +#[derive(Clone)] +pub struct i8x2_arr([i8; 2]); + +#[repr(simd)] +#[derive(Clone)] +pub struct f32x2_arr([f32; 2]); + extern "unadjusted" { #[rustc_intrinsic_const_vector_arg(0)] // OK fn foo1(a: i8x2); } extern "unadjusted" { - #[rustc_intrinsic_const_vector_arg(0,1)] // OK + #[rustc_intrinsic_const_vector_arg(0, 1)] // OK fn foo2(a: i8x2, b: i8x2); } +extern "unadjusted" { + #[rustc_intrinsic_const_vector_arg(0)] // OK + fn foo3(a: i8x2_arr); +} + +extern "unadjusted" { + #[rustc_intrinsic_const_vector_arg(0)] // OK + fn foo4(a: f32x2); +} + +extern "unadjusted" { + #[rustc_intrinsic_const_vector_arg(0)] // OK + fn foo5(a: f32x2_arr); +} + fn main() { unsafe { - foo1(i8x2(0,1)); //~ ERROR argument at index 0 must be a constant - foo1({ i8x2(0,1) }); //~ ERROR argument at index 0 must be a constant - foo1(const { i8x2(0,1) }); // OK + foo1(i8x2(0, 1)); //~ ERROR argument at index 0 must be a constant + foo1({ i8x2(0, 1) }); //~ ERROR argument at index 0 must be a constant + foo1(const { i8x2(0, 1) }); // OK + + foo2(const { i8x2(0, 1) }, { i8x2(2, 3) }); //~ ERROR argument at index 1 must be a constant + foo2(const { i8x2(0, 1) }, const { i8x2(2, 3) }); // OK + + foo3(i8x2_arr([0, 1])); //~ ERROR argument at index 0 must be a constant + foo3(const { i8x2_arr([0, 1]) }); // OK + + foo4(f32x2(0.0, 1.0)); //~ ERROR argument at index 0 must be a constant + foo4(const { f32x2(0.0, 1.0) }); // OK - foo2(const { i8x2(0,1) }, { i8x2(2,3) }); //~ ERROR argument at index 1 must be a constant - foo2(const { i8x2(0,1) }, const { i8x2(2,3) }); // OK + foo5(f32x2_arr([0.0, 1.0])); //~ ERROR argument at index 0 must be a constant + foo5(const { f32x2_arr([0.0, 1.0]) }); // OK } } diff --git a/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg_calls.stderr b/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg_calls.stderr index 43a7d73efa5c3..0415755a23b62 100644 --- a/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg_calls.stderr +++ b/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg_calls.stderr @@ -1,20 +1,38 @@ error: argument at index 0 must be a constant - --> $DIR/rustc_intrinsic_const_vector_arg_calls.rs:27:9 + --> $DIR/rustc_intrinsic_const_vector_arg_calls.rs:54:9 | -LL | foo1(i8x2(0,1)); - | ^^^^^^^^^^^^^^^ +LL | foo1(i8x2(0, 1)); + | ^^^^^^^^^^^^^^^^ error: argument at index 0 must be a constant - --> $DIR/rustc_intrinsic_const_vector_arg_calls.rs:28:9 + --> $DIR/rustc_intrinsic_const_vector_arg_calls.rs:55:9 | -LL | foo1({ i8x2(0,1) }); - | ^^^^^^^^^^^^^^^^^^^ +LL | foo1({ i8x2(0, 1) }); + | ^^^^^^^^^^^^^^^^^^^^ error: argument at index 1 must be a constant - --> $DIR/rustc_intrinsic_const_vector_arg_calls.rs:31:9 + --> $DIR/rustc_intrinsic_const_vector_arg_calls.rs:58:9 | -LL | foo2(const { i8x2(0,1) }, { i8x2(2,3) }); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | foo2(const { i8x2(0, 1) }, { i8x2(2, 3) }); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 3 previous errors +error: argument at index 0 must be a constant + --> $DIR/rustc_intrinsic_const_vector_arg_calls.rs:61:9 + | +LL | foo3(i8x2_arr([0, 1])); + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: argument at index 0 must be a constant + --> $DIR/rustc_intrinsic_const_vector_arg_calls.rs:64:9 + | +LL | foo4(f32x2(0.0, 1.0)); + | ^^^^^^^^^^^^^^^^^^^^^ + +error: argument at index 0 must be a constant + --> $DIR/rustc_intrinsic_const_vector_arg_calls.rs:67:9 + | +LL | foo5(f32x2_arr([0.0, 1.0])); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 6 previous errors From 859db1e3452429d7ef5b76d80d45f0547edad5bf Mon Sep 17 00:00:00 2001 From: George Wort Date: Thu, 18 Jan 2024 17:39:41 +0000 Subject: [PATCH 03/15] Removed rust-analyzer change and rebased --- compiler/rustc_borrowck/src/type_check/mod.rs | 15 ++++++++++----- compiler/rustc_codegen_ssa/src/mir/block.rs | 6 +++--- compiler/rustc_passes/src/check_attr.rs | 19 ++++++++----------- .../crates/hir-expand/src/inert_attr_macro.rs | 1 - 4 files changed, 21 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index eb2d2017f9e12..9316aa9a10856 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -1645,11 +1645,16 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { if index >= args.len() as u128 { span_mirbug!(self, term, "index out of bounds"); } else { - if !matches!(args[index as usize], Operand::Constant(_)) { - self.tcx().sess.emit_err(IntrinsicConstVectorArgNonConst { - span: term.source_info.span, - index, - }); + if !matches!( + args[index.get() as usize], + Spanned { node: Operand::Constant(_), .. } + ) { + self.tcx().dcx().emit_err( + IntrinsicConstVectorArgNonConst { + span: term.source_info.span, + index: index.get(), + }, + ); } } } diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index f682145d7fc69..7ca9d38b28139 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -927,7 +927,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { if let mir::Operand::Constant(constant) = &arg.node { let (llval, ty) = self.early_evaluate_const_vector(bx, constant); let llval = llval.unwrap_or_else(|| { - bx.tcx().sess.emit_err(errors::ShuffleIndicesEvaluation { + bx.tcx().dcx().emit_err(errors::ShuffleIndicesEvaluation { span: constant.span, }); // We've errored, so we don't have to produce working code. @@ -1022,7 +1022,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { .map(|item: &NestedMetaItem| match item { NestedMetaItem::Lit(MetaItemLit { kind: LitKind::Int(index, _), .. - }) => *index as usize, + }) => index.get() as usize, _ => span_bug!(item.span(), "attribute argument must be an integer"), }) .collect() @@ -1041,7 +1041,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let (llval, ty) = self.early_evaluate_const_vector(bx, &constant); let llval = llval.unwrap_or_else(|| { bx.tcx() - .sess + .dcx() .emit_err(errors::ConstVectorEvaluation { span: constant.span }); // We've errored, so we don't have to produce working code. let llty = bx.backend_type(bx.layout_of(ty)); diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index d0815ee480bf7..01460118b0c07 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -2098,14 +2098,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> { span: Span, target: Target, ) -> bool { - let hir = self.tcx.hir(); - if let Target::ForeignFn = target - && let Some(parent) = hir.opt_parent_id(hir_id) && let hir::Node::Item(Item { kind: ItemKind::ForeignMod { abi: Abi::Unadjusted, .. }, .. - }) = self.tcx.hir_node(parent) + }) = self.tcx.parent_hir_node(hir_id) { let Some(list) = attr.meta_item_list() else { // The attribute form is validated on AST. @@ -2120,10 +2117,10 @@ impl<'tcx> CheckAttrVisitor<'tcx> { for meta in list { if let Some(LitKind::Int(val, _)) = meta.lit().map(|lit| &lit.kind) { if *val >= arg_count { - self.tcx.sess.emit_err(errors::RustcIntrinsicConstVectorArgOutOfBounds { + self.tcx.dcx().emit_err(errors::RustcIntrinsicConstVectorArgOutOfBounds { attr_span: attr.span, span: span, - index: *val, + index: val.get(), arg_count: decl.inputs.len(), }); return false; @@ -2165,7 +2162,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { None } - let param_ty = decl.inputs[*val as usize]; + let param_ty = decl.inputs[val.get() as usize]; let type_id = get_type_def(self.tcx, param_ty); let is_simd = if let Some(type_id) = type_id { self.tcx @@ -2177,15 +2174,15 @@ impl<'tcx> CheckAttrVisitor<'tcx> { false }; if !is_simd { - self.tcx.sess.emit_err(errors::RustcIntrinsicConstVectorArgNonVector { + self.tcx.dcx().emit_err(errors::RustcIntrinsicConstVectorArgNonVector { attr_span: attr.span, param_span: param_ty.span, - index: *val, + index: val.get(), }); return false; } } else { - self.tcx.sess.emit_err(errors::RustcIntrinsicConstVectorArgInvalid { + self.tcx.dcx().emit_err(errors::RustcIntrinsicConstVectorArgInvalid { span: meta.span(), }); return false; @@ -2193,7 +2190,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } else { self.tcx - .sess + .dcx() .emit_err(errors::RustcIntrinsicConstVectorArg { attr_span: attr.span, span }); return false; } diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs index 0675b37abc594..7ead7e9390152 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs @@ -485,7 +485,6 @@ pub const INERT_ATTRIBUTES: &[BuiltinAttribute] = &[ rustc_attr!( rustc_const_panic_str, Normal, template!(Word), WarnFollowing, INTERNAL_UNSTABLE ), - rustc_attr!(rustc_intrinsic_const_vector_arg, Normal, template!(List: "arg_index1, arg_index2, ..."), ErrorFollowing, INTERNAL_UNSTABLE), // ========================================================================== // Internal attributes, Layout related: From 489c4497557515eef539fee334f3cddb3b5c446e Mon Sep 17 00:00:00 2001 From: James Barford-Evans Date: Tue, 16 Jul 2024 16:16:53 +0100 Subject: [PATCH 04/15] fixes from rebase --- compiler/rustc_borrowck/src/type_check/mod.rs | 4 +++- compiler/rustc_codegen_ssa/src/mir/block.rs | 2 +- compiler/rustc_feature/src/builtin_attrs.rs | 2 +- compiler/rustc_passes/src/check_attr.rs | 3 +-- compiler/rustc_span/src/symbol.rs | 2 +- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 9316aa9a10856..8d6d4318cc7cb 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -52,7 +52,9 @@ use rustc_mir_dataflow::ResultsCursor; use crate::renumber::RegionCtxt; use crate::session_diagnostics::{ - IntrinsicConstVectorArgNonConst, MoveUnsized, SimdShuffleLastConst, + IntrinsicConstVectorArgNonConst, + MoveUnsized, + SimdIntrinsicArgConst, }; use crate::{ borrow_set::BorrowSet, diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 7ca9d38b28139..7ddf334db604c 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -169,7 +169,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> { if destination.is_some() { let caller = with_no_trimmed_paths!(tcx.def_path_str(fx.instance.def_id())); let callee = with_no_trimmed_paths!(tcx.def_path_str(instance.def_id())); - tcx.dcx().emit_err(CompilerBuiltinsCannotCall { caller, callee }); + tcx.dcx().emit_err(errors::CompilerBuiltinsCannotCall { caller, callee }); } else { info!( "compiler_builtins call to diverging function {:?} replaced with abort", diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 8e452c36669b0..78d00bf8744de 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -838,7 +838,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ EncodeCrossCrate::No, INTERNAL_UNSTABLE ), rustc_attr!( - rustc_intrinsic_const_vector_arg, Normal, template!(List: "arg1_index, arg2_index, ..."), ErrorFollowing, INTERNAL_UNSTABLE + rustc_intrinsic_const_vector_arg, Normal, template!(List: "arg1_index, arg2_index, ..."), ErrorFollowing, EncodeCrossCrate::Yes, INTERNAL_UNSTABLE ), // ========================================================================== diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 01460118b0c07..d53af47555fb4 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -16,7 +16,6 @@ use rustc_hir::def::Res; use rustc_hir::def_id::{DefId, LocalModDefId}; use rustc_hir::intravisit::{self, Visitor}; -use rustc_hir::{self as hir}; use rustc_hir::{ self, FnSig, ForeignItem, HirId, Item, ItemKind, Path, PathSegment, QPath, TraitItem, TyKind, CRATE_HIR_ID, CRATE_OWNER_ID, @@ -210,7 +209,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { [sym::rustc_safe_intrinsic] => { self.check_rustc_safe_intrinsic(hir_id, attr, span, target) } - sym::rustc_intrinsic_const_vector_arg => { + [sym::rustc_intrinsic_const_vector_arg] => { self.check_rustc_intrinsic_const_vector_arg(hir_id, attr, span, target) } _ => true, diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 79b0f82a15a66..1fadd4c5a347b 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1632,8 +1632,8 @@ symbols! { rustc_inherit_overflow_checks, rustc_insignificant_dtor, rustc_intrinsic, - rustc_intrinsic_must_be_overridden, rustc_intrinsic_const_vector_arg, + rustc_intrinsic_must_be_overridden, rustc_layout, rustc_layout_scalar_valid_range_end, rustc_layout_scalar_valid_range_start, From 860f66eaf081a8efce199e3912efa8ff8cda605d Mon Sep 17 00:00:00 2001 From: James Barford-Evans Date: Wed, 17 Jul 2024 13:14:16 +0100 Subject: [PATCH 05/15] Update tests to use //@ when specifying -Z --- tests/ui/internal-lints/rustc_intrinsic_const_vector_arg.rs | 2 +- .../ui/internal-lints/rustc_intrinsic_const_vector_arg_calls.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg.rs b/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg.rs index d8f45e9b13994..4b241a002cc8d 100644 --- a/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg.rs +++ b/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg.rs @@ -1,4 +1,4 @@ -// compile-flags: -Z unstable-options +//@ compile-flags: -Z unstable-options #![feature(abi_unadjusted)] #![feature(inline_const)] #![feature(intrinsics)] diff --git a/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg_calls.rs b/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg_calls.rs index 0d6501341fdb9..bb6372cbe1394 100644 --- a/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg_calls.rs +++ b/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg_calls.rs @@ -1,4 +1,4 @@ -// compile-flags: -Z unstable-options +//@ compile-flags: -Z unstable-options #![feature(abi_unadjusted)] #![feature(inline_const)] #![feature(intrinsics)] From e0f293346639a22b7516e4440c2d638c6c706eba Mon Sep 17 00:00:00 2001 From: James Barford-Evans Date: Wed, 17 Jul 2024 15:35:58 +0100 Subject: [PATCH 06/15] tests - remove unneeded attribute and update stderr files --- .../rustc_intrinsic_const_vector_arg.rs | 1 - .../rustc_intrinsic_const_vector_arg.stderr | 20 +++++++++---------- .../rustc_intrinsic_const_vector_arg_calls.rs | 1 - ...tc_intrinsic_const_vector_arg_calls.stderr | 12 +++++------ 4 files changed, 16 insertions(+), 18 deletions(-) diff --git a/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg.rs b/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg.rs index 4b241a002cc8d..ee0a0341a6a70 100644 --- a/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg.rs +++ b/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg.rs @@ -1,6 +1,5 @@ //@ compile-flags: -Z unstable-options #![feature(abi_unadjusted)] -#![feature(inline_const)] #![feature(intrinsics)] #![allow(non_camel_case_types)] #![feature(portable_simd)] diff --git a/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg.stderr b/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg.stderr index 7ea9483da25dd..a7016e1ba4e60 100644 --- a/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg.stderr +++ b/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg.stderr @@ -1,17 +1,17 @@ error: malformed `rustc_intrinsic_const_vector_arg` attribute input - --> $DIR/rustc_intrinsic_const_vector_arg.rs:19:5 + --> $DIR/rustc_intrinsic_const_vector_arg.rs:18:5 | LL | #[rustc_intrinsic_const_vector_arg] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_intrinsic_const_vector_arg(arg1_index, arg2_index, ...)]` error: malformed `rustc_intrinsic_const_vector_arg` attribute input - --> $DIR/rustc_intrinsic_const_vector_arg.rs:24:5 + --> $DIR/rustc_intrinsic_const_vector_arg.rs:23:5 | LL | #[rustc_intrinsic_const_vector_arg = "1"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_intrinsic_const_vector_arg(arg1_index, arg2_index, ...)]` error: attribute should be applied to functions in `extern "unadjusted"` modules - --> $DIR/rustc_intrinsic_const_vector_arg.rs:28:1 + --> $DIR/rustc_intrinsic_const_vector_arg.rs:27:1 | LL | #[rustc_intrinsic_const_vector_arg(0)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -19,7 +19,7 @@ LL | pub struct foo3(i8x2); | ---------------------- not a function in an `extern "unadjusted"` module error: attribute should be applied to functions in `extern "unadjusted"` modules - --> $DIR/rustc_intrinsic_const_vector_arg.rs:32:5 + --> $DIR/rustc_intrinsic_const_vector_arg.rs:31:5 | LL | #[rustc_intrinsic_const_vector_arg(0)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -27,7 +27,7 @@ LL | fn foo4(a: i8x2); | ----------------- not a function in an `extern "unadjusted"` module error: function does not have a parameter at index 0 - --> $DIR/rustc_intrinsic_const_vector_arg.rs:37:5 + --> $DIR/rustc_intrinsic_const_vector_arg.rs:36:5 | LL | #[rustc_intrinsic_const_vector_arg(0)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -35,7 +35,7 @@ LL | fn foo5(); | ---------- function has 0 arguments error: function does not have a parameter at index 1 - --> $DIR/rustc_intrinsic_const_vector_arg.rs:42:5 + --> $DIR/rustc_intrinsic_const_vector_arg.rs:41:5 | LL | #[rustc_intrinsic_const_vector_arg(1)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -43,13 +43,13 @@ LL | fn foo6(a: i8x2); | ----------------- function has 1 arguments error: attribute requires a parameter index - --> $DIR/rustc_intrinsic_const_vector_arg.rs:47:40 + --> $DIR/rustc_intrinsic_const_vector_arg.rs:46:40 | LL | #[rustc_intrinsic_const_vector_arg("bar")] | ^^^^^ error: function does not have a parameter at index 2 - --> $DIR/rustc_intrinsic_const_vector_arg.rs:52:5 + --> $DIR/rustc_intrinsic_const_vector_arg.rs:51:5 | LL | #[rustc_intrinsic_const_vector_arg(0, 2)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -57,7 +57,7 @@ LL | fn foo8(a: i8x2, b: i8); | ------------------------ function has 2 arguments error: parameter at index 0 must be a simd type defined in the local crate - --> $DIR/rustc_intrinsic_const_vector_arg.rs:57:5 + --> $DIR/rustc_intrinsic_const_vector_arg.rs:56:5 | LL | #[rustc_intrinsic_const_vector_arg(0)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -65,7 +65,7 @@ LL | fn foo9(a: i8); | -- parameter is a non-simd type or is not defined locally error: parameter at index 0 must be a simd type defined in the local crate - --> $DIR/rustc_intrinsic_const_vector_arg.rs:62:5 + --> $DIR/rustc_intrinsic_const_vector_arg.rs:61:5 | LL | #[rustc_intrinsic_const_vector_arg(0)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg_calls.rs b/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg_calls.rs index bb6372cbe1394..ce40deede1c3d 100644 --- a/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg_calls.rs +++ b/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg_calls.rs @@ -1,6 +1,5 @@ //@ compile-flags: -Z unstable-options #![feature(abi_unadjusted)] -#![feature(inline_const)] #![feature(intrinsics)] #![allow(non_camel_case_types)] #![feature(repr_simd)] diff --git a/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg_calls.stderr b/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg_calls.stderr index 0415755a23b62..b76fc807fb522 100644 --- a/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg_calls.stderr +++ b/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg_calls.stderr @@ -1,35 +1,35 @@ error: argument at index 0 must be a constant - --> $DIR/rustc_intrinsic_const_vector_arg_calls.rs:54:9 + --> $DIR/rustc_intrinsic_const_vector_arg_calls.rs:53:9 | LL | foo1(i8x2(0, 1)); | ^^^^^^^^^^^^^^^^ error: argument at index 0 must be a constant - --> $DIR/rustc_intrinsic_const_vector_arg_calls.rs:55:9 + --> $DIR/rustc_intrinsic_const_vector_arg_calls.rs:54:9 | LL | foo1({ i8x2(0, 1) }); | ^^^^^^^^^^^^^^^^^^^^ error: argument at index 1 must be a constant - --> $DIR/rustc_intrinsic_const_vector_arg_calls.rs:58:9 + --> $DIR/rustc_intrinsic_const_vector_arg_calls.rs:57:9 | LL | foo2(const { i8x2(0, 1) }, { i8x2(2, 3) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: argument at index 0 must be a constant - --> $DIR/rustc_intrinsic_const_vector_arg_calls.rs:61:9 + --> $DIR/rustc_intrinsic_const_vector_arg_calls.rs:60:9 | LL | foo3(i8x2_arr([0, 1])); | ^^^^^^^^^^^^^^^^^^^^^^ error: argument at index 0 must be a constant - --> $DIR/rustc_intrinsic_const_vector_arg_calls.rs:64:9 + --> $DIR/rustc_intrinsic_const_vector_arg_calls.rs:63:9 | LL | foo4(f32x2(0.0, 1.0)); | ^^^^^^^^^^^^^^^^^^^^^ error: argument at index 0 must be a constant - --> $DIR/rustc_intrinsic_const_vector_arg_calls.rs:67:9 + --> $DIR/rustc_intrinsic_const_vector_arg_calls.rs:66:9 | LL | foo5(f32x2_arr([0.0, 1.0])); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ From 0c13d85666d8cb25c9918150a7fdd1623070177c Mon Sep 17 00:00:00 2001 From: James Barford-Evans Date: Mon, 22 Jul 2024 15:15:04 +0100 Subject: [PATCH 07/15] add const vector args to codegen_attrs --- .../rustc_codegen_ssa/src/codegen_attrs.rs | 22 ++++++++++++++++++- .../src/middle/codegen_fn_attrs.rs | 4 ++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index bfa4c683d56ed..9cee66ba06464 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -1,4 +1,4 @@ -use rustc_ast::{ast, attr, MetaItemKind, NestedMetaItem}; +use rustc_ast::{ast, attr, LitKind, MetaItemKind, MetaItemLit, NestedMetaItem}; use rustc_attr::{list_contains_name, InlineAttr, InstructionSetAttr, OptimizeAttr}; use rustc_errors::{codes::*, struct_span_code_err, DiagMessage, SubdiagMessage}; use rustc_hir as hir; @@ -523,6 +523,26 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { )) }) } + sym::rustc_intrinsic_const_vector_arg => { + let mut indicies: Vec = Vec::new(); + if let Some(item_list) = attr.meta_item_list() { + for item in item_list { + match item { + NestedMetaItem::Lit(MetaItemLit { + kind: LitKind::Int(index, _), + .. + }) => { + indicies.push(index.get() as usize); + } + _ => { + tcx.dcx() + .emit_err(errors::IntrinsicConstVectorArg { span: attr.span }); + } + } + } + } + codegen_fn_attrs.const_vector_indices = Some(indicies); + } _ => {} } } diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs index 3ddf889b63afe..c7998c5f44c03 100644 --- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs +++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs @@ -48,6 +48,9 @@ pub struct CodegenFnAttrs { /// The `#[patchable_function_entry(...)]` attribute. Indicates how many nops should be around /// the function entry. pub patchable_function_entry: Option, + /// The `#[rustc_intrinsic_const_vector_arg(...)]` attribute. The indices + /// of const vector arguments + pub const_vector_indices: Option>, } #[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)] @@ -148,6 +151,7 @@ impl CodegenFnAttrs { instruction_set: None, alignment: None, patchable_function_entry: None, + const_vector_indices: None, } } From 6560527d0e1078f5395fd23763aaf5d3d7cde432 Mon Sep 17 00:00:00 2001 From: James Barford-Evans Date: Mon, 22 Jul 2024 15:15:28 +0100 Subject: [PATCH 08/15] add error --- compiler/rustc_codegen_ssa/src/errors.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index d9faac7358939..82e102a233931 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -605,6 +605,13 @@ pub struct ConstVectorEvaluation { pub span: Span, } +#[derive(Diagnostic)] +#[diag(codegen_ssa_intrinsic_const_vector_arg)] +pub struct IntrinsicConstVectorArg { + #[primary_span] + pub span: Span, +} + #[derive(Diagnostic)] #[diag(codegen_ssa_missing_memory_ordering)] pub struct MissingMemoryOrdering; From 4a49ae6fad4af31ca9bb3608ad8fc3b6f00c22d8 Mon Sep 17 00:00:00 2001 From: James Barford-Evans Date: Mon, 22 Jul 2024 15:16:28 +0100 Subject: [PATCH 09/15] add error message --- compiler/rustc_codegen_ssa/messages.ftl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/compiler/rustc_codegen_ssa/messages.ftl b/compiler/rustc_codegen_ssa/messages.ftl index be8271229a72a..128e3ce4a0cd4 100644 --- a/compiler/rustc_codegen_ssa/messages.ftl +++ b/compiler/rustc_codegen_ssa/messages.ftl @@ -33,6 +33,8 @@ codegen_ssa_expected_used_symbol = expected `used`, `used(compiler)` or `used(li codegen_ssa_extern_funcs_not_found = some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified +codegen_ssa_intrinsic_const_vector_arg = invalid argument, must be integer literal + codegen_ssa_extract_bundled_libs_archive_member = failed to get data from archive member '{$rlib}': {$error} codegen_ssa_extract_bundled_libs_convert_name = failed to convert name '{$rlib}': {$error} codegen_ssa_extract_bundled_libs_mmap_file = failed to mmap file '{$rlib}': {$error} From 25f9653a2eb27f3d2eee5aa003f99087eed28670 Mon Sep 17 00:00:00 2001 From: James Barford-Evans Date: Mon, 22 Jul 2024 15:18:37 +0100 Subject: [PATCH 10/15] call the .codegen_fn_attrs() to retrieve attributes --- compiler/rustc_codegen_ssa/src/mir/block.rs | 47 +++++---------------- 1 file changed, 10 insertions(+), 37 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 7ddf334db604c..41864ef80389d 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -11,7 +11,7 @@ use crate::traits::*; use crate::MemFlags; use rustc_ast as ast; -use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece, LitKind, MetaItemLit, NestedMetaItem}; +use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_hir::lang_items::LangItem; use rustc_middle::mir::{self, AssertKind, BasicBlock, SwitchTargets, UnwindTerminateReason}; use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, ValidityRequirement}; @@ -926,14 +926,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { if i == 2 && intrinsic.name == sym::simd_shuffle { if let mir::Operand::Constant(constant) = &arg.node { let (llval, ty) = self.early_evaluate_const_vector(bx, constant); - let llval = llval.unwrap_or_else(|| { - bx.tcx().dcx().emit_err(errors::ShuffleIndicesEvaluation { - span: constant.span, - }); - // We've errored, so we don't have to produce working code. - let llty = bx.backend_type(bx.layout_of(ty)); - bx.const_undef(llty) - }); + return OperandRef { val: Immediate(llval), layout: bx.layout_of(ty), @@ -1011,42 +1004,22 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { (args, None) }; - let const_vec_arg_indexes = (|| { - if let Some(def) = def - && let Some(attr) = - bx.tcx().get_attr(def.def_id(), sym::rustc_intrinsic_const_vector_arg) - { - attr.meta_item_list() - .iter() - .flatten() - .map(|item: &NestedMetaItem| match item { - NestedMetaItem::Lit(MetaItemLit { - kind: LitKind::Int(index, _), .. - }) => index.get() as usize, - _ => span_bug!(item.span(), "attribute argument must be an integer"), - }) - .collect() - } else { - Vec::::new() - } - })(); + let const_vec_arg_indexes = if let Some(def) = def + && bx.tcx().get_attr(def.def_id(), sym::rustc_intrinsic_const_vector_arg).is_some() + { + let val = bx.tcx().codegen_fn_attrs(def.def_id()); + val.const_vector_indices.as_ref().unwrap() + } else { + &Vec::::new() + }; let mut copied_constant_arguments = vec![]; 'make_args: for (i, arg) in first_args.iter().enumerate() { let mut op = if const_vec_arg_indexes.contains(&i) { - // Force the specified argument to be constant by using const-qualification to promote any complex rvalues to constant. if let mir::Operand::Constant(constant) = &arg.node && constant.ty().is_simd() { let (llval, ty) = self.early_evaluate_const_vector(bx, &constant); - let llval = llval.unwrap_or_else(|| { - bx.tcx() - .dcx() - .emit_err(errors::ConstVectorEvaluation { span: constant.span }); - // We've errored, so we don't have to produce working code. - let llty = bx.backend_type(bx.layout_of(ty)); - bx.const_undef(llty) - }); OperandRef { val: Immediate(llval), layout: bx.layout_of(ty) } } else { span_bug!(span, "argument at {i} must be a constant vector"); From a98491c4a51fb56c61027e96f305e096ad27a09f Mon Sep 17 00:00:00 2001 From: James Barford-Evans Date: Mon, 22 Jul 2024 15:20:00 +0100 Subject: [PATCH 11/15] allow for slices to be treated in the same manner for a const vector --- .../rustc_codegen_ssa/src/mir/constant.rs | 77 +++++++++++++++---- 1 file changed, 61 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/mir/constant.rs b/compiler/rustc_codegen_ssa/src/mir/constant.rs index 5dcfbe68c7156..4658ece1be11f 100644 --- a/compiler/rustc_codegen_ssa/src/mir/constant.rs +++ b/compiler/rustc_codegen_ssa/src/mir/constant.rs @@ -1,8 +1,10 @@ +use crate::errors; use crate::mir::operand::OperandRef; use crate::traits::*; use rustc_middle::mir; use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::ty::layout::HasTyCtxt; +use rustc_middle::ty::ValTree; use rustc_middle::ty::{self, Ty}; use rustc_middle::{bug, span_bug}; use rustc_target::abi::Abi; @@ -47,7 +49,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { }, // We should never encounter `Const::Val` unless MIR opts (like const prop) evaluate // a constant and write that value back into `Operand`s. This could happen, but is unlikely. - // Also: all users of `simd_shuffle` are on unstable and already need to take a lot of care + // Also: all use`rs of `simd_shuffle` are on unstable and already need to take a lot of care // around intrinsics. For an issue to happen here, it would require a macro expanding to a // `simd_shuffle` call without wrapping the constant argument in a `const {}` block, but // the user pass through arbitrary expressions. @@ -64,7 +66,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { &mut self, bx: &Bx, constant: &mir::ConstOperand<'tcx>, - ) -> (Option, Ty<'tcx>) { + ) -> (Bx::Value, Ty<'tcx>) { let ty = self.monomorphize(constant.ty()); let val = self .eval_unevaluated_mir_constant_to_valtree(constant) @@ -73,27 +75,70 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { .flatten() .map(|val| { let field_ty = ty.builtin_index().unwrap(); - let values: Vec<_> = val - .unwrap_branch() - .iter() - .map(|field| { - if let Some(prim) = field.try_to_scalar() { - let layout = bx.layout_of(field_ty); - let Abi::Scalar(scalar) = layout.abi else { - bug!("from_const: invalid ByVal layout: {:#?}", layout); - }; - bx.scalar_to_backend(prim, scalar, bx.immediate_backend_type(layout)) - } else { - bug!("field is not a scalar {:?}", field) + let mut values: Vec = Vec::new(); + // For reliably being able to handle either: + // pub struct defn(i32, i32) + // call(1, 0); + // OR + // pub struct defn([i32, 2]) + // call([1, 0]); + // + // And outputting: @call(<2 x i32> ) + // thus treating them the same if they are a const vector + for field in val.unwrap_branch().iter() { + match field { + ValTree::Branch(_) => { + let scalars = self.flatten_branch_to_scalars(bx, field, field_ty); + values.extend(scalars); } - }) - .collect(); + ValTree::Leaf(_) => { + let scalar = self.extract_scalar(bx, field, field_ty); + values.push(scalar); + } + } + } if ty.is_simd() { bx.const_vector(&values) } else { bx.const_struct(&values, false) } + }) + .unwrap_or_else(|| { + bx.tcx().dcx().emit_err(errors::ShuffleIndicesEvaluation { span: constant.span }); + // We've errored, so we don't have to produce working code. + let llty = bx.backend_type(bx.layout_of(ty)); + bx.const_undef(llty) }); (val, ty) } + + fn flatten_branch_to_scalars( + &mut self, + bx: &Bx, + branch: &ValTree<'tcx>, + field_ty: Ty<'tcx>, + ) -> Vec { + branch + .unwrap_branch() + .iter() + .map(|field| match field { + ValTree::Branch(_) => { + bug!("Cannot have arbitrarily nested const vectors: {:#?}", field) + } + ValTree::Leaf(_) => self.extract_scalar(bx, field, field_ty), + }) + .collect() + } + + fn extract_scalar(&mut self, bx: &Bx, field: &ValTree<'tcx>, field_ty: Ty<'tcx>) -> Bx::Value { + if let Some(prim) = field.try_to_scalar() { + let layout = bx.layout_of(field_ty); + let Abi::Scalar(scalar) = layout.abi else { + bug!("from_const: invalid ByVal layout: {:#?}", layout); + }; + bx.scalar_to_backend(prim, scalar, bx.immediate_backend_type(layout)) + } else { + bug!("field is not a scalar {:?}", field) + } + } } From 0309238ba4c1114d96d6a529ac461a7f20676381 Mon Sep 17 00:00:00 2001 From: James Barford-Evans Date: Mon, 22 Jul 2024 16:15:24 +0100 Subject: [PATCH 12/15] refactor to use .lit() --- compiler/rustc_borrowck/src/type_check/mod.rs | 29 +++++++------------ 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 8d6d4318cc7cb..87fc911b09254 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -52,9 +52,7 @@ use rustc_mir_dataflow::ResultsCursor; use crate::renumber::RegionCtxt; use crate::session_diagnostics::{ - IntrinsicConstVectorArgNonConst, - MoveUnsized, - SimdIntrinsicArgConst, + IntrinsicConstVectorArgNonConst, MoveUnsized, SimdIntrinsicArgConst, }; use crate::{ borrow_set::BorrowSet, @@ -1639,18 +1637,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { { match attr.meta_item_list() { Some(items) => { - items.into_iter().for_each(|item: rustc_ast::NestedMetaItem| match item { - rustc_ast::NestedMetaItem::Lit(rustc_ast::MetaItemLit { - kind: rustc_ast::LitKind::Int(index, _), - .. - }) => { - if index >= args.len() as u128 { - span_mirbug!(self, term, "index out of bounds"); - } else { - if !matches!( - args[index.get() as usize], - Spanned { node: Operand::Constant(_), .. } - ) { + items.into_iter().for_each(|item| { + if let Some(rustc_ast::LitKind::Int(index, _)) = + item.lit().map(|lit| &lit.kind) + { + if let Some(arg) = args.get::(index.get() as usize) { + if !matches!(arg, Spanned { node: Operand::Constant(_), .. }) { self.tcx().dcx().emit_err( IntrinsicConstVectorArgNonConst { span: term.source_info.span, @@ -1659,15 +1651,14 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ); } } - } - _ => { - span_mirbug!(self, term, "invalid index"); + } else { + span_mirbug!(self, term, "literal kind"); } }); } - // Error is reported by `rustc_attr!` None => (), } + // Error is reported by `rustc_attr!` } } debug!(?func_ty); From 6961ec6d54116ab6db7b1f9f9b90af3126953deb Mon Sep 17 00:00:00 2001 From: James Barford-Evans Date: Mon, 22 Jul 2024 20:12:10 +0100 Subject: [PATCH 13/15] reformatted & test updates --- compiler/rustc_codegen_ssa/messages.ftl | 3 ++- compiler/rustc_codegen_ssa/src/errors.rs | 2 +- compiler/rustc_codegen_ssa/src/mir/constant.rs | 2 +- .../rustc_intrinsic_const_vector_arg.rs | 3 ++- .../rustc_intrinsic_const_vector_arg.stderr | 14 ++++++++++---- 5 files changed, 16 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_codegen_ssa/messages.ftl b/compiler/rustc_codegen_ssa/messages.ftl index 128e3ce4a0cd4..5b375aaabaf24 100644 --- a/compiler/rustc_codegen_ssa/messages.ftl +++ b/compiler/rustc_codegen_ssa/messages.ftl @@ -33,7 +33,6 @@ codegen_ssa_expected_used_symbol = expected `used`, `used(compiler)` or `used(li codegen_ssa_extern_funcs_not_found = some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified -codegen_ssa_intrinsic_const_vector_arg = invalid argument, must be integer literal codegen_ssa_extract_bundled_libs_archive_member = failed to get data from archive member '{$rlib}': {$error} codegen_ssa_extract_bundled_libs_convert_name = failed to convert name '{$rlib}': {$error} @@ -64,6 +63,8 @@ codegen_ssa_incorrect_cgu_reuse_type = codegen_ssa_insufficient_vs_code_product = VS Code is a different product, and is not sufficient. +codegen_ssa_invalid_intrinsic_const_vector_arg = invalid argument, must be integer literal + codegen_ssa_invalid_link_ordinal_nargs = incorrect number of arguments to `#[link_ordinal]` .note = the attribute requires exactly one argument diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index 82e102a233931..9e7316557bc87 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -606,7 +606,7 @@ pub struct ConstVectorEvaluation { } #[derive(Diagnostic)] -#[diag(codegen_ssa_intrinsic_const_vector_arg)] +#[diag(codegen_ssa_invalid_intrinsic_const_vector_arg)] pub struct IntrinsicConstVectorArg { #[primary_span] pub span: Span, diff --git a/compiler/rustc_codegen_ssa/src/mir/constant.rs b/compiler/rustc_codegen_ssa/src/mir/constant.rs index 4658ece1be11f..3d2e4b8d5e1ba 100644 --- a/compiler/rustc_codegen_ssa/src/mir/constant.rs +++ b/compiler/rustc_codegen_ssa/src/mir/constant.rs @@ -49,7 +49,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { }, // We should never encounter `Const::Val` unless MIR opts (like const prop) evaluate // a constant and write that value back into `Operand`s. This could happen, but is unlikely. - // Also: all use`rs of `simd_shuffle` are on unstable and already need to take a lot of care + // Also: all users of `simd_shuffle` are on unstable and already need to take a lot of care // around intrinsics. For an issue to happen here, it would require a macro expanding to a // `simd_shuffle` call without wrapping the constant argument in a `const {}` block, but // the user pass through arbitrary expressions. diff --git a/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg.rs b/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg.rs index ee0a0341a6a70..43285dfd1c059 100644 --- a/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg.rs +++ b/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg.rs @@ -43,7 +43,8 @@ extern "unadjusted" { } extern "unadjusted" { - #[rustc_intrinsic_const_vector_arg("bar")] //~ ERROR attribute requires a parameter index + #[rustc_intrinsic_const_vector_arg("bar")] //~ ERROR invalid argument, must be integer literal + //~^ ERROR attribute requires a parameter index fn foo7(a: i8x2); } diff --git a/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg.stderr b/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg.stderr index a7016e1ba4e60..33cbc68dc58a3 100644 --- a/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg.stderr +++ b/tests/ui/internal-lints/rustc_intrinsic_const_vector_arg.stderr @@ -49,7 +49,7 @@ LL | #[rustc_intrinsic_const_vector_arg("bar")] | ^^^^^ error: function does not have a parameter at index 2 - --> $DIR/rustc_intrinsic_const_vector_arg.rs:51:5 + --> $DIR/rustc_intrinsic_const_vector_arg.rs:52:5 | LL | #[rustc_intrinsic_const_vector_arg(0, 2)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -57,7 +57,7 @@ LL | fn foo8(a: i8x2, b: i8); | ------------------------ function has 2 arguments error: parameter at index 0 must be a simd type defined in the local crate - --> $DIR/rustc_intrinsic_const_vector_arg.rs:56:5 + --> $DIR/rustc_intrinsic_const_vector_arg.rs:57:5 | LL | #[rustc_intrinsic_const_vector_arg(0)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -65,12 +65,18 @@ LL | fn foo9(a: i8); | -- parameter is a non-simd type or is not defined locally error: parameter at index 0 must be a simd type defined in the local crate - --> $DIR/rustc_intrinsic_const_vector_arg.rs:61:5 + --> $DIR/rustc_intrinsic_const_vector_arg.rs:62:5 | LL | #[rustc_intrinsic_const_vector_arg(0)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ LL | fn foo10(a: Simd); | ----------- parameter is a non-simd type or is not defined locally -error: aborting due to 10 previous errors +error: invalid argument, must be integer literal + --> $DIR/rustc_intrinsic_const_vector_arg.rs:46:5 + | +LL | #[rustc_intrinsic_const_vector_arg("bar")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 11 previous errors From 9bffa2f9fb554a9a943552add0a388653deabe5c Mon Sep 17 00:00:00 2001 From: James Barford-Evans Date: Wed, 24 Jul 2024 11:26:28 +0100 Subject: [PATCH 14/15] fix from rebase that made the type blow up --- compiler/rustc_codegen_ssa/src/mir/constant.rs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/mir/constant.rs b/compiler/rustc_codegen_ssa/src/mir/constant.rs index 3d2e4b8d5e1ba..69c917c843f05 100644 --- a/compiler/rustc_codegen_ssa/src/mir/constant.rs +++ b/compiler/rustc_codegen_ssa/src/mir/constant.rs @@ -68,13 +68,18 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { constant: &mir::ConstOperand<'tcx>, ) -> (Bx::Value, Ty<'tcx>) { let ty = self.monomorphize(constant.ty()); + let ty_is_simd = ty.is_simd(); + let field_ty = if ty_is_simd { + ty.simd_size_and_type(bx.tcx()).1 + } else { + ty.builtin_index().unwrap() + }; let val = self .eval_unevaluated_mir_constant_to_valtree(constant) .ok() .map(|x| x.ok()) .flatten() .map(|val| { - let field_ty = ty.builtin_index().unwrap(); let mut values: Vec = Vec::new(); // For reliably being able to handle either: // pub struct defn(i32, i32) @@ -88,20 +93,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { for field in val.unwrap_branch().iter() { match field { ValTree::Branch(_) => { - let scalars = self.flatten_branch_to_scalars(bx, field, field_ty); + let scalars = self.flatten_branch_to_scalars(bx, &field, field_ty); values.extend(scalars); } ValTree::Leaf(_) => { - let scalar = self.extract_scalar(bx, field, field_ty); + let scalar = self.extract_scalar(bx, &field, field_ty); values.push(scalar); } } } - if ty.is_simd() { - bx.const_vector(&values) - } else { - bx.const_struct(&values, false) - } + if ty_is_simd { bx.const_vector(&values) } else { bx.const_struct(&values, false) } }) .unwrap_or_else(|| { bx.tcx().dcx().emit_err(errors::ShuffleIndicesEvaluation { span: constant.span }); From 4b09873b071d4be7cb0e4f25a5669b75d660ed42 Mon Sep 17 00:00:00 2001 From: James Barford-Evans Date: Wed, 24 Jul 2024 11:27:07 +0100 Subject: [PATCH 15/15] fix for failing tests from calling `get_attr()` --- compiler/rustc_codegen_ssa/src/mir/block.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 41864ef80389d..8274f5988112e 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -1004,11 +1004,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { (args, None) }; - let const_vec_arg_indexes = if let Some(def) = def - && bx.tcx().get_attr(def.def_id(), sym::rustc_intrinsic_const_vector_arg).is_some() - { + let const_vec_arg_indexes = if let Some(def) = def { let val = bx.tcx().codegen_fn_attrs(def.def_id()); - val.const_vector_indices.as_ref().unwrap() + let const_vector_indices = &val.const_vector_indices; + if let Some(const_vector_i) = const_vector_indices { + &const_vector_i.as_ref() + } else { + &Vec::::new() + } } else { &Vec::::new() };