Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Open
Changes from 1 commit
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
7f9018c
introduce `repr(scalable)`
davidtwco May 18, 2022
48c8407
mention prctl use for child processes
davidtwco Jul 14, 2025
55f532e
rename to rfcs#3838
davidtwco Jul 14, 2025
6afaff7
permit `repr(transparent)` newtypes
davidtwco Jul 14, 2025
35fd341
elaborate on choosing `N`
davidtwco Jul 14, 2025
f514a3e
rename to `rustc_scalable_vector`
davidtwco Jul 28, 2025
2a7705a
add asserts into sve example
davidtwco Jul 28, 2025
8709d8c
add missing words
davidtwco Jul 28, 2025
b96e2b7
clarify details of code example
davidtwco Jul 28, 2025
83d0b93
clarify details of type marker
davidtwco Jul 28, 2025
dcb29b4
avoid introducing scalable vectors in guide-level
davidtwco Jul 28, 2025
4123a3a
s/stablised/stabilised
davidtwco Jul 28, 2025
e5b546c
remove trailing whitespaces
davidtwco Aug 4, 2025
388170a
improve explanation and justification for manual N
davidtwco Aug 4, 2025
16bb4eb
prohibit generic instantiation/trait impls
davidtwco Aug 5, 2025
ca4aa06
mention ffi-safety
davidtwco Aug 5, 2025
5011dc6
add much more prior art
davidtwco Aug 6, 2025
494da8a
move vector length at runtime warning into section
davidtwco Aug 6, 2025
6186245
updated representation of tuples of vectors
davidtwco Aug 6, 2025
9466d26
another possibility for removing restrictions
davidtwco Aug 6, 2025
c6d836d
clarify function pointers
davidtwco Aug 6, 2025
968ae3e
correct no action rationale
davidtwco Aug 6, 2025
530378c
mention dyn incompatibility
davidtwco Aug 6, 2025
0fe50a8
does not build on `repr(simd)`
davidtwco Aug 7, 2025
442beea
fix inconsistency with array support
davidtwco Aug 12, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
prohibit generic instantiation/trait impls
  • Loading branch information
davidtwco committed Aug 5, 2025
commit 16bb4ebaad14dcc681dd434552c67cad66e852a8
103 changes: 65 additions & 38 deletions text/3838-scalable-vectors.md
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,9 @@ behave like value types but the exact size cannot be known at compilation time.
Scalable vector types have some further restrictions due to limitations of the
codegen backend:

- Can only be in the signature of a function if it is annotated with the
appropriate target feature (see [*ABI*][abi])

- Cannot be stored in compound types (structs, enums, etc)

- Including coroutines, so these types cannot be held across an await
Expand All @@ -235,12 +238,20 @@ codegen backend:

- Cannot be used in arrays

- Cannot be the type of a static variable.
- Cannot be the type of a static variable

- Cannot be instantiated into generic functions (see
[*Target features*][target-features])
Comment on lines +272 to +273

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this also exclude e.g. size_of::<svfloat32_t>()?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does, which is unfortunate and I'd prefer to support it. This restriction is only present as requiring the target feature be present when the type is used seems like it won't be possible, and I've not had time to experiment with using an indirect ABI (as per #3838 (comment)), so a restriction here makes the RFC, as written, technically feasible in the meantime.

Copy link

@hanna-kruppe hanna-kruppe Aug 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do C and C++ compilers deal with this dilemma? Do they support sizeof(svfloat32_t) as runtime value, and if so, do they either require the target feature to be available for that or implicitly enable it?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like sizeless types are prohibited from being used with sizeof:

<source>:9:5: error: invalid application of 'sizeof' to sizeless type 'svuint8x3_t' (aka '__clang_svuint8x3_t')
    9 |     sizeof(svuint8x3_t);
      |     ^     ~~~~~~~~~~~~~
1 error generated.


- Cannot have trait implementations (see [*Target features*][target-features])

- Including blanket implementations (i.e. `impl<T> Foo for T` is not a valid
candidate for a scalable vector)
Comment on lines +275 to +278

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this is intended to prevent a scalable vector value and types from bleeding into generic code, without relying entirely on post-mono errors? If so, note that they can also be smuggled in via associated types (slight modification of Ralf's earlier example):

trait Tr { type Assoc; }

fn foo<T: Tr>() {
  size_of::<T::Assoc>();
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not just avoiding post-mono errors, but just avoiding any potential issues with target features needing to be be applied to trait methods but not the trait definition (#3820 is related to this). I'd expect that smuggling in instantiation via associated types to be prohibited by the existing restriction on generic instantiation - I don't think it's worth elaborating on that too much as I do intend to remove this restriction once investigating using an indirect ABI and hopefully finding that feasible.


Some of these limitations may be able to be lifted in future depending on what
is supported by rustc's codegen backends.
is supported by rustc's codegen backends or with evolution of the language.

## ABI
### ABI
[abi]: #abi

Rust currently always passes SIMD vectors on the stack to avoid ABI mismatches
Expand All @@ -256,23 +267,24 @@ Therefore, there is an additional restriction that these types cannot be used in
the argument or return types of functions unless those functions are annotated
with the relevant target feature.

## Target features
### Target features
[target-features]: #target-features

Similarly to the issues with the ABI of scalable vectors, without the relevant
target features, few operations can actually be performed on scalable vectors -
causing issues for the use of scalable vectors in generic code and with traits.
Similarly to the challenges with the ABI of scalable vectors, without the
relevant target features, few operations can actually be performed on scalable
vectors - causing issues for the use of scalable vectors in generic code and
with traits implementations.

For example, implementations of traits like `Clone` would not be able to
actually perform a clone, and generic functions that are instantiated with
scalable vectors would during instruction selection in the codegen backend.

When a scalable vector is instantiated into a generic function during
monomorphisation, or a trait method is being implemented for a scalable vector,
then the relevant target feature will be added to the function.
Without a mechanism for a generic function to be able to inherit target features
from its instantiated types or for trait methods to have target features, it is
not possible for these types to be used with generic functions or traits.

For example, when instantiating `std::mem::size_of_val` with a scalable vector
during monomorphisation, the relevant target feature will be added to `size_of_val`
for codegen.
See
[*Trait implementations and generic instantiation*][trait-implementations-and-generic-instantiation].

## Implementing `rustc_scalable_vector`
[implementing-rustc_scalable_vector]: #implementing-rustc_scalable_vector
Expand Down Expand Up @@ -651,43 +663,47 @@ There are not many languages with support for scalable vectors:
# Unresolved questions
[unresolved-questions]: #unresolved-questions

There are currently no unresolved questions.
There is one outstanding unresolved question for scalable vectors:

- How to support trait implementations and generic instantiation for scalable vectors?

- See [*Target features*][target-features] and
[*Trait implementations and generic instantiation*][trait-implementations-and-generic-instantiation]

# Future possibilities
[future-possibilities]: #future-possibilities

There are a handful of future possibilities enabled by this RFC:
There are a handful of future possibilities enabled by this RFC - relaxing
restrictions, architecture-agnostic use or extending the feature to support more
features of the architecture extensions:

## General mechanism for target-feature-affected types
[general-mechanism-target-feature-types]: #general-mechanism-for-target-feature-affected-types
## Trait implementations and generic instantiation
[trait-implementations-and-generic-instantiation]: #trait-implementations-and-generic-instantiation

A more general mechanism for enforcing that SIMD types are only used in
`target_feature`-annotated functions would be useful, as this would enable SVE
types to have fewer distinct restrictions than other SIMD types, and would
enable SIMD vectors to be passed by-register, a performance improvement.
Improvements to the language's `target_feature` infrastructure could enable the
restrictions on trait implementations and generic instantiation to be lifted:

Such a mechanism would need to be introduced gradually to existing SIMD types
with a forward compatibility lint. This will be addressed in a forthcoming RFC.
- Some variety of [rfcs#3820: `target_feature_traits`][rfcs#3280] could help
traits be implemented on scalable vectors

## Relaxed restrictions
[relaxed-restrictions]: #relaxed-restrictions
- Efforts to integrate target features with the effect system ([rust#143352])
may help enable generic instantiation of scalable vectors

Some of the restrictions on these types (e.g. use in compound types) could be
- Any mechanism that could be applied to scalable vector types could also be
used to enforce that existing SIMD types are only used in
`target_feature`-annotated functions, which would enable fixed-length
vectors to be passed by-register, improving performance

## Compound types
[compound-types]: #compound-types

The restriction that scalable vectors cannot be used in compound types could be
relaxed at a later time either by extending rustc's codegen or leveraging newly
added support in LLVM.

However, as C also has restriction and scalable vectors are nevertheless used in
production code, it is unlikely there will be much demand for those restrictions
to be relaxed.

## Portable SIMD
[portable-simd]: #portable-simd

Given that there are significant differences between scalable vectors and
fixed-length vectors, and that `std::simd` is unstable, it is worth
experimenting with architecture-specific support and implementation initially.
Later, there are a variety of approaches that could be taken to incorporate
support for scalable vectors into Portable SIMD.
However, as C also has thus restriction and scalable vectors are nevertheless
used in production code, it is unlikely there will be much demand for those
restrictions to be relaxed in LLVM.

## RISC-V Vector Extension's tuple types
[rvv-tuples]: #risc-v-vector-extensions-tuple-types
Expand All @@ -703,14 +719,25 @@ types in LLVM, would both be `<vscale x 4 x i32>`.
RVV's tuple types need to be lowered to target-specific types in the backend
which is out-of-scope of this general infrastructure for scalable vectors.

## Portable SIMD
[portable-simd]: #portable-simd

Given that there are significant differences between scalable vectors and
fixed-length vectors, and that `std::simd` is unstable, it is worth
experimenting with architecture-specific support and implementation initially.
Later, there are a variety of approaches that could be taken to incorporate
support for scalable vectors into Portable SIMD.

[acle_sizeless]: https://arm-software.github.io/acle/main/acle.html#formal-definition-of-sizeless-types
[dotnet]: https://github.com/dotnet/runtime/issues/93095
[prctl]: https://www.kernel.org/doc/Documentation/arm64/sve.txt
[quote_amanieu]: https://github.com/rust-lang/rust/pull/118917#issuecomment-2202256754
[rfcs#1199]: https://rust-lang.github.io/rfcs/1199-simd-infrastructure.html
[rfcs#3268]: https://github.com/rust-lang/rfcs/pull/3268
[rfcs#3729]: https://github.com/rust-lang/rfcs/pull/3729
[rfcs#3280]: https://github.com/rust-lang/rfcs/pull/3280
[rust#63633]: https://github.com/rust-lang/rust/issues/63633
[rust#143352]: https://github.com/rust-lang/rust/issues/143352
[rvv_bitsperblock]: https://github.com/llvm/llvm-project/blob/837b2d464ff16fe0d892dcf2827747c97dd5465e/llvm/include/llvm/TargetParser/RISCVTargetParser.h#L51
[rvv_typesystem]: https://github.com/riscv-non-isa/rvv-intrinsic-doc/blob/main/doc/rvv-intrinsic-spec.adoc#type-system
[sve_minlength]: https://developer.arm.com/documentation/102476/0101/Introducing-SVE#:~:text=a%20minimum%20of%20128%20bits