hir/trait_sel: prohibit scalable vectors in types

Extend well-formedness checking and HIR analysis to prohibit the use of
scalable vectors in structs, enums, unions, tuples and arrays. LLVM does
not support scalable vectors being members of other types, so these
restrictions are necessary.

Co-authored-by: Jamie Cunliffe <Jamie.Cunliffe@arm.com>
This commit is contained in:
David Wood 2025-07-09 16:25:29 +00:00
parent 78b06057ef
commit ba9262936e
No known key found for this signature in database
18 changed files with 742 additions and 6 deletions

View file

@ -270,6 +270,8 @@ ast_passes_precise_capturing_duplicated = duplicate `use<...>` precise capturing
ast_passes_precise_capturing_not_allowed_here = `use<...>` precise capturing syntax not allowed in {$loc}
ast_passes_scalable_vector_not_tuple_struct = scalable vectors must be tuple structs
ast_passes_static_without_body =
free static item without body
.suggestion = provide a definition for the static

View file

@ -1319,6 +1319,14 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}
ItemKind::Struct(ident, generics, vdata) => {
self.with_tilde_const(Some(TildeConstReason::Struct { span: item.span }), |this| {
// Scalable vectors can only be tuple structs
let is_scalable_vector =
item.attrs.iter().any(|attr| attr.has_name(sym::rustc_scalable_vector));
if is_scalable_vector && !matches!(vdata, VariantData::Tuple(..)) {
this.dcx()
.emit_err(errors::ScalableVectorNotTupleStruct { span: item.span });
}
match vdata {
VariantData::Struct { fields, .. } => {
this.visit_attrs_vis_ident(&item.attrs, &item.vis, ident);

View file

@ -990,3 +990,10 @@ pub(crate) struct AbiX86Interrupt {
pub spans: Vec<Span>,
pub param_count: usize,
}
#[derive(Diagnostic)]
#[diag(ast_passes_scalable_vector_not_tuple_struct)]
pub(crate) struct ScalableVectorNotTupleStruct {
#[primary_span]
pub span: Span,
}

View file

@ -1,7 +1,7 @@
use std::cell::LazyCell;
use std::ops::ControlFlow;
use rustc_abi::{ExternAbi, FieldIdx};
use rustc_abi::{ExternAbi, FieldIdx, ScalableElt};
use rustc_data_structures::unord::{UnordMap, UnordSet};
use rustc_errors::codes::*;
use rustc_errors::{EmissionGuarantee, MultiSpan};
@ -92,7 +92,9 @@ fn check_struct(tcx: TyCtxt<'_>, def_id: LocalDefId) {
let span = tcx.def_span(def_id);
def.destructor(tcx); // force the destructor to be evaluated
if def.repr().simd() {
if let Some(scalable) = def.repr().scalable {
check_scalable_vector(tcx, span, def_id, scalable);
} else if def.repr().simd() {
check_simd(tcx, span, def_id);
}
@ -1426,6 +1428,100 @@ fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
}
}
#[tracing::instrument(skip(tcx), level = "debug")]
fn check_scalable_vector(tcx: TyCtxt<'_>, span: Span, def_id: LocalDefId, scalable: ScalableElt) {
let ty = tcx.type_of(def_id).instantiate_identity();
let ty::Adt(def, args) = ty.kind() else { return };
if !def.is_struct() {
tcx.dcx().delayed_bug("`rustc_scalable_vector` applied to non-struct");
return;
}
let fields = &def.non_enum_variant().fields;
match scalable {
ScalableElt::ElementCount(..) if fields.is_empty() => {
let mut err =
tcx.dcx().struct_span_err(span, "scalable vectors must have a single field");
err.help("scalable vector types' only field must be a primitive scalar type");
err.emit();
return;
}
ScalableElt::ElementCount(..) if fields.len() >= 2 => {
tcx.dcx().struct_span_err(span, "scalable vectors cannot have multiple fields").emit();
return;
}
ScalableElt::Container if fields.is_empty() => {
let mut err =
tcx.dcx().struct_span_err(span, "scalable vectors must have a single field");
err.help("tuples of scalable vectors can only contain multiple of the same scalable vector type");
err.emit();
return;
}
_ => {}
}
match scalable {
ScalableElt::ElementCount(..) => {
let element_ty = &fields[FieldIdx::ZERO].ty(tcx, args);
// Check that `element_ty` only uses types valid in the lanes of a scalable vector
// register: scalar types which directly match a "machine" type - integers, floats and
// bools
match element_ty.kind() {
ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Bool => (),
_ => {
let mut err = tcx.dcx().struct_span_err(
span,
"element type of a scalable vector must be a primitive scalar",
);
err.help("only `u*`, `i*`, `f*` and `bool` types are accepted");
err.emit();
}
}
}
ScalableElt::Container => {
let mut prev_field_ty = None;
for field in fields.iter() {
let element_ty = field.ty(tcx, args);
if let ty::Adt(def, _) = element_ty.kind()
&& def.repr().scalable()
{
match def
.repr()
.scalable
.expect("`repr().scalable.is_some()` != `repr().scalable()`")
{
ScalableElt::ElementCount(_) => { /* expected field */ }
ScalableElt::Container => {
tcx.dcx().span_err(
tcx.def_span(field.did),
"scalable vector structs cannot contain other scalable vector structs",
);
break;
}
}
} else {
tcx.dcx().span_err(
tcx.def_span(field.did),
"scalable vector structs can only have scalable vector fields",
);
break;
}
if let Some(prev_ty) = prev_field_ty.replace(element_ty)
&& prev_ty != element_ty
{
tcx.dcx().span_err(
tcx.def_span(field.did),
"all fields in a scalable vector struct must be the same type",
);
break;
}
}
}
}
}
pub(super) fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: ty::AdtDef<'_>) {
let repr = def.repr();
if repr.packed() {

View file

@ -2,7 +2,7 @@ use std::cell::LazyCell;
use std::ops::{ControlFlow, Deref};
use hir::intravisit::{self, Visitor};
use rustc_abi::ExternAbi;
use rustc_abi::{ExternAbi, ScalableElt};
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
use rustc_errors::codes::*;
use rustc_errors::{Applicability, ErrorGuaranteed, pluralize, struct_span_code_err};
@ -1038,7 +1038,21 @@ fn check_type_defn<'tcx>(
hir_ty.span,
Some(WellFormedLoc::Ty(field_id)),
ty.into(),
)
);
if matches!(ty.kind(), ty::Adt(def, _) if def.repr().scalable())
&& !matches!(adt_def.repr().scalable, Some(ScalableElt::Container))
{
// Scalable vectors can only be fields of structs if the type has a
// `rustc_scalable_vector` attribute w/out specifying an element count
tcx.dcx().span_err(
hir_ty.span,
format!(
"scalable vectors cannot be fields of a {}",
adt_def.variant_descr()
),
);
}
}
// For DST, or when drop needs to copy things around, all

View file

@ -771,9 +771,25 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
}
ty::Tuple(tys) => {
if let Some((_last, rest)) = tys.split_last() {
if let Some((last, rest)) = tys.split_last() {
for &elem in rest {
self.require_sized(elem, ObligationCauseCode::TupleElem);
if elem.is_scalable_vector() && !self.span.is_dummy() {
self.tcx()
.dcx()
.struct_span_err(
self.span,
"scalable vectors cannot be tuple fields",
)
.emit();
}
}
if last.is_scalable_vector() && !self.span.is_dummy() {
self.tcx()
.dcx()
.struct_span_err(self.span, "scalable vectors cannot be tuple fields")
.emit();
}
}
}

View file

@ -0,0 +1,93 @@
//@ compile-flags: --crate-type=lib
#![allow(internal_features)]
#![feature(extern_types)]
#![feature(never_type)]
#![feature(rustc_attrs)]
struct Foo;
enum Bar {}
union Baz { x: u16 }
extern "C" {
type Qux;
}
#[rustc_scalable_vector(4)]
struct TyChar(char);
//~^ ERROR: element type of a scalable vector must be a primitive scalar
#[rustc_scalable_vector(2)]
struct TyConstPtr(*const u8);
//~^ ERROR: element type of a scalable vector must be a primitive scalar
#[rustc_scalable_vector(2)]
struct TyMutPtr(*mut u8);
//~^ ERROR: element type of a scalable vector must be a primitive scalar
#[rustc_scalable_vector(4)]
struct TyStruct(Foo);
//~^ ERROR: element type of a scalable vector must be a primitive scalar
#[rustc_scalable_vector(4)]
struct TyEnum(Bar);
//~^ ERROR: element type of a scalable vector must be a primitive scalar
#[rustc_scalable_vector(4)]
struct TyUnion(Baz);
//~^ ERROR: element type of a scalable vector must be a primitive scalar
#[rustc_scalable_vector(4)]
struct TyForeign(Qux);
//~^ ERROR: element type of a scalable vector must be a primitive scalar
#[rustc_scalable_vector(4)]
struct TyArray([u32; 4]);
//~^ ERROR: element type of a scalable vector must be a primitive scalar
#[rustc_scalable_vector(4)]
struct TySlice([u32]);
//~^ ERROR: element type of a scalable vector must be a primitive scalar
#[rustc_scalable_vector(4)]
struct TyRef<'a>(&'a u32);
//~^ ERROR: element type of a scalable vector must be a primitive scalar
#[rustc_scalable_vector(4)]
struct TyFnPtr(fn(u32) -> u32);
//~^ ERROR: element type of a scalable vector must be a primitive scalar
#[rustc_scalable_vector(4)]
struct TyDyn(dyn std::io::Write);
//~^ ERROR: element type of a scalable vector must be a primitive scalar
#[rustc_scalable_vector(4)]
struct TyNever(!);
//~^ ERROR: element type of a scalable vector must be a primitive scalar
#[rustc_scalable_vector(4)]
struct TyTuple((u32, u32));
//~^ ERROR: element type of a scalable vector must be a primitive scalar
type ValidAlias = u32;
type InvalidAlias = String;
#[rustc_scalable_vector(4)]
struct TyValidAlias(ValidAlias);
#[rustc_scalable_vector(4)]
struct TyInvalidAlias(InvalidAlias);
//~^ ERROR: element type of a scalable vector must be a primitive scalar
trait Tr {
type Valid;
type Invalid;
}
impl Tr for () {
type Valid = u32;
type Invalid = String;
}
struct TyValidProjection(<() as Tr>::Valid);
struct TyInvalidProjection(<() as Tr>::Invalid);
// FIXME: element type of a scalable vector must be a primitive scalar

View file

@ -0,0 +1,122 @@
error: element type of a scalable vector must be a primitive scalar
--> $DIR/illformed-element-type.rs:15:1
|
LL | struct TyChar(char);
| ^^^^^^^^^^^^^
|
= help: only `u*`, `i*`, `f*` and `bool` types are accepted
error: element type of a scalable vector must be a primitive scalar
--> $DIR/illformed-element-type.rs:19:1
|
LL | struct TyConstPtr(*const u8);
| ^^^^^^^^^^^^^^^^^
|
= help: only `u*`, `i*`, `f*` and `bool` types are accepted
error: element type of a scalable vector must be a primitive scalar
--> $DIR/illformed-element-type.rs:23:1
|
LL | struct TyMutPtr(*mut u8);
| ^^^^^^^^^^^^^^^
|
= help: only `u*`, `i*`, `f*` and `bool` types are accepted
error: element type of a scalable vector must be a primitive scalar
--> $DIR/illformed-element-type.rs:27:1
|
LL | struct TyStruct(Foo);
| ^^^^^^^^^^^^^^^
|
= help: only `u*`, `i*`, `f*` and `bool` types are accepted
error: element type of a scalable vector must be a primitive scalar
--> $DIR/illformed-element-type.rs:31:1
|
LL | struct TyEnum(Bar);
| ^^^^^^^^^^^^^
|
= help: only `u*`, `i*`, `f*` and `bool` types are accepted
error: element type of a scalable vector must be a primitive scalar
--> $DIR/illformed-element-type.rs:35:1
|
LL | struct TyUnion(Baz);
| ^^^^^^^^^^^^^^
|
= help: only `u*`, `i*`, `f*` and `bool` types are accepted
error: element type of a scalable vector must be a primitive scalar
--> $DIR/illformed-element-type.rs:39:1
|
LL | struct TyForeign(Qux);
| ^^^^^^^^^^^^^^^^
|
= help: only `u*`, `i*`, `f*` and `bool` types are accepted
error: element type of a scalable vector must be a primitive scalar
--> $DIR/illformed-element-type.rs:43:1
|
LL | struct TyArray([u32; 4]);
| ^^^^^^^^^^^^^^
|
= help: only `u*`, `i*`, `f*` and `bool` types are accepted
error: element type of a scalable vector must be a primitive scalar
--> $DIR/illformed-element-type.rs:47:1
|
LL | struct TySlice([u32]);
| ^^^^^^^^^^^^^^
|
= help: only `u*`, `i*`, `f*` and `bool` types are accepted
error: element type of a scalable vector must be a primitive scalar
--> $DIR/illformed-element-type.rs:51:1
|
LL | struct TyRef<'a>(&'a u32);
| ^^^^^^^^^^^^^^^^
|
= help: only `u*`, `i*`, `f*` and `bool` types are accepted
error: element type of a scalable vector must be a primitive scalar
--> $DIR/illformed-element-type.rs:55:1
|
LL | struct TyFnPtr(fn(u32) -> u32);
| ^^^^^^^^^^^^^^
|
= help: only `u*`, `i*`, `f*` and `bool` types are accepted
error: element type of a scalable vector must be a primitive scalar
--> $DIR/illformed-element-type.rs:59:1
|
LL | struct TyDyn(dyn std::io::Write);
| ^^^^^^^^^^^^
|
= help: only `u*`, `i*`, `f*` and `bool` types are accepted
error: element type of a scalable vector must be a primitive scalar
--> $DIR/illformed-element-type.rs:63:1
|
LL | struct TyNever(!);
| ^^^^^^^^^^^^^^
|
= help: only `u*`, `i*`, `f*` and `bool` types are accepted
error: element type of a scalable vector must be a primitive scalar
--> $DIR/illformed-element-type.rs:67:1
|
LL | struct TyTuple((u32, u32));
| ^^^^^^^^^^^^^^
|
= help: only `u*`, `i*`, `f*` and `bool` types are accepted
error: element type of a scalable vector must be a primitive scalar
--> $DIR/illformed-element-type.rs:77:1
|
LL | struct TyInvalidAlias(InvalidAlias);
| ^^^^^^^^^^^^^^^^^^^^^
|
= help: only `u*`, `i*`, `f*` and `bool` types are accepted
error: aborting due to 15 previous errors

View file

@ -0,0 +1,36 @@
//@ compile-flags: --crate-type=lib
#![allow(internal_features)]
#![feature(rustc_attrs)]
#[rustc_scalable_vector(2)]
struct ValidI64(i64);
#[rustc_scalable_vector(4)]
struct ValidI32(i32);
#[rustc_scalable_vector]
struct ValidTuple(ValidI32, ValidI32, ValidI32);
#[rustc_scalable_vector]
struct Struct { x: ValidI64, y: ValidI64 }
//~^ ERROR: scalable vectors must be tuple structs
#[rustc_scalable_vector]
struct DifferentVectorTypes(ValidI64, ValidI32);
//~^ ERROR: all fields in a scalable vector struct must be the same type
#[rustc_scalable_vector]
struct NonVectorTypes(u32, u64);
//~^ ERROR: scalable vector structs can only have scalable vector fields
#[rustc_scalable_vector]
struct DifferentNonVectorTypes(u32, u64);
//~^ ERROR: scalable vector structs can only have scalable vector fields
#[rustc_scalable_vector]
struct SomeVectorTypes(ValidI64, u64);
//~^ ERROR: scalable vector structs can only have scalable vector fields
#[rustc_scalable_vector]
struct NestedTuple(ValidTuple, ValidTuple);
//~^ ERROR: scalable vector structs cannot contain other scalable vector structs

View file

@ -0,0 +1,38 @@
error: scalable vectors must be tuple structs
--> $DIR/illformed-tuples-of-scalable-vectors.rs:15:1
|
LL | struct Struct { x: ValidI64, y: ValidI64 }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: all fields in a scalable vector struct must be the same type
--> $DIR/illformed-tuples-of-scalable-vectors.rs:19:39
|
LL | struct DifferentVectorTypes(ValidI64, ValidI32);
| ^^^^^^^^
error: scalable vector structs can only have scalable vector fields
--> $DIR/illformed-tuples-of-scalable-vectors.rs:23:23
|
LL | struct NonVectorTypes(u32, u64);
| ^^^
error: scalable vector structs can only have scalable vector fields
--> $DIR/illformed-tuples-of-scalable-vectors.rs:27:32
|
LL | struct DifferentNonVectorTypes(u32, u64);
| ^^^
error: scalable vector structs can only have scalable vector fields
--> $DIR/illformed-tuples-of-scalable-vectors.rs:31:34
|
LL | struct SomeVectorTypes(ValidI64, u64);
| ^^^
error: scalable vector structs cannot contain other scalable vector structs
--> $DIR/illformed-tuples-of-scalable-vectors.rs:35:20
|
LL | struct NestedTuple(ValidTuple, ValidTuple);
| ^^^^^^^^^^
error: aborting due to 6 previous errors

View file

@ -0,0 +1,23 @@
//@ compile-flags: --crate-type=lib
#![allow(internal_features)]
#![feature(rustc_attrs)]
#[rustc_scalable_vector(2)]
struct ValidI64(i64);
struct Struct {
x: ValidI64,
//~^ ERROR: scalable vectors cannot be fields of a struct
in_tuple: (ValidI64,),
//~^ ERROR: scalable vectors cannot be tuple fields
}
struct TupleStruct(ValidI64);
//~^ ERROR: scalable vectors cannot be fields of a struct
enum Enum {
StructVariant { _ty: ValidI64 },
//~^ ERROR: scalable vectors cannot be fields of a variant
TupleVariant(ValidI64),
//~^ ERROR: scalable vectors cannot be fields of a variant
}

View file

@ -0,0 +1,32 @@
error: scalable vectors cannot be fields of a struct
--> $DIR/illformed-within-types.rs:9:8
|
LL | x: ValidI64,
| ^^^^^^^^
error: scalable vectors cannot be tuple fields
--> $DIR/illformed-within-types.rs:11:15
|
LL | in_tuple: (ValidI64,),
| ^^^^^^^^^^^
error: scalable vectors cannot be fields of a struct
--> $DIR/illformed-within-types.rs:15:20
|
LL | struct TupleStruct(ValidI64);
| ^^^^^^^^
error: scalable vectors cannot be fields of a variant
--> $DIR/illformed-within-types.rs:19:26
|
LL | StructVariant { _ty: ValidI64 },
| ^^^^^^^^
error: scalable vectors cannot be fields of a variant
--> $DIR/illformed-within-types.rs:21:18
|
LL | TupleVariant(ValidI64),
| ^^^^^^^^
error: aborting due to 5 previous errors

View file

@ -0,0 +1,59 @@
//@ compile-flags: --crate-type=lib
#![allow(internal_features)]
#![feature(rustc_attrs)]
#[rustc_scalable_vector(4)]
struct NoFieldsStructWithElementCount {}
//~^ ERROR: scalable vectors must have a single field
//~^^ ERROR: scalable vectors must be tuple structs
#[rustc_scalable_vector(4)]
struct NoFieldsTupleWithElementCount();
//~^ ERROR: scalable vectors must have a single field
#[rustc_scalable_vector(4)]
struct NoFieldsUnitWithElementCount;
//~^ ERROR: scalable vectors must have a single field
//~^^ ERROR: scalable vectors must be tuple structs
#[rustc_scalable_vector]
struct NoFieldsStructWithoutElementCount {}
//~^ ERROR: scalable vectors must have a single field
//~^^ ERROR: scalable vectors must be tuple structs
#[rustc_scalable_vector]
struct NoFieldsTupleWithoutElementCount();
//~^ ERROR: scalable vectors must have a single field
#[rustc_scalable_vector]
struct NoFieldsUnitWithoutElementCount;
//~^ ERROR: scalable vectors must have a single field
//~^^ ERROR: scalable vectors must be tuple structs
#[rustc_scalable_vector(4)]
struct MultipleFieldsStructWithElementCount {
//~^ ERROR: scalable vectors cannot have multiple fields
//~^^ ERROR: scalable vectors must be tuple structs
_ty: f32,
other: u32,
}
#[rustc_scalable_vector(4)]
struct MultipleFieldsTupleWithElementCount(f32, u32);
//~^ ERROR: scalable vectors cannot have multiple fields
#[rustc_scalable_vector]
struct MultipleFieldsStructWithoutElementCount {
//~^ ERROR: scalable vectors must be tuple structs
_ty: f32,
//~^ ERROR: scalable vector structs can only have scalable vector fields
other: u32,
}
#[rustc_scalable_vector]
struct MultipleFieldsTupleWithoutElementCount(f32, u32);
//~^ ERROR: scalable vector structs can only have scalable vector fields
#[rustc_scalable_vector(2)]
struct SingleFieldStruct { _ty: f64 }
//~^ ERROR: scalable vectors must be tuple structs

View file

@ -0,0 +1,125 @@
error: scalable vectors must be tuple structs
--> $DIR/illformed.rs:6:1
|
LL | struct NoFieldsStructWithElementCount {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: scalable vectors must be tuple structs
--> $DIR/illformed.rs:15:1
|
LL | struct NoFieldsUnitWithElementCount;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: scalable vectors must be tuple structs
--> $DIR/illformed.rs:20:1
|
LL | struct NoFieldsStructWithoutElementCount {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: scalable vectors must be tuple structs
--> $DIR/illformed.rs:29:1
|
LL | struct NoFieldsUnitWithoutElementCount;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: scalable vectors must be tuple structs
--> $DIR/illformed.rs:34:1
|
LL | / struct MultipleFieldsStructWithElementCount {
LL | |
LL | |
LL | | _ty: f32,
LL | | other: u32,
LL | | }
| |_^
error: scalable vectors must be tuple structs
--> $DIR/illformed.rs:46:1
|
LL | / struct MultipleFieldsStructWithoutElementCount {
LL | |
LL | | _ty: f32,
... |
LL | | }
| |_^
error: scalable vectors must be tuple structs
--> $DIR/illformed.rs:58:1
|
LL | struct SingleFieldStruct { _ty: f64 }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: scalable vectors must have a single field
--> $DIR/illformed.rs:6:1
|
LL | struct NoFieldsStructWithElementCount {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: scalable vector types' only field must be a primitive scalar type
error: scalable vectors must have a single field
--> $DIR/illformed.rs:11:1
|
LL | struct NoFieldsTupleWithElementCount();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: scalable vector types' only field must be a primitive scalar type
error: scalable vectors must have a single field
--> $DIR/illformed.rs:15:1
|
LL | struct NoFieldsUnitWithElementCount;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: scalable vector types' only field must be a primitive scalar type
error: scalable vectors must have a single field
--> $DIR/illformed.rs:20:1
|
LL | struct NoFieldsStructWithoutElementCount {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: tuples of scalable vectors can only contain multiple of the same scalable vector type
error: scalable vectors must have a single field
--> $DIR/illformed.rs:25:1
|
LL | struct NoFieldsTupleWithoutElementCount();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: tuples of scalable vectors can only contain multiple of the same scalable vector type
error: scalable vectors must have a single field
--> $DIR/illformed.rs:29:1
|
LL | struct NoFieldsUnitWithoutElementCount;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: tuples of scalable vectors can only contain multiple of the same scalable vector type
error: scalable vectors cannot have multiple fields
--> $DIR/illformed.rs:34:1
|
LL | struct MultipleFieldsStructWithElementCount {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: scalable vectors cannot have multiple fields
--> $DIR/illformed.rs:42:1
|
LL | struct MultipleFieldsTupleWithElementCount(f32, u32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: scalable vector structs can only have scalable vector fields
--> $DIR/illformed.rs:48:5
|
LL | _ty: f32,
| ^^^^^^^^
error: scalable vector structs can only have scalable vector fields
--> $DIR/illformed.rs:54:47
|
LL | struct MultipleFieldsTupleWithoutElementCount(f32, u32);
| ^^^
error: aborting due to 17 previous errors

View file

@ -160,3 +160,4 @@ struct Okay(f32);
#[rustc_scalable_vector]
struct OkayNoArg(f32);
//~^ ERROR: scalable vector structs can only have scalable vector fields

View file

@ -327,7 +327,13 @@ LL | #[rustc_scalable_vector(65536)]
|
= note: the value may not exceed `u16::MAX`
error: aborting due to 38 previous errors
error: scalable vector structs can only have scalable vector fields
--> $DIR/invalid.rs:162:18
|
LL | struct OkayNoArg(f32);
| ^^^
error: aborting due to 39 previous errors
Some errors have detailed explanations: E0539, E0805.
For more information about an error, try `rustc --explain E0539`.

View file

@ -0,0 +1,10 @@
//@ check-pass
//@ compile-flags: --crate-type=lib
#![feature(rustc_attrs)]
#[rustc_scalable_vector(16)]
struct ScalableU8(u8);
fn main() {
let x: [ScalableU8; 4] = todo!();
}

View file

@ -0,0 +1,48 @@
//@ check-pass
//@ compile-flags: --crate-type=lib
#![feature(rustc_attrs)]
#[rustc_scalable_vector(16)]
struct ScalableU8(u8);
#[rustc_scalable_vector(8)]
struct ScalableU16(u16);
#[rustc_scalable_vector(4)]
struct ScalableU32(u32);
#[rustc_scalable_vector(2)]
struct ScalableU64(u64);
#[rustc_scalable_vector(1)]
struct ScalableU128(u128);
#[rustc_scalable_vector(16)]
struct ScalableI8(i8);
#[rustc_scalable_vector(8)]
struct ScalableI16(i16);
#[rustc_scalable_vector(4)]
struct ScalableI32(i32);
#[rustc_scalable_vector(2)]
struct ScalableI64(i64);
#[rustc_scalable_vector(1)]
struct ScalableI128(i128);
#[rustc_scalable_vector(8)]
struct ScalableF16(f32);
#[rustc_scalable_vector(4)]
struct ScalableF32(f32);
#[rustc_scalable_vector(2)]
struct ScalableF64(f64);
#[rustc_scalable_vector(16)]
struct ScalableBool(bool);
#[rustc_scalable_vector]
struct ScalableTuple(ScalableU8, ScalableU8, ScalableU8);