Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

reject partial init and reinit of uninitialized data #54941

Merged
merged 9 commits into from
Oct 17, 2018
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