Skip to content

Commit 5f9c7f9

Browse files
committed
Auto merge of #51688 - spastorino:error-note-field-after-move, r=nikomatsakis
Fix erroneous error note when using field after move Closes #51512 r? @nikomatsakis
2 parents 01cc982 + 1dae309 commit 5f9c7f9

File tree

10 files changed

+768
-486
lines changed

10 files changed

+768
-486
lines changed

src/librustc_borrowck/borrowck/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -680,7 +680,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
680680
let mut err = self.cannot_act_on_moved_value(use_span,
681681
verb,
682682
msg,
683-
&format!("{}", nl),
683+
Some(format!("{}", nl)),
684684
Origin::Ast);
685685
let need_note = match lp.ty.sty {
686686
ty::TypeVariants::TyClosure(id, _) => {

src/librustc_mir/borrow_check/error_reporting.rs

Lines changed: 85 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -52,15 +52,17 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
5252

5353
self.moved_error_reported.insert(root_place.clone());
5454

55-
let item_msg = match self.describe_place(place) {
55+
let item_msg = match self.describe_place_with_options(place, IncludingDowncast(true)) {
5656
Some(name) => format!("`{}`", name),
5757
None => "value".to_owned(),
5858
};
5959
self.tcx
6060
.cannot_act_on_uninitialized_variable(
6161
span,
6262
desired_action.as_noun(),
63-
&self.describe_place(place).unwrap_or("_".to_owned()),
63+
&self
64+
.describe_place_with_options(place, IncludingDowncast(true))
65+
.unwrap_or("_".to_owned()),
6466
Origin::Mir,
6567
)
6668
.span_label(span, format!("use of possibly uninitialized {}", item_msg))
@@ -72,14 +74,17 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
7274
span,
7375
desired_action.as_noun(),
7476
msg,
75-
&self.describe_place(place).unwrap_or("_".to_owned()),
77+
self.describe_place_with_options(&place, IncludingDowncast(true)),
7678
Origin::Mir,
7779
);
7880

7981
let mut is_loop_move = false;
80-
for moi in mois {
82+
for moi in &mois {
8183
let move_msg = ""; //FIXME: add " (into closure)"
82-
let move_span = self.mir.source_info(self.move_data.moves[*moi].source).span;
84+
let move_span = self
85+
.mir
86+
.source_info(self.move_data.moves[**moi].source)
87+
.span;
8388
if span == move_span {
8489
err.span_label(
8590
span,
@@ -116,16 +121,23 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
116121
};
117122

118123
if needs_note {
119-
let note_msg = match self.describe_place(place) {
120-
Some(name) => format!("`{}`", name),
121-
None => "value".to_owned(),
122-
};
124+
let mpi = self.move_data.moves[*mois[0]].path;
125+
let place = &self.move_data.move_paths[mpi].place;
126+
127+
if let Some(ty) = self.retrieve_type_for_place(place) {
128+
let note_msg = match self
129+
.describe_place_with_options(place, IncludingDowncast(true))
130+
{
131+
Some(name) => format!("`{}`", name),
132+
None => "value".to_owned(),
133+
};
123134

124-
err.note(&format!(
125-
"move occurs because {} has type `{}`, \
126-
which does not implement the `Copy` trait",
127-
note_msg, ty
128-
));
135+
err.note(&format!(
136+
"move occurs because {} has type `{}`, \
137+
which does not implement the `Copy` trait",
138+
note_msg, ty
139+
));
140+
}
129141
}
130142
}
131143

@@ -644,8 +656,10 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
644656
let local_decl = &self.mir.local_decls[*local];
645657
if let Some(name) = local_decl.name {
646658
if local_decl.can_be_made_mutable() {
647-
err.span_label(local_decl.source_info.span,
648-
format!("consider changing this to `mut {}`", name));
659+
err.span_label(
660+
local_decl.source_info.span,
661+
format!("consider changing this to `mut {}`", name),
662+
);
649663
}
650664
}
651665
}
@@ -654,12 +668,26 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
654668
}
655669
}
656670

671+
pub(super) struct IncludingDowncast(bool);
672+
657673
impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
658674
// End-user visible description of `place` if one can be found. If the
659675
// place is a temporary for instance, None will be returned.
660676
pub(super) fn describe_place(&self, place: &Place<'tcx>) -> Option<String> {
677+
self.describe_place_with_options(place, IncludingDowncast(false))
678+
}
679+
680+
// End-user visible description of `place` if one can be found. If the
681+
// place is a temporary for instance, None will be returned.
682+
// `IncludingDowncast` parameter makes the function return `Err` if `ProjectionElem` is
683+
// `Downcast` and `IncludingDowncast` is true
684+
pub(super) fn describe_place_with_options(
685+
&self,
686+
place: &Place<'tcx>,
687+
including_downcast: IncludingDowncast,
688+
) -> Option<String> {
661689
let mut buf = String::new();
662-
match self.append_place_to_string(place, &mut buf, false) {
690+
match self.append_place_to_string(place, &mut buf, false, &including_downcast) {
663691
Ok(()) => Some(buf),
664692
Err(()) => None,
665693
}
@@ -671,6 +699,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
671699
place: &Place<'tcx>,
672700
buf: &mut String,
673701
mut autoderef: bool,
702+
including_downcast: &IncludingDowncast,
674703
) -> Result<(), ()> {
675704
match *place {
676705
Place::Local(local) => {
@@ -692,15 +721,33 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
692721
}
693722
} else {
694723
if autoderef {
695-
self.append_place_to_string(&proj.base, buf, autoderef)?;
724+
self.append_place_to_string(
725+
&proj.base,
726+
buf,
727+
autoderef,
728+
&including_downcast,
729+
)?;
696730
} else {
697731
buf.push_str(&"*");
698-
self.append_place_to_string(&proj.base, buf, autoderef)?;
732+
self.append_place_to_string(
733+
&proj.base,
734+
buf,
735+
autoderef,
736+
&including_downcast,
737+
)?;
699738
}
700739
}
701740
}
702741
ProjectionElem::Downcast(..) => {
703-
self.append_place_to_string(&proj.base, buf, autoderef)?;
742+
self.append_place_to_string(
743+
&proj.base,
744+
buf,
745+
autoderef,
746+
&including_downcast,
747+
)?;
748+
if including_downcast.0 {
749+
return Err(());
750+
}
704751
}
705752
ProjectionElem::Field(field, _ty) => {
706753
autoderef = true;
@@ -711,14 +758,24 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
711758
buf.push_str(&name);
712759
} else {
713760
let field_name = self.describe_field(&proj.base, field);
714-
self.append_place_to_string(&proj.base, buf, autoderef)?;
761+
self.append_place_to_string(
762+
&proj.base,
763+
buf,
764+
autoderef,
765+
&including_downcast,
766+
)?;
715767
buf.push_str(&format!(".{}", field_name));
716768
}
717769
}
718770
ProjectionElem::Index(index) => {
719771
autoderef = true;
720772

721-
self.append_place_to_string(&proj.base, buf, autoderef)?;
773+
self.append_place_to_string(
774+
&proj.base,
775+
buf,
776+
autoderef,
777+
&including_downcast,
778+
)?;
722779
buf.push_str("[");
723780
if let Err(_) = self.append_local_to_string(index, buf) {
724781
buf.push_str("..");
@@ -730,7 +787,12 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
730787
// Since it isn't possible to borrow an element on a particular index and
731788
// then use another while the borrow is held, don't output indices details
732789
// to avoid confusing the end-user
733-
self.append_place_to_string(&proj.base, buf, autoderef)?;
790+
self.append_place_to_string(
791+
&proj.base,
792+
buf,
793+
autoderef,
794+
&including_downcast,
795+
)?;
734796
buf.push_str(&"[..]");
735797
}
736798
};

0 commit comments

Comments
 (0)