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:
parent
78b06057ef
commit
ba9262936e
18 changed files with 742 additions and 6 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
93
tests/ui/scalable-vectors/illformed-element-type.rs
Normal file
93
tests/ui/scalable-vectors/illformed-element-type.rs
Normal 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
|
||||
122
tests/ui/scalable-vectors/illformed-element-type.stderr
Normal file
122
tests/ui/scalable-vectors/illformed-element-type.stderr
Normal 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
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
||||
23
tests/ui/scalable-vectors/illformed-within-types.rs
Normal file
23
tests/ui/scalable-vectors/illformed-within-types.rs
Normal 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
|
||||
}
|
||||
32
tests/ui/scalable-vectors/illformed-within-types.stderr
Normal file
32
tests/ui/scalable-vectors/illformed-within-types.stderr
Normal 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
|
||||
|
||||
59
tests/ui/scalable-vectors/illformed.rs
Normal file
59
tests/ui/scalable-vectors/illformed.rs
Normal 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
|
||||
125
tests/ui/scalable-vectors/illformed.stderr
Normal file
125
tests/ui/scalable-vectors/illformed.stderr
Normal 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
|
||||
|
||||
|
|
@ -160,3 +160,4 @@ struct Okay(f32);
|
|||
|
||||
#[rustc_scalable_vector]
|
||||
struct OkayNoArg(f32);
|
||||
//~^ ERROR: scalable vector structs can only have scalable vector fields
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
10
tests/ui/scalable-vectors/wellformed-arrays.rs
Normal file
10
tests/ui/scalable-vectors/wellformed-arrays.rs
Normal 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!();
|
||||
}
|
||||
48
tests/ui/scalable-vectors/wellformed.rs
Normal file
48
tests/ui/scalable-vectors/wellformed.rs
Normal 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);
|
||||
Loading…
Add table
Add a link
Reference in a new issue