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:
commit
610b4e503c
11 changed files with 327 additions and 53 deletions
|
|
@ -1,12 +0,0 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/feature-gate-type_changing_struct_update.rs:20:11
|
||||
|
|
||||
LL | ..m1
|
||||
| ^^ expected struct `State2`, found struct `State1`
|
||||
|
|
||||
= note: expected struct `Machine<State2>`
|
||||
found struct `Machine<State1>`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
// gate-test-type_changing_struct_update
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Machine<S> {
|
||||
state: S,
|
||||
|
|
@ -17,9 +19,10 @@ fn update_to_state2() {
|
|||
};
|
||||
let m2: Machine<State2> = Machine {
|
||||
state: State2,
|
||||
..m1 //~ ERROR mismatched types
|
||||
..m1
|
||||
//~^ ERROR type changing struct updating is experimental [E0658]
|
||||
//~| ERROR mismatched types [E0308]
|
||||
};
|
||||
// FIXME: this should trigger feature gate
|
||||
assert_eq!(State2, m2.state);
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
error[E0658]: type changing struct updating is experimental
|
||||
--> $DIR/feature-gate.rs:22:11
|
||||
|
|
||||
LL | ..m1
|
||||
| ^^
|
||||
|
|
||||
= note: see issue #86555 <https://github.com/rust-lang/rust/issues/86555> for more information
|
||||
= help: add `#![feature(type_changing_struct_update)]` to the crate attributes to enable
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/feature-gate.rs:22:11
|
||||
|
|
||||
LL | ..m1
|
||||
| ^^ expected struct `State2`, found struct `State1`
|
||||
|
|
||||
= note: expected struct `Machine<State2>`
|
||||
found struct `Machine<State1>`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0308, E0658.
|
||||
For more information about an error, try `rustc --explain E0308`.
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
#![feature(type_changing_struct_update)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Machine<'a, S> {
|
||||
state: S,
|
||||
lt_str: &'a str,
|
||||
common_field: i32,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct State1;
|
||||
#[derive(Clone)]
|
||||
struct State2;
|
||||
|
||||
fn update_to_state2() {
|
||||
let s = String::from("hello");
|
||||
let m1: Machine<State1> = Machine {
|
||||
state: State1,
|
||||
lt_str: &s,
|
||||
//~^ ERROR `s` does not live long enough [E0597]
|
||||
// FIXME: The error here actually comes from line 34. The
|
||||
// span of the error message should be corrected to line 34
|
||||
common_field: 2,
|
||||
};
|
||||
// update lifetime
|
||||
let m3: Machine<'static, State1> = Machine {
|
||||
lt_str: "hello, too",
|
||||
..m1.clone()
|
||||
};
|
||||
// update lifetime and type
|
||||
let m4: Machine<'static, State2> = Machine {
|
||||
state: State2,
|
||||
lt_str: "hello, again",
|
||||
..m1.clone()
|
||||
};
|
||||
// updating to `static should fail.
|
||||
let m2: Machine<'static, State1> = Machine {
|
||||
..m1
|
||||
};
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
error[E0597]: `s` does not live long enough
|
||||
--> $DIR/lifetime-update.rs:20:17
|
||||
|
|
||||
LL | lt_str: &s,
|
||||
| ^^ borrowed value does not live long enough
|
||||
...
|
||||
LL | let m2: Machine<'static, State1> = Machine {
|
||||
| ------------------------ type annotation requires that `s` is borrowed for `'static`
|
||||
...
|
||||
LL | }
|
||||
| - `s` dropped here while still borrowed
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0597`.
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
#![feature(type_changing_struct_update)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
struct Machine<'a, S, M> {
|
||||
state: S,
|
||||
message: M,
|
||||
lt_str: &'a str,
|
||||
common_field: i32,
|
||||
}
|
||||
|
||||
struct State1;
|
||||
struct State2;
|
||||
|
||||
struct Message1;
|
||||
struct Message2;
|
||||
|
||||
fn update() {
|
||||
let m1: Machine<State1, Message1> = Machine {
|
||||
state: State1,
|
||||
message: Message1,
|
||||
lt_str: "hello",
|
||||
common_field: 2,
|
||||
};
|
||||
// single type update
|
||||
let m2: Machine<State2, Message1> = Machine {
|
||||
state: State2,
|
||||
..m1
|
||||
};
|
||||
// multiple type update
|
||||
let m3: Machine<State2, Message2> = Machine {
|
||||
state: State2,
|
||||
message: Message2,
|
||||
..m1
|
||||
};
|
||||
}
|
||||
|
||||
fn fail_update() {
|
||||
let m1: Machine<f64, f64> = Machine {
|
||||
state: 3.2,
|
||||
message: 6.4,
|
||||
lt_str: "hello",
|
||||
common_field: 2,
|
||||
};
|
||||
// single type update fail
|
||||
let m2: Machine<i32, f64> = Machine {
|
||||
..m1
|
||||
//~^ ERROR mismatched types [E0308]
|
||||
};
|
||||
// multiple type update fail
|
||||
let m3 = Machine::<i32, i32> {
|
||||
..m1
|
||||
//~^ ERROR mismatched types [E0308]
|
||||
//~| ERROR mismatched types [E0308]
|
||||
};
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/type-generic-update.rs:46:11
|
||||
|
|
||||
LL | ..m1
|
||||
| ^^ field type mismatch: Machine.state
|
||||
|
|
||||
= note: expected type `i32`
|
||||
found type `f64`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/type-generic-update.rs:51:11
|
||||
|
|
||||
LL | ..m1
|
||||
| ^^ field type mismatch: Machine.state
|
||||
|
|
||||
= note: expected type `i32`
|
||||
found type `f64`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/type-generic-update.rs:51:11
|
||||
|
|
||||
LL | ..m1
|
||||
| ^^ field type mismatch: Machine.message
|
||||
|
|
||||
= note: expected type `i32`
|
||||
found type `f64`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
Loading…
Add table
Add a link
Reference in a new issue