@@ -52,15 +52,17 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
52
52
53
53
self . moved_error_reported . insert ( root_place. clone ( ) ) ;
54
54
55
- let item_msg = match self . describe_place ( place) {
55
+ let item_msg = match self . describe_place_with_options ( place, IncludingDowncast ( true ) ) {
56
56
Some ( name) => format ! ( "`{}`" , name) ,
57
57
None => "value" . to_owned ( ) ,
58
58
} ;
59
59
self . tcx
60
60
. cannot_act_on_uninitialized_variable (
61
61
span,
62
62
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 ( ) ) ,
64
66
Origin :: Mir ,
65
67
)
66
68
. span_label ( span, format ! ( "use of possibly uninitialized {}" , item_msg) )
@@ -72,14 +74,17 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
72
74
span,
73
75
desired_action. as_noun ( ) ,
74
76
msg,
75
- & self . describe_place ( place) . unwrap_or ( "_" . to_owned ( ) ) ,
77
+ self . describe_place_with_options ( & place, IncludingDowncast ( true ) ) ,
76
78
Origin :: Mir ,
77
79
) ;
78
80
79
81
let mut is_loop_move = false ;
80
- for moi in mois {
82
+ for moi in & mois {
81
83
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 ;
83
88
if span == move_span {
84
89
err. span_label (
85
90
span,
@@ -116,16 +121,23 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
116
121
} ;
117
122
118
123
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
+ } ;
123
134
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
+ }
129
141
}
130
142
}
131
143
@@ -644,8 +656,10 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
644
656
let local_decl = & self . mir . local_decls [ * local] ;
645
657
if let Some ( name) = local_decl. name {
646
658
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
+ ) ;
649
663
}
650
664
}
651
665
}
@@ -654,12 +668,26 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
654
668
}
655
669
}
656
670
671
+ pub ( super ) struct IncludingDowncast ( bool ) ;
672
+
657
673
impl < ' cx , ' gcx , ' tcx > MirBorrowckCtxt < ' cx , ' gcx , ' tcx > {
658
674
// End-user visible description of `place` if one can be found. If the
659
675
// place is a temporary for instance, None will be returned.
660
676
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 > {
661
689
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 ) {
663
691
Ok ( ( ) ) => Some ( buf) ,
664
692
Err ( ( ) ) => None ,
665
693
}
@@ -671,6 +699,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
671
699
place : & Place < ' tcx > ,
672
700
buf : & mut String ,
673
701
mut autoderef : bool ,
702
+ including_downcast : & IncludingDowncast ,
674
703
) -> Result < ( ) , ( ) > {
675
704
match * place {
676
705
Place :: Local ( local) => {
@@ -692,15 +721,33 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
692
721
}
693
722
} else {
694
723
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
+ ) ?;
696
730
} else {
697
731
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
+ ) ?;
699
738
}
700
739
}
701
740
}
702
741
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
+ }
704
751
}
705
752
ProjectionElem :: Field ( field, _ty) => {
706
753
autoderef = true ;
@@ -711,14 +758,24 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
711
758
buf. push_str ( & name) ;
712
759
} else {
713
760
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
+ ) ?;
715
767
buf. push_str ( & format ! ( ".{}" , field_name) ) ;
716
768
}
717
769
}
718
770
ProjectionElem :: Index ( index) => {
719
771
autoderef = true ;
720
772
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
+ ) ?;
722
779
buf. push_str ( "[" ) ;
723
780
if let Err ( _) = self . append_local_to_string ( index, buf) {
724
781
buf. push_str ( ".." ) ;
@@ -730,7 +787,12 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
730
787
// Since it isn't possible to borrow an element on a particular index and
731
788
// then use another while the borrow is held, don't output indices details
732
789
// 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
+ ) ?;
734
796
buf. push_str ( & "[..]" ) ;
735
797
}
736
798
} ;
0 commit comments