Rollup merge of #90035 - SparrowLii:rfc2528, r=jackh726

implement rfc-2528 type_changing-struct-update

This PR implement rfc2528-type_changing-struct-update.
The main change process is as follows:
1. Move the processing part of `base_expr` into `check_expr_struct_fields` to avoid returning `remaining_fields` (a relatively complex hash table)
2. Before performing the type consistency check(`check_expr_has_type_or_error`), if the `type_changing_struct_update` feature is set, enter a different processing flow, otherwise keep the original flow
3. In the case of the same structure definition, check each field in `remaining_fields`. If the field in `base_expr` is not the suptype of the field in `adt_ty`, an error(`FeildMisMatch`) will be reported.

The MIR part does not need to be changed, because only the items contained in `remaining_fields` will be extracted from `base_expr` when MIR is generated. This means that fields with different types in `base_expr` will not be used
Updates #86618
cc `@nikomatsakis`
This commit is contained in:
Matthias Krüger 2021-11-09 19:00:41 +01:00 committed by GitHub
commit 610b4e503c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 327 additions and 53 deletions

View file

@ -0,0 +1,33 @@
# `type_changing_struct_update`
The tracking issue for this feature is: [#86555]
[#86555]: https://github.com/rust-lang/rust/issues/86555
------------------------
This implements [RFC2528]. When turned on, you can create instances of the same struct
that have different generic type or lifetime parameters.
[RFC2528]: https://github.com/rust-lang/rfcs/blob/master/text/2528-type-changing-struct-update-syntax.md
```rust
#![allow(unused_variables, dead_code)]
#![feature(type_changing_struct_update)]
fn main () {
struct Foo<T, U> {
field1: T,
field2: U,
}
let base: Foo<String, i32> = Foo {
field1: String::from("hello"),
field2: 1234,
};
let updated: Foo<f64, i32> = Foo {
field1: 3.14,
..base
};
}
```