@@ -1053,12 +1053,12 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
1053
1053
// End-user visible description of `lvalue`
1054
1054
fn describe_lvalue ( & self , lvalue : & Lvalue ) -> String {
1055
1055
let mut buf = String :: new ( ) ;
1056
- self . append_lvalue_to_string ( lvalue, & mut buf) ;
1056
+ self . append_lvalue_to_string ( lvalue, & mut buf, None ) ;
1057
1057
buf
1058
1058
}
1059
1059
1060
1060
// Appends end-user visible description of `lvalue` to `buf`.
1061
- fn append_lvalue_to_string ( & self , lvalue : & Lvalue , buf : & mut String ) {
1061
+ fn append_lvalue_to_string ( & self , lvalue : & Lvalue , buf : & mut String , autoderef : Option < bool > ) {
1062
1062
match * lvalue {
1063
1063
Lvalue :: Local ( local) => {
1064
1064
let local = & self . mir . local_decls [ local] ;
@@ -1071,15 +1071,25 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
1071
1071
buf. push_str ( & format ! ( "{}" , & self . tcx. item_name( static_. def_id) ) ) ;
1072
1072
}
1073
1073
Lvalue :: Projection ( ref proj) => {
1074
+ let mut autoderef = autoderef. unwrap_or ( false ) ;
1074
1075
let ( prefix, suffix, index_operand) = match proj. elem {
1075
- ProjectionElem :: Deref =>
1076
- ( "(*" , format ! ( ")" ) , None ) ,
1076
+ ProjectionElem :: Deref => {
1077
+ if autoderef {
1078
+ ( "" , format ! ( "" ) , None )
1079
+ } else {
1080
+ ( "(*" , format ! ( ")" ) , None )
1081
+ }
1082
+ } ,
1077
1083
ProjectionElem :: Downcast ( ..) =>
1078
1084
( "" , format ! ( "" ) , None ) , // (dont emit downcast info)
1079
- ProjectionElem :: Field ( field, _ty) =>
1080
- ( "" , format ! ( ".{}" , field. index( ) ) , None ) , // FIXME: report name of field
1081
- ProjectionElem :: Index ( index) =>
1082
- ( "" , format ! ( "" ) , Some ( index) ) ,
1085
+ ProjectionElem :: Field ( field, _ty) => {
1086
+ autoderef = true ;
1087
+ ( "" , format ! ( ".{}" , self . describe_field( & proj. base, field. index( ) ) ) , None )
1088
+ } ,
1089
+ ProjectionElem :: Index ( index) => {
1090
+ autoderef = true ;
1091
+ ( "" , format ! ( "" ) , Some ( index) )
1092
+ } ,
1083
1093
ProjectionElem :: ConstantIndex { offset, min_length, from_end : true } =>
1084
1094
( "" , format ! ( "[{} of {}]" , offset, min_length) , None ) ,
1085
1095
ProjectionElem :: ConstantIndex { offset, min_length, from_end : false } =>
@@ -1092,10 +1102,10 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
1092
1102
( "" , format ! ( "[{}:-{}]" , from, to) , None ) ,
1093
1103
} ;
1094
1104
buf. push_str ( prefix) ;
1095
- self . append_lvalue_to_string ( & proj. base , buf) ;
1105
+ self . append_lvalue_to_string ( & proj. base , buf, Some ( autoderef ) ) ;
1096
1106
if let Some ( index) = index_operand {
1097
1107
buf. push_str ( "[" ) ;
1098
- self . append_lvalue_to_string ( & Lvalue :: Local ( index) , buf) ;
1108
+ self . append_lvalue_to_string ( & Lvalue :: Local ( index) , buf, None ) ;
1099
1109
buf. push_str ( "]" ) ;
1100
1110
} else {
1101
1111
buf. push_str ( & suffix) ;
@@ -1104,6 +1114,77 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
1104
1114
}
1105
1115
}
1106
1116
1117
+ // End-user visible description of the `field_index`nth field of `base`
1118
+ fn describe_field ( & self , base : & Lvalue , field_index : usize ) -> String {
1119
+ match * base {
1120
+ Lvalue :: Local ( local) => {
1121
+ let local = & self . mir . local_decls [ local] ;
1122
+ self . describe_field_from_ty ( & local. ty , field_index)
1123
+ } ,
1124
+ Lvalue :: Static ( ref static_) => {
1125
+ self . describe_field_from_ty ( & static_. ty , field_index)
1126
+ } ,
1127
+ Lvalue :: Projection ( ref proj) => {
1128
+ match proj. elem {
1129
+ ProjectionElem :: Deref =>
1130
+ self . describe_field ( & proj. base , field_index) ,
1131
+ ProjectionElem :: Downcast ( ..) => {
1132
+ debug ! ( "End-user description not implemented for field of projection {:?}" ,
1133
+ proj) ;
1134
+ format ! ( "<downcast>{}" , field_index)
1135
+ } ,
1136
+ ProjectionElem :: Field ( ..) => {
1137
+ debug ! ( "End-user description not implemented for field of projection {:?}" ,
1138
+ proj) ;
1139
+ format ! ( "<field>{}" , field_index)
1140
+ } ,
1141
+ ProjectionElem :: Index ( ..) => {
1142
+ debug ! ( "End-user description not implemented for field of projection {:?}" ,
1143
+ proj) ;
1144
+ format ! ( "<index>{}" , field_index)
1145
+ } ,
1146
+ ProjectionElem :: ConstantIndex { .. } => {
1147
+ debug ! ( "End-user description not implemented for field of projection {:?}" ,
1148
+ proj) ;
1149
+ format ! ( "<constant_index>{}" , field_index)
1150
+ } ,
1151
+ ProjectionElem :: Subslice { .. } => {
1152
+ debug ! ( "End-user description not implemented for field of projection {:?}" ,
1153
+ proj) ;
1154
+ format ! ( "<subslice>{}" , field_index)
1155
+ }
1156
+ }
1157
+ }
1158
+ }
1159
+ }
1160
+
1161
+ // End-user visible description of the `field_index`nth field of `ty`
1162
+ fn describe_field_from_ty ( & self , ty : & ty:: Ty , field_index : usize ) -> String {
1163
+ if ty. is_box ( ) {
1164
+ // If the type is a box, the field is described from the boxed type
1165
+ self . describe_field_from_ty ( & ty. boxed_ty ( ) , field_index)
1166
+ }
1167
+ else {
1168
+ match ty. sty {
1169
+ ty:: TyAdt ( def, _) => {
1170
+ if def. is_enum ( ) {
1171
+ format ! ( "{}" , field_index)
1172
+ }
1173
+ else {
1174
+ format ! ( "{}" , def. struct_variant( ) . fields[ field_index] . name)
1175
+ }
1176
+ } ,
1177
+ ty:: TyTuple ( _, _) => {
1178
+ format ! ( "{}" , field_index)
1179
+ } ,
1180
+ _ => {
1181
+ debug ! ( "End-user description not implemented for field of type {:?}" , ty. sty) ;
1182
+ format ! ( "<ty>{}" , field_index)
1183
+ }
1184
+ }
1185
+ }
1186
+ }
1187
+
1107
1188
// Retrieve span of given borrow from the current MIR representation
1108
1189
fn retrieve_borrow_span ( & self , borrow : & BorrowData ) -> Span {
1109
1190
self . mir . basic_blocks ( ) [ borrow. location . block ]
0 commit comments