You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Auto merge of #51131 - qnighy:unsized-locals, r=eddyb
Implement Unsized Rvalues
This PR is the first step to implement RFC1909: unsized rvalues (#48055).
## Implemented
- `Sized` is removed for arguments and local bindings. (under `#![feature(unsized_locals)]`)
- Unsized locations are allowed in MIR
- Unsized places and operands are correctly translated at codegen
## Not implemented in this PR
- Additional `Sized` checks:
- tuple struct constructor (accidentally compiles now)
- closure arguments at closure generation (accidentally compiles now)
- upvars (ICEs now)
- Generating vtable for `fn method(self)` (ICEs now)
- VLAs: `[e; n]` where `n` isn't const
- Reduce unnecessary allocations
## Current status
- [x] Fix `__rust_probestack` (rust-lang/compiler-builtins#244)
- [x] Get the fix merged
- [x] `#![feature(unsized_locals)]`
- [x] Give it a tracking issue number
- [x] Lift sized checks in typeck and MIR-borrowck
- [ ] <del>Forbid `A(unsized-expr)`</del> will be another PR
- [x] Minimum working codegen
- [x] Add more examples and fill in unimplemented codegen paths
- [ ] <del>Loosen object-safety rules (will be another PR)</del>
- [ ] <del>Implement `Box<FnOnce>` (will be another PR)</del>
- [ ] <del>Reduce temporaries (will be another PR)</del>
The RFC also describes an extension to the array literal syntax: `[e; dyn n]`. In the syntax, `n` isn't necessarily a constant expression. The array is dynamically allocated on the stack and has the type of `[T]`, instead of `[T; n]`.
131
+
132
+
```rust,ignore
133
+
#![feature(unsized_locals)]
134
+
135
+
fn mergesort<T: Ord>(a: &mut [T]) {
136
+
let mut tmp = [T; dyn a.len()];
137
+
// ...
138
+
}
139
+
140
+
fn main() {
141
+
let mut a = [3, 1, 5, 6];
142
+
mergesort(&mut a);
143
+
assert_eq!(a, [1, 3, 5, 6]);
144
+
}
145
+
```
146
+
147
+
VLAs are not implemented yet. The syntax isn't final, either. We may need an alternative syntax for Rust 2015 because, in Rust 2015, expressions like `[e; dyn(1)]` would be ambiguous. One possible alternative proposed in the RFC is `[e; n]`: if `n` captures one or more local variables, then it is considered as `[e; dyn n]`.
148
+
149
+
## Advisory on stack usage
150
+
151
+
It's advised not to casually use the `#![feature(unsized_locals)]` feature. Typical use-cases are:
152
+
153
+
- When you need a by-value trait objects.
154
+
- When you really need a fast allocation of small temporary arrays.
155
+
156
+
Another pitfall is repetitive allocation and temporaries. Currently the compiler simply extends the stack frame every time it encounters an unsized assignment. So for example, the code
0 commit comments