Rollup merge of #80726 - lcnr:unsize-query, r=oli-obk
relax adt unsizing requirements Changes unsizing of structs in case the last struct field shares generic params with other adt fields which do not change. This change is currently insta stable and changes the language, so it at least requires a lang fcp. I feel like the current state is fairly unintuitive. An example for what's now allowed would be https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=6dd331d23f5c9ffc8c978175aae2e967 ```rust struct A<T, U: ?Sized>(T, B<T, U>); // previously ERR // struct A<T, U: ?Sized>(T, B<[u32; 1], U>); // ok struct B<T, U: ?Sized>(T, U); fn main() { let x = A([0; 1], B([0; 1], [0; 1])); let y: &A<[u32; 1], [u32]> = &x; assert_eq!(y.1.1.len(), 1); } ```
This commit is contained in:
commit
676ff77fb7
7 changed files with 98 additions and 20 deletions
|
|
@ -0,0 +1,10 @@
|
|||
// Test that we allow unsizing even if there is an unchanged param in the
|
||||
// field getting unsized.
|
||||
struct A<T, U: ?Sized + 'static>(T, B<T, U>);
|
||||
struct B<T, U: ?Sized>(T, U);
|
||||
|
||||
fn main() {
|
||||
let x: A<[u32; 1], [u32; 1]> = A([0; 1], B([0; 1], [0; 1]));
|
||||
let y: &A<[u32; 1], [u32]> = &x; //~ ERROR mismatched types
|
||||
assert_eq!(y.1.1.len(), 1);
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/feature-gate-relaxed_struct_unsize.rs:8:34
|
||||
|
|
||||
LL | let y: &A<[u32; 1], [u32]> = &x;
|
||||
| ------------------- ^^ expected slice `[u32]`, found array `[u32; 1]`
|
||||
| |
|
||||
| expected due to this
|
||||
|
|
||||
= note: expected reference `&A<[u32; 1], [u32]>`
|
||||
found reference `&A<[u32; 1], [u32; 1]>`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
12
src/test/ui/unsized/unchanged-param.rs
Normal file
12
src/test/ui/unsized/unchanged-param.rs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#![feature(relaxed_struct_unsize)]
|
||||
// run-pass
|
||||
// Test that we allow unsizing even if there is an unchanged param in the
|
||||
// field getting unsized.
|
||||
struct A<T, U: ?Sized + 'static>(T, B<T, U>);
|
||||
struct B<T, U: ?Sized>(T, U);
|
||||
|
||||
fn main() {
|
||||
let x: A<[u32; 1], [u32; 1]> = A([0; 1], B([0; 1], [0; 1]));
|
||||
let y: &A<[u32; 1], [u32]> = &x;
|
||||
assert_eq!(y.1.1.len(), 1);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue