From a8a982bb61d500f9e54de8f546f8522e1783c874 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 10 Aug 2018 17:34:56 -0400 Subject: [PATCH 1/4] treat local variables specially --- src/librustc_mir/borrow_check/mod.rs | 49 ++++++++++------------------ 1 file changed, 17 insertions(+), 32 deletions(-) diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index f96b9b8082fa7..75e9b5f2df022 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -798,12 +798,6 @@ enum LocalMutationIsAllowed { No, } -struct AccessErrorsReported { - mutability_error: bool, - #[allow(dead_code)] - conflict_error: bool, -} - #[derive(Copy, Clone)] enum InitializationRequiringAction { Update, @@ -1072,7 +1066,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { kind: (ShallowOrDeep, ReadOrWrite), is_local_mutation_allowed: LocalMutationIsAllowed, flow_state: &Flows<'cx, 'gcx, 'tcx>, - ) -> AccessErrorsReported { + ) { let (sd, rw) = kind; if let Activation(_, borrow_index) = rw { @@ -1082,10 +1076,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { place: {:?} borrow_index: {:?}", place_span.0, borrow_index ); - return AccessErrorsReported { - mutability_error: false, - conflict_error: true, - }; + return; } } @@ -1097,10 +1088,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { "access_place: suppressing error place_span=`{:?}` kind=`{:?}`", place_span, kind ); - return AccessErrorsReported { - mutability_error: false, - conflict_error: true, - }; + return; } let mutability_error = @@ -1122,11 +1110,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { self.access_place_error_reported .insert((place_span.0.clone(), place_span.1)); } - - AccessErrorsReported { - mutability_error, - conflict_error, - } } fn check_access_for_conflict( @@ -1275,23 +1258,25 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { } } - let errors_reported = self.access_place( + // Special case: you can assign a immutable local variable + // (e.g., `x = ...`) so long as it has never been initialized + // before (at this point in the flow). + if let &Place::Local(local) = place_span.0 { + if let Mutability::Not = self.mir.local_decls[local].mutability { + // check for reassignments to immutable local variables + self.check_if_reassignment_to_immutable_state(context, place_span, flow_state); + return; + } + } + + // Otherwise, use the normal access permission rules. + self.access_place( context, place_span, (kind, Write(WriteKind::Mutate)), - // We want immutable upvars to cause an "assignment to immutable var" - // error, not an "reassignment of immutable var" error, because the - // latter can't find a good previous assignment span. - // - // There's probably a better way to do this. - LocalMutationIsAllowed::ExceptUpvars, + LocalMutationIsAllowed::No, flow_state, ); - - if !errors_reported.mutability_error { - // check for reassignments to immutable local variables - self.check_if_reassignment_to_immutable_state(context, place_span, flow_state); - } } fn consume_rvalue( From 78e987ab8f71c733ab1081018492f87ba47e9da5 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 10 Aug 2018 18:05:01 -0400 Subject: [PATCH 2/4] just check whether a variable is initialized Don't iterate over all things that are initialized. --- src/librustc_mir/borrow_check/mod.rs | 38 +++++++++---------- .../ui/did_you_mean/issue-35937.nll.stderr | 19 ++++------ 2 files changed, 26 insertions(+), 31 deletions(-) diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 75e9b5f2df022..ce0e76a636db2 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -1264,7 +1264,12 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { if let &Place::Local(local) = place_span.0 { if let Mutability::Not = self.mir.local_decls[local].mutability { // check for reassignments to immutable local variables - self.check_if_reassignment_to_immutable_state(context, place_span, flow_state); + self.check_if_reassignment_to_immutable_state( + context, + local, + place_span, + flow_state, + ); return; } } @@ -1575,27 +1580,20 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { fn check_if_reassignment_to_immutable_state( &mut self, context: Context, - (place, span): (&Place<'tcx>, Span), + local: Local, + place_span: (&Place<'tcx>, Span), flow_state: &Flows<'cx, 'gcx, 'tcx>, ) { - debug!("check_if_reassignment_to_immutable_state({:?})", place); - // determine if this path has a non-mut owner (and thus needs checking). - let err_place = match self.is_mutable(place, LocalMutationIsAllowed::No) { - Ok(..) => return, - Err(place) => place, - }; - debug!( - "check_if_reassignment_to_immutable_state({:?}) - is an imm local", - place - ); - - for i in flow_state.ever_inits.iter_incoming() { - let init = self.move_data.inits[i]; - let init_place = &self.move_data.move_paths[init.path].place; - if places_conflict::places_conflict(self.tcx, self.mir, &init_place, place, Deep) { - self.report_illegal_reassignment(context, (place, span), init.span, err_place); - break; - } + debug!("check_if_reassignment_to_immutable_state({:?})", local); + + // Check if any of the initializiations of `local` have happened yet: + let mpi = self.move_data.rev_lookup.find_local(local); + let init_indices = &self.move_data.init_path_map[mpi]; + let first_init_index = init_indices.iter().find(|ii| flow_state.ever_inits.contains(ii)); + if let Some(&init_index) = first_init_index { + // And, if so, report an error. + let init = &self.move_data.inits[init_index]; + self.report_illegal_reassignment(context, place_span, init.span, place_span.0); } } diff --git a/src/test/ui/did_you_mean/issue-35937.nll.stderr b/src/test/ui/did_you_mean/issue-35937.nll.stderr index 804e5f0531f85..34bdf48e2a65f 100644 --- a/src/test/ui/did_you_mean/issue-35937.nll.stderr +++ b/src/test/ui/did_you_mean/issue-35937.nll.stderr @@ -6,26 +6,23 @@ LL | let f = Foo { v: Vec::new() }; LL | f.v.push("cat".to_string()); //~ ERROR cannot borrow | ^^^ cannot borrow as mutable -error[E0384]: cannot assign twice to immutable variable `s` +error[E0594]: cannot assign to `s.x`, as `s` is not declared as mutable --> $DIR/issue-35937.rs:26:5 | LL | let s = S { x: 42 }; - | - - | | - | first assignment to `s` - | consider changing this to `mut s` + | - help: consider changing this to be mutable: `mut s` LL | s.x += 1; //~ ERROR cannot assign - | ^^^^^^^^ cannot assign twice to immutable variable + | ^^^^^^^^ cannot assign -error[E0384]: cannot assign to immutable argument `s` +error[E0594]: cannot assign to `s.x`, as `s` is not declared as mutable --> $DIR/issue-35937.rs:30:5 | LL | fn bar(s: S) { - | - consider changing this to `mut s` + | - help: consider changing this to be mutable: `mut s` LL | s.x += 1; //~ ERROR cannot assign - | ^^^^^^^^ cannot assign to immutable argument + | ^^^^^^^^ cannot assign error: aborting due to 3 previous errors -Some errors occurred: E0384, E0596. -For more information about an error, try `rustc --explain E0384`. +Some errors occurred: E0594, E0596. +For more information about an error, try `rustc --explain E0594`. From 4e50c5b6e45fc1b21b0e0bd6f7c9c5389e0b637f Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Sat, 11 Aug 2018 06:15:58 -0400 Subject: [PATCH 3/4] add tests for assigning fields without initializing var We did not seem to have any! --- src/test/ui/nll/assign_mutable_fields.rs | 34 ++++++++++++++ src/test/ui/nll/assign_mutable_fields.stderr | 9 ++++ .../ui/nll/reassignment_immutable_fields.rs | 32 ++++++++++++++ .../nll/reassignment_immutable_fields.stderr | 44 +++++++++++++++++++ ...assignment_immutable_fields_overlapping.rs | 28 ++++++++++++ ...gnment_immutable_fields_overlapping.stderr | 20 +++++++++ .../reassignment_immutable_fields_twice.rs | 29 ++++++++++++ ...reassignment_immutable_fields_twice.stderr | 38 ++++++++++++++++ 8 files changed, 234 insertions(+) create mode 100644 src/test/ui/nll/assign_mutable_fields.rs create mode 100644 src/test/ui/nll/assign_mutable_fields.stderr create mode 100644 src/test/ui/nll/reassignment_immutable_fields.rs create mode 100644 src/test/ui/nll/reassignment_immutable_fields.stderr create mode 100644 src/test/ui/nll/reassignment_immutable_fields_overlapping.rs create mode 100644 src/test/ui/nll/reassignment_immutable_fields_overlapping.stderr create mode 100644 src/test/ui/nll/reassignment_immutable_fields_twice.rs create mode 100644 src/test/ui/nll/reassignment_immutable_fields_twice.stderr diff --git a/src/test/ui/nll/assign_mutable_fields.rs b/src/test/ui/nll/assign_mutable_fields.rs new file mode 100644 index 0000000000000..8025b998d5d1d --- /dev/null +++ b/src/test/ui/nll/assign_mutable_fields.rs @@ -0,0 +1,34 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Currently, we permit you to assign to individual fields of a mut +// var, but we do not permit you to use the complete var afterwards. +// We hope to fix this at some point. +// +// FIXME(#21232) + +#![feature(nll)] + +fn assign_both_fields_and_use() { + let mut x: (u32, u32); + x.0 = 1; + x.1 = 22; + drop(x.0); + drop(x.1); +} + +fn assign_both_fields_the_use_var() { + let mut x: (u32, u32); + x.0 = 1; + x.1 = 22; + drop(x); //~ ERROR +} + +fn main() { } diff --git a/src/test/ui/nll/assign_mutable_fields.stderr b/src/test/ui/nll/assign_mutable_fields.stderr new file mode 100644 index 0000000000000..278dcce4acdee --- /dev/null +++ b/src/test/ui/nll/assign_mutable_fields.stderr @@ -0,0 +1,9 @@ +error[E0381]: use of possibly uninitialized variable: `x` + --> $DIR/assign_mutable_fields.rs:31:10 + | +LL | drop(x); //~ ERROR + | ^ use of possibly uninitialized `x` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0381`. diff --git a/src/test/ui/nll/reassignment_immutable_fields.rs b/src/test/ui/nll/reassignment_immutable_fields.rs new file mode 100644 index 0000000000000..3660017e75dc0 --- /dev/null +++ b/src/test/ui/nll/reassignment_immutable_fields.rs @@ -0,0 +1,32 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// This test is currently disallowed, but we hope someday to support it. +// +// FIXME(#21232) + +#![feature(nll)] + +fn assign_both_fields_and_use() { + let x: (u32, u32); + x.0 = 1; //~ ERROR + x.1 = 22; //~ ERROR + drop(x.0); + drop(x.1); +} + +fn assign_both_fields_the_use_var() { + let x: (u32, u32); + x.0 = 1; //~ ERROR + x.1 = 22; //~ ERROR + drop(x); //~ ERROR +} + +fn main() { } diff --git a/src/test/ui/nll/reassignment_immutable_fields.stderr b/src/test/ui/nll/reassignment_immutable_fields.stderr new file mode 100644 index 0000000000000..853e82d0e9923 --- /dev/null +++ b/src/test/ui/nll/reassignment_immutable_fields.stderr @@ -0,0 +1,44 @@ +error[E0594]: cannot assign to `x.0`, as `x` is not declared as mutable + --> $DIR/reassignment_immutable_fields.rs:19:5 + | +LL | let x: (u32, u32); + | - help: consider changing this to be mutable: `mut x` +LL | x.0 = 1; //~ ERROR + | ^^^^^^^ cannot assign + +error[E0594]: cannot assign to `x.1`, as `x` is not declared as mutable + --> $DIR/reassignment_immutable_fields.rs:20:5 + | +LL | let x: (u32, u32); + | - help: consider changing this to be mutable: `mut x` +LL | x.0 = 1; //~ ERROR +LL | x.1 = 22; //~ ERROR + | ^^^^^^^^ cannot assign + +error[E0594]: cannot assign to `x.0`, as `x` is not declared as mutable + --> $DIR/reassignment_immutable_fields.rs:27:5 + | +LL | let x: (u32, u32); + | - help: consider changing this to be mutable: `mut x` +LL | x.0 = 1; //~ ERROR + | ^^^^^^^ cannot assign + +error[E0594]: cannot assign to `x.1`, as `x` is not declared as mutable + --> $DIR/reassignment_immutable_fields.rs:28:5 + | +LL | let x: (u32, u32); + | - help: consider changing this to be mutable: `mut x` +LL | x.0 = 1; //~ ERROR +LL | x.1 = 22; //~ ERROR + | ^^^^^^^^ cannot assign + +error[E0381]: use of possibly uninitialized variable: `x` + --> $DIR/reassignment_immutable_fields.rs:29:10 + | +LL | drop(x); //~ ERROR + | ^ use of possibly uninitialized `x` + +error: aborting due to 5 previous errors + +Some errors occurred: E0381, E0594. +For more information about an error, try `rustc --explain E0381`. diff --git a/src/test/ui/nll/reassignment_immutable_fields_overlapping.rs b/src/test/ui/nll/reassignment_immutable_fields_overlapping.rs new file mode 100644 index 0000000000000..17a82bf0c9bea --- /dev/null +++ b/src/test/ui/nll/reassignment_immutable_fields_overlapping.rs @@ -0,0 +1,28 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// This should never be allowed -- `foo.a` and `foo.b` are +// overlapping, so since `x` is not `mut` we should not permit +// reassignment. + +#![feature(nll)] + +union Foo { + a: u32, + b: u32, +} + +unsafe fn overlapping_fields() { + let x: Foo; + x.a = 1; //~ ERROR + x.b = 22; //~ ERROR +} + +fn main() { } diff --git a/src/test/ui/nll/reassignment_immutable_fields_overlapping.stderr b/src/test/ui/nll/reassignment_immutable_fields_overlapping.stderr new file mode 100644 index 0000000000000..1981b1497002b --- /dev/null +++ b/src/test/ui/nll/reassignment_immutable_fields_overlapping.stderr @@ -0,0 +1,20 @@ +error[E0594]: cannot assign to `x.a`, as `x` is not declared as mutable + --> $DIR/reassignment_immutable_fields_overlapping.rs:24:5 + | +LL | let x: Foo; + | - help: consider changing this to be mutable: `mut x` +LL | x.a = 1; //~ ERROR + | ^^^^^^^ cannot assign + +error[E0594]: cannot assign to `x.b`, as `x` is not declared as mutable + --> $DIR/reassignment_immutable_fields_overlapping.rs:25:5 + | +LL | let x: Foo; + | - help: consider changing this to be mutable: `mut x` +LL | x.a = 1; //~ ERROR +LL | x.b = 22; //~ ERROR + | ^^^^^^^^ cannot assign + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0594`. diff --git a/src/test/ui/nll/reassignment_immutable_fields_twice.rs b/src/test/ui/nll/reassignment_immutable_fields_twice.rs new file mode 100644 index 0000000000000..e413ad4f9473b --- /dev/null +++ b/src/test/ui/nll/reassignment_immutable_fields_twice.rs @@ -0,0 +1,29 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// This should never be allowed -- since `x` is not `mut`, so `x.0` +// cannot be assigned twice. + +#![feature(nll)] + +fn var_then_field() { + let x: (u32, u32); + x = (22, 44); + x.0 = 1; //~ ERROR +} + +fn same_field_twice() { + let x: (u32, u32); + x.0 = 1; //~ ERROR + x.0 = 22; //~ ERROR + x.1 = 44; //~ ERROR +} + +fn main() { } diff --git a/src/test/ui/nll/reassignment_immutable_fields_twice.stderr b/src/test/ui/nll/reassignment_immutable_fields_twice.stderr new file mode 100644 index 0000000000000..cf0461f275c91 --- /dev/null +++ b/src/test/ui/nll/reassignment_immutable_fields_twice.stderr @@ -0,0 +1,38 @@ +error[E0594]: cannot assign to `x.0`, as `x` is not declared as mutable + --> $DIR/reassignment_immutable_fields_twice.rs:19:5 + | +LL | let x: (u32, u32); + | - help: consider changing this to be mutable: `mut x` +LL | x = (22, 44); +LL | x.0 = 1; //~ ERROR + | ^^^^^^^ cannot assign + +error[E0594]: cannot assign to `x.0`, as `x` is not declared as mutable + --> $DIR/reassignment_immutable_fields_twice.rs:24:5 + | +LL | let x: (u32, u32); + | - help: consider changing this to be mutable: `mut x` +LL | x.0 = 1; //~ ERROR + | ^^^^^^^ cannot assign + +error[E0594]: cannot assign to `x.0`, as `x` is not declared as mutable + --> $DIR/reassignment_immutable_fields_twice.rs:25:5 + | +LL | let x: (u32, u32); + | - help: consider changing this to be mutable: `mut x` +LL | x.0 = 1; //~ ERROR +LL | x.0 = 22; //~ ERROR + | ^^^^^^^^ cannot assign + +error[E0594]: cannot assign to `x.1`, as `x` is not declared as mutable + --> $DIR/reassignment_immutable_fields_twice.rs:26:5 + | +LL | let x: (u32, u32); + | - help: consider changing this to be mutable: `mut x` +... +LL | x.1 = 44; //~ ERROR + | ^^^^^^^^ cannot assign + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0594`. From 58e4b54bd49a2a554ee8a573827b9ccbf7a9b65e Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 14 Aug 2018 08:24:44 -0400 Subject: [PATCH 4/4] move tests to borrowck directory, remove feature(nll) now compare-mode can show us the differences --- .../assign_mutable_fields.nll.stderr} | 2 +- .../assign_mutable_fields.rs | 6 +- .../ui/borrowck/assign_mutable_fields.stderr | 21 +++++++ .../reassignment_immutable_fields.nll.stderr} | 10 ++-- .../reassignment_immutable_fields.rs | 6 +- .../reassignment_immutable_fields.stderr | 56 +++++++++++++++++++ ...t_immutable_fields_overlapping.nll.stderr} | 4 +- ...assignment_immutable_fields_overlapping.rs | 2 - ...gnment_immutable_fields_overlapping.stderr | 20 +++++++ ...ignment_immutable_fields_twice.nll.stderr} | 8 +-- .../reassignment_immutable_fields_twice.rs | 2 - ...reassignment_immutable_fields_twice.stderr | 38 +++++++++++++ .../immut-function-arguments.ast.nll.stderr | 14 ++--- .../ui/immut-function-arguments.mir.stderr | 14 ++--- .../mut/mutable-class-fields.ast.nll.stderr | 11 ++-- .../ui/mut/mutable-class-fields.mir.stderr | 11 ++-- 16 files changed, 173 insertions(+), 52 deletions(-) rename src/test/ui/{nll/assign_mutable_fields.stderr => borrowck/assign_mutable_fields.nll.stderr} (85%) rename src/test/ui/{nll => borrowck}/assign_mutable_fields.rs (94%) create mode 100644 src/test/ui/borrowck/assign_mutable_fields.stderr rename src/test/ui/{nll/reassignment_immutable_fields.stderr => borrowck/reassignment_immutable_fields.nll.stderr} (83%) rename src/test/ui/{nll => borrowck}/reassignment_immutable_fields.rs (94%) create mode 100644 src/test/ui/borrowck/reassignment_immutable_fields.stderr rename src/test/ui/{nll/reassignment_immutable_fields_overlapping.stderr => borrowck/reassignment_immutable_fields_overlapping.nll.stderr} (82%) rename src/test/ui/{nll => borrowck}/reassignment_immutable_fields_overlapping.rs (97%) create mode 100644 src/test/ui/borrowck/reassignment_immutable_fields_overlapping.stderr rename src/test/ui/{nll/reassignment_immutable_fields_twice.stderr => borrowck/reassignment_immutable_fields_twice.nll.stderr} (87%) rename src/test/ui/{nll => borrowck}/reassignment_immutable_fields_twice.rs (97%) create mode 100644 src/test/ui/borrowck/reassignment_immutable_fields_twice.stderr diff --git a/src/test/ui/nll/assign_mutable_fields.stderr b/src/test/ui/borrowck/assign_mutable_fields.nll.stderr similarity index 85% rename from src/test/ui/nll/assign_mutable_fields.stderr rename to src/test/ui/borrowck/assign_mutable_fields.nll.stderr index 278dcce4acdee..5147075347283 100644 --- a/src/test/ui/nll/assign_mutable_fields.stderr +++ b/src/test/ui/borrowck/assign_mutable_fields.nll.stderr @@ -1,5 +1,5 @@ error[E0381]: use of possibly uninitialized variable: `x` - --> $DIR/assign_mutable_fields.rs:31:10 + --> $DIR/assign_mutable_fields.rs:29:10 | LL | drop(x); //~ ERROR | ^ use of possibly uninitialized `x` diff --git a/src/test/ui/nll/assign_mutable_fields.rs b/src/test/ui/borrowck/assign_mutable_fields.rs similarity index 94% rename from src/test/ui/nll/assign_mutable_fields.rs rename to src/test/ui/borrowck/assign_mutable_fields.rs index 8025b998d5d1d..4e41f44ef5bb3 100644 --- a/src/test/ui/nll/assign_mutable_fields.rs +++ b/src/test/ui/borrowck/assign_mutable_fields.rs @@ -14,14 +14,12 @@ // // FIXME(#21232) -#![feature(nll)] - fn assign_both_fields_and_use() { let mut x: (u32, u32); x.0 = 1; x.1 = 22; - drop(x.0); - drop(x.1); + drop(x.0); //~ ERROR + drop(x.1); //~ ERROR } fn assign_both_fields_the_use_var() { diff --git a/src/test/ui/borrowck/assign_mutable_fields.stderr b/src/test/ui/borrowck/assign_mutable_fields.stderr new file mode 100644 index 0000000000000..677887babd038 --- /dev/null +++ b/src/test/ui/borrowck/assign_mutable_fields.stderr @@ -0,0 +1,21 @@ +error[E0381]: use of possibly uninitialized variable: `x.0` + --> $DIR/assign_mutable_fields.rs:21:10 + | +LL | drop(x.0); //~ ERROR + | ^^^ use of possibly uninitialized `x.0` + +error[E0381]: use of possibly uninitialized variable: `x.1` + --> $DIR/assign_mutable_fields.rs:22:10 + | +LL | drop(x.1); //~ ERROR + | ^^^ use of possibly uninitialized `x.1` + +error[E0381]: use of possibly uninitialized variable: `x` + --> $DIR/assign_mutable_fields.rs:29:10 + | +LL | drop(x); //~ ERROR + | ^ use of possibly uninitialized `x` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0381`. diff --git a/src/test/ui/nll/reassignment_immutable_fields.stderr b/src/test/ui/borrowck/reassignment_immutable_fields.nll.stderr similarity index 83% rename from src/test/ui/nll/reassignment_immutable_fields.stderr rename to src/test/ui/borrowck/reassignment_immutable_fields.nll.stderr index 853e82d0e9923..97f3bf5b81f66 100644 --- a/src/test/ui/nll/reassignment_immutable_fields.stderr +++ b/src/test/ui/borrowck/reassignment_immutable_fields.nll.stderr @@ -1,5 +1,5 @@ error[E0594]: cannot assign to `x.0`, as `x` is not declared as mutable - --> $DIR/reassignment_immutable_fields.rs:19:5 + --> $DIR/reassignment_immutable_fields.rs:17:5 | LL | let x: (u32, u32); | - help: consider changing this to be mutable: `mut x` @@ -7,7 +7,7 @@ LL | x.0 = 1; //~ ERROR | ^^^^^^^ cannot assign error[E0594]: cannot assign to `x.1`, as `x` is not declared as mutable - --> $DIR/reassignment_immutable_fields.rs:20:5 + --> $DIR/reassignment_immutable_fields.rs:18:5 | LL | let x: (u32, u32); | - help: consider changing this to be mutable: `mut x` @@ -16,7 +16,7 @@ LL | x.1 = 22; //~ ERROR | ^^^^^^^^ cannot assign error[E0594]: cannot assign to `x.0`, as `x` is not declared as mutable - --> $DIR/reassignment_immutable_fields.rs:27:5 + --> $DIR/reassignment_immutable_fields.rs:25:5 | LL | let x: (u32, u32); | - help: consider changing this to be mutable: `mut x` @@ -24,7 +24,7 @@ LL | x.0 = 1; //~ ERROR | ^^^^^^^ cannot assign error[E0594]: cannot assign to `x.1`, as `x` is not declared as mutable - --> $DIR/reassignment_immutable_fields.rs:28:5 + --> $DIR/reassignment_immutable_fields.rs:26:5 | LL | let x: (u32, u32); | - help: consider changing this to be mutable: `mut x` @@ -33,7 +33,7 @@ LL | x.1 = 22; //~ ERROR | ^^^^^^^^ cannot assign error[E0381]: use of possibly uninitialized variable: `x` - --> $DIR/reassignment_immutable_fields.rs:29:10 + --> $DIR/reassignment_immutable_fields.rs:27:10 | LL | drop(x); //~ ERROR | ^ use of possibly uninitialized `x` diff --git a/src/test/ui/nll/reassignment_immutable_fields.rs b/src/test/ui/borrowck/reassignment_immutable_fields.rs similarity index 94% rename from src/test/ui/nll/reassignment_immutable_fields.rs rename to src/test/ui/borrowck/reassignment_immutable_fields.rs index 3660017e75dc0..c49ae2f9567fc 100644 --- a/src/test/ui/nll/reassignment_immutable_fields.rs +++ b/src/test/ui/borrowck/reassignment_immutable_fields.rs @@ -12,14 +12,12 @@ // // FIXME(#21232) -#![feature(nll)] - fn assign_both_fields_and_use() { let x: (u32, u32); x.0 = 1; //~ ERROR x.1 = 22; //~ ERROR - drop(x.0); - drop(x.1); + drop(x.0); //~ ERROR + drop(x.1); //~ ERROR } fn assign_both_fields_the_use_var() { diff --git a/src/test/ui/borrowck/reassignment_immutable_fields.stderr b/src/test/ui/borrowck/reassignment_immutable_fields.stderr new file mode 100644 index 0000000000000..54d12f8fae85d --- /dev/null +++ b/src/test/ui/borrowck/reassignment_immutable_fields.stderr @@ -0,0 +1,56 @@ +error[E0594]: cannot assign to field `x.0` of immutable binding + --> $DIR/reassignment_immutable_fields.rs:17:5 + | +LL | let x: (u32, u32); + | - consider changing this to `mut x` +LL | x.0 = 1; //~ ERROR + | ^^^^^^^ cannot mutably borrow field of immutable binding + +error[E0594]: cannot assign to field `x.1` of immutable binding + --> $DIR/reassignment_immutable_fields.rs:18:5 + | +LL | let x: (u32, u32); + | - consider changing this to `mut x` +LL | x.0 = 1; //~ ERROR +LL | x.1 = 22; //~ ERROR + | ^^^^^^^^ cannot mutably borrow field of immutable binding + +error[E0381]: use of possibly uninitialized variable: `x.0` + --> $DIR/reassignment_immutable_fields.rs:19:10 + | +LL | drop(x.0); //~ ERROR + | ^^^ use of possibly uninitialized `x.0` + +error[E0381]: use of possibly uninitialized variable: `x.1` + --> $DIR/reassignment_immutable_fields.rs:20:10 + | +LL | drop(x.1); //~ ERROR + | ^^^ use of possibly uninitialized `x.1` + +error[E0594]: cannot assign to field `x.0` of immutable binding + --> $DIR/reassignment_immutable_fields.rs:25:5 + | +LL | let x: (u32, u32); + | - consider changing this to `mut x` +LL | x.0 = 1; //~ ERROR + | ^^^^^^^ cannot mutably borrow field of immutable binding + +error[E0594]: cannot assign to field `x.1` of immutable binding + --> $DIR/reassignment_immutable_fields.rs:26:5 + | +LL | let x: (u32, u32); + | - consider changing this to `mut x` +LL | x.0 = 1; //~ ERROR +LL | x.1 = 22; //~ ERROR + | ^^^^^^^^ cannot mutably borrow field of immutable binding + +error[E0381]: use of possibly uninitialized variable: `x` + --> $DIR/reassignment_immutable_fields.rs:27:10 + | +LL | drop(x); //~ ERROR + | ^ use of possibly uninitialized `x` + +error: aborting due to 7 previous errors + +Some errors occurred: E0381, E0594. +For more information about an error, try `rustc --explain E0381`. diff --git a/src/test/ui/nll/reassignment_immutable_fields_overlapping.stderr b/src/test/ui/borrowck/reassignment_immutable_fields_overlapping.nll.stderr similarity index 82% rename from src/test/ui/nll/reassignment_immutable_fields_overlapping.stderr rename to src/test/ui/borrowck/reassignment_immutable_fields_overlapping.nll.stderr index 1981b1497002b..c433d6e25c9de 100644 --- a/src/test/ui/nll/reassignment_immutable_fields_overlapping.stderr +++ b/src/test/ui/borrowck/reassignment_immutable_fields_overlapping.nll.stderr @@ -1,5 +1,5 @@ error[E0594]: cannot assign to `x.a`, as `x` is not declared as mutable - --> $DIR/reassignment_immutable_fields_overlapping.rs:24:5 + --> $DIR/reassignment_immutable_fields_overlapping.rs:22:5 | LL | let x: Foo; | - help: consider changing this to be mutable: `mut x` @@ -7,7 +7,7 @@ LL | x.a = 1; //~ ERROR | ^^^^^^^ cannot assign error[E0594]: cannot assign to `x.b`, as `x` is not declared as mutable - --> $DIR/reassignment_immutable_fields_overlapping.rs:25:5 + --> $DIR/reassignment_immutable_fields_overlapping.rs:23:5 | LL | let x: Foo; | - help: consider changing this to be mutable: `mut x` diff --git a/src/test/ui/nll/reassignment_immutable_fields_overlapping.rs b/src/test/ui/borrowck/reassignment_immutable_fields_overlapping.rs similarity index 97% rename from src/test/ui/nll/reassignment_immutable_fields_overlapping.rs rename to src/test/ui/borrowck/reassignment_immutable_fields_overlapping.rs index 17a82bf0c9bea..add23ec8f245b 100644 --- a/src/test/ui/nll/reassignment_immutable_fields_overlapping.rs +++ b/src/test/ui/borrowck/reassignment_immutable_fields_overlapping.rs @@ -12,8 +12,6 @@ // overlapping, so since `x` is not `mut` we should not permit // reassignment. -#![feature(nll)] - union Foo { a: u32, b: u32, diff --git a/src/test/ui/borrowck/reassignment_immutable_fields_overlapping.stderr b/src/test/ui/borrowck/reassignment_immutable_fields_overlapping.stderr new file mode 100644 index 0000000000000..70849905f92ab --- /dev/null +++ b/src/test/ui/borrowck/reassignment_immutable_fields_overlapping.stderr @@ -0,0 +1,20 @@ +error[E0594]: cannot assign to field `x.a` of immutable binding + --> $DIR/reassignment_immutable_fields_overlapping.rs:22:5 + | +LL | let x: Foo; + | - consider changing this to `mut x` +LL | x.a = 1; //~ ERROR + | ^^^^^^^ cannot mutably borrow field of immutable binding + +error[E0594]: cannot assign to field `x.b` of immutable binding + --> $DIR/reassignment_immutable_fields_overlapping.rs:23:5 + | +LL | let x: Foo; + | - consider changing this to `mut x` +LL | x.a = 1; //~ ERROR +LL | x.b = 22; //~ ERROR + | ^^^^^^^^ cannot mutably borrow field of immutable binding + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0594`. diff --git a/src/test/ui/nll/reassignment_immutable_fields_twice.stderr b/src/test/ui/borrowck/reassignment_immutable_fields_twice.nll.stderr similarity index 87% rename from src/test/ui/nll/reassignment_immutable_fields_twice.stderr rename to src/test/ui/borrowck/reassignment_immutable_fields_twice.nll.stderr index cf0461f275c91..2160ae20c425a 100644 --- a/src/test/ui/nll/reassignment_immutable_fields_twice.stderr +++ b/src/test/ui/borrowck/reassignment_immutable_fields_twice.nll.stderr @@ -1,5 +1,5 @@ error[E0594]: cannot assign to `x.0`, as `x` is not declared as mutable - --> $DIR/reassignment_immutable_fields_twice.rs:19:5 + --> $DIR/reassignment_immutable_fields_twice.rs:17:5 | LL | let x: (u32, u32); | - help: consider changing this to be mutable: `mut x` @@ -8,7 +8,7 @@ LL | x.0 = 1; //~ ERROR | ^^^^^^^ cannot assign error[E0594]: cannot assign to `x.0`, as `x` is not declared as mutable - --> $DIR/reassignment_immutable_fields_twice.rs:24:5 + --> $DIR/reassignment_immutable_fields_twice.rs:22:5 | LL | let x: (u32, u32); | - help: consider changing this to be mutable: `mut x` @@ -16,7 +16,7 @@ LL | x.0 = 1; //~ ERROR | ^^^^^^^ cannot assign error[E0594]: cannot assign to `x.0`, as `x` is not declared as mutable - --> $DIR/reassignment_immutable_fields_twice.rs:25:5 + --> $DIR/reassignment_immutable_fields_twice.rs:23:5 | LL | let x: (u32, u32); | - help: consider changing this to be mutable: `mut x` @@ -25,7 +25,7 @@ LL | x.0 = 22; //~ ERROR | ^^^^^^^^ cannot assign error[E0594]: cannot assign to `x.1`, as `x` is not declared as mutable - --> $DIR/reassignment_immutable_fields_twice.rs:26:5 + --> $DIR/reassignment_immutable_fields_twice.rs:24:5 | LL | let x: (u32, u32); | - help: consider changing this to be mutable: `mut x` diff --git a/src/test/ui/nll/reassignment_immutable_fields_twice.rs b/src/test/ui/borrowck/reassignment_immutable_fields_twice.rs similarity index 97% rename from src/test/ui/nll/reassignment_immutable_fields_twice.rs rename to src/test/ui/borrowck/reassignment_immutable_fields_twice.rs index e413ad4f9473b..c7e7e5c453357 100644 --- a/src/test/ui/nll/reassignment_immutable_fields_twice.rs +++ b/src/test/ui/borrowck/reassignment_immutable_fields_twice.rs @@ -11,8 +11,6 @@ // This should never be allowed -- since `x` is not `mut`, so `x.0` // cannot be assigned twice. -#![feature(nll)] - fn var_then_field() { let x: (u32, u32); x = (22, 44); diff --git a/src/test/ui/borrowck/reassignment_immutable_fields_twice.stderr b/src/test/ui/borrowck/reassignment_immutable_fields_twice.stderr new file mode 100644 index 0000000000000..b3c013d8b1f49 --- /dev/null +++ b/src/test/ui/borrowck/reassignment_immutable_fields_twice.stderr @@ -0,0 +1,38 @@ +error[E0594]: cannot assign to field `x.0` of immutable binding + --> $DIR/reassignment_immutable_fields_twice.rs:17:5 + | +LL | let x: (u32, u32); + | - consider changing this to `mut x` +LL | x = (22, 44); +LL | x.0 = 1; //~ ERROR + | ^^^^^^^ cannot mutably borrow field of immutable binding + +error[E0594]: cannot assign to field `x.0` of immutable binding + --> $DIR/reassignment_immutable_fields_twice.rs:22:5 + | +LL | let x: (u32, u32); + | - consider changing this to `mut x` +LL | x.0 = 1; //~ ERROR + | ^^^^^^^ cannot mutably borrow field of immutable binding + +error[E0594]: cannot assign to field `x.0` of immutable binding + --> $DIR/reassignment_immutable_fields_twice.rs:23:5 + | +LL | let x: (u32, u32); + | - consider changing this to `mut x` +LL | x.0 = 1; //~ ERROR +LL | x.0 = 22; //~ ERROR + | ^^^^^^^^ cannot mutably borrow field of immutable binding + +error[E0594]: cannot assign to field `x.1` of immutable binding + --> $DIR/reassignment_immutable_fields_twice.rs:24:5 + | +LL | let x: (u32, u32); + | - consider changing this to `mut x` +... +LL | x.1 = 44; //~ ERROR + | ^^^^^^^^ cannot mutably borrow field of immutable binding + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0594`. diff --git a/src/test/ui/immut-function-arguments.ast.nll.stderr b/src/test/ui/immut-function-arguments.ast.nll.stderr index c823634062740..d33814a0fc5f5 100644 --- a/src/test/ui/immut-function-arguments.ast.nll.stderr +++ b/src/test/ui/immut-function-arguments.ast.nll.stderr @@ -1,19 +1,19 @@ -error[E0384]: cannot assign to immutable argument `y` +error[E0594]: cannot assign to `*y`, as `y` is not declared as mutable --> $DIR/immut-function-arguments.rs:15:5 | LL | fn f(y: Box) { - | - consider changing this to `mut y` + | - help: consider changing this to be mutable: `mut y` LL | *y = 5; //[ast]~ ERROR cannot assign - | ^^^^^^ cannot assign to immutable argument + | ^^^^^^ cannot assign -error[E0384]: cannot assign to immutable argument `q` +error[E0594]: cannot assign to `*q`, as `q` is not declared as mutable --> $DIR/immut-function-arguments.rs:20:35 | LL | let _frob = |q: Box| { *q = 2; }; //[ast]~ ERROR cannot assign - | - ^^^^^^ cannot assign to immutable argument + | - ^^^^^^ cannot assign | | - | consider changing this to `mut q` + | help: consider changing this to be mutable: `mut q` error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0384`. +For more information about this error, try `rustc --explain E0594`. diff --git a/src/test/ui/immut-function-arguments.mir.stderr b/src/test/ui/immut-function-arguments.mir.stderr index c823634062740..d33814a0fc5f5 100644 --- a/src/test/ui/immut-function-arguments.mir.stderr +++ b/src/test/ui/immut-function-arguments.mir.stderr @@ -1,19 +1,19 @@ -error[E0384]: cannot assign to immutable argument `y` +error[E0594]: cannot assign to `*y`, as `y` is not declared as mutable --> $DIR/immut-function-arguments.rs:15:5 | LL | fn f(y: Box) { - | - consider changing this to `mut y` + | - help: consider changing this to be mutable: `mut y` LL | *y = 5; //[ast]~ ERROR cannot assign - | ^^^^^^ cannot assign to immutable argument + | ^^^^^^ cannot assign -error[E0384]: cannot assign to immutable argument `q` +error[E0594]: cannot assign to `*q`, as `q` is not declared as mutable --> $DIR/immut-function-arguments.rs:20:35 | LL | let _frob = |q: Box| { *q = 2; }; //[ast]~ ERROR cannot assign - | - ^^^^^^ cannot assign to immutable argument + | - ^^^^^^ cannot assign | | - | consider changing this to `mut q` + | help: consider changing this to be mutable: `mut q` error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0384`. +For more information about this error, try `rustc --explain E0594`. diff --git a/src/test/ui/mut/mutable-class-fields.ast.nll.stderr b/src/test/ui/mut/mutable-class-fields.ast.nll.stderr index 1d1e58de587d4..033a3bd6cb4c3 100644 --- a/src/test/ui/mut/mutable-class-fields.ast.nll.stderr +++ b/src/test/ui/mut/mutable-class-fields.ast.nll.stderr @@ -1,14 +1,11 @@ -error[E0384]: cannot assign twice to immutable variable `nyan` +error[E0594]: cannot assign to `nyan.how_hungry`, as `nyan` is not declared as mutable --> $DIR/mutable-class-fields.rs:28:3 | LL | let nyan : cat = cat(52, 99); - | ---- - | | - | first assignment to `nyan` - | consider changing this to `mut nyan` + | ---- help: consider changing this to be mutable: `mut nyan` LL | nyan.how_hungry = 0; //[ast]~ ERROR cannot assign - | ^^^^^^^^^^^^^^^^^^^ cannot assign twice to immutable variable + | ^^^^^^^^^^^^^^^^^^^ cannot assign error: aborting due to previous error -For more information about this error, try `rustc --explain E0384`. +For more information about this error, try `rustc --explain E0594`. diff --git a/src/test/ui/mut/mutable-class-fields.mir.stderr b/src/test/ui/mut/mutable-class-fields.mir.stderr index 1d1e58de587d4..033a3bd6cb4c3 100644 --- a/src/test/ui/mut/mutable-class-fields.mir.stderr +++ b/src/test/ui/mut/mutable-class-fields.mir.stderr @@ -1,14 +1,11 @@ -error[E0384]: cannot assign twice to immutable variable `nyan` +error[E0594]: cannot assign to `nyan.how_hungry`, as `nyan` is not declared as mutable --> $DIR/mutable-class-fields.rs:28:3 | LL | let nyan : cat = cat(52, 99); - | ---- - | | - | first assignment to `nyan` - | consider changing this to `mut nyan` + | ---- help: consider changing this to be mutable: `mut nyan` LL | nyan.how_hungry = 0; //[ast]~ ERROR cannot assign - | ^^^^^^^^^^^^^^^^^^^ cannot assign twice to immutable variable + | ^^^^^^^^^^^^^^^^^^^ cannot assign error: aborting due to previous error -For more information about this error, try `rustc --explain E0384`. +For more information about this error, try `rustc --explain E0594`.