summaryrefslogtreecommitdiffstats
path: root/src/test/ui/rfcs/rfc-2528-type-changing-struct-update
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/ui/rfcs/rfc-2528-type-changing-struct-update')
-rw-r--r--src/test/ui/rfcs/rfc-2528-type-changing-struct-update/coerce-in-base-expr.rs28
-rw-r--r--src/test/ui/rfcs/rfc-2528-type-changing-struct-update/feature-gate.rs29
-rw-r--r--src/test/ui/rfcs/rfc-2528-type-changing-struct-update/feature-gate.stderr22
-rw-r--r--src/test/ui/rfcs/rfc-2528-type-changing-struct-update/issue-92010-trait-bound-not-satisfied.rs12
-rw-r--r--src/test/ui/rfcs/rfc-2528-type-changing-struct-update/issue-92010-trait-bound-not-satisfied.stderr12
-rw-r--r--src/test/ui/rfcs/rfc-2528-type-changing-struct-update/issue-96878.rs31
-rw-r--r--src/test/ui/rfcs/rfc-2528-type-changing-struct-update/lifetime-update.rs43
-rw-r--r--src/test/ui/rfcs/rfc-2528-type-changing-struct-update/lifetime-update.stderr15
-rw-r--r--src/test/ui/rfcs/rfc-2528-type-changing-struct-update/type-generic-update.rs56
-rw-r--r--src/test/ui/rfcs/rfc-2528-type-changing-struct-update/type-generic-update.stderr21
10 files changed, 269 insertions, 0 deletions
diff --git a/src/test/ui/rfcs/rfc-2528-type-changing-struct-update/coerce-in-base-expr.rs b/src/test/ui/rfcs/rfc-2528-type-changing-struct-update/coerce-in-base-expr.rs
new file mode 100644
index 000000000..75e48bf4a
--- /dev/null
+++ b/src/test/ui/rfcs/rfc-2528-type-changing-struct-update/coerce-in-base-expr.rs
@@ -0,0 +1,28 @@
+// check-pass
+
+#![feature(type_changing_struct_update)]
+#![allow(incomplete_features)]
+
+use std::any::Any;
+
+struct Foo<A, B: ?Sized, C: ?Sized> {
+ a: A,
+ b: Box<B>,
+ c: Box<C>,
+}
+
+struct B;
+struct C;
+
+fn main() {
+ let y = Foo::<usize, dyn Any, dyn Any> {
+ a: 0,
+ b: Box::new(B),
+ ..Foo {
+ a: 0,
+ b: Box::new(B),
+ // C needs to be told to coerce to `Box<dyn Any>`
+ c: Box::new(C),
+ }
+ };
+}
diff --git a/src/test/ui/rfcs/rfc-2528-type-changing-struct-update/feature-gate.rs b/src/test/ui/rfcs/rfc-2528-type-changing-struct-update/feature-gate.rs
new file mode 100644
index 000000000..1e8b99ba5
--- /dev/null
+++ b/src/test/ui/rfcs/rfc-2528-type-changing-struct-update/feature-gate.rs
@@ -0,0 +1,29 @@
+// gate-test-type_changing_struct_update
+
+#[derive(Debug)]
+struct Machine<S> {
+ state: S,
+ common_field1: &'static str,
+ common_field2: i32,
+}
+#[derive(Debug)]
+struct State1;
+#[derive(Debug, PartialEq)]
+struct State2;
+
+fn update_to_state2() {
+ let m1: Machine<State1> = Machine {
+ state: State1,
+ common_field1: "hello",
+ common_field2: 2,
+ };
+ let m2: Machine<State2> = Machine {
+ state: State2,
+ ..m1
+ //~^ ERROR type changing struct updating is experimental [E0658]
+ //~| ERROR mismatched types [E0308]
+ };
+ assert_eq!(State2, m2.state);
+}
+
+fn main() {}
diff --git a/src/test/ui/rfcs/rfc-2528-type-changing-struct-update/feature-gate.stderr b/src/test/ui/rfcs/rfc-2528-type-changing-struct-update/feature-gate.stderr
new file mode 100644
index 000000000..2217b8c04
--- /dev/null
+++ b/src/test/ui/rfcs/rfc-2528-type-changing-struct-update/feature-gate.stderr
@@ -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`.
diff --git a/src/test/ui/rfcs/rfc-2528-type-changing-struct-update/issue-92010-trait-bound-not-satisfied.rs b/src/test/ui/rfcs/rfc-2528-type-changing-struct-update/issue-92010-trait-bound-not-satisfied.rs
new file mode 100644
index 000000000..f1a54ee58
--- /dev/null
+++ b/src/test/ui/rfcs/rfc-2528-type-changing-struct-update/issue-92010-trait-bound-not-satisfied.rs
@@ -0,0 +1,12 @@
+#[derive(Clone)]
+struct P<T> {
+ x: T,
+ y: f64,
+}
+
+impl<T> P<T> {
+ fn y(&self, y: f64) -> Self { P{y, .. self.clone() } }
+ //~^ mismatched types [E0308]
+}
+
+fn main() {}
diff --git a/src/test/ui/rfcs/rfc-2528-type-changing-struct-update/issue-92010-trait-bound-not-satisfied.stderr b/src/test/ui/rfcs/rfc-2528-type-changing-struct-update/issue-92010-trait-bound-not-satisfied.stderr
new file mode 100644
index 000000000..5957ea7c9
--- /dev/null
+++ b/src/test/ui/rfcs/rfc-2528-type-changing-struct-update/issue-92010-trait-bound-not-satisfied.stderr
@@ -0,0 +1,12 @@
+error[E0308]: mismatched types
+ --> $DIR/issue-92010-trait-bound-not-satisfied.rs:8:43
+ |
+LL | fn y(&self, y: f64) -> Self { P{y, .. self.clone() } }
+ | ^^^^^^^^^^^^ expected struct `P`, found `&P<T>`
+ |
+ = note: expected struct `P<T>`
+ found reference `&P<T>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/rfcs/rfc-2528-type-changing-struct-update/issue-96878.rs b/src/test/ui/rfcs/rfc-2528-type-changing-struct-update/issue-96878.rs
new file mode 100644
index 000000000..3dfbef0ee
--- /dev/null
+++ b/src/test/ui/rfcs/rfc-2528-type-changing-struct-update/issue-96878.rs
@@ -0,0 +1,31 @@
+// check-pass
+
+#![feature(type_changing_struct_update)]
+#![allow(incomplete_features)]
+
+use std::borrow::Cow;
+use std::marker::PhantomData;
+
+#[derive(Default)]
+struct NonGeneric {
+ field1: usize,
+}
+
+#[derive(Default)]
+struct Generic<T, U> {
+ field1: T,
+ field2: U,
+}
+
+#[derive(Default)]
+struct MoreGeneric<'a, const N: usize> {
+ // If only `for<const N: usize> [u32; N]: Default`...
+ field1: PhantomData<[u32; N]>,
+ field2: Cow<'a, str>,
+}
+
+fn main() {
+ let default1 = NonGeneric { ..Default::default() };
+ let default2: Generic<i32, f32> = Generic { ..Default::default() };
+ let default3: MoreGeneric<'static, 12> = MoreGeneric { ..Default::default() };
+}
diff --git a/src/test/ui/rfcs/rfc-2528-type-changing-struct-update/lifetime-update.rs b/src/test/ui/rfcs/rfc-2528-type-changing-struct-update/lifetime-update.rs
new file mode 100644
index 000000000..df2fef55d
--- /dev/null
+++ b/src/test/ui/rfcs/rfc-2528-type-changing-struct-update/lifetime-update.rs
@@ -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() {}
diff --git a/src/test/ui/rfcs/rfc-2528-type-changing-struct-update/lifetime-update.stderr b/src/test/ui/rfcs/rfc-2528-type-changing-struct-update/lifetime-update.stderr
new file mode 100644
index 000000000..5f93ad6e0
--- /dev/null
+++ b/src/test/ui/rfcs/rfc-2528-type-changing-struct-update/lifetime-update.stderr
@@ -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`.
diff --git a/src/test/ui/rfcs/rfc-2528-type-changing-struct-update/type-generic-update.rs b/src/test/ui/rfcs/rfc-2528-type-changing-struct-update/type-generic-update.rs
new file mode 100644
index 000000000..dae1241d3
--- /dev/null
+++ b/src/test/ui/rfcs/rfc-2528-type-changing-struct-update/type-generic-update.rs
@@ -0,0 +1,56 @@
+#![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]
+ };
+}
+
+fn main() {}
diff --git a/src/test/ui/rfcs/rfc-2528-type-changing-struct-update/type-generic-update.stderr b/src/test/ui/rfcs/rfc-2528-type-changing-struct-update/type-generic-update.stderr
new file mode 100644
index 000000000..6f31b1a96
--- /dev/null
+++ b/src/test/ui/rfcs/rfc-2528-type-changing-struct-update/type-generic-update.stderr
@@ -0,0 +1,21 @@
+error[E0308]: mismatched types
+ --> $DIR/type-generic-update.rs:46:11
+ |
+LL | ..m1
+ | ^^ expected `i32`, found `f64`
+ |
+ = note: expected struct `Machine<'_, i32, _>`
+ found struct `Machine<'_, f64, _>`
+
+error[E0308]: mismatched types
+ --> $DIR/type-generic-update.rs:51:11
+ |
+LL | ..m1
+ | ^^ expected `i32`, found `f64`
+ |
+ = note: expected struct `Machine<'_, i32, i32>`
+ found struct `Machine<'_, f64, f64>`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.