@@ -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+
657673impl < ' 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