Skip to content

Commit

Permalink
Auto merge of #54941 - pnkfelix:issue-21232-reject-partial-reinit, r=…
Browse files Browse the repository at this point in the history
…nikomatsakis

reject partial init and reinit of uninitialized data

Reject partial initialization of uninitialized structured types (i.e. structs and tuples) and also reject partial *reinitialization* of such types.

Fix #54986

Fix #54499

cc #21232
  • Loading branch information
bors committed Oct 17, 2018
2 parents 9d7f0da + 233fdb4 commit cbbd70d
Show file tree
Hide file tree
Showing 53 changed files with 1,689 additions and 206 deletions.
14 changes: 13 additions & 1 deletion src/librustc/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1967,7 +1967,10 @@ impl<'tcx> Place<'tcx> {
Place::Projection(Box::new(PlaceProjection { base: self, elem }))
}

/// Find the innermost `Local` from this `Place`.
/// Find the innermost `Local` from this `Place`, *if* it is either a local itself or
/// a single deref of a local.
///
/// FIXME: can we safely swap the semantics of `fn base_local` below in here instead?
pub fn local(&self) -> Option<Local> {
match self {
Place::Local(local) |
Expand All @@ -1978,6 +1981,15 @@ impl<'tcx> Place<'tcx> {
_ => None,
}
}

/// Find the innermost `Local` from this `Place`.
pub fn base_local(&self) -> Option<Local> {
match self {
Place::Local(local) => Some(*local),
Place::Projection(box Projection { base, elem: _ }) => base.base_local(),
Place::Promoted(..) | Place::Static(..) => None,
}
}
}

impl<'tcx> Debug for Place<'tcx> {
Expand Down
25 changes: 13 additions & 12 deletions src/librustc_mir/borrow_check/error_reporting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,16 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
&mut self,
context: Context,
desired_action: InitializationRequiringAction,
(place, span): (&Place<'tcx>, Span),
(moved_place, used_place, span): (&Place<'tcx>, &Place<'tcx>, Span),
mpi: MovePathIndex,
) {
debug!(
"report_use_of_moved_or_uninitialized: context={:?} desired_action={:?} place={:?} \
span={:?} mpi={:?}",
context, desired_action, place, span, mpi
"report_use_of_moved_or_uninitialized: context={:?} desired_action={:?} \
moved_place={:?} used_place={:?} span={:?} mpi={:?}",
context, desired_action, moved_place, used_place, span, mpi
);

let use_spans = self.move_spans(place, context.loc)
let use_spans = self.move_spans(moved_place, context.loc)
.or_else(|| self.borrow_spans(span, context.loc));
let span = use_spans.args_or_use();

Expand All @@ -75,7 +75,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
.collect();

if move_out_indices.is_empty() {
let root_place = self.prefixes(&place, PrefixSet::All).last().unwrap();
let root_place = self.prefixes(&used_place, PrefixSet::All).last().unwrap();

if self.uninitialized_error_reported
.contains(&root_place.clone())
Expand All @@ -89,14 +89,15 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {

self.uninitialized_error_reported.insert(root_place.clone());

let item_msg = match self.describe_place_with_options(place, IncludingDowncast(true)) {
let item_msg = match self.describe_place_with_options(used_place,
IncludingDowncast(true)) {
Some(name) => format!("`{}`", name),
None => "value".to_owned(),
};
let mut err = self.infcx.tcx.cannot_act_on_uninitialized_variable(
span,
desired_action.as_noun(),
&self.describe_place_with_options(place, IncludingDowncast(true))
&self.describe_place_with_options(moved_place, IncludingDowncast(true))
.unwrap_or("_".to_owned()),
Origin::Mir,
);
Expand All @@ -111,7 +112,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
} else {
if let Some((reported_place, _)) = self.move_error_reported.get(&move_out_indices) {
if self.prefixes(&reported_place, PrefixSet::All)
.any(|p| p == place)
.any(|p| p == used_place)
{
debug!(
"report_use_of_moved_or_uninitialized place: error suppressed \
Expand All @@ -128,7 +129,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
span,
desired_action.as_noun(),
msg,
self.describe_place_with_options(&place, IncludingDowncast(true)),
self.describe_place_with_options(&moved_place, IncludingDowncast(true)),
Origin::Mir,
);

Expand Down Expand Up @@ -181,7 +182,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
);
}

if let Some(ty) = self.retrieve_type_for_place(place) {
if let Some(ty) = self.retrieve_type_for_place(used_place) {
let needs_note = match ty.sty {
ty::Closure(id, _) => {
let tables = self.infcx.tcx.typeck_tables_of(id);
Expand Down Expand Up @@ -219,7 +220,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
}

if let Some((_, mut old_err)) = self.move_error_reported
.insert(move_out_indices, (place.clone(), err))
.insert(move_out_indices, (used_place.clone(), err))
{
// Cancel the old error so it doesn't ICE.
old_err.cancel();
Expand Down
Loading

0 comments on commit cbbd70d

Please sign in to comment.