diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index f12e05121b76a..468c530f59c59 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -615,8 +615,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 ce871f06cb6bf..b473f0e23a614 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -2134,18 +2134,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