From e0f590857b15442e79c40d7b07ee494ec4b5d397 Mon Sep 17 00:00:00 2001 From: Xiangfei Ding Date: Tue, 17 Feb 2026 20:39:00 +0000 Subject: [PATCH] Allow partially initializing structs Signed-off-by: Xiangfei Ding --- .../src/diagnostics/conflict_errors.rs | 11 + compiler/rustc_borrowck/src/lib.rs | 55 ++-- .../src/type_check/liveness/trace.rs | 19 +- compiler/rustc_feature/src/unstable.rs | 2 + compiler/rustc_middle/src/ty/util.rs | 8 + .../src/drop_flag_effects.rs | 1 + .../src/impls/initialized.rs | 55 +++- .../src/move_paths/builder.rs | 16 +- compiler/rustc_span/src/symbol.rs | 1 + .../partial-initialization-across-await.rs | 3 + ...partial-initialization-across-await.stderr | 36 ++- tests/ui/borrowck/assign_mutable_fields.rs | 10 +- .../ui/borrowck/assign_mutable_fields.stderr | 25 +- .../ui/borrowck/borrowck-field-sensitivity.rs | 3 + .../borrowck-field-sensitivity.stderr | 35 ++- .../ui/borrowck/borrowck-partial-reinit-4.rs | 1 + .../borrowck/borrowck-partial-reinit-4.stderr | 14 +- .../ui/borrowck/borrowck-uninit-ref-chain.rs | 4 + .../borrowck/borrowck-uninit-ref-chain.stderr | 47 +++- .../borrowck/borrowck-union-uninitialized.rs | 2 + .../borrowck-union-uninitialized.stderr | 27 +- ...llow-possibly-uninitialized.classic.stderr | 80 ++++++ .../disallow-possibly-uninitialized.rs | 17 +- .../disallow-possibly-uninitialized.stderr | 43 ---- ...-mutation-marks-mut-as-used.classic.stderr | 61 +++++ ...-54499-field-mutation-marks-mut-as-used.rs | 21 +- ...99-field-mutation-marks-mut-as-used.stderr | 33 --- ...ield-mutation-of-never-init.classic.stderr | 61 +++++ ...ssue-54499-field-mutation-of-never-init.rs | 20 +- ...-54499-field-mutation-of-never-init.stderr | 33 --- tests/ui/borrowck/partial-init-locals.rs | 26 ++ tests/ui/borrowck/partial-init-locals.stderr | 13 + .../borrowck/reassignment_immutable_fields.rs | 6 +- .../reassignment_immutable_fields.stderr | 25 +- ...assignment_immutable_fields_overlapping.rs | 3 +- ...gnment_immutable_fields_overlapping.stderr | 15 +- .../reassignment_immutable_fields_twice.rs | 6 +- ...reassignment_immutable_fields_twice.stderr | 13 +- .../partial-initialization-across-yield.rs | 3 + ...partial-initialization-across-yield.stderr | 36 ++- .../feature-gate-partial-init-locals.rs | 7 + .../feature-gate-partial-init-locals.stderr | 23 ++ ...tial-init-and-erroneous-use.classic.stderr | 118 +++++++++ ...nit-and-erroneous-use.partial_init.stderr} | 32 +-- ...ue-21232-partial-init-and-erroneous-use.rs | 21 +- ...21232-partial-init-and-use.classic.stderr} | 242 +++++++++++++----- .../nll/issue-21232-partial-init-and-use.rs | 195 +++++++++----- 47 files changed, 1166 insertions(+), 362 deletions(-) create mode 100644 tests/ui/borrowck/disallow-possibly-uninitialized.classic.stderr delete mode 100644 tests/ui/borrowck/disallow-possibly-uninitialized.stderr create mode 100644 tests/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.classic.stderr delete mode 100644 tests/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.stderr create mode 100644 tests/ui/borrowck/issue-54499-field-mutation-of-never-init.classic.stderr delete mode 100644 tests/ui/borrowck/issue-54499-field-mutation-of-never-init.stderr create mode 100644 tests/ui/borrowck/partial-init-locals.rs create mode 100644 tests/ui/borrowck/partial-init-locals.stderr create mode 100644 tests/ui/feature-gates/feature-gate-partial-init-locals.rs create mode 100644 tests/ui/feature-gates/feature-gate-partial-init-locals.stderr create mode 100644 tests/ui/nll/issue-21232-partial-init-and-erroneous-use.classic.stderr rename tests/ui/nll/{issue-21232-partial-init-and-erroneous-use.stderr => issue-21232-partial-init-and-erroneous-use.partial_init.stderr} (73%) rename tests/ui/nll/{issue-21232-partial-init-and-use.stderr => issue-21232-partial-init-and-use.classic.stderr} (53%) diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 641121597848c..caaaaeddb522a 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -26,6 +26,7 @@ use rustc_middle::ty::{ suggest_constraining_type_params, }; use rustc_mir_dataflow::move_paths::{InitKind, MoveOutIndex, MovePathIndex}; +use rustc_session::parse::feature_err; use rustc_span::def_id::{DefId, LocalDefId}; use rustc_span::hygiene::DesugaringKind; use rustc_span::{BytePos, ExpnKind, Ident, MacroKind, Span, Symbol, kw, sym}; @@ -826,6 +827,16 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { "partial initialization isn't supported, fully initialize the binding with a \ default value and mutate it, or use `std::mem::MaybeUninit`", ); + if !tcx.features().partial_init_locals() { + feature_err( + tcx.sess, + sym::partial_init_locals, + span, + "#![feature(partial_init_locals)] might be able to \ + enable the initialisation here", + ) + .emit(); + } } err.span_label(span, format!("{path} {used} here but it {isnt_initialized}")); diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 114f9d864e735..28329b9e87c2e 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -1177,6 +1177,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> { /// access. /// /// Returns `true` if an error is reported. + #[instrument(level = "debug", skip(self, state))] fn access_place( &mut self, location: Location, @@ -2000,9 +2001,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> { // // 1. Move of `a.b.c`, use of `a.b.c` // 2. Move of `a.b.c`, use of `a.b.c.d` (without first reinitializing `a.b.c.d`) - // 3. Uninitialized `(a.b.c: &_)`, use of `*a.b.c`; note that with - // partial initialization support, one might have `a.x` - // initialized but not `a.b`. + // 3. Uninitialized `(a.b.c: &_)`, use of `*a.b.c` // // OK scenarios: // @@ -2201,6 +2200,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> { debug!("check_if_assigned_path_is_moved place: {:?}", place); // None case => assigning to `x` does not require `x` be initialized. + let tcx = self.infcx.tcx; + let partial_init_locals = tcx.features().partial_init_locals(); for (place_base, elem) in place.iter_projections().rev() { match elem { ProjectionElem::Index(_/*operand*/) | @@ -2235,7 +2236,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> { // if type of `P` has a dtor, then // assigning to `P.f` requires `P` itself // be already initialized - let tcx = self.infcx.tcx; let base_ty = place_base.ty(self.body(), tcx).ty; match base_ty.kind() { ty::Adt(def, _) if def.has_dtor(tcx) => { @@ -2248,6 +2248,9 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> { break; } + ty::Adt(def, _) if partial_init_locals && !def.has_dtor(tcx) => {} + ty::Tuple(..) if partial_init_locals => {} + // Once `let s; s.x = V; read(s.x);`, // is allowed, remove this match arm. ty::Adt(..) | ty::Tuple(..) => { @@ -2351,6 +2354,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> { /// Checks the permissions for the given place and read or write kind /// /// Returns `true` if an error is reported. + #[instrument(level = "debug", skip(self, state))] fn check_access_permissions( &mut self, (place, span): (Place<'tcx>, Span), @@ -2359,11 +2363,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> { state: &BorrowckDomain, location: Location, ) -> bool { - debug!( - "check_access_permissions({:?}, {:?}, is_local_mutation_allowed: {:?})", - place, kind, is_local_mutation_allowed - ); - let error_access; let the_place_err; @@ -2451,23 +2450,29 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> { // partial initialization, do not complain about mutability // errors except for actual mutation (as opposed to an attempt // to do a partial initialization). - let previously_initialized = self.is_local_ever_initialized(place.local, state); - - // at this point, we have set up the error reporting state. - if let Some(init_index) = previously_initialized { - if let (AccessKind::Mutate, Some(_)) = (error_access, place.as_local()) { - // If this is a mutate access to an immutable local variable with no projections - // report the error as an illegal reassignment - let init = &self.move_data.inits[init_index]; - let assigned_span = init.span(self.body); - self.report_illegal_reassignment((place, span), assigned_span, place); - } else { - self.report_mutability_error(place, span, the_place_err, error_access, location) - } - true + let Some(init_index) = self.is_local_ever_initialized(place.local, state) else { + return false; + }; + // NOTE(partial_init_locals): now we need to check again if the local is possibly uninitialised. + if self.root_cx.tcx.features().partial_init_locals() + && let Some(mpi) = self.move_path_for_place(Place::from(place.local).as_ref()) + && state.uninits.contains(mpi) + { + // Partial init is still in progress, so mutable access on the local is not required. + return false; + } + + // At this point, we have set up the error reporting state. + if let (AccessKind::Mutate, Some(_)) = (error_access, place.as_local()) { + // If this is a mutate access to an immutable local variable with no projections + // report the error as an illegal reassignment + let init = &self.move_data.inits[init_index]; + let assigned_span = init.span(self.body); + self.report_illegal_reassignment((place, span), assigned_span, place); } else { - false + self.report_mutability_error(place, span, the_place_err, error_access, location) } + true } fn is_local_ever_initialized(&self, local: Local, state: &BorrowckDomain) -> Option { @@ -2511,12 +2516,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> { /// Whether this value can be written or borrowed mutably. /// Returns the root place if the place passed in is a projection. + #[instrument(level = "debug", skip(self), ret)] fn is_mutable( &self, place: PlaceRef<'tcx>, is_local_mutation_allowed: LocalMutationIsAllowed, ) -> Result, PlaceRef<'tcx>> { - debug!("is_mutable: place={:?}, is_local...={:?}", place, is_local_mutation_allowed); match place.last_projection() { None => { let local = &self.body.local_decls[place.local]; diff --git a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs index 840210496eb44..b088cec6b1172 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs @@ -16,7 +16,7 @@ use rustc_trait_selection::error_reporting::InferCtxtErrorExt; use rustc_trait_selection::traits::ObligationCtxt; use rustc_trait_selection::traits::query::dropck_outlives; use rustc_trait_selection::traits::query::type_op::{DropckOutlives, TypeOp, TypeOpOutput}; -use tracing::debug; +use tracing::{debug, instrument}; use crate::polonius; use crate::region_infer::values; @@ -544,6 +544,11 @@ impl<'tcx> LivenessContext<'_, '_, 'tcx> { /// the regions in its type must be live at `location`. The /// precise set will depend on the dropck constraints, and in /// particular this takes `#[may_dangle]` into account. + #[instrument( + level = "debug", + skip(self, live_at), + fields(live_at = ?values::pretty_print_points(self.location_map, live_at.iter()))) + ] fn add_drop_live_facts_for( &mut self, dropped_local: Local, @@ -551,18 +556,6 @@ impl<'tcx> LivenessContext<'_, '_, 'tcx> { drop_locations: &[Location], live_at: &IntervalSet, ) { - debug!( - "add_drop_live_constraint(\ - dropped_local={:?}, \ - dropped_ty={:?}, \ - drop_locations={:?}, \ - live_at={:?})", - dropped_local, - dropped_ty, - drop_locations, - values::pretty_print_points(self.location_map, live_at.iter()), - ); - let local_span = self.body().local_decls()[dropped_local].source_info.span; let drop_data = self.drop_data.entry(dropped_ty).or_insert_with({ let typeck = &self.typeck; diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 39e886227d946..72d386d3dca0a 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -621,6 +621,8 @@ declare_features! ( (unstable, opaque_generic_const_args, "1.95.0", Some(151972)), /// Allows using `#[optimize(X)]`. (unstable, optimize_attribute, "1.34.0", Some(54882)), + /// Allows partial initialisation of no-Drop `struct`s and tuples. + (unstable, partial_init_locals, "CURRENT_RUSTC_VERSION", None), /// Allows specifying nop padding on functions for dynamic patching. (unstable, patchable_function_entry, "1.81.0", Some(123115)), /// Experimental features that make `Pin` more ergonomic. diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index e7c7d59248700..4b37642bb4fb6 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -941,6 +941,14 @@ impl<'tcx> TyCtxt<'tcx> { | ty::AliasTermKind::ProjectionConst => None, } } + + pub fn ty_can_partial_init_locals(self, ty: Ty<'tcx>) -> bool { + match ty.kind() { + ty::Tuple(..) => true, + ty::Adt(def, _) => !def.has_dtor(self), + _ => false, + } + } } struct OpaqueTypeExpander<'tcx> { diff --git a/compiler/rustc_mir_dataflow/src/drop_flag_effects.rs b/compiler/rustc_mir_dataflow/src/drop_flag_effects.rs index 1402a1a8b9136..54b1033d7038b 100644 --- a/compiler/rustc_mir_dataflow/src/drop_flag_effects.rs +++ b/compiler/rustc_mir_dataflow/src/drop_flag_effects.rs @@ -62,6 +62,7 @@ pub fn on_lookup_result_bits<'tcx, F>( } } +/// Invoke `each_child` on each of the **descendants** of the `move_path_index`. pub fn on_all_children_bits<'tcx, F>( move_data: &MoveData<'tcx>, move_path_index: MovePathIndex, diff --git a/compiler/rustc_mir_dataflow/src/impls/initialized.rs b/compiler/rustc_mir_dataflow/src/impls/initialized.rs index dee08d34427fe..4fa8699b1ef04 100644 --- a/compiler/rustc_mir_dataflow/src/impls/initialized.rs +++ b/compiler/rustc_mir_dataflow/src/impls/initialized.rs @@ -341,13 +341,55 @@ impl<'a, 'tcx> MaybeInitializedPlaces<'a, 'tcx> { impl<'tcx> MaybeUninitializedPlaces<'_, 'tcx> { fn update_bits( + &self, state: &mut >::Domain, path: MovePathIndex, dfstate: DropFlagState, ) { + let partial_init_locals = self.tcx.features().partial_init_locals(); match dfstate { DropFlagState::Absent => state.gen_(path), - DropFlagState::Present => state.kill(path), + DropFlagState::Present => { + if partial_init_locals { + self.kill_partial_init_ancestors(state, path); + } else { + state.kill(path); + } + } + } + } + + /// Kill ancestors on the move path, which has no destructor and all children are definitely + /// initialised. + /// + /// Call this function only when the language feature is enabled. + #[instrument(level = "debug", skip_all)] + fn kill_partial_init_ancestors( + &self, + state: &mut >::Domain, + mut path: MovePathIndex, + ) { + loop { + state.kill(path); + debug!(?path, "kill"); + path = if let Some(parent) = self.move_data.move_paths[path].parent { + parent + } else { + break; + }; + if !self.tcx.ty_can_partial_init_locals( + self.move_data.move_paths[path].place.ty(self.body, self.tcx).ty, + ) { + break; + } + let mut child = self.move_data.move_paths[path].first_child; + while let Some(child_mpi) = child { + if state.contains(child_mpi) { + debug!(?child_mpi, "found uninit, bail"); + return; + } + child = self.move_data.move_paths[child_mpi].next_sibling; + } } } } @@ -519,7 +561,7 @@ impl<'tcx> Analysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> { location: Location, ) { drop_flag_effects_for_location(self.body, self.move_data, location, |path, s| { - Self::update_bits(state, path, s) + self.update_bits(state, path, s) }); // Unlike in `MaybeInitializedPlaces` above, we don't need to change the state when a @@ -533,7 +575,7 @@ impl<'tcx> Analysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> { location: Location, ) -> TerminatorEdges<'mir, 'tcx> { drop_flag_effects_for_location(self.body, self.move_data, location, |path, s| { - Self::update_bits(state, path, s) + self.update_bits(state, path, s) }); if self.skip_unreachable_unwind.contains(location.block) { let mir::TerminatorKind::Drop { target, unwind, .. } = terminator.kind else { bug!() }; @@ -550,6 +592,7 @@ impl<'tcx> Analysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> { _block: mir::BasicBlock, return_places: CallReturnPlaces<'_, 'tcx>, ) { + let partial_init_locals = self.tcx.features().partial_init_locals(); return_places.for_each(|place| { // when a call returns successfully, that means we need to set // the bits for that dest_place to 0 (initialized). @@ -557,7 +600,11 @@ impl<'tcx> Analysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> { self.move_data(), self.move_data().rev_lookup.find(place.as_ref()), |mpi| { - state.kill(mpi); + if partial_init_locals { + self.kill_partial_init_ancestors(state, mpi); + } else { + state.kill(mpi); + } }, ); }); diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs index 224abf6901b33..5ff91da421a2a 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs @@ -574,7 +574,7 @@ impl<'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> MoveDataBuilder<'a, 'tcx, F> { } } - if let LookupResult::Exact(path) = self.data.rev_lookup.find(place) { + if let LookupResult::Exact(mut path) = self.data.rev_lookup.find(place) { let init = self.data.inits.push(Init { location: InitLocation::Statement(self.loc), path, @@ -588,6 +588,20 @@ impl<'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> MoveDataBuilder<'a, 'tcx, F> { self.data.init_path_map[path].push(init); self.data.init_loc_map[self.loc].push(init); + + // NOTE(partial_init_locals): + // Note that we can walk the partial init'ed paths and attach the init indices, + // so that they could be considered, albeit partially, ever-initialised. + if self.tcx.features().partial_init_locals() { + while let Some(parent) = self.data.move_paths[path].parent { + path = parent; + let place = self.data.move_paths[path].place; + if !self.tcx.ty_can_partial_init_locals(place.ty(self.body, self.tcx).ty) { + break; + } + self.data.init_path_map[path].push(init); + } + } } } } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 257ac3f51c2c1..1f6f7d6dfdb95 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1477,6 +1477,7 @@ symbols! { param_attrs, parent_label, partial_cmp, + partial_init_locals, partial_ord, passes, pat, diff --git a/tests/ui/async-await/partial-initialization-across-await.rs b/tests/ui/async-await/partial-initialization-across-await.rs index b355739f70b3b..cbfce631f3bb0 100644 --- a/tests/ui/async-await/partial-initialization-across-await.rs +++ b/tests/ui/async-await/partial-initialization-across-await.rs @@ -11,6 +11,7 @@ async fn noop() {} async fn test_tuple() { let mut t: (i32, i32); t.0 = 42; //~ ERROR E0381 + //~^ ERROR E0658 noop().await; t.1 = 88; let _ = t; @@ -19,6 +20,7 @@ async fn test_tuple() { async fn test_tuple_struct() { let mut t: T; t.0 = 42; //~ ERROR E0381 + //~^ ERROR E0658 noop().await; t.1 = 88; let _ = t; @@ -27,6 +29,7 @@ async fn test_tuple_struct() { async fn test_struct() { let mut t: S; t.x = 42; //~ ERROR E0381 + //~^ ERROR E0658 noop().await; t.y = 88; let _ = t; diff --git a/tests/ui/async-await/partial-initialization-across-await.stderr b/tests/ui/async-await/partial-initialization-across-await.stderr index 6a0eeffb94611..22f65e99b09bf 100644 --- a/tests/ui/async-await/partial-initialization-across-await.stderr +++ b/tests/ui/async-await/partial-initialization-across-await.stderr @@ -1,3 +1,12 @@ +error[E0658]: #![feature(partial_init_locals)] might be able to enable the initialisation here + --> $DIR/partial-initialization-across-await.rs:13:5 + | +LL | t.0 = 42; + | ^^^^^^^^ + | + = help: add `#![feature(partial_init_locals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + error[E0381]: partially assigned binding `t` isn't fully initialized --> $DIR/partial-initialization-across-await.rs:13:5 | @@ -8,8 +17,17 @@ LL | t.0 = 42; | = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` +error[E0658]: #![feature(partial_init_locals)] might be able to enable the initialisation here + --> $DIR/partial-initialization-across-await.rs:22:5 + | +LL | t.0 = 42; + | ^^^^^^^^ + | + = help: add `#![feature(partial_init_locals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + error[E0381]: partially assigned binding `t` isn't fully initialized - --> $DIR/partial-initialization-across-await.rs:21:5 + --> $DIR/partial-initialization-across-await.rs:22:5 | LL | let mut t: T; | ----- binding declared here but left uninitialized @@ -18,8 +36,17 @@ LL | t.0 = 42; | = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` +error[E0658]: #![feature(partial_init_locals)] might be able to enable the initialisation here + --> $DIR/partial-initialization-across-await.rs:31:5 + | +LL | t.x = 42; + | ^^^^^^^^ + | + = help: add `#![feature(partial_init_locals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + error[E0381]: partially assigned binding `t` isn't fully initialized - --> $DIR/partial-initialization-across-await.rs:29:5 + --> $DIR/partial-initialization-across-await.rs:31:5 | LL | let mut t: S; | ----- binding declared here but left uninitialized @@ -28,6 +55,7 @@ LL | t.x = 42; | = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` -error: aborting due to 3 previous errors +error: aborting due to 6 previous errors -For more information about this error, try `rustc --explain E0381`. +Some errors have detailed explanations: E0381, E0658. +For more information about an error, try `rustc --explain E0381`. diff --git a/tests/ui/borrowck/assign_mutable_fields.rs b/tests/ui/borrowck/assign_mutable_fields.rs index b60726d0c8b38..75b19d1e0cac9 100644 --- a/tests/ui/borrowck/assign_mutable_fields.rs +++ b/tests/ui/borrowck/assign_mutable_fields.rs @@ -6,7 +6,9 @@ fn assign_both_fields_and_use() { let mut x: (u32, u32); - x.0 = 1; //~ ERROR + x.0 = 1; + //~^ ERROR E0381 + //~| ERROR E0658 x.1 = 22; drop(x.0); drop(x.1); @@ -14,9 +16,11 @@ fn assign_both_fields_and_use() { fn assign_both_fields_the_use_var() { let mut x: (u32, u32); - x.0 = 1; //~ ERROR + x.0 = 1; + //~^ ERROR E0381 + //~| ERROR E0658 x.1 = 22; drop(x); } -fn main() { } +fn main() {} diff --git a/tests/ui/borrowck/assign_mutable_fields.stderr b/tests/ui/borrowck/assign_mutable_fields.stderr index 1ed92865da55b..9aa9998d3aafe 100644 --- a/tests/ui/borrowck/assign_mutable_fields.stderr +++ b/tests/ui/borrowck/assign_mutable_fields.stderr @@ -1,3 +1,12 @@ +error[E0658]: #![feature(partial_init_locals)] might be able to enable the initialisation here + --> $DIR/assign_mutable_fields.rs:9:5 + | +LL | x.0 = 1; + | ^^^^^^^ + | + = help: add `#![feature(partial_init_locals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + error[E0381]: partially assigned binding `x` isn't fully initialized --> $DIR/assign_mutable_fields.rs:9:5 | @@ -8,8 +17,17 @@ LL | x.0 = 1; | = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` +error[E0658]: #![feature(partial_init_locals)] might be able to enable the initialisation here + --> $DIR/assign_mutable_fields.rs:19:5 + | +LL | x.0 = 1; + | ^^^^^^^ + | + = help: add `#![feature(partial_init_locals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + error[E0381]: partially assigned binding `x` isn't fully initialized - --> $DIR/assign_mutable_fields.rs:17:5 + --> $DIR/assign_mutable_fields.rs:19:5 | LL | let mut x: (u32, u32); | ----- binding declared here but left uninitialized @@ -18,6 +36,7 @@ LL | x.0 = 1; | = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` -error: aborting due to 2 previous errors +error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0381`. +Some errors have detailed explanations: E0381, E0658. +For more information about an error, try `rustc --explain E0381`. diff --git a/tests/ui/borrowck/borrowck-field-sensitivity.rs b/tests/ui/borrowck/borrowck-field-sensitivity.rs index 03edf445ee97b..c390933757ce5 100644 --- a/tests/ui/borrowck/borrowck-field-sensitivity.rs +++ b/tests/ui/borrowck/borrowck-field-sensitivity.rs @@ -79,12 +79,14 @@ fn fu_move_after_fu_move() { fn copy_after_field_assign_after_uninit() { let mut x: A; x.a = 1; //~ ERROR E0381 + //~^ ERROR E0658 drop(x.a); } fn borrow_after_field_assign_after_uninit() { let mut x: A; x.a = 1; //~ ERROR E0381 + //~^ ERROR E0658 let p = &x.a; drop(*p); } @@ -92,6 +94,7 @@ fn borrow_after_field_assign_after_uninit() { fn move_after_field_assign_after_uninit() { let mut x: A; x.b = Box::new(1); //~ ERROR E0381 + //~^ ERROR E0658 drop(x.b); } diff --git a/tests/ui/borrowck/borrowck-field-sensitivity.stderr b/tests/ui/borrowck/borrowck-field-sensitivity.stderr index b30dd144a4d80..bc8fcdd7ba913 100644 --- a/tests/ui/borrowck/borrowck-field-sensitivity.stderr +++ b/tests/ui/borrowck/borrowck-field-sensitivity.stderr @@ -122,6 +122,15 @@ LL | let _z = A { a: 4, .. x }; | = note: move occurs because `x.b` has type `Box`, which does not implement the `Copy` trait +error[E0658]: #![feature(partial_init_locals)] might be able to enable the initialisation here + --> $DIR/borrowck-field-sensitivity.rs:81:5 + | +LL | x.a = 1; + | ^^^^^^^ + | + = help: add `#![feature(partial_init_locals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + error[E0381]: partially assigned binding `x` isn't fully initialized --> $DIR/borrowck-field-sensitivity.rs:81:5 | @@ -132,8 +141,17 @@ LL | x.a = 1; | = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` +error[E0658]: #![feature(partial_init_locals)] might be able to enable the initialisation here + --> $DIR/borrowck-field-sensitivity.rs:88:5 + | +LL | x.a = 1; + | ^^^^^^^ + | + = help: add `#![feature(partial_init_locals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + error[E0381]: partially assigned binding `x` isn't fully initialized - --> $DIR/borrowck-field-sensitivity.rs:87:5 + --> $DIR/borrowck-field-sensitivity.rs:88:5 | LL | let mut x: A; | ----- binding declared here but left uninitialized @@ -142,8 +160,17 @@ LL | x.a = 1; | = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` +error[E0658]: #![feature(partial_init_locals)] might be able to enable the initialisation here + --> $DIR/borrowck-field-sensitivity.rs:96:5 + | +LL | x.b = Box::new(1); + | ^^^ + | + = help: add `#![feature(partial_init_locals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + error[E0381]: partially assigned binding `x` isn't fully initialized - --> $DIR/borrowck-field-sensitivity.rs:94:5 + --> $DIR/borrowck-field-sensitivity.rs:96:5 | LL | let mut x: A; | ----- binding declared here but left uninitialized @@ -152,7 +179,7 @@ LL | x.b = Box::new(1); | = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` -error: aborting due to 14 previous errors +error: aborting due to 17 previous errors -Some errors have detailed explanations: E0381, E0382, E0499, E0505. +Some errors have detailed explanations: E0381, E0382, E0499, E0505, E0658. For more information about an error, try `rustc --explain E0381`. diff --git a/tests/ui/borrowck/borrowck-partial-reinit-4.rs b/tests/ui/borrowck/borrowck-partial-reinit-4.rs index a43a1936678ff..214e836c2e9a6 100644 --- a/tests/ui/borrowck/borrowck-partial-reinit-4.rs +++ b/tests/ui/borrowck/borrowck-partial-reinit-4.rs @@ -15,6 +15,7 @@ impl Drop for Test2 { fn stuff() { let mut x : (Test2, Test2); (x.0).0 = Some(Test); //~ ERROR E0381 + //~^ ERROR E0658 } fn main() { diff --git a/tests/ui/borrowck/borrowck-partial-reinit-4.stderr b/tests/ui/borrowck/borrowck-partial-reinit-4.stderr index 4833e689c19b3..c0f4d035cce95 100644 --- a/tests/ui/borrowck/borrowck-partial-reinit-4.stderr +++ b/tests/ui/borrowck/borrowck-partial-reinit-4.stderr @@ -1,3 +1,12 @@ +error[E0658]: #![feature(partial_init_locals)] might be able to enable the initialisation here + --> $DIR/borrowck-partial-reinit-4.rs:17:5 + | +LL | (x.0).0 = Some(Test); + | ^^^^^^^ + | + = help: add `#![feature(partial_init_locals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + error[E0381]: assigned binding `x.0` isn't fully initialized --> $DIR/borrowck-partial-reinit-4.rs:17:5 | @@ -8,6 +17,7 @@ LL | (x.0).0 = Some(Test); | = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` -error: aborting due to 1 previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0381`. +Some errors have detailed explanations: E0381, E0658. +For more information about an error, try `rustc --explain E0381`. diff --git a/tests/ui/borrowck/borrowck-uninit-ref-chain.rs b/tests/ui/borrowck/borrowck-uninit-ref-chain.rs index c36b9707d2287..3d2abdc78a56f 100644 --- a/tests/ui/borrowck/borrowck-uninit-ref-chain.rs +++ b/tests/ui/borrowck/borrowck-uninit-ref-chain.rs @@ -16,18 +16,22 @@ fn main() { let mut a: S; a.x = 0; //~ ERROR [E0381] + //~^ ERROR E0658 let _b = &a.x; let mut a: S<&&i32, &&i32>; a.x = &&0; //~ ERROR [E0381] + //~^ ERROR E0658 let _b = &**a.x; let mut a: S; a.x = 0; //~ ERROR [E0381] + //~^ ERROR E0658 let _b = &a.y; let mut a: S<&&i32, &&i32>; a.x = &&0; //~ ERROR [E0381] + //~^ ERROR E0658 let _b = &**a.y; } diff --git a/tests/ui/borrowck/borrowck-uninit-ref-chain.stderr b/tests/ui/borrowck/borrowck-uninit-ref-chain.stderr index b1d508e2ac395..8603880e634a5 100644 --- a/tests/ui/borrowck/borrowck-uninit-ref-chain.stderr +++ b/tests/ui/borrowck/borrowck-uninit-ref-chain.stderr @@ -1,3 +1,39 @@ +error[E0658]: #![feature(partial_init_locals)] might be able to enable the initialisation here + --> $DIR/borrowck-uninit-ref-chain.rs:18:5 + | +LL | a.x = 0; + | ^^^^^^^ + | + = help: add `#![feature(partial_init_locals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: #![feature(partial_init_locals)] might be able to enable the initialisation here + --> $DIR/borrowck-uninit-ref-chain.rs:23:5 + | +LL | a.x = &&0; + | ^^^^^^^^^ + | + = help: add `#![feature(partial_init_locals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: #![feature(partial_init_locals)] might be able to enable the initialisation here + --> $DIR/borrowck-uninit-ref-chain.rs:29:5 + | +LL | a.x = 0; + | ^^^^^^^ + | + = help: add `#![feature(partial_init_locals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: #![feature(partial_init_locals)] might be able to enable the initialisation here + --> $DIR/borrowck-uninit-ref-chain.rs:34:5 + | +LL | a.x = &&0; + | ^^^^^^^^^ + | + = help: add `#![feature(partial_init_locals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + error[E0381]: used binding `x` isn't initialized --> $DIR/borrowck-uninit-ref-chain.rs:8:14 | @@ -48,7 +84,7 @@ LL | a.x = 0; = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` error[E0381]: partially assigned binding `a` isn't fully initialized - --> $DIR/borrowck-uninit-ref-chain.rs:22:5 + --> $DIR/borrowck-uninit-ref-chain.rs:23:5 | LL | let mut a: S<&&i32, &&i32>; | ----- binding declared here but left uninitialized @@ -58,7 +94,7 @@ LL | a.x = &&0; = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` error[E0381]: partially assigned binding `a` isn't fully initialized - --> $DIR/borrowck-uninit-ref-chain.rs:27:5 + --> $DIR/borrowck-uninit-ref-chain.rs:29:5 | LL | let mut a: S; | ----- binding declared here but left uninitialized @@ -68,7 +104,7 @@ LL | a.x = 0; = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` error[E0381]: partially assigned binding `a` isn't fully initialized - --> $DIR/borrowck-uninit-ref-chain.rs:31:5 + --> $DIR/borrowck-uninit-ref-chain.rs:34:5 | LL | let mut a: S<&&i32, &&i32>; | ----- binding declared here but left uninitialized @@ -77,6 +113,7 @@ LL | a.x = &&0; | = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` -error: aborting due to 7 previous errors +error: aborting due to 11 previous errors -For more information about this error, try `rustc --explain E0381`. +Some errors have detailed explanations: E0381, E0658. +For more information about an error, try `rustc --explain E0381`. diff --git a/tests/ui/borrowck/borrowck-union-uninitialized.rs b/tests/ui/borrowck/borrowck-union-uninitialized.rs index bbe9f22aac307..3126b08a532e7 100644 --- a/tests/ui/borrowck/borrowck-union-uninitialized.rs +++ b/tests/ui/borrowck/borrowck-union-uninitialized.rs @@ -11,7 +11,9 @@ fn main() { let mut s: S; let mut u: U; s.a = 0; //~ ERROR E0381 + //~^ ERROR E0658 u.a = 0; //~ ERROR E0381 + //~^ ERROR E0658 let sa = s.a; let ua = u.a; } diff --git a/tests/ui/borrowck/borrowck-union-uninitialized.stderr b/tests/ui/borrowck/borrowck-union-uninitialized.stderr index b7ff5f3955ee5..efd9f19a52858 100644 --- a/tests/ui/borrowck/borrowck-union-uninitialized.stderr +++ b/tests/ui/borrowck/borrowck-union-uninitialized.stderr @@ -1,3 +1,21 @@ +error[E0658]: #![feature(partial_init_locals)] might be able to enable the initialisation here + --> $DIR/borrowck-union-uninitialized.rs:13:9 + | +LL | s.a = 0; + | ^^^^^^^ + | + = help: add `#![feature(partial_init_locals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: #![feature(partial_init_locals)] might be able to enable the initialisation here + --> $DIR/borrowck-union-uninitialized.rs:15:9 + | +LL | u.a = 0; + | ^^^^^^^ + | + = help: add `#![feature(partial_init_locals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + error[E0381]: partially assigned binding `s` isn't fully initialized --> $DIR/borrowck-union-uninitialized.rs:13:9 | @@ -10,16 +28,17 @@ LL | s.a = 0; = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` error[E0381]: partially assigned binding `u` isn't fully initialized - --> $DIR/borrowck-union-uninitialized.rs:14:9 + --> $DIR/borrowck-union-uninitialized.rs:15:9 | LL | let mut u: U; | ----- binding declared here but left uninitialized -LL | s.a = 0; +... LL | u.a = 0; | ^^^^^^^ `u` partially assigned here but it isn't fully initialized | = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` -error: aborting due to 2 previous errors +error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0381`. +Some errors have detailed explanations: E0381, E0658. +For more information about an error, try `rustc --explain E0381`. diff --git a/tests/ui/borrowck/disallow-possibly-uninitialized.classic.stderr b/tests/ui/borrowck/disallow-possibly-uninitialized.classic.stderr new file mode 100644 index 0000000000000..11aca50aa259f --- /dev/null +++ b/tests/ui/borrowck/disallow-possibly-uninitialized.classic.stderr @@ -0,0 +1,80 @@ +error[E0658]: #![feature(partial_init_locals)] might be able to enable the initialisation here + --> $DIR/disallow-possibly-uninitialized.rs:11:5 + | +LL | t.0 = 1; + | ^^^^^^^ + | + = help: add `#![feature(partial_init_locals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: #![feature(partial_init_locals)] might be able to enable the initialisation here + --> $DIR/disallow-possibly-uninitialized.rs:17:5 + | +LL | t.1 = 1; + | ^^^^^^^ + | + = help: add `#![feature(partial_init_locals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: #![feature(partial_init_locals)] might be able to enable the initialisation here + --> $DIR/disallow-possibly-uninitialized.rs:23:5 + | +LL | t.0 = 1; + | ^^^^^^^ + | + = help: add `#![feature(partial_init_locals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: #![feature(partial_init_locals)] might be able to enable the initialisation here + --> $DIR/disallow-possibly-uninitialized.rs:28:5 + | +LL | t.0 = 1; + | ^^^^^^^ + | + = help: add `#![feature(partial_init_locals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0381]: partially assigned binding `t` isn't fully initialized + --> $DIR/disallow-possibly-uninitialized.rs:11:5 + | +LL | let mut t: (u64, u64); + | ----- binding declared here but left uninitialized +LL | t.0 = 1; + | ^^^^^^^ `t` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` + +error[E0381]: partially assigned binding `t` isn't fully initialized + --> $DIR/disallow-possibly-uninitialized.rs:17:5 + | +LL | let mut t: (u64, u64); + | ----- binding declared here but left uninitialized +LL | t.1 = 1; + | ^^^^^^^ `t` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` + +error[E0381]: partially assigned binding `t` isn't fully initialized + --> $DIR/disallow-possibly-uninitialized.rs:23:5 + | +LL | let mut t: (u64, u64); + | ----- binding declared here but left uninitialized +LL | t.0 = 1; + | ^^^^^^^ `t` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` + +error[E0381]: partially assigned binding `t` isn't fully initialized + --> $DIR/disallow-possibly-uninitialized.rs:28:5 + | +LL | let mut t: (u64,); + | ----- binding declared here but left uninitialized +LL | t.0 = 1; + | ^^^^^^^ `t` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` + +error: aborting due to 8 previous errors + +Some errors have detailed explanations: E0381, E0658. +For more information about an error, try `rustc --explain E0381`. diff --git a/tests/ui/borrowck/disallow-possibly-uninitialized.rs b/tests/ui/borrowck/disallow-possibly-uninitialized.rs index 17de40d5ba967..7578a6d2f411f 100644 --- a/tests/ui/borrowck/disallow-possibly-uninitialized.rs +++ b/tests/ui/borrowck/disallow-possibly-uninitialized.rs @@ -1,22 +1,31 @@ +//@ revisions: classic partial_init +//@[partial_init] check-pass + // Test that we don't allow partial initialization. // This may be relaxed in the future (see #54987). +#![cfg_attr(partial_init, feature(partial_init_locals))] + fn main() { let mut t: (u64, u64); t.0 = 1; - //~^ ERROR E0381 + //[classic]~^ ERROR E0381 + //[classic]~| ERROR E0658 t.1 = 1; let mut t: (u64, u64); t.1 = 1; - //~^ ERROR E0381 + //[classic]~^ ERROR E0381 + //[classic]~| ERROR E0658 t.0 = 1; let mut t: (u64, u64); t.0 = 1; - //~^ ERROR E0381 + //[classic]~^ ERROR E0381 + //[classic]~| ERROR E0658 let mut t: (u64,); t.0 = 1; - //~^ ERROR E0381 + //[classic]~^ ERROR E0381 + //[classic]~| ERROR E0658 } diff --git a/tests/ui/borrowck/disallow-possibly-uninitialized.stderr b/tests/ui/borrowck/disallow-possibly-uninitialized.stderr deleted file mode 100644 index 9a84c6fefae59..0000000000000 --- a/tests/ui/borrowck/disallow-possibly-uninitialized.stderr +++ /dev/null @@ -1,43 +0,0 @@ -error[E0381]: partially assigned binding `t` isn't fully initialized - --> $DIR/disallow-possibly-uninitialized.rs:6:5 - | -LL | let mut t: (u64, u64); - | ----- binding declared here but left uninitialized -LL | t.0 = 1; - | ^^^^^^^ `t` partially assigned here but it isn't fully initialized - | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` - -error[E0381]: partially assigned binding `t` isn't fully initialized - --> $DIR/disallow-possibly-uninitialized.rs:11:5 - | -LL | let mut t: (u64, u64); - | ----- binding declared here but left uninitialized -LL | t.1 = 1; - | ^^^^^^^ `t` partially assigned here but it isn't fully initialized - | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` - -error[E0381]: partially assigned binding `t` isn't fully initialized - --> $DIR/disallow-possibly-uninitialized.rs:16:5 - | -LL | let mut t: (u64, u64); - | ----- binding declared here but left uninitialized -LL | t.0 = 1; - | ^^^^^^^ `t` partially assigned here but it isn't fully initialized - | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` - -error[E0381]: partially assigned binding `t` isn't fully initialized - --> $DIR/disallow-possibly-uninitialized.rs:20:5 - | -LL | let mut t: (u64,); - | ----- binding declared here but left uninitialized -LL | t.0 = 1; - | ^^^^^^^ `t` partially assigned here but it isn't fully initialized - | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` - -error: aborting due to 4 previous errors - -For more information about this error, try `rustc --explain E0381`. diff --git a/tests/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.classic.stderr b/tests/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.classic.stderr new file mode 100644 index 0000000000000..2c2b757c8c777 --- /dev/null +++ b/tests/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.classic.stderr @@ -0,0 +1,61 @@ +error[E0658]: #![feature(partial_init_locals)] might be able to enable the initialisation here + --> $DIR/issue-54499-field-mutation-marks-mut-as-used.rs:19:9 + | +LL | t.0 = S(1); + | ^^^^^^^^^^ + | + = help: add `#![feature(partial_init_locals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: #![feature(partial_init_locals)] might be able to enable the initialisation here + --> $DIR/issue-54499-field-mutation-marks-mut-as-used.rs:29:9 + | +LL | u.0 = S(1); + | ^^^^^^^^^^ + | + = help: add `#![feature(partial_init_locals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: #![feature(partial_init_locals)] might be able to enable the initialisation here + --> $DIR/issue-54499-field-mutation-marks-mut-as-used.rs:38:9 + | +LL | v.x = S(1); + | ^^^^^^^^^^ + | + = help: add `#![feature(partial_init_locals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0381]: partially assigned binding `t` isn't fully initialized + --> $DIR/issue-54499-field-mutation-marks-mut-as-used.rs:19:9 + | +LL | let mut t: Tuple; + | ----- binding declared here but left uninitialized +LL | t.0 = S(1); + | ^^^^^^^^^^ `t` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` + +error[E0381]: partially assigned binding `u` isn't fully initialized + --> $DIR/issue-54499-field-mutation-marks-mut-as-used.rs:29:9 + | +LL | let mut u: Tpair; + | ----- binding declared here but left uninitialized +LL | u.0 = S(1); + | ^^^^^^^^^^ `u` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` + +error[E0381]: partially assigned binding `v` isn't fully initialized + --> $DIR/issue-54499-field-mutation-marks-mut-as-used.rs:38:9 + | +LL | let mut v: Spair; + | ----- binding declared here but left uninitialized +LL | v.x = S(1); + | ^^^^^^^^^^ `v` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0381, E0658. +For more information about an error, try `rustc --explain E0381`. diff --git a/tests/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.rs b/tests/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.rs index 205ea10c90bf0..f2930fbcedd15 100644 --- a/tests/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.rs +++ b/tests/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.rs @@ -1,24 +1,34 @@ +//@ revisions: classic partial_init +//@[partial_init] check-pass + +#![cfg_attr(partial_init, feature(partial_init_locals))] #![warn(unused)] #[derive(Debug)] struct S(i32); type Tuple = (S, i32); struct Tpair(S, i32); -struct Spair { x: S, y: i32 } +struct Spair { + x: S, + y: i32, +} fn main() { { let mut t: Tuple; t.0 = S(1); - //~^ ERROR E0381 + //[classic]~^ ERROR E0381 + //[classic]~| ERROR E0658 t.1 = 2; - println!("{:?} {:?}", t.0, t.1); + t.0 = S(2); + println!("{:?} {:?}", t.0.0, t.1); } { let mut u: Tpair; u.0 = S(1); - //~^ ERROR E0381 + //[classic]~^ ERROR E0381 + //[classic]~| ERROR E0658 u.1 = 2; println!("{:?} {:?}", u.0, u.1); } @@ -26,7 +36,8 @@ fn main() { { let mut v: Spair; v.x = S(1); - //~^ ERROR E0381 + //[classic]~^ ERROR E0381 + //[classic]~| ERROR E0658 v.y = 2; println!("{:?} {:?}", v.x, v.y); } diff --git a/tests/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.stderr b/tests/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.stderr deleted file mode 100644 index 2a0eba396f144..0000000000000 --- a/tests/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.stderr +++ /dev/null @@ -1,33 +0,0 @@ -error[E0381]: partially assigned binding `t` isn't fully initialized - --> $DIR/issue-54499-field-mutation-marks-mut-as-used.rs:12:9 - | -LL | let mut t: Tuple; - | ----- binding declared here but left uninitialized -LL | t.0 = S(1); - | ^^^^^^^^^^ `t` partially assigned here but it isn't fully initialized - | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` - -error[E0381]: partially assigned binding `u` isn't fully initialized - --> $DIR/issue-54499-field-mutation-marks-mut-as-used.rs:20:9 - | -LL | let mut u: Tpair; - | ----- binding declared here but left uninitialized -LL | u.0 = S(1); - | ^^^^^^^^^^ `u` partially assigned here but it isn't fully initialized - | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` - -error[E0381]: partially assigned binding `v` isn't fully initialized - --> $DIR/issue-54499-field-mutation-marks-mut-as-used.rs:28:9 - | -LL | let mut v: Spair; - | ----- binding declared here but left uninitialized -LL | v.x = S(1); - | ^^^^^^^^^^ `v` partially assigned here but it isn't fully initialized - | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0381`. diff --git a/tests/ui/borrowck/issue-54499-field-mutation-of-never-init.classic.stderr b/tests/ui/borrowck/issue-54499-field-mutation-of-never-init.classic.stderr new file mode 100644 index 0000000000000..3b059abe0a899 --- /dev/null +++ b/tests/ui/borrowck/issue-54499-field-mutation-of-never-init.classic.stderr @@ -0,0 +1,61 @@ +error[E0658]: #![feature(partial_init_locals)] might be able to enable the initialisation here + --> $DIR/issue-54499-field-mutation-of-never-init.rs:19:9 + | +LL | t.0 = S(1); + | ^^^^^^^^^^ + | + = help: add `#![feature(partial_init_locals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: #![feature(partial_init_locals)] might be able to enable the initialisation here + --> $DIR/issue-54499-field-mutation-of-never-init.rs:28:9 + | +LL | u.0 = S(1); + | ^^^^^^^^^^ + | + = help: add `#![feature(partial_init_locals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: #![feature(partial_init_locals)] might be able to enable the initialisation here + --> $DIR/issue-54499-field-mutation-of-never-init.rs:37:9 + | +LL | v.x = S(1); + | ^^^^^^^^^^ + | + = help: add `#![feature(partial_init_locals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0381]: partially assigned binding `t` isn't fully initialized + --> $DIR/issue-54499-field-mutation-of-never-init.rs:19:9 + | +LL | let t: Tuple; + | - binding declared here but left uninitialized +LL | t.0 = S(1); + | ^^^^^^^^^^ `t` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` + +error[E0381]: partially assigned binding `u` isn't fully initialized + --> $DIR/issue-54499-field-mutation-of-never-init.rs:28:9 + | +LL | let u: Tpair; + | - binding declared here but left uninitialized +LL | u.0 = S(1); + | ^^^^^^^^^^ `u` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` + +error[E0381]: partially assigned binding `v` isn't fully initialized + --> $DIR/issue-54499-field-mutation-of-never-init.rs:37:9 + | +LL | let v: Spair; + | - binding declared here but left uninitialized +LL | v.x = S(1); + | ^^^^^^^^^^ `v` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0381, E0658. +For more information about an error, try `rustc --explain E0381`. diff --git a/tests/ui/borrowck/issue-54499-field-mutation-of-never-init.rs b/tests/ui/borrowck/issue-54499-field-mutation-of-never-init.rs index 50d0c40fdf6f5..b05b8b6238e6f 100644 --- a/tests/ui/borrowck/issue-54499-field-mutation-of-never-init.rs +++ b/tests/ui/borrowck/issue-54499-field-mutation-of-never-init.rs @@ -1,24 +1,33 @@ +//@ revisions: classic partial_init +//@[partial_init] check-pass + +#![cfg_attr(partial_init, feature(partial_init_locals))] #![warn(unused)] #[derive(Debug)] struct S(i32); type Tuple = (S, i32); struct Tpair(S, i32); -struct Spair { x: S, y: i32 } +struct Spair { + x: S, + y: i32, +} fn main() { { let t: Tuple; t.0 = S(1); - //~^ ERROR E0381 + //[classic]~^ ERROR E0381 + //[classic]~| ERROR E0658 t.1 = 2; - println!("{:?} {:?}", t.0, t.1); + println!("{:?} {:?}", t.0.0, t.1); } { let u: Tpair; u.0 = S(1); - //~^ ERROR E0381 + //[classic]~^ ERROR E0381 + //[classic]~| ERROR E0658 u.1 = 2; println!("{:?} {:?}", u.0, u.1); } @@ -26,7 +35,8 @@ fn main() { { let v: Spair; v.x = S(1); - //~^ ERROR E0381 + //[classic]~^ ERROR E0381 + //[classic]~| ERROR E0658 v.y = 2; println!("{:?} {:?}", v.x, v.y); } diff --git a/tests/ui/borrowck/issue-54499-field-mutation-of-never-init.stderr b/tests/ui/borrowck/issue-54499-field-mutation-of-never-init.stderr deleted file mode 100644 index 67a62583057f6..0000000000000 --- a/tests/ui/borrowck/issue-54499-field-mutation-of-never-init.stderr +++ /dev/null @@ -1,33 +0,0 @@ -error[E0381]: partially assigned binding `t` isn't fully initialized - --> $DIR/issue-54499-field-mutation-of-never-init.rs:12:9 - | -LL | let t: Tuple; - | - binding declared here but left uninitialized -LL | t.0 = S(1); - | ^^^^^^^^^^ `t` partially assigned here but it isn't fully initialized - | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` - -error[E0381]: partially assigned binding `u` isn't fully initialized - --> $DIR/issue-54499-field-mutation-of-never-init.rs:20:9 - | -LL | let u: Tpair; - | - binding declared here but left uninitialized -LL | u.0 = S(1); - | ^^^^^^^^^^ `u` partially assigned here but it isn't fully initialized - | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` - -error[E0381]: partially assigned binding `v` isn't fully initialized - --> $DIR/issue-54499-field-mutation-of-never-init.rs:28:9 - | -LL | let v: Spair; - | - binding declared here but left uninitialized -LL | v.x = S(1); - | ^^^^^^^^^^ `v` partially assigned here but it isn't fully initialized - | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0381`. diff --git a/tests/ui/borrowck/partial-init-locals.rs b/tests/ui/borrowck/partial-init-locals.rs new file mode 100644 index 0000000000000..3bcd7135c9902 --- /dev/null +++ b/tests/ui/borrowck/partial-init-locals.rs @@ -0,0 +1,26 @@ +#![feature(partial_init_locals)] + +struct A(u8); +struct B(A); +struct C(B); + +impl Drop for C { + fn drop(&mut self) {} +} + +fn foo() -> u8 { + 2 +} + +fn main() { + let a: A; + a.0 = 1; + let _ = &a.0; + let _ = &a; + let b: B; + b.0.0 = foo(); + let _ = &b; + + let c: C; + c.0.0.0 = 1; //~ ERROR: assigned binding `c` isn't fully initialized +} diff --git a/tests/ui/borrowck/partial-init-locals.stderr b/tests/ui/borrowck/partial-init-locals.stderr new file mode 100644 index 0000000000000..34400412f3f4e --- /dev/null +++ b/tests/ui/borrowck/partial-init-locals.stderr @@ -0,0 +1,13 @@ +error[E0381]: assigned binding `c` isn't fully initialized + --> $DIR/partial-init-locals.rs:25:5 + | +LL | let c: C; + | - binding declared here but left uninitialized +LL | c.0.0.0 = 1; + | ^^^^^^^^^^^ `c` assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0381`. diff --git a/tests/ui/borrowck/reassignment_immutable_fields.rs b/tests/ui/borrowck/reassignment_immutable_fields.rs index fd2ab62a40f1d..cfbfbf33a7260 100644 --- a/tests/ui/borrowck/reassignment_immutable_fields.rs +++ b/tests/ui/borrowck/reassignment_immutable_fields.rs @@ -4,7 +4,8 @@ fn assign_both_fields_and_use() { let x: (u32, u32); - x.0 = 1; //~ ERROR + x.0 = 1; //~ ERROR E0658 + //~^ ERROR E0381 x.1 = 22; drop(x.0); drop(x.1); @@ -12,7 +13,8 @@ fn assign_both_fields_and_use() { fn assign_both_fields_the_use_var() { let x: (u32, u32); - x.0 = 1; //~ ERROR + x.0 = 1; //~ ERROR E0658 + //~^ ERROR E0381 x.1 = 22; drop(x); } diff --git a/tests/ui/borrowck/reassignment_immutable_fields.stderr b/tests/ui/borrowck/reassignment_immutable_fields.stderr index e6b25573e7040..7d87b731db8a1 100644 --- a/tests/ui/borrowck/reassignment_immutable_fields.stderr +++ b/tests/ui/borrowck/reassignment_immutable_fields.stderr @@ -1,3 +1,12 @@ +error[E0658]: #![feature(partial_init_locals)] might be able to enable the initialisation here + --> $DIR/reassignment_immutable_fields.rs:7:5 + | +LL | x.0 = 1; + | ^^^^^^^ + | + = help: add `#![feature(partial_init_locals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + error[E0381]: partially assigned binding `x` isn't fully initialized --> $DIR/reassignment_immutable_fields.rs:7:5 | @@ -8,8 +17,17 @@ LL | x.0 = 1; | = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` +error[E0658]: #![feature(partial_init_locals)] might be able to enable the initialisation here + --> $DIR/reassignment_immutable_fields.rs:16:5 + | +LL | x.0 = 1; + | ^^^^^^^ + | + = help: add `#![feature(partial_init_locals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + error[E0381]: partially assigned binding `x` isn't fully initialized - --> $DIR/reassignment_immutable_fields.rs:15:5 + --> $DIR/reassignment_immutable_fields.rs:16:5 | LL | let x: (u32, u32); | - binding declared here but left uninitialized @@ -18,6 +36,7 @@ LL | x.0 = 1; | = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` -error: aborting due to 2 previous errors +error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0381`. +Some errors have detailed explanations: E0381, E0658. +For more information about an error, try `rustc --explain E0381`. diff --git a/tests/ui/borrowck/reassignment_immutable_fields_overlapping.rs b/tests/ui/borrowck/reassignment_immutable_fields_overlapping.rs index d7aad6c01bd26..e1e18b86913f2 100644 --- a/tests/ui/borrowck/reassignment_immutable_fields_overlapping.rs +++ b/tests/ui/borrowck/reassignment_immutable_fields_overlapping.rs @@ -9,7 +9,8 @@ union Foo { unsafe fn overlapping_fields() { let x: Foo; - x.a = 1; //~ ERROR + x.a = 1; //~ ERROR E0658 + //~^ ERROR E0381 x.b = 22; //~ ERROR } diff --git a/tests/ui/borrowck/reassignment_immutable_fields_overlapping.stderr b/tests/ui/borrowck/reassignment_immutable_fields_overlapping.stderr index 81e5bc45d4d38..46326454ce1b3 100644 --- a/tests/ui/borrowck/reassignment_immutable_fields_overlapping.stderr +++ b/tests/ui/borrowck/reassignment_immutable_fields_overlapping.stderr @@ -1,3 +1,12 @@ +error[E0658]: #![feature(partial_init_locals)] might be able to enable the initialisation here + --> $DIR/reassignment_immutable_fields_overlapping.rs:12:5 + | +LL | x.a = 1; + | ^^^^^^^ + | + = help: add `#![feature(partial_init_locals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + error[E0381]: partially assigned binding `x` isn't fully initialized --> $DIR/reassignment_immutable_fields_overlapping.rs:12:5 | @@ -9,7 +18,7 @@ LL | x.a = 1; = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` error[E0594]: cannot assign to `x.b`, as `x` is not declared as mutable - --> $DIR/reassignment_immutable_fields_overlapping.rs:13:5 + --> $DIR/reassignment_immutable_fields_overlapping.rs:14:5 | LL | x.b = 22; | ^^^^^^^^ cannot assign @@ -19,7 +28,7 @@ help: consider changing this to be mutable LL | let mut x: Foo; | +++ -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0381, E0594. +Some errors have detailed explanations: E0381, E0594, E0658. For more information about an error, try `rustc --explain E0381`. diff --git a/tests/ui/borrowck/reassignment_immutable_fields_twice.rs b/tests/ui/borrowck/reassignment_immutable_fields_twice.rs index 2775a54c8304b..5d92d5cbed5db 100644 --- a/tests/ui/borrowck/reassignment_immutable_fields_twice.rs +++ b/tests/ui/borrowck/reassignment_immutable_fields_twice.rs @@ -9,9 +9,11 @@ fn var_then_field() { fn same_field_twice() { let x: (u32, u32); - x.0 = 1; //~ ERROR + x.0 = 1; + //~^ ERROR + //~| ERROR E0381 x.0 = 22; x.1 = 44; } -fn main() { } +fn main() {} diff --git a/tests/ui/borrowck/reassignment_immutable_fields_twice.stderr b/tests/ui/borrowck/reassignment_immutable_fields_twice.stderr index ba0457809ad43..e5cb9d9ae045a 100644 --- a/tests/ui/borrowck/reassignment_immutable_fields_twice.stderr +++ b/tests/ui/borrowck/reassignment_immutable_fields_twice.stderr @@ -9,6 +9,15 @@ help: consider changing this to be mutable LL | let mut x: (u32, u32); | +++ +error[E0658]: #![feature(partial_init_locals)] might be able to enable the initialisation here + --> $DIR/reassignment_immutable_fields_twice.rs:12:5 + | +LL | x.0 = 1; + | ^^^^^^^ + | + = help: add `#![feature(partial_init_locals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + error[E0381]: partially assigned binding `x` isn't fully initialized --> $DIR/reassignment_immutable_fields_twice.rs:12:5 | @@ -19,7 +28,7 @@ LL | x.0 = 1; | = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0381, E0594. +Some errors have detailed explanations: E0381, E0594, E0658. For more information about an error, try `rustc --explain E0381`. diff --git a/tests/ui/coroutine/partial-initialization-across-yield.rs b/tests/ui/coroutine/partial-initialization-across-yield.rs index ab6f9c5b1e981..62254abe7ad47 100644 --- a/tests/ui/coroutine/partial-initialization-across-yield.rs +++ b/tests/ui/coroutine/partial-initialization-across-yield.rs @@ -10,6 +10,7 @@ fn test_tuple() { let _ = #[coroutine] || { let mut t: (i32, i32); t.0 = 42; //~ ERROR E0381 + //~^ ERROR E0658 yield; t.1 = 88; let _ = t; @@ -20,6 +21,7 @@ fn test_tuple_struct() { let _ = #[coroutine] || { let mut t: T; t.0 = 42; //~ ERROR E0381 + //~^ ERROR E0658 yield; t.1 = 88; let _ = t; @@ -30,6 +32,7 @@ fn test_struct() { let _ = #[coroutine] || { let mut t: S; t.x = 42; //~ ERROR E0381 + //~^ ERROR E0658 yield; t.y = 88; let _ = t; diff --git a/tests/ui/coroutine/partial-initialization-across-yield.stderr b/tests/ui/coroutine/partial-initialization-across-yield.stderr index 3f9f1c046ba4b..98d7eb77b0d62 100644 --- a/tests/ui/coroutine/partial-initialization-across-yield.stderr +++ b/tests/ui/coroutine/partial-initialization-across-yield.stderr @@ -1,3 +1,12 @@ +error[E0658]: #![feature(partial_init_locals)] might be able to enable the initialisation here + --> $DIR/partial-initialization-across-yield.rs:12:9 + | +LL | t.0 = 42; + | ^^^^^^^^ + | + = help: add `#![feature(partial_init_locals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + error[E0381]: partially assigned binding `t` isn't fully initialized --> $DIR/partial-initialization-across-yield.rs:12:9 | @@ -8,8 +17,17 @@ LL | t.0 = 42; | = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` +error[E0658]: #![feature(partial_init_locals)] might be able to enable the initialisation here + --> $DIR/partial-initialization-across-yield.rs:23:9 + | +LL | t.0 = 42; + | ^^^^^^^^ + | + = help: add `#![feature(partial_init_locals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + error[E0381]: partially assigned binding `t` isn't fully initialized - --> $DIR/partial-initialization-across-yield.rs:22:9 + --> $DIR/partial-initialization-across-yield.rs:23:9 | LL | let mut t: T; | ----- binding declared here but left uninitialized @@ -18,8 +36,17 @@ LL | t.0 = 42; | = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` +error[E0658]: #![feature(partial_init_locals)] might be able to enable the initialisation here + --> $DIR/partial-initialization-across-yield.rs:34:9 + | +LL | t.x = 42; + | ^^^^^^^^ + | + = help: add `#![feature(partial_init_locals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + error[E0381]: partially assigned binding `t` isn't fully initialized - --> $DIR/partial-initialization-across-yield.rs:32:9 + --> $DIR/partial-initialization-across-yield.rs:34:9 | LL | let mut t: S; | ----- binding declared here but left uninitialized @@ -28,6 +55,7 @@ LL | t.x = 42; | = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` -error: aborting due to 3 previous errors +error: aborting due to 6 previous errors -For more information about this error, try `rustc --explain E0381`. +Some errors have detailed explanations: E0381, E0658. +For more information about an error, try `rustc --explain E0381`. diff --git a/tests/ui/feature-gates/feature-gate-partial-init-locals.rs b/tests/ui/feature-gates/feature-gate-partial-init-locals.rs new file mode 100644 index 0000000000000..a332aff351cb9 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-partial-init-locals.rs @@ -0,0 +1,7 @@ +struct A(u8); + +fn main() { + let a: A; + a.0 = 1; //~ ERROR partially assigned binding `a` isn't fully initialized + //~^ ERROR E0658 +} diff --git a/tests/ui/feature-gates/feature-gate-partial-init-locals.stderr b/tests/ui/feature-gates/feature-gate-partial-init-locals.stderr new file mode 100644 index 0000000000000..1a170cd2e388b --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-partial-init-locals.stderr @@ -0,0 +1,23 @@ +error[E0658]: #![feature(partial_init_locals)] might be able to enable the initialisation here + --> $DIR/feature-gate-partial-init-locals.rs:5:5 + | +LL | a.0 = 1; + | ^^^^^^^ + | + = help: add `#![feature(partial_init_locals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0381]: partially assigned binding `a` isn't fully initialized + --> $DIR/feature-gate-partial-init-locals.rs:5:5 + | +LL | let a: A; + | - binding declared here but left uninitialized +LL | a.0 = 1; + | ^^^^^^^ `a` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0381, E0658. +For more information about an error, try `rustc --explain E0381`. diff --git a/tests/ui/nll/issue-21232-partial-init-and-erroneous-use.classic.stderr b/tests/ui/nll/issue-21232-partial-init-and-erroneous-use.classic.stderr new file mode 100644 index 0000000000000..d0e6c515578e0 --- /dev/null +++ b/tests/ui/nll/issue-21232-partial-init-and-erroneous-use.classic.stderr @@ -0,0 +1,118 @@ +error[E0658]: #![feature(partial_init_locals)] might be able to enable the initialisation here + --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:31:5 + | +LL | d.x = 10; + | ^^^^^^^^ + | + = help: add `#![feature(partial_init_locals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0381]: assigned binding `d` isn't fully initialized + --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:31:5 + | +LL | let d: D; + | - binding declared here but left uninitialized +LL | d.x = 10; + | ^^^^^^^^ `d` assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` + +error[E0658]: #![feature(partial_init_locals)] might be able to enable the initialisation here + --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:37:5 + | +LL | d.x = 10; + | ^^^^^^^^ + | + = help: add `#![feature(partial_init_locals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0381]: assigned binding `d` isn't fully initialized + --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:37:5 + | +LL | let mut d: D; + | ----- binding declared here but left uninitialized +LL | d.x = 10; + | ^^^^^^^^ `d` assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` + +error[E0382]: assign of moved value: `d` + --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:44:5 + | +LL | let mut d = D { x: 0, s: S { y: 0, z: 0 } }; + | ----- move occurs because `d` has type `D`, which does not implement the `Copy` trait +LL | drop(d); + | - value moved here +LL | d.x = 10; + | ^^^^^^^^ value assigned here after move + | +note: if `D` implemented `Clone`, you could clone the value + --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:15:1 + | +LL | struct D { + | ^^^^^^^^ consider implementing `Clone` for this type +... +LL | drop(d); + | - you could clone this value + +error[E0658]: #![feature(partial_init_locals)] might be able to enable the initialisation here + --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:50:5 + | +LL | d.s.y = 20; + | ^^^^^^^^^^ + | + = help: add `#![feature(partial_init_locals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0381]: partially assigned binding `d` isn't fully initialized + --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:50:5 + | +LL | let d: D; + | - binding declared here but left uninitialized +LL | d.s.y = 20; + | ^^^^^^^^^^ `d.s` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` + +error[E0658]: #![feature(partial_init_locals)] might be able to enable the initialisation here + --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:56:5 + | +LL | d.s.y = 20; + | ^^^^^^^^^^ + | + = help: add `#![feature(partial_init_locals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0381]: partially assigned binding `d` isn't fully initialized + --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:56:5 + | +LL | let mut d: D; + | ----- binding declared here but left uninitialized +LL | d.s.y = 20; + | ^^^^^^^^^^ `d.s` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` + +error[E0382]: assign to part of moved value: `d` + --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:63:5 + | +LL | let mut d = D { x: 0, s: S { y: 0, z: 0 } }; + | ----- move occurs because `d` has type `D`, which does not implement the `Copy` trait +LL | drop(d); + | - value moved here +LL | d.s.y = 20; + | ^^^^^^^^^^ value partially assigned here after move + | +note: if `D` implemented `Clone`, you could clone the value + --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:15:1 + | +LL | struct D { + | ^^^^^^^^ consider implementing `Clone` for this type +... +LL | drop(d); + | - you could clone this value + +error: aborting due to 10 previous errors + +Some errors have detailed explanations: E0381, E0382, E0658. +For more information about an error, try `rustc --explain E0381`. diff --git a/tests/ui/nll/issue-21232-partial-init-and-erroneous-use.stderr b/tests/ui/nll/issue-21232-partial-init-and-erroneous-use.partial_init.stderr similarity index 73% rename from tests/ui/nll/issue-21232-partial-init-and-erroneous-use.stderr rename to tests/ui/nll/issue-21232-partial-init-and-erroneous-use.partial_init.stderr index 3363c4ea28bf8..32ed71b12a2d4 100644 --- a/tests/ui/nll/issue-21232-partial-init-and-erroneous-use.stderr +++ b/tests/ui/nll/issue-21232-partial-init-and-erroneous-use.partial_init.stderr @@ -1,5 +1,5 @@ error[E0381]: assigned binding `d` isn't fully initialized - --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:28:5 + --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:31:5 | LL | let d: D; | - binding declared here but left uninitialized @@ -9,7 +9,7 @@ LL | d.x = 10; = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` error[E0381]: assigned binding `d` isn't fully initialized - --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:33:5 + --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:37:5 | LL | let mut d: D; | ----- binding declared here but left uninitialized @@ -19,9 +19,9 @@ LL | d.x = 10; = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` error[E0382]: assign of moved value: `d` - --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:39:5 + --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:44:5 | -LL | let mut d = D { x: 0, s: S{ y: 0, z: 0 } }; +LL | let mut d = D { x: 0, s: S { y: 0, z: 0 } }; | ----- move occurs because `d` has type `D`, which does not implement the `Copy` trait LL | drop(d); | - value moved here @@ -29,7 +29,7 @@ LL | d.x = 10; | ^^^^^^^^ value assigned here after move | note: if `D` implemented `Clone`, you could clone the value - --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:11:1 + --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:15:1 | LL | struct D { | ^^^^^^^^ consider implementing `Clone` for this type @@ -37,38 +37,38 @@ LL | struct D { LL | drop(d); | - you could clone this value -error[E0381]: partially assigned binding `d` isn't fully initialized - --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:45:5 +error[E0381]: assigned binding `d` isn't fully initialized + --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:50:5 | LL | let d: D; | - binding declared here but left uninitialized LL | d.s.y = 20; - | ^^^^^^^^^^ `d.s` partially assigned here but it isn't fully initialized + | ^^^^^^^^^^ `d` assigned here but it isn't fully initialized | = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` -error[E0381]: partially assigned binding `d` isn't fully initialized - --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:50:5 +error[E0381]: assigned binding `d` isn't fully initialized + --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:56:5 | LL | let mut d: D; | ----- binding declared here but left uninitialized LL | d.s.y = 20; - | ^^^^^^^^^^ `d.s` partially assigned here but it isn't fully initialized + | ^^^^^^^^^^ `d` assigned here but it isn't fully initialized | = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` -error[E0382]: assign to part of moved value: `d` - --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:56:5 +error[E0382]: assign of moved value: `d` + --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:63:5 | -LL | let mut d = D { x: 0, s: S{ y: 0, z: 0} }; +LL | let mut d = D { x: 0, s: S { y: 0, z: 0 } }; | ----- move occurs because `d` has type `D`, which does not implement the `Copy` trait LL | drop(d); | - value moved here LL | d.s.y = 20; - | ^^^^^^^^^^ value partially assigned here after move + | ^^^^^^^^^^ value assigned here after move | note: if `D` implemented `Clone`, you could clone the value - --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:11:1 + --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:15:1 | LL | struct D { | ^^^^^^^^ consider implementing `Clone` for this type diff --git a/tests/ui/nll/issue-21232-partial-init-and-erroneous-use.rs b/tests/ui/nll/issue-21232-partial-init-and-erroneous-use.rs index 46a156d2af9ee..f0a82a12378ef 100644 --- a/tests/ui/nll/issue-21232-partial-init-and-erroneous-use.rs +++ b/tests/ui/nll/issue-21232-partial-init-and-erroneous-use.rs @@ -1,3 +1,7 @@ +//@ revisions: classic partial_init + +#![cfg_attr(partial_init, feature(partial_init_locals))] + // This test enumerates various cases of interest where an ADT or tuple is // partially initialized and then used in some way that is wrong *even* // after rust-lang/rust#54987 is implemented. @@ -18,23 +22,24 @@ struct S { z: u32, } - impl Drop for D { - fn drop(&mut self) { } + fn drop(&mut self) {} } fn cannot_partially_init_adt_with_drop() { let d: D; d.x = 10; //~ ERROR E0381 + //[classic]~^ ERROR E0658 } fn cannot_partially_init_mutable_adt_with_drop() { let mut d: D; d.x = 10; //~ ERROR E0381 + //[classic]~^ ERROR E0658 } fn cannot_partially_reinit_adt_with_drop() { - let mut d = D { x: 0, s: S{ y: 0, z: 0 } }; + let mut d = D { x: 0, s: S { y: 0, z: 0 } }; drop(d); d.x = 10; //~^ ERROR assign of moved value: `d` [E0382] @@ -43,18 +48,20 @@ fn cannot_partially_reinit_adt_with_drop() { fn cannot_partially_init_inner_adt_via_outer_with_drop() { let d: D; d.s.y = 20; //~ ERROR E0381 + //[classic]~^ ERROR E0658 } fn cannot_partially_init_inner_adt_via_mutable_outer_with_drop() { let mut d: D; d.s.y = 20; //~ ERROR E0381 + //[classic]~^ ERROR E0658 } fn cannot_partially_reinit_inner_adt_via_outer_with_drop() { - let mut d = D { x: 0, s: S{ y: 0, z: 0} }; + 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] + d.s.y = 20; //[classic]~ ERROR assign to part of moved value: `d` [E0382] + //[partial_init]~^ ERROR assign of moved value: `d` [E0382] } -fn main() { } +fn main() {} diff --git a/tests/ui/nll/issue-21232-partial-init-and-use.stderr b/tests/ui/nll/issue-21232-partial-init-and-use.classic.stderr similarity index 53% rename from tests/ui/nll/issue-21232-partial-init-and-use.stderr rename to tests/ui/nll/issue-21232-partial-init-and-use.classic.stderr index 496a298a36ce9..eea6087663a9d 100644 --- a/tests/ui/nll/issue-21232-partial-init-and-use.stderr +++ b/tests/ui/nll/issue-21232-partial-init-and-use.classic.stderr @@ -1,59 +1,86 @@ +error[E0658]: #![feature(partial_init_locals)] might be able to enable the initialisation here + --> $DIR/issue-21232-partial-init-and-use.rs:136:5 + | +LL | s.x = 10; + | ^^^^^^^^ + | + = help: add `#![feature(partial_init_locals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + error[E0381]: partially assigned binding `s` isn't fully initialized - --> $DIR/issue-21232-partial-init-and-use.rs:97:5 + --> $DIR/issue-21232-partial-init-and-use.rs:136:5 | LL | let s: S; | - binding declared here but left uninitialized -LL | s.x = 10; s.y = Box::new(20); +LL | s.x = 10; | ^^^^^^^^ `s` partially assigned here but it isn't fully initialized | = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` +error[E0658]: #![feature(partial_init_locals)] might be able to enable the initialisation here + --> $DIR/issue-21232-partial-init-and-use.rs:144:5 + | +LL | t.0 = 10; + | ^^^^^^^^ + | + = help: add `#![feature(partial_init_locals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + error[E0381]: partially assigned binding `t` isn't fully initialized - --> $DIR/issue-21232-partial-init-and-use.rs:103:5 + --> $DIR/issue-21232-partial-init-and-use.rs:144:5 | LL | let t: T; | - binding declared here but left uninitialized -LL | t.0 = 10; t.1 = Box::new(20); +LL | t.0 = 10; | ^^^^^^^^ `t` partially assigned here but it isn't fully initialized | = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` error[E0382]: assign to part of moved value: `s` - --> $DIR/issue-21232-partial-init-and-use.rs:109:5 + --> $DIR/issue-21232-partial-init-and-use.rs:153:5 | -LL | let mut s: S = S::new(); drop(s); - | ----- - value moved here - | | - | move occurs because `s` has type `S>`, which does not implement the `Copy` trait -LL | s.x = 10; s.y = Box::new(20); +LL | let mut s: S = S::new(); + | ----- move occurs because `s` has type `S>`, which does not implement the `Copy` trait +LL | drop(s); + | - value moved here +LL | s.x = 10; | ^^^^^^^^ value partially assigned here after move | note: if `S>` implemented `Clone`, you could clone the value - --> $DIR/issue-21232-partial-init-and-use.rs:15:1 + --> $DIR/issue-21232-partial-init-and-use.rs:20:1 | LL | struct S { | ^^^^^^^^^^^ consider implementing `Clone` for this type ... -LL | let mut s: S = S::new(); drop(s); - | - you could clone this value +LL | drop(s); + | - you could clone this value error[E0382]: assign to part of moved value: `t` - --> $DIR/issue-21232-partial-init-and-use.rs:116:5 + --> $DIR/issue-21232-partial-init-and-use.rs:162:5 | -LL | let mut t: T = (0, Box::new(0)); drop(t); - | ----- - value moved here - | | - | move occurs because `t` has type `(u32, Box)`, which does not implement the `Copy` trait -LL | t.0 = 10; t.1 = Box::new(20); +LL | let mut t: T = (0, Box::new(0)); + | ----- move occurs because `t` has type `(u32, Box)`, which does not implement the `Copy` trait +LL | drop(t); + | - value moved here +LL | t.0 = 10; | ^^^^^^^^ value partially assigned here after move | help: consider cloning the value if the performance cost is acceptable | -LL | let mut t: T = (0, Box::new(0)); drop(t.clone()); - | ++++++++ +LL | drop(t.clone()); + | ++++++++ + +error[E0658]: #![feature(partial_init_locals)] might be able to enable the initialisation here + --> $DIR/issue-21232-partial-init-and-use.rs:170:5 + | +LL | s.x = 10; + | ^^^^^^^^ + | + = help: add `#![feature(partial_init_locals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0381]: partially assigned binding `s` isn't fully initialized - --> $DIR/issue-21232-partial-init-and-use.rs:123:5 + --> $DIR/issue-21232-partial-init-and-use.rs:170:5 | LL | let s: S; | - binding declared here but left uninitialized @@ -62,8 +89,17 @@ LL | s.x = 10; | = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` +error[E0658]: #![feature(partial_init_locals)] might be able to enable the initialisation here + --> $DIR/issue-21232-partial-init-and-use.rs:177:5 + | +LL | t.0 = 10; + | ^^^^^^^^ + | + = help: add `#![feature(partial_init_locals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + error[E0381]: partially assigned binding `t` isn't fully initialized - --> $DIR/issue-21232-partial-init-and-use.rs:129:5 + --> $DIR/issue-21232-partial-init-and-use.rs:177:5 | LL | let t: T; | - binding declared here but left uninitialized @@ -73,41 +109,50 @@ LL | t.0 = 10; = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` error[E0382]: assign to part of moved value: `s` - --> $DIR/issue-21232-partial-init-and-use.rs:135:5 + --> $DIR/issue-21232-partial-init-and-use.rs:185:5 | -LL | let mut s: S = S::new(); drop(s); - | ----- - value moved here - | | - | move occurs because `s` has type `S>`, which does not implement the `Copy` trait +LL | let mut s: S = S::new(); + | ----- move occurs because `s` has type `S>`, which does not implement the `Copy` trait +LL | drop(s); + | - value moved here LL | s.x = 10; | ^^^^^^^^ value partially assigned here after move | note: if `S>` implemented `Clone`, you could clone the value - --> $DIR/issue-21232-partial-init-and-use.rs:15:1 + --> $DIR/issue-21232-partial-init-and-use.rs:20:1 | LL | struct S { | ^^^^^^^^^^^ consider implementing `Clone` for this type ... -LL | let mut s: S = S::new(); drop(s); - | - you could clone this value +LL | drop(s); + | - you could clone this value error[E0382]: assign to part of moved value: `t` - --> $DIR/issue-21232-partial-init-and-use.rs:142:5 + --> $DIR/issue-21232-partial-init-and-use.rs:193:5 | -LL | let mut t: T = (0, Box::new(0)); drop(t); - | ----- - value moved here - | | - | move occurs because `t` has type `(u32, Box)`, which does not implement the `Copy` trait +LL | let mut t: T = (0, Box::new(0)); + | ----- move occurs because `t` has type `(u32, Box)`, which does not implement the `Copy` trait +LL | drop(t); + | - value moved here LL | t.0 = 10; | ^^^^^^^^ value partially assigned here after move | help: consider cloning the value if the performance cost is acceptable | -LL | let mut t: T = (0, Box::new(0)); drop(t.clone()); - | ++++++++ +LL | drop(t.clone()); + | ++++++++ + +error[E0658]: #![feature(partial_init_locals)] might be able to enable the initialisation here + --> $DIR/issue-21232-partial-init-and-use.rs:200:5 + | +LL | s.x = 10; + | ^^^^^^^^ + | + = help: add `#![feature(partial_init_locals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0381]: partially assigned binding `s` isn't fully initialized - --> $DIR/issue-21232-partial-init-and-use.rs:149:5 + --> $DIR/issue-21232-partial-init-and-use.rs:200:5 | LL | let s: S; | - binding declared here but left uninitialized @@ -116,8 +161,17 @@ LL | s.x = 10; | = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` +error[E0658]: #![feature(partial_init_locals)] might be able to enable the initialisation here + --> $DIR/issue-21232-partial-init-and-use.rs:207:5 + | +LL | t.0 = 10; + | ^^^^^^^^ + | + = help: add `#![feature(partial_init_locals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + error[E0381]: partially assigned binding `t` isn't fully initialized - --> $DIR/issue-21232-partial-init-and-use.rs:155:5 + --> $DIR/issue-21232-partial-init-and-use.rs:207:5 | LL | let t: Tvoid; | - binding declared here but left uninitialized @@ -126,48 +180,75 @@ LL | t.0 = 10; | = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` +error[E0658]: #![feature(partial_init_locals)] might be able to enable the initialisation here + --> $DIR/issue-21232-partial-init-and-use.rs:223:5 + | +LL | q.r.f.x = 10; + | ^^^^^^^^^^^^ + | + = help: add `#![feature(partial_init_locals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + error[E0381]: partially assigned binding `q` isn't fully initialized - --> $DIR/issue-21232-partial-init-and-use.rs:170:5 + --> $DIR/issue-21232-partial-init-and-use.rs:223:5 | LL | let q: Q>; | - binding declared here but left uninitialized -LL | q.r.f.x = 10; q.r.f.y = Box::new(20); +LL | q.r.f.x = 10; | ^^^^^^^^^^^^ `q.r.f` partially assigned here but it isn't fully initialized | = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` +error[E0658]: #![feature(partial_init_locals)] might be able to enable the initialisation here + --> $DIR/issue-21232-partial-init-and-use.rs:231:5 + | +LL | q.r.f.0 = 10; + | ^^^^^^^^^^^^ + | + = help: add `#![feature(partial_init_locals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + error[E0381]: partially assigned binding `q` isn't fully initialized - --> $DIR/issue-21232-partial-init-and-use.rs:176:5 + --> $DIR/issue-21232-partial-init-and-use.rs:231:5 | LL | let q: Q; | - binding declared here but left uninitialized -LL | q.r.f.0 = 10; q.r.f.1 = Box::new(20); +LL | q.r.f.0 = 10; | ^^^^^^^^^^^^ `q.r.f` partially assigned here but it isn't fully initialized | = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` error[E0382]: assign to part of moved value: `q.r` - --> $DIR/issue-21232-partial-init-and-use.rs:182:5 + --> $DIR/issue-21232-partial-init-and-use.rs:240: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); +LL | 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:189:5 + --> $DIR/issue-21232-partial-init-and-use.rs:249: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); +LL | 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, Box)>`, which does not implement the `Copy` trait +error[E0658]: #![feature(partial_init_locals)] might be able to enable the initialisation here + --> $DIR/issue-21232-partial-init-and-use.rs:257:5 + | +LL | q.r.f.x = 10; + | ^^^^^^^^^^^^ + | + = help: add `#![feature(partial_init_locals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + error[E0381]: partially assigned binding `q` isn't fully initialized - --> $DIR/issue-21232-partial-init-and-use.rs:196:5 + --> $DIR/issue-21232-partial-init-and-use.rs:257:5 | LL | let q: Q>; | - binding declared here but left uninitialized @@ -176,8 +257,17 @@ LL | q.r.f.x = 10; | = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` +error[E0658]: #![feature(partial_init_locals)] might be able to enable the initialisation here + --> $DIR/issue-21232-partial-init-and-use.rs:264:5 + | +LL | q.r.f.0 = 10; + | ^^^^^^^^^^^^ + | + = help: add `#![feature(partial_init_locals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + error[E0381]: partially assigned binding `q` isn't fully initialized - --> $DIR/issue-21232-partial-init-and-use.rs:202:5 + --> $DIR/issue-21232-partial-init-and-use.rs:264:5 | LL | let q: Q; | - binding declared here but left uninitialized @@ -187,27 +277,36 @@ LL | q.r.f.0 = 10; = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` error[E0382]: assign to part of moved value: `q.r` - --> $DIR/issue-21232-partial-init-and-use.rs:208:5 + --> $DIR/issue-21232-partial-init-and-use.rs:272:5 | -LL | let mut q: Q> = Q::new(S::new()); drop(q.r); - | --- value moved here +LL | 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:215:5 + --> $DIR/issue-21232-partial-init-and-use.rs:280:5 | -LL | let mut q: Q = Q::new((0, Box::new(0))); drop(q.r); - | --- value moved here +LL | 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, Box)>`, which does not implement the `Copy` trait +error[E0658]: #![feature(partial_init_locals)] might be able to enable the initialisation here + --> $DIR/issue-21232-partial-init-and-use.rs:287:5 + | +LL | q.r.f.x = 10; + | ^^^^^^^^^^^^ + | + = help: add `#![feature(partial_init_locals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + error[E0381]: partially assigned binding `q` isn't fully initialized - --> $DIR/issue-21232-partial-init-and-use.rs:222:5 + --> $DIR/issue-21232-partial-init-and-use.rs:287:5 | LL | let mut q: Q>; | ----- binding declared here but left uninitialized @@ -216,8 +315,17 @@ LL | q.r.f.x = 10; | = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` +error[E0658]: #![feature(partial_init_locals)] might be able to enable the initialisation here + --> $DIR/issue-21232-partial-init-and-use.rs:294:5 + | +LL | q.r.f.0 = 10; + | ^^^^^^^^^^^^ + | + = help: add `#![feature(partial_init_locals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + error[E0381]: partially assigned binding `q` isn't fully initialized - --> $DIR/issue-21232-partial-init-and-use.rs:228:5 + --> $DIR/issue-21232-partial-init-and-use.rs:294:5 | LL | let mut q: Q; | ----- binding declared here but left uninitialized @@ -227,7 +335,7 @@ LL | q.r.f.0 = 10; = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` error[E0382]: assign to part of moved value: `c` - --> $DIR/issue-21232-partial-init-and-use.rs:245:13 + --> $DIR/issue-21232-partial-init-and-use.rs:312:13 | LL | let mut c = (1, "".to_owned()); | ----- move occurs because `c` has type `(i32, String)`, which does not implement the `Copy` trait @@ -243,7 +351,7 @@ LL | ref c2 => { | +++ error[E0382]: assign to part of moved value: `c` - --> $DIR/issue-21232-partial-init-and-use.rs:255:13 + --> $DIR/issue-21232-partial-init-and-use.rs:322:13 | LL | let mut c = (1, (1, "".to_owned())); | ----- move occurs because `c` has type `(i32, (i32, String))`, which does not implement the `Copy` trait @@ -259,7 +367,7 @@ LL | ref c2 => { | +++ error[E0382]: assign to part of moved value: `c.1` - --> $DIR/issue-21232-partial-init-and-use.rs:263:13 + --> $DIR/issue-21232-partial-init-and-use.rs:330:13 | LL | c2 => { | -- value moved here @@ -272,7 +380,7 @@ help: borrow this binding in the pattern to avoid moving the value LL | ref c2 => { | +++ -error: aborting due to 23 previous errors +error: aborting due to 35 previous errors -Some errors have detailed explanations: E0381, E0382. +Some errors have detailed explanations: E0381, E0382, E0658. For more information about an error, try `rustc --explain E0381`. diff --git a/tests/ui/nll/issue-21232-partial-init-and-use.rs b/tests/ui/nll/issue-21232-partial-init-and-use.rs index ad3eb248351d4..ac7a4a6631d0c 100644 --- a/tests/ui/nll/issue-21232-partial-init-and-use.rs +++ b/tests/ui/nll/issue-21232-partial-init-and-use.rs @@ -12,6 +12,11 @@ // tests that are meant to continue failing to compile once // rust-lang/rust#54987 is implemented. +//@ revisions: classic partial_init +//@[partial_init] check-pass + +#![cfg_attr(partial_init, feature(partial_init_locals))] + struct S { x: u32, @@ -20,21 +25,39 @@ struct S { y: Y, } -enum Void { } +enum Void {} type B = Box; -impl S { fn new() -> Self { S { x: 0, y: Box::new(0) } } } +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); } +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); } +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, @@ -46,8 +69,16 @@ struct R { 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 } } } +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 @@ -67,92 +98,114 @@ impl R { fn new(f: F) -> Self { R { w: 0, f } } } // where the errors for #54986 will be emitted. 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 ); - } } + (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); } } - } } + (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 E0381 + s.x = 10; //[classic]~ ERROR E0381 + //[classic]~^ ERROR E0658 + s.y = Box::new(20); 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 E0381 + t.0 = 10; //[classic]~ ERROR E0381 + //[classic]~^ ERROR E0658 + t.1 = Box::new(20); 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] + let mut s: S = S::new(); + drop(s); + s.x = 10; + //[classic]~^ ERROR assign to part of moved value: `s` [E0382] + s.y = Box::new(20); 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] + let mut t: T = (0, Box::new(0)); + drop(t); + t.0 = 10; + //[classic]~^ ERROR assign to part of moved value: `t` [E0382] + t.1 = Box::new(20); use_fully!(tuple t); } fn test_0100_local_partial_init_and_use_struct() { let s: S; - s.x = 10; //~ ERROR E0381 + s.x = 10; //[classic]~ ERROR E0381 + //[classic]~^ ERROR E0658 use_part!(struct s); } fn test_0101_local_partial_init_and_use_tuple() { let t: T; - t.0 = 10; //~ ERROR E0381 + t.0 = 10; //[classic]~ ERROR E0381 + //[classic]~^ ERROR E0658 use_part!(tuple t); } fn test_0110_local_partial_reinit_and_use_struct() { - let mut s: S = S::new(); drop(s); + let mut s: S = S::new(); + drop(s); s.x = 10; - //~^ ERROR assign to part of moved value: `s` [E0382] + //[classic]~^ 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); + let mut t: T = (0, Box::new(0)); + drop(t); t.0 = 10; - //~^ ERROR assign to part of moved value: `t` [E0382] + //[classic]~^ 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 E0381 + s.x = 10; //[classic]~ ERROR E0381 + //[classic]~^ ERROR E0658 use_part!(struct s); } fn test_0201_local_void_init_and_use_tuple() { let t: Tvoid; - t.0 = 10; //~ ERROR E0381 + t.0 = 10; //[classic]~ ERROR E0381 + //[classic]~^ ERROR E0658 use_part!(tuple t); } @@ -167,65 +220,79 @@ fn test_0201_local_void_init_and_use_tuple() { 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 E0381 + q.r.f.x = 10; //[classic]~ ERROR E0381 + //[classic]~^ ERROR E0658 + q.r.f.y = Box::new(20); 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 E0381 + q.r.f.0 = 10; //[classic]~ ERROR E0381 + //[classic]~^ ERROR E0658 + q.r.f.1 = Box::new(20); 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] + let mut q: Q> = Q::new(S::new()); + drop(q.r); + q.r.f.x = 10; + //[classic]~^ ERROR assign to part of moved value: `q.r` [E0382] + q.r.f.y = Box::new(20); 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] + let mut q: Q = Q::new((0, Box::new(0))); + drop(q.r); + q.r.f.0 = 10; + //[classic]~^ ERROR assign to part of moved value: `q.r` [E0382] + q.r.f.1 = Box::new(20); use_fully!(tuple q.r.f); } fn test_1100_field_partial_init_and_use_struct() { let q: Q>; - q.r.f.x = 10; //~ ERROR E0381 + q.r.f.x = 10; //[classic]~ ERROR E0381 + //[classic]~^ ERROR E0658 use_part!(struct q.r.f); } fn test_1101_field_partial_init_and_use_tuple() { let q: Q; - q.r.f.0 = 10; //~ ERROR E0381 + q.r.f.0 = 10; //[classic]~ ERROR E0381 + //[classic]~^ ERROR E0658 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); + 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] + //[classic]~^ 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); + 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] + //[classic]~^ 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 E0381 + q.r.f.x = 10; //[classic]~ ERROR E0381 + //[classic]~^ ERROR E0658 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 E0381 + q.r.f.0 = 10; //[classic]~ ERROR E0381 + //[classic]~^ ERROR E0658 use_part!(tuple q.r.f); } @@ -242,7 +309,7 @@ fn issue_26996() { let mut c = (1, "".to_owned()); match c { c2 => { - c.0 = 2; //~ ERROR assign to part of moved value + c.0 = 2; //[classic]~ ERROR assign to part of moved value assert_eq!(c2.0, 1); } } @@ -252,7 +319,7 @@ fn issue_27021() { let mut c = (1, (1, "".to_owned())); match c { c2 => { - (c.1).0 = 2; //~ ERROR assign to part of moved value + (c.1).0 = 2; //[classic]~ ERROR assign to part of moved value assert_eq!((c2.1).0, 1); } } @@ -260,7 +327,7 @@ fn issue_27021() { let mut c = (1, (1, (1, "".to_owned()))); match c.1 { c2 => { - ((c.1).1).0 = 3; //~ ERROR assign to part of moved value + ((c.1).1).0 = 3; //[classic]~ ERROR assign to part of moved value assert_eq!((c2.1).0, 1); } }