diff --git a/src/test/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.ast.stderr b/src/test/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.ast.stderr new file mode 100644 index 0000000000000..d72cc20971b0e --- /dev/null +++ b/src/test/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.ast.stderr @@ -0,0 +1,39 @@ +error[E0381]: use of possibly uninitialized variable: `t.0` + --> $DIR/issue-54499-field-mutation-marks-mut-as-used.rs:25:31 + | +LL | println!("{:?} {:?}", t.0, t.1); + | ^^^ use of possibly uninitialized `t.0` + +error[E0381]: use of possibly uninitialized variable: `t.1` + --> $DIR/issue-54499-field-mutation-marks-mut-as-used.rs:25:36 + | +LL | println!("{:?} {:?}", t.0, t.1); + | ^^^ use of possibly uninitialized `t.1` + +error[E0381]: use of possibly uninitialized variable: `u.0` + --> $DIR/issue-54499-field-mutation-marks-mut-as-used.rs:35:31 + | +LL | println!("{:?} {:?}", u.0, u.1); + | ^^^ use of possibly uninitialized `u.0` + +error[E0381]: use of possibly uninitialized variable: `u.1` + --> $DIR/issue-54499-field-mutation-marks-mut-as-used.rs:35:36 + | +LL | println!("{:?} {:?}", u.0, u.1); + | ^^^ use of possibly uninitialized `u.1` + +error[E0381]: use of possibly uninitialized variable: `v.x` + --> $DIR/issue-54499-field-mutation-marks-mut-as-used.rs:45:31 + | +LL | println!("{:?} {:?}", v.x, v.y); + | ^^^ use of possibly uninitialized `v.x` + +error[E0381]: use of possibly uninitialized variable: `v.y` + --> $DIR/issue-54499-field-mutation-marks-mut-as-used.rs:45:36 + | +LL | println!("{:?} {:?}", v.x, v.y); + | ^^^ use of possibly uninitialized `v.y` + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0381`. diff --git a/src/test/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.nll.stderr b/src/test/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.nll.stderr new file mode 100644 index 0000000000000..ebc6c7fca62b9 --- /dev/null +++ b/src/test/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.nll.stderr @@ -0,0 +1,21 @@ +error[E0381]: assign to part of possibly uninitialized variable: `t` + --> $DIR/issue-54499-field-mutation-marks-mut-as-used.rs:22:9 + | +LL | t.0 = S(1); + | ^^^^^^^^^^ use of possibly uninitialized `t` + +error[E0381]: assign to part of possibly uninitialized variable: `u` + --> $DIR/issue-54499-field-mutation-marks-mut-as-used.rs:32:9 + | +LL | u.0 = S(1); + | ^^^^^^^^^^ use of possibly uninitialized `u` + +error[E0381]: assign to part of possibly uninitialized variable: `v` + --> $DIR/issue-54499-field-mutation-marks-mut-as-used.rs:42:9 + | +LL | v.x = S(1); + | ^^^^^^^^^^ use of possibly uninitialized `v` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0381`. diff --git a/src/test/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.rs b/src/test/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.rs new file mode 100644 index 0000000000000..4358e8e440237 --- /dev/null +++ b/src/test/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.rs @@ -0,0 +1,49 @@ +// revisions: ast nll + +// Since we are testing nll migration explicitly as a separate +// revision, don't worry about the --compare-mode=nll on this test. + +// ignore-compare-mode-nll + +//[ast]compile-flags: -Z borrowck=ast +//[nll]compile-flags: -Z borrowck=migrate -Z two-phase-borrows + +#![warn(unused)] +#[derive(Debug)] +struct S(i32); + +type Tuple = (S, i32); +struct Tpair(S, i32); +struct Spair { x: S, y: i32 } + +fn main() { + { + let mut t: Tuple; + t.0 = S(1); + //[nll]~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381] + t.1 = 2; + println!("{:?} {:?}", t.0, t.1); + //[ast]~^ ERROR use of possibly uninitialized variable: `t.0` [E0381] + //[ast]~| ERROR use of possibly uninitialized variable: `t.1` [E0381] + } + + { + let mut u: Tpair; + u.0 = S(1); + //[nll]~^ ERROR assign to part of possibly uninitialized variable: `u` [E0381] + u.1 = 2; + println!("{:?} {:?}", u.0, u.1); + //[ast]~^ ERROR use of possibly uninitialized variable: `u.0` [E0381] + //[ast]~| ERROR use of possibly uninitialized variable: `u.1` [E0381] + } + + { + let mut v: Spair; + v.x = S(1); + //[nll]~^ ERROR assign to part of possibly uninitialized variable: `v` [E0381] + v.y = 2; + println!("{:?} {:?}", v.x, v.y); + //[ast]~^ ERROR use of possibly uninitialized variable: `v.x` [E0381] + //[ast]~| ERROR use of possibly uninitialized variable: `v.y` [E0381] + } +} diff --git a/src/test/ui/borrowck/issue-54499-field-mutation-of-moved-out-with-mut.ast.stderr b/src/test/ui/borrowck/issue-54499-field-mutation-of-moved-out-with-mut.ast.stderr new file mode 100644 index 0000000000000..e3b5341d2bcff --- /dev/null +++ b/src/test/ui/borrowck/issue-54499-field-mutation-of-moved-out-with-mut.ast.stderr @@ -0,0 +1,69 @@ +error[E0382]: use of moved value: `t.0` + --> $DIR/issue-54499-field-mutation-of-moved-out-with-mut.rs:25:31 + | +LL | drop(t); + | - value moved here +... +LL | println!("{:?} {:?}", t.0, t.1); + | ^^^ value used here after move + | + = note: move occurs because `t` has type `(S, i32)`, which does not implement the `Copy` trait + +error[E0382]: use of moved value: `t.1` + --> $DIR/issue-54499-field-mutation-of-moved-out-with-mut.rs:25:36 + | +LL | drop(t); + | - value moved here +... +LL | println!("{:?} {:?}", t.0, t.1); + | ^^^ value used here after move + | + = note: move occurs because `t` has type `(S, i32)`, which does not implement the `Copy` trait + +error[E0382]: use of moved value: `u.0` + --> $DIR/issue-54499-field-mutation-of-moved-out-with-mut.rs:33:31 + | +LL | drop(u); + | - value moved here +... +LL | println!("{:?} {:?}", u.0, u.1); + | ^^^ value used here after move + | + = note: move occurs because `u` has type `Tpair`, which does not implement the `Copy` trait + +error[E0382]: use of moved value: `u.1` + --> $DIR/issue-54499-field-mutation-of-moved-out-with-mut.rs:33:36 + | +LL | drop(u); + | - value moved here +... +LL | println!("{:?} {:?}", u.0, u.1); + | ^^^ value used here after move + | + = note: move occurs because `u` has type `Tpair`, which does not implement the `Copy` trait + +error[E0382]: use of moved value: `v.x` + --> $DIR/issue-54499-field-mutation-of-moved-out-with-mut.rs:41:31 + | +LL | drop(v); + | - value moved here +... +LL | println!("{:?} {:?}", v.x, v.y); + | ^^^ value used here after move + | + = note: move occurs because `v` has type `Spair`, which does not implement the `Copy` trait + +error[E0382]: use of moved value: `v.y` + --> $DIR/issue-54499-field-mutation-of-moved-out-with-mut.rs:41:36 + | +LL | drop(v); + | - value moved here +... +LL | println!("{:?} {:?}", v.x, v.y); + | ^^^ value used here after move + | + = note: move occurs because `v` has type `Spair`, which does not implement the `Copy` trait + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/borrowck/issue-54499-field-mutation-of-moved-out-with-mut.nll.stderr b/src/test/ui/borrowck/issue-54499-field-mutation-of-moved-out-with-mut.nll.stderr new file mode 100644 index 0000000000000..001ed59059cc8 --- /dev/null +++ b/src/test/ui/borrowck/issue-54499-field-mutation-of-moved-out-with-mut.nll.stderr @@ -0,0 +1,33 @@ +error[E0382]: assign to part of moved value: `t` + --> $DIR/issue-54499-field-mutation-of-moved-out-with-mut.rs:23:9 + | +LL | drop(t); + | - value moved here +LL | t.0 = S(1); + | ^^^^^^^^^^ value partially assigned here after move + | + = note: move occurs because `t` has type `(S, i32)`, which does not implement the `Copy` trait + +error[E0382]: assign to part of moved value: `u` + --> $DIR/issue-54499-field-mutation-of-moved-out-with-mut.rs:31:9 + | +LL | drop(u); + | - value moved here +LL | u.0 = S(1); + | ^^^^^^^^^^ value partially assigned here after move + | + = note: move occurs because `u` has type `Tpair`, which does not implement the `Copy` trait + +error[E0382]: assign to part of moved value: `v` + --> $DIR/issue-54499-field-mutation-of-moved-out-with-mut.rs:39:9 + | +LL | drop(v); + | - value moved here +LL | v.x = S(1); + | ^^^^^^^^^^ value partially assigned here after move + | + = note: move occurs because `v` has type `Spair`, which does not implement the `Copy` trait + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/borrowck/issue-54499-field-mutation-of-moved-out-with-mut.rs b/src/test/ui/borrowck/issue-54499-field-mutation-of-moved-out-with-mut.rs new file mode 100644 index 0000000000000..b6339c4a3c754 --- /dev/null +++ b/src/test/ui/borrowck/issue-54499-field-mutation-of-moved-out-with-mut.rs @@ -0,0 +1,43 @@ +// revisions: ast nll + +// Since we are testing nll migration explicitly as a separate +// revision, don't worry about the --compare-mode=nll on this test. + +// ignore-compare-mode-nll + +//[ast]compile-flags: -Z borrowck=ast +//[nll]compile-flags: -Z borrowck=migrate -Z two-phase-borrows + +#![warn(unused)] +#[derive(Debug)] +struct S(i32); + +type Tuple = (S, i32); +struct Tpair(S, i32); +struct Spair { x: S, y: i32 } + +fn main() { + { + let mut t: Tuple = (S(0), 0); + drop(t); + t.0 = S(1); + t.1 = 2; + println!("{:?} {:?}", t.0, t.1); + } + + { + let mut u: Tpair = Tpair(S(0), 0); + drop(u); + u.0 = S(1); + u.1 = 2; + println!("{:?} {:?}", u.0, u.1); + } + + { + let mut v: Spair = Spair { x: S(0), y: 0 }; + drop(v); + v.x = S(1); + v.y = 2; + println!("{:?} {:?}", v.x, v.y); + } +} diff --git a/src/test/ui/borrowck/issue-54499-field-mutation-of-moved-out.ast.stderr b/src/test/ui/borrowck/issue-54499-field-mutation-of-moved-out.ast.stderr new file mode 100644 index 0000000000000..565272af39049 --- /dev/null +++ b/src/test/ui/borrowck/issue-54499-field-mutation-of-moved-out.ast.stderr @@ -0,0 +1,124 @@ +error[E0594]: cannot assign to field `t.0` of immutable binding + --> $DIR/issue-54499-field-mutation-of-moved-out.rs:23:9 + | +LL | let t: Tuple = (S(0), 0); + | - help: make this binding mutable: `mut t` +LL | drop(t); +LL | t.0 = S(1); + | ^^^^^^^^^^ cannot mutably borrow field of immutable binding + +error[E0594]: cannot assign to field `t.1` of immutable binding + --> $DIR/issue-54499-field-mutation-of-moved-out.rs:27:9 + | +LL | let t: Tuple = (S(0), 0); + | - help: make this binding mutable: `mut t` +... +LL | t.1 = 2; + | ^^^^^^^ cannot mutably borrow field of immutable binding + +error[E0594]: cannot assign to field `u.0` of immutable binding + --> $DIR/issue-54499-field-mutation-of-moved-out.rs:38:9 + | +LL | let u: Tpair = Tpair(S(0), 0); + | - help: make this binding mutable: `mut u` +LL | drop(u); +LL | u.0 = S(1); + | ^^^^^^^^^^ cannot mutably borrow field of immutable binding + +error[E0594]: cannot assign to field `u.1` of immutable binding + --> $DIR/issue-54499-field-mutation-of-moved-out.rs:42:9 + | +LL | let u: Tpair = Tpair(S(0), 0); + | - help: make this binding mutable: `mut u` +... +LL | u.1 = 2; + | ^^^^^^^ cannot mutably borrow field of immutable binding + +error[E0594]: cannot assign to field `v.x` of immutable binding + --> $DIR/issue-54499-field-mutation-of-moved-out.rs:53:9 + | +LL | let v: Spair = Spair { x: S(0), y: 0 }; + | - help: make this binding mutable: `mut v` +LL | drop(v); +LL | v.x = S(1); + | ^^^^^^^^^^ cannot mutably borrow field of immutable binding + +error[E0594]: cannot assign to field `v.y` of immutable binding + --> $DIR/issue-54499-field-mutation-of-moved-out.rs:57:9 + | +LL | let v: Spair = Spair { x: S(0), y: 0 }; + | - help: make this binding mutable: `mut v` +... +LL | v.y = 2; + | ^^^^^^^ cannot mutably borrow field of immutable binding + +error[E0382]: use of moved value: `t.0` + --> $DIR/issue-54499-field-mutation-of-moved-out.rs:30:31 + | +LL | drop(t); + | - value moved here +... +LL | println!("{:?} {:?}", t.0, t.1); + | ^^^ value used here after move + | + = note: move occurs because `t` has type `(S, i32)`, which does not implement the `Copy` trait + +error[E0382]: use of moved value: `t.1` + --> $DIR/issue-54499-field-mutation-of-moved-out.rs:30:36 + | +LL | drop(t); + | - value moved here +... +LL | println!("{:?} {:?}", t.0, t.1); + | ^^^ value used here after move + | + = note: move occurs because `t` has type `(S, i32)`, which does not implement the `Copy` trait + +error[E0382]: use of moved value: `u.0` + --> $DIR/issue-54499-field-mutation-of-moved-out.rs:45:31 + | +LL | drop(u); + | - value moved here +... +LL | println!("{:?} {:?}", u.0, u.1); + | ^^^ value used here after move + | + = note: move occurs because `u` has type `Tpair`, which does not implement the `Copy` trait + +error[E0382]: use of moved value: `u.1` + --> $DIR/issue-54499-field-mutation-of-moved-out.rs:45:36 + | +LL | drop(u); + | - value moved here +... +LL | println!("{:?} {:?}", u.0, u.1); + | ^^^ value used here after move + | + = note: move occurs because `u` has type `Tpair`, which does not implement the `Copy` trait + +error[E0382]: use of moved value: `v.x` + --> $DIR/issue-54499-field-mutation-of-moved-out.rs:60:31 + | +LL | drop(v); + | - value moved here +... +LL | println!("{:?} {:?}", v.x, v.y); + | ^^^ value used here after move + | + = note: move occurs because `v` has type `Spair`, which does not implement the `Copy` trait + +error[E0382]: use of moved value: `v.y` + --> $DIR/issue-54499-field-mutation-of-moved-out.rs:60:36 + | +LL | drop(v); + | - value moved here +... +LL | println!("{:?} {:?}", v.x, v.y); + | ^^^ value used here after move + | + = note: move occurs because `v` has type `Spair`, which does not implement the `Copy` trait + +error: aborting due to 12 previous errors + +Some errors occurred: E0382, E0594. +For more information about an error, try `rustc --explain E0382`. diff --git a/src/test/ui/borrowck/issue-54499-field-mutation-of-moved-out.nll.stderr b/src/test/ui/borrowck/issue-54499-field-mutation-of-moved-out.nll.stderr new file mode 100644 index 0000000000000..d35d0058027d4 --- /dev/null +++ b/src/test/ui/borrowck/issue-54499-field-mutation-of-moved-out.nll.stderr @@ -0,0 +1,88 @@ +error[E0594]: cannot assign to `t.0`, as `t` is not declared as mutable + --> $DIR/issue-54499-field-mutation-of-moved-out.rs:23:9 + | +LL | let t: Tuple = (S(0), 0); + | - help: consider changing this to be mutable: `mut t` +LL | drop(t); +LL | t.0 = S(1); + | ^^^^^^^^^^ cannot assign + +error[E0382]: assign to part of moved value: `t` + --> $DIR/issue-54499-field-mutation-of-moved-out.rs:23:9 + | +LL | drop(t); + | - value moved here +LL | t.0 = S(1); + | ^^^^^^^^^^ value partially assigned here after move + | + = note: move occurs because `t` has type `(S, i32)`, which does not implement the `Copy` trait + +error[E0594]: cannot assign to `t.1`, as `t` is not declared as mutable + --> $DIR/issue-54499-field-mutation-of-moved-out.rs:27:9 + | +LL | let t: Tuple = (S(0), 0); + | - help: consider changing this to be mutable: `mut t` +... +LL | t.1 = 2; + | ^^^^^^^ cannot assign + +error[E0594]: cannot assign to `u.0`, as `u` is not declared as mutable + --> $DIR/issue-54499-field-mutation-of-moved-out.rs:38:9 + | +LL | let u: Tpair = Tpair(S(0), 0); + | - help: consider changing this to be mutable: `mut u` +LL | drop(u); +LL | u.0 = S(1); + | ^^^^^^^^^^ cannot assign + +error[E0382]: assign to part of moved value: `u` + --> $DIR/issue-54499-field-mutation-of-moved-out.rs:38:9 + | +LL | drop(u); + | - value moved here +LL | u.0 = S(1); + | ^^^^^^^^^^ value partially assigned here after move + | + = note: move occurs because `u` has type `Tpair`, which does not implement the `Copy` trait + +error[E0594]: cannot assign to `u.1`, as `u` is not declared as mutable + --> $DIR/issue-54499-field-mutation-of-moved-out.rs:42:9 + | +LL | let u: Tpair = Tpair(S(0), 0); + | - help: consider changing this to be mutable: `mut u` +... +LL | u.1 = 2; + | ^^^^^^^ cannot assign + +error[E0594]: cannot assign to `v.x`, as `v` is not declared as mutable + --> $DIR/issue-54499-field-mutation-of-moved-out.rs:53:9 + | +LL | let v: Spair = Spair { x: S(0), y: 0 }; + | - help: consider changing this to be mutable: `mut v` +LL | drop(v); +LL | v.x = S(1); + | ^^^^^^^^^^ cannot assign + +error[E0382]: assign to part of moved value: `v` + --> $DIR/issue-54499-field-mutation-of-moved-out.rs:53:9 + | +LL | drop(v); + | - value moved here +LL | v.x = S(1); + | ^^^^^^^^^^ value partially assigned here after move + | + = note: move occurs because `v` has type `Spair`, which does not implement the `Copy` trait + +error[E0594]: cannot assign to `v.y`, as `v` is not declared as mutable + --> $DIR/issue-54499-field-mutation-of-moved-out.rs:57:9 + | +LL | let v: Spair = Spair { x: S(0), y: 0 }; + | - help: consider changing this to be mutable: `mut v` +... +LL | v.y = 2; + | ^^^^^^^ cannot assign + +error: aborting due to 9 previous errors + +Some errors occurred: E0382, E0594. +For more information about an error, try `rustc --explain E0382`. diff --git a/src/test/ui/borrowck/issue-54499-field-mutation-of-moved-out.rs b/src/test/ui/borrowck/issue-54499-field-mutation-of-moved-out.rs new file mode 100644 index 0000000000000..b19dcd65a6c7e --- /dev/null +++ b/src/test/ui/borrowck/issue-54499-field-mutation-of-moved-out.rs @@ -0,0 +1,64 @@ +// revisions: ast nll + +// Since we are testing nll migration explicitly as a separate +// revision, don't worry about the --compare-mode=nll on this test. + +// ignore-compare-mode-nll + +//[ast]compile-flags: -Z borrowck=ast +//[nll]compile-flags: -Z borrowck=migrate -Z two-phase-borrows + +#![warn(unused)] +#[derive(Debug)] +struct S(i32); + +type Tuple = (S, i32); +struct Tpair(S, i32); +struct Spair { x: S, y: i32 } + +fn main() { + { + let t: Tuple = (S(0), 0); + drop(t); + t.0 = S(1); + //[ast]~^ ERROR cannot assign to field `t.0` of immutable binding [E0594] + //[nll]~^^ ERROR assign to part of moved value: `t` [E0382] + //[nll]~| ERROR cannot assign to `t.0`, as `t` is not declared as mutable [E0594] + t.1 = 2; + //[ast]~^ ERROR cannot assign to field `t.1` of immutable binding [E0594] + //[nll]~^^ ERROR cannot assign to `t.1`, as `t` is not declared as mutable [E0594] + println!("{:?} {:?}", t.0, t.1); + //[ast]~^ ERROR use of moved value: `t.0` [E0382] + //[ast]~| ERROR use of moved value: `t.1` [E0382] + } + + { + let u: Tpair = Tpair(S(0), 0); + drop(u); + u.0 = S(1); + //[ast]~^ ERROR cannot assign to field `u.0` of immutable binding [E0594] + //[nll]~^^ ERROR assign to part of moved value: `u` [E0382] + //[nll]~| ERROR cannot assign to `u.0`, as `u` is not declared as mutable [E0594] + u.1 = 2; + //[ast]~^ ERROR cannot assign to field `u.1` of immutable binding [E0594] + //[nll]~^^ ERROR cannot assign to `u.1`, as `u` is not declared as mutable [E0594] + println!("{:?} {:?}", u.0, u.1); + //[ast]~^ ERROR use of moved value: `u.0` [E0382] + //[ast]~| ERROR use of moved value: `u.1` [E0382] + } + + { + let v: Spair = Spair { x: S(0), y: 0 }; + drop(v); + v.x = S(1); + //[ast]~^ ERROR cannot assign to field `v.x` of immutable binding [E0594] + //[nll]~^^ ERROR assign to part of moved value: `v` [E0382] + //[nll]~| ERROR cannot assign to `v.x`, as `v` is not declared as mutable [E0594] + v.y = 2; + //[ast]~^ ERROR cannot assign to field `v.y` of immutable binding [E0594] + //[nll]~^^ ERROR cannot assign to `v.y`, as `v` is not declared as mutable [E0594] + println!("{:?} {:?}", v.x, v.y); + //[ast]~^ ERROR use of moved value: `v.x` [E0382] + //[ast]~| ERROR use of moved value: `v.y` [E0382] + } +} diff --git a/src/test/ui/borrowck/issue-54499-field-mutation-of-never-init.ast.stderr b/src/test/ui/borrowck/issue-54499-field-mutation-of-never-init.ast.stderr new file mode 100644 index 0000000000000..ea6b63b7a297d --- /dev/null +++ b/src/test/ui/borrowck/issue-54499-field-mutation-of-never-init.ast.stderr @@ -0,0 +1,91 @@ +error[E0594]: cannot assign to field `t.0` of immutable binding + --> $DIR/issue-54499-field-mutation-of-never-init.rs:22:9 + | +LL | let t: Tuple; + | - help: make this binding mutable: `mut t` +LL | t.0 = S(1); + | ^^^^^^^^^^ cannot mutably borrow field of immutable binding + +error[E0594]: cannot assign to field `t.1` of immutable binding + --> $DIR/issue-54499-field-mutation-of-never-init.rs:25:9 + | +LL | let t: Tuple; + | - help: make this binding mutable: `mut t` +... +LL | t.1 = 2; + | ^^^^^^^ cannot mutably borrow field of immutable binding + +error[E0594]: cannot assign to field `u.0` of immutable binding + --> $DIR/issue-54499-field-mutation-of-never-init.rs:34:9 + | +LL | let u: Tpair; + | - help: make this binding mutable: `mut u` +LL | u.0 = S(1); + | ^^^^^^^^^^ cannot mutably borrow field of immutable binding + +error[E0594]: cannot assign to field `u.1` of immutable binding + --> $DIR/issue-54499-field-mutation-of-never-init.rs:37:9 + | +LL | let u: Tpair; + | - help: make this binding mutable: `mut u` +... +LL | u.1 = 2; + | ^^^^^^^ cannot mutably borrow field of immutable binding + +error[E0594]: cannot assign to field `v.x` of immutable binding + --> $DIR/issue-54499-field-mutation-of-never-init.rs:46:9 + | +LL | let v: Spair; + | - help: make this binding mutable: `mut v` +LL | v.x = S(1); + | ^^^^^^^^^^ cannot mutably borrow field of immutable binding + +error[E0594]: cannot assign to field `v.y` of immutable binding + --> $DIR/issue-54499-field-mutation-of-never-init.rs:49:9 + | +LL | let v: Spair; + | - help: make this binding mutable: `mut v` +... +LL | v.y = 2; + | ^^^^^^^ cannot mutably borrow field of immutable binding + +error[E0381]: use of possibly uninitialized variable: `t.0` + --> $DIR/issue-54499-field-mutation-of-never-init.rs:27:31 + | +LL | println!("{:?} {:?}", t.0, t.1); + | ^^^ use of possibly uninitialized `t.0` + +error[E0381]: use of possibly uninitialized variable: `t.1` + --> $DIR/issue-54499-field-mutation-of-never-init.rs:27:36 + | +LL | println!("{:?} {:?}", t.0, t.1); + | ^^^ use of possibly uninitialized `t.1` + +error[E0381]: use of possibly uninitialized variable: `u.0` + --> $DIR/issue-54499-field-mutation-of-never-init.rs:39:31 + | +LL | println!("{:?} {:?}", u.0, u.1); + | ^^^ use of possibly uninitialized `u.0` + +error[E0381]: use of possibly uninitialized variable: `u.1` + --> $DIR/issue-54499-field-mutation-of-never-init.rs:39:36 + | +LL | println!("{:?} {:?}", u.0, u.1); + | ^^^ use of possibly uninitialized `u.1` + +error[E0381]: use of possibly uninitialized variable: `v.x` + --> $DIR/issue-54499-field-mutation-of-never-init.rs:51:31 + | +LL | println!("{:?} {:?}", v.x, v.y); + | ^^^ use of possibly uninitialized `v.x` + +error[E0381]: use of possibly uninitialized variable: `v.y` + --> $DIR/issue-54499-field-mutation-of-never-init.rs:51:36 + | +LL | println!("{:?} {:?}", v.x, v.y); + | ^^^ use of possibly uninitialized `v.y` + +error: aborting due to 12 previous errors + +Some errors occurred: E0381, E0594. +For more information about an error, try `rustc --explain E0381`. diff --git a/src/test/ui/borrowck/issue-54499-field-mutation-of-never-init.nll.stderr b/src/test/ui/borrowck/issue-54499-field-mutation-of-never-init.nll.stderr new file mode 100644 index 0000000000000..3dc2b5b3b8f9f --- /dev/null +++ b/src/test/ui/borrowck/issue-54499-field-mutation-of-never-init.nll.stderr @@ -0,0 +1,21 @@ +error[E0381]: assign to part of possibly uninitialized variable: `t` + --> $DIR/issue-54499-field-mutation-of-never-init.rs:22:9 + | +LL | t.0 = S(1); + | ^^^^^^^^^^ use of possibly uninitialized `t` + +error[E0381]: assign to part of possibly uninitialized variable: `u` + --> $DIR/issue-54499-field-mutation-of-never-init.rs:34:9 + | +LL | u.0 = S(1); + | ^^^^^^^^^^ use of possibly uninitialized `u` + +error[E0381]: assign to part of possibly uninitialized variable: `v` + --> $DIR/issue-54499-field-mutation-of-never-init.rs:46:9 + | +LL | v.x = S(1); + | ^^^^^^^^^^ use of possibly uninitialized `v` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0381`. diff --git a/src/test/ui/borrowck/issue-54499-field-mutation-of-never-init.rs b/src/test/ui/borrowck/issue-54499-field-mutation-of-never-init.rs new file mode 100644 index 0000000000000..03eb9621ee215 --- /dev/null +++ b/src/test/ui/borrowck/issue-54499-field-mutation-of-never-init.rs @@ -0,0 +1,55 @@ +// revisions: ast nll + +// Since we are testing nll migration explicitly as a separate +// revision, don't worry about the --compare-mode=nll on this test. + +// ignore-compare-mode-nll + +//[ast]compile-flags: -Z borrowck=ast +//[nll]compile-flags: -Z borrowck=migrate -Z two-phase-borrows + +#![warn(unused)] +#[derive(Debug)] +struct S(i32); + +type Tuple = (S, i32); +struct Tpair(S, i32); +struct Spair { x: S, y: i32 } + +fn main() { + { + let t: Tuple; + t.0 = S(1); + //[ast]~^ ERROR cannot assign to field `t.0` of immutable binding [E0594] + //[nll]~^^ ERROR assign to part of possibly uninitialized variable: `t` [E0381] + t.1 = 2; + //[ast]~^ ERROR cannot assign to field `t.1` of immutable binding [E0594] + println!("{:?} {:?}", t.0, t.1); + //[ast]~^ ERROR use of possibly uninitialized variable: `t.0` [E0381] + //[ast]~| ERROR use of possibly uninitialized variable: `t.1` [E0381] + } + + { + let u: Tpair; + u.0 = S(1); + //[ast]~^ ERROR cannot assign to field `u.0` of immutable binding [E0594] + //[nll]~^^ ERROR assign to part of possibly uninitialized variable: `u` [E0381] + u.1 = 2; + //[ast]~^ ERROR cannot assign to field `u.1` of immutable binding [E0594] + println!("{:?} {:?}", u.0, u.1); + //[ast]~^ ERROR use of possibly uninitialized variable: `u.0` [E0381] + //[ast]~| ERROR use of possibly uninitialized variable: `u.1` [E0381] + } + + { + let v: Spair; + v.x = S(1); + //[ast]~^ ERROR cannot assign to field `v.x` of immutable binding [E0594] + //[nll]~^^ ERROR assign to part of possibly uninitialized variable: `v` [E0381] + v.y = 2; + //[ast]~^ ERROR cannot assign to field `v.y` of immutable binding [E0594] + println!("{:?} {:?}", v.x, v.y); + //[ast]~^ ERROR use of possibly uninitialized variable: `v.x` [E0381] + //[ast]~| ERROR use of possibly uninitialized variable: `v.y` [E0381] + } +} diff --git a/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.rs b/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.rs new file mode 100644 index 0000000000000..abafd330573ee --- /dev/null +++ b/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.rs @@ -0,0 +1,66 @@ +// This test enumerates various cases of interest where a ADT or tuple is +// partially initialized and then used in some way that is wrong *even* +// after rust-lang/rust#54987 is implemented. +// +// See rust-lang/rust#21232, rust-lang/rust#54986, and rust-lang/rust#54987. +// +// See issue-21232-partial-init-and-use.rs for cases of tests that are +// meant to compile and run successfully once rust-lang/rust#54987 is +// implemented. + +#![feature(nll)] + +struct D { + x: u32, + s: S, +} + +struct S { + y: u32, + z: u32, +} + + +impl Drop for D { + fn drop(&mut self) { } +} + +fn cannot_partially_init_adt_with_drop() { + let d: D; + d.x = 10; + //~^ ERROR assign of possibly uninitialized variable: `d` [E0381] +} + +fn cannot_partially_init_mutable_adt_with_drop() { + let mut d: D; + d.x = 10; + //~^ ERROR assign of possibly uninitialized variable: `d` [E0381] +} + +fn cannot_partially_reinit_adt_with_drop() { + let mut d = D { x: 0, s: S{ y: 0, z: 0 } }; + drop(d); + d.x = 10; + //~^ ERROR assign of moved value: `d` [E0382] +} + +fn cannot_partially_init_inner_adt_via_outer_with_drop() { + let d: D; + d.s.y = 20; + //~^ ERROR assign to part of possibly uninitialized variable: `d` [E0381] +} + +fn cannot_partially_init_inner_adt_via_mutable_outer_with_drop() { + let mut d: D; + d.s.y = 20; + //~^ ERROR assign to part of possibly uninitialized variable: `d` [E0381] +} + +fn cannot_partially_reinit_inner_adt_via_outer_with_drop() { + let mut d = D { x: 0, s: S{ y: 0, z: 0} }; + drop(d); + d.s.y = 20; + //~^ ERROR assign to part of moved value: `d` [E0382] +} + +fn main() { } diff --git a/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.stderr b/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.stderr new file mode 100644 index 0000000000000..e29c44760a987 --- /dev/null +++ b/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.stderr @@ -0,0 +1,48 @@ +error[E0381]: assign of possibly uninitialized variable: `d` + --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:30:5 + | +LL | d.x = 10; + | ^^^^^^^^ use of possibly uninitialized `d` + +error[E0381]: assign of possibly uninitialized variable: `d` + --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:36:5 + | +LL | d.x = 10; + | ^^^^^^^^ use of possibly uninitialized `d` + +error[E0382]: assign of moved value: `d` + --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:43:5 + | +LL | drop(d); + | - value moved here +LL | d.x = 10; + | ^^^^^^^^ value assigned here after move + | + = note: move occurs because `d` has type `D`, which does not implement the `Copy` trait + +error[E0381]: assign to part of possibly uninitialized variable: `d` + --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:49:5 + | +LL | d.s.y = 20; + | ^^^^^^^^^^ use of possibly uninitialized `d.s` + +error[E0381]: assign to part of possibly uninitialized variable: `d` + --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:55:5 + | +LL | d.s.y = 20; + | ^^^^^^^^^^ use of possibly uninitialized `d.s` + +error[E0382]: assign to part of moved value: `d` + --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:62:5 + | +LL | drop(d); + | - value moved here +LL | d.s.y = 20; + | ^^^^^^^^^^ value partially assigned here after move + | + = note: move occurs because `d` has type `D`, which does not implement the `Copy` trait + +error: aborting due to 6 previous errors + +Some errors occurred: E0381, E0382. +For more information about an error, try `rustc --explain E0381`. diff --git a/src/test/ui/nll/issue-21232-partial-init-and-use.rs b/src/test/ui/nll/issue-21232-partial-init-and-use.rs new file mode 100644 index 0000000000000..e3ae4c0dcbe57 --- /dev/null +++ b/src/test/ui/nll/issue-21232-partial-init-and-use.rs @@ -0,0 +1,311 @@ +// This test enumerates various cases of interest for partial +// [re]initialization of ADTs and tuples. +// +// See rust-lang/rust#21232, rust-lang/rust#54986, and rust-lang/rust#54987. +// +// All of tests in this file are expected to change from being +// rejected, at least under NLL (by rust-lang/rust#54986) to being +// **accepted** when rust-lang/rust#54987 is implemented. +// (That's why there are assertions in the code.) +// +// See issue-21232-partial-init-and-erroneous-use.rs for cases of +// tests that are meant to continue failing to compile once +// rust-lang/rust#54987 is implemented. + +#![feature(nll)] + +struct S { + x: u32, + + // Note that even though `y` may implement `Drop`, under #54987 we + // will still allow partial initialization of `S` itself. + y: Y, +} + +enum Void { } + +type B = Box; + +impl S { fn new() -> Self { S { x: 0, y: Box::new(0) } } } + +fn borrow_s(s: &S) { assert_eq!(s.x, 10); assert_eq!(*s.y, 20); } +fn move_s(s: S) { assert_eq!(s.x, 10); assert_eq!(*s.y, 20); } +fn borrow_field(x: &u32) { assert_eq!(*x, 10); } + +type T = (u32, B); +type Tvoid = (u32, Void); + +fn borrow_t(t: &T) { assert_eq!(t.0, 10); assert_eq!(*t.1, 20); } +fn move_t(t: T) { assert_eq!(t.0, 10); assert_eq!(*t.1, 20); } + +struct Q { + v: u32, + r: R, +} + +struct R { + w: u32, + f: F, +} + +impl Q { fn new(f: F) -> Self { Q { v: 0, r: R::new(f) } } } +impl R { fn new(f: F) -> Self { R { w: 0, f } } } + +// Axes to cover: +// * local/field: Is the structure in a local or a field +// * fully/partial/void: Are we fully initializing it before using any part? +// Is whole type empty due to a void component? +// * init/reinit: First initialization, or did we previously inititalize and then move out? +// * struct/tuple: Is this a struct or a (X, Y). +// +// As a shorthand for the cases above, adding a numeric summary to +// each test's fn name to denote each point on each axis. +// +// E.g. 1000 = field fully init struct; 0211 = local void reinit tuple + +// It got pretty monotonous writing the same code over and over, and I +// feared I would forget details. So I abstracted some desiderata into +// macros. But I left the initialization code inline, because that's +// where the errors for #54986 will be emited. + +macro_rules! use_fully { + (struct $s:expr) => { { + borrow_field(& $s.x ); + borrow_s(& $s ); + move_s( $s ); + } }; + + (tuple $t:expr) => { { + borrow_field(& $t.0 ); + borrow_t(& $t ); + move_t( $t ); + } } +} + +macro_rules! use_part { + (struct $s:expr) => { { + borrow_field(& $s.x ); + match $s { S { ref x, y: _ } => { borrow_field(x); } } + } }; + + (tuple $t:expr) => { { + borrow_field(& $t.0 ); + match $t { (ref x, _) => { borrow_field(x); } } + } } +} + +fn test_0000_local_fully_init_and_use_struct() { + let s: S; + s.x = 10; s.y = Box::new(20); + //~^ ERROR assign to part of possibly uninitialized variable: `s` [E0381] + use_fully!(struct s); +} + +fn test_0001_local_fully_init_and_use_tuple() { + let t: T; + t.0 = 10; t.1 = Box::new(20); + //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381] + use_fully!(tuple t); +} + +fn test_0010_local_fully_reinit_and_use_struct() { + let mut s: S = S::new(); drop(s); + s.x = 10; s.y = Box::new(20); + //~^ ERROR assign to part of moved value: `s` [E0382] + use_fully!(struct s); +} + +fn test_0011_local_fully_reinit_and_use_tuple() { + let mut t: T = (0, Box::new(0)); drop(t); + t.0 = 10; t.1 = Box::new(20); + //~^ ERROR assign to part of moved value: `t` [E0382] + use_fully!(tuple t); +} + +fn test_0100_local_partial_init_and_use_struct() { + let s: S; + s.x = 10; + //~^ ERROR assign to part of possibly uninitialized variable: `s` [E0381] + use_part!(struct s); +} + +fn test_0101_local_partial_init_and_use_tuple() { + let t: T; + t.0 = 10; + //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381] + use_part!(tuple t); +} + +fn test_0110_local_partial_reinit_and_use_struct() { + let mut s: S = S::new(); drop(s); + s.x = 10; + //~^ ERROR assign to part of moved value: `s` [E0382] + use_part!(struct s); +} + +fn test_0111_local_partial_reinit_and_use_tuple() { + let mut t: T = (0, Box::new(0)); drop(t); + t.0 = 10; + //~^ ERROR assign to part of moved value: `t` [E0382] + use_part!(tuple t); +} + +fn test_0200_local_void_init_and_use_struct() { + let s: S; + s.x = 10; + //~^ ERROR assign to part of possibly uninitialized variable: `s` [E0381] + use_part!(struct s); +} + +fn test_0201_local_void_init_and_use_tuple() { + let t: Tvoid; + t.0 = 10; + //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381] + use_part!(tuple t); +} + +// NOTE: uniform structure of tests here makes n21n (aka combining +// Void with Reinit) an (even more) senseless case, as we cannot +// safely create initial instance containing Void to move out of and +// then reinitialize. While I was tempted to sidestep this via some +// unsafe code (eek), lets just instead not encode such tests. + +// fn test_0210_local_void_reinit_and_use_struct() { unimplemented!() } +// fn test_0211_local_void_reinit_and_use_tuple() { unimplemented!() } + +fn test_1000_field_fully_init_and_use_struct() { + let q: Q>; + q.r.f.x = 10; q.r.f.y = Box::new(20); + //~^ ERROR assign to part of possibly uninitialized variable: `q` [E0381] + use_fully!(struct q.r.f); +} + +fn test_1001_field_fully_init_and_use_tuple() { + let q: Q; + q.r.f.0 = 10; q.r.f.1 = Box::new(20); + //~^ ERROR assign to part of possibly uninitialized variable: `q` [E0381] + use_fully!(tuple q.r.f); +} + +fn test_1010_field_fully_reinit_and_use_struct() { + let mut q: Q> = Q::new(S::new()); drop(q.r); + q.r.f.x = 10; q.r.f.y = Box::new(20); + //~^ ERROR assign to part of moved value: `q.r` [E0382] + use_fully!(struct q.r.f); +} + +fn test_1011_field_fully_reinit_and_use_tuple() { + let mut q: Q = Q::new((0, Box::new(0))); drop(q.r); + q.r.f.0 = 10; q.r.f.1 = Box::new(20); + //~^ ERROR assign to part of moved value: `q.r` [E0382] + use_fully!(tuple q.r.f); +} + +fn test_1100_field_partial_init_and_use_struct() { + let q: Q>; + q.r.f.x = 10; + //~^ ERROR assign to part of possibly uninitialized variable: `q` [E0381] + use_part!(struct q.r.f); +} + +fn test_1101_field_partial_init_and_use_tuple() { + let q: Q; + q.r.f.0 = 10; + //~^ ERROR assign to part of possibly uninitialized variable: `q` [E0381] + use_part!(tuple q.r.f); +} + +fn test_1110_field_partial_reinit_and_use_struct() { + let mut q: Q> = Q::new(S::new()); drop(q.r); + q.r.f.x = 10; + //~^ ERROR assign to part of moved value: `q.r` [E0382] + use_part!(struct q.r.f); +} + +fn test_1111_field_partial_reinit_and_use_tuple() { + let mut q: Q = Q::new((0, Box::new(0))); drop(q.r); + q.r.f.0 = 10; + //~^ ERROR assign to part of moved value: `q.r` [E0382] + use_part!(tuple q.r.f); +} + +fn test_1200_field_void_init_and_use_struct() { + let mut q: Q>; + q.r.f.x = 10; + //~^ ERROR assign to part of possibly uninitialized variable: `q` [E0381] + use_part!(struct q.r.f); +} + +fn test_1201_field_void_init_and_use_tuple() { + let mut q: Q; + q.r.f.0 = 10; + //~^ ERROR assign to part of possibly uninitialized variable: `q` [E0381] + use_part!(tuple q.r.f); +} + +// See NOTE abve. + +// fn test_1210_field_void_reinit_and_use_struct() { unimplemented!() } +// fn test_1211_field_void_reinit_and_use_tuple() { unimplemented!() } + +// The below are some additional cases of interest that have been +// transcribed from other bugs based on old erroneous codegen when we +// encountered partial writes. + +fn issue_26996() { + let mut c = (1, "".to_owned()); + match c { + c2 => { + c.0 = 2; //~ ERROR assign to part of moved value + assert_eq!(c2.0, 1); + } + } +} + +fn issue_27021() { + let mut c = (1, (1, "".to_owned())); + match c { + c2 => { + (c.1).0 = 2; //~ ERROR assign to part of moved value + assert_eq!((c2.1).0, 1); + } + } + + let mut c = (1, (1, (1, "".to_owned()))); + match c.1 { + c2 => { + ((c.1).1).0 = 3; //~ ERROR assign to part of moved value + assert_eq!((c2.1).0, 1); + } + } +} + +fn main() { + test_0000_local_fully_init_and_use_struct(); + test_0001_local_fully_init_and_use_tuple(); + test_0010_local_fully_reinit_and_use_struct(); + test_0011_local_fully_reinit_and_use_tuple(); + test_0100_local_partial_init_and_use_struct(); + test_0101_local_partial_init_and_use_tuple(); + test_0110_local_partial_reinit_and_use_struct(); + test_0111_local_partial_reinit_and_use_tuple(); + test_0200_local_void_init_and_use_struct(); + test_0201_local_void_init_and_use_tuple(); + // test_0210_local_void_reinit_and_use_struct(); + // test_0211_local_void_reinit_and_use_tuple(); + test_1000_field_fully_init_and_use_struct(); + test_1001_field_fully_init_and_use_tuple(); + test_1010_field_fully_reinit_and_use_struct(); + test_1011_field_fully_reinit_and_use_tuple(); + test_1100_field_partial_init_and_use_struct(); + test_1101_field_partial_init_and_use_tuple(); + test_1110_field_partial_reinit_and_use_struct(); + test_1111_field_partial_reinit_and_use_tuple(); + test_1200_field_void_init_and_use_struct(); + test_1201_field_void_init_and_use_tuple(); + // test_1210_field_void_reinit_and_use_struct(); + // test_1211_field_void_reinit_and_use_tuple(); + + issue_26996(); + issue_27021(); +} diff --git a/src/test/ui/nll/issue-21232-partial-init-and-use.stderr b/src/test/ui/nll/issue-21232-partial-init-and-use.stderr new file mode 100644 index 0000000000000..aec7f676fcebd --- /dev/null +++ b/src/test/ui/nll/issue-21232-partial-init-and-use.stderr @@ -0,0 +1,186 @@ +error[E0381]: assign to part of possibly uninitialized variable: `s` + --> $DIR/issue-21232-partial-init-and-use.rs:99:5 + | +LL | s.x = 10; s.y = Box::new(20); + | ^^^^^^^^ use of possibly uninitialized `s` + +error[E0381]: assign to part of possibly uninitialized variable: `t` + --> $DIR/issue-21232-partial-init-and-use.rs:106:5 + | +LL | t.0 = 10; t.1 = Box::new(20); + | ^^^^^^^^ use of possibly uninitialized `t` + +error[E0382]: assign to part of moved value: `s` + --> $DIR/issue-21232-partial-init-and-use.rs:113:5 + | +LL | let mut s: S = S::new(); drop(s); + | - value moved here +LL | s.x = 10; s.y = Box::new(20); + | ^^^^^^^^ value partially assigned here after move + | + = note: move occurs because `s` has type `S>`, which does not implement the `Copy` trait + +error[E0382]: assign to part of moved value: `t` + --> $DIR/issue-21232-partial-init-and-use.rs:120:5 + | +LL | let mut t: T = (0, Box::new(0)); drop(t); + | - value moved here +LL | t.0 = 10; t.1 = Box::new(20); + | ^^^^^^^^ value partially assigned here after move + | + = note: move occurs because `t` has type `(u32, std::boxed::Box)`, which does not implement the `Copy` trait + +error[E0381]: assign to part of possibly uninitialized variable: `s` + --> $DIR/issue-21232-partial-init-and-use.rs:127:5 + | +LL | s.x = 10; + | ^^^^^^^^ use of possibly uninitialized `s` + +error[E0381]: assign to part of possibly uninitialized variable: `t` + --> $DIR/issue-21232-partial-init-and-use.rs:134:5 + | +LL | t.0 = 10; + | ^^^^^^^^ use of possibly uninitialized `t` + +error[E0382]: assign to part of moved value: `s` + --> $DIR/issue-21232-partial-init-and-use.rs:141:5 + | +LL | let mut s: S = S::new(); drop(s); + | - value moved here +LL | s.x = 10; + | ^^^^^^^^ value partially assigned here after move + | + = note: move occurs because `s` has type `S>`, which does not implement the `Copy` trait + +error[E0382]: assign to part of moved value: `t` + --> $DIR/issue-21232-partial-init-and-use.rs:148:5 + | +LL | let mut t: T = (0, Box::new(0)); drop(t); + | - value moved here +LL | t.0 = 10; + | ^^^^^^^^ value partially assigned here after move + | + = note: move occurs because `t` has type `(u32, std::boxed::Box)`, which does not implement the `Copy` trait + +error[E0381]: assign to part of possibly uninitialized variable: `s` + --> $DIR/issue-21232-partial-init-and-use.rs:155:5 + | +LL | s.x = 10; + | ^^^^^^^^ use of possibly uninitialized `s` + +error[E0381]: assign to part of possibly uninitialized variable: `t` + --> $DIR/issue-21232-partial-init-and-use.rs:162:5 + | +LL | t.0 = 10; + | ^^^^^^^^ use of possibly uninitialized `t` + +error[E0381]: assign to part of possibly uninitialized variable: `q` + --> $DIR/issue-21232-partial-init-and-use.rs:178:5 + | +LL | q.r.f.x = 10; q.r.f.y = Box::new(20); + | ^^^^^^^^^^^^ use of possibly uninitialized `q.r.f` + +error[E0381]: assign to part of possibly uninitialized variable: `q` + --> $DIR/issue-21232-partial-init-and-use.rs:185:5 + | +LL | q.r.f.0 = 10; q.r.f.1 = Box::new(20); + | ^^^^^^^^^^^^ use of possibly uninitialized `q.r.f` + +error[E0382]: assign to part of moved value: `q.r` + --> $DIR/issue-21232-partial-init-and-use.rs:192:5 + | +LL | let mut q: Q> = Q::new(S::new()); drop(q.r); + | --- value moved here +LL | q.r.f.x = 10; q.r.f.y = Box::new(20); + | ^^^^^^^^^^^^ value partially assigned here after move + | + = note: move occurs because `q.r` has type `R>>`, which does not implement the `Copy` trait + +error[E0382]: assign to part of moved value: `q.r` + --> $DIR/issue-21232-partial-init-and-use.rs:199:5 + | +LL | let mut q: Q = Q::new((0, Box::new(0))); drop(q.r); + | --- value moved here +LL | q.r.f.0 = 10; q.r.f.1 = Box::new(20); + | ^^^^^^^^^^^^ value partially assigned here after move + | + = note: move occurs because `q.r` has type `R<(u32, std::boxed::Box)>`, which does not implement the `Copy` trait + +error[E0381]: assign to part of possibly uninitialized variable: `q` + --> $DIR/issue-21232-partial-init-and-use.rs:206:5 + | +LL | q.r.f.x = 10; + | ^^^^^^^^^^^^ use of possibly uninitialized `q.r.f` + +error[E0381]: assign to part of possibly uninitialized variable: `q` + --> $DIR/issue-21232-partial-init-and-use.rs:213:5 + | +LL | q.r.f.0 = 10; + | ^^^^^^^^^^^^ use of possibly uninitialized `q.r.f` + +error[E0382]: assign to part of moved value: `q.r` + --> $DIR/issue-21232-partial-init-and-use.rs:220:5 + | +LL | let mut q: Q> = Q::new(S::new()); drop(q.r); + | --- value moved here +LL | q.r.f.x = 10; + | ^^^^^^^^^^^^ value partially assigned here after move + | + = note: move occurs because `q.r` has type `R>>`, which does not implement the `Copy` trait + +error[E0382]: assign to part of moved value: `q.r` + --> $DIR/issue-21232-partial-init-and-use.rs:227:5 + | +LL | let mut q: Q = Q::new((0, Box::new(0))); drop(q.r); + | --- value moved here +LL | q.r.f.0 = 10; + | ^^^^^^^^^^^^ value partially assigned here after move + | + = note: move occurs because `q.r` has type `R<(u32, std::boxed::Box)>`, which does not implement the `Copy` trait + +error[E0381]: assign to part of possibly uninitialized variable: `q` + --> $DIR/issue-21232-partial-init-and-use.rs:234:5 + | +LL | q.r.f.x = 10; + | ^^^^^^^^^^^^ use of possibly uninitialized `q.r.f` + +error[E0381]: assign to part of possibly uninitialized variable: `q` + --> $DIR/issue-21232-partial-init-and-use.rs:241:5 + | +LL | q.r.f.0 = 10; + | ^^^^^^^^^^^^ use of possibly uninitialized `q.r.f` + +error[E0382]: assign to part of moved value: `c` + --> $DIR/issue-21232-partial-init-and-use.rs:259:13 + | +LL | c2 => { + | -- value moved here +LL | c.0 = 2; //~ ERROR assign to part of moved value + | ^^^^^^^ value partially assigned here after move + | + = note: move occurs because `c` has type `(i32, std::string::String)`, which does not implement the `Copy` trait + +error[E0382]: assign to part of moved value: `c` + --> $DIR/issue-21232-partial-init-and-use.rs:269:13 + | +LL | c2 => { + | -- value moved here +LL | (c.1).0 = 2; //~ ERROR assign to part of moved value + | ^^^^^^^^^^^ value partially assigned here after move + | + = note: move occurs because `c` has type `(i32, (i32, std::string::String))`, which does not implement the `Copy` trait + +error[E0382]: assign to part of moved value: `c.1` + --> $DIR/issue-21232-partial-init-and-use.rs:277:13 + | +LL | c2 => { + | -- value moved here +LL | ((c.1).1).0 = 3; //~ ERROR assign to part of moved value + | ^^^^^^^^^^^^^^^ value partially assigned here after move + | + = note: move occurs because `c.1` has type `(i32, (i32, std::string::String))`, which does not implement the `Copy` trait + +error: aborting due to 23 previous errors + +Some errors occurred: E0381, E0382. +For more information about an error, try `rustc --explain E0381`.