11
11
use rustc:: hir;
12
12
use rustc:: mir:: * ;
13
13
use rustc:: ty;
14
- use rustc_data_structures:: indexed_vec:: Idx ;
15
14
use rustc_errors:: DiagnosticBuilder ;
15
+ use rustc_data_structures:: indexed_vec:: Idx ;
16
16
use syntax_pos:: Span ;
17
17
18
18
use borrow_check:: MirBorrowckCtxt ;
@@ -38,6 +38,7 @@ enum GroupedMoveError<'tcx> {
38
38
// Match place can't be moved from
39
39
// e.g. match x[0] { s => (), } where x: &[String]
40
40
MovesFromMatchPlace {
41
+ original_path : Place < ' tcx > ,
41
42
span : Span ,
42
43
move_from : Place < ' tcx > ,
43
44
kind : IllegalMoveOriginKind < ' tcx > ,
@@ -46,37 +47,43 @@ enum GroupedMoveError<'tcx> {
46
47
// Part of a pattern can't be moved from,
47
48
// e.g. match &String::new() { &x => (), }
48
49
MovesFromPattern {
50
+ original_path : Place < ' tcx > ,
49
51
span : Span ,
50
52
move_from : MovePathIndex ,
51
53
kind : IllegalMoveOriginKind < ' tcx > ,
52
54
binds_to : Vec < Local > ,
53
55
} ,
54
56
// Everything that isn't from pattern matching.
55
57
OtherIllegalMove {
58
+ original_path : Place < ' tcx > ,
56
59
span : Span ,
57
60
kind : IllegalMoveOriginKind < ' tcx > ,
58
61
} ,
59
62
}
60
63
61
64
impl < ' a , ' gcx , ' tcx > MirBorrowckCtxt < ' a , ' gcx , ' tcx > {
62
- pub ( crate ) fn report_move_errors ( & mut self , move_errors : Vec < MoveError < ' tcx > > ) {
65
+ pub ( crate ) fn report_move_errors ( & mut self , move_errors : Vec < ( Place < ' tcx > , MoveError < ' tcx > ) > ) {
63
66
let grouped_errors = self . group_move_errors ( move_errors) ;
64
67
for error in grouped_errors {
65
68
self . report ( error) ;
66
69
}
67
70
}
68
71
69
- fn group_move_errors ( & self , errors : Vec < MoveError < ' tcx > > ) -> Vec < GroupedMoveError < ' tcx > > {
72
+ fn group_move_errors (
73
+ & self ,
74
+ errors : Vec < ( Place < ' tcx > , MoveError < ' tcx > ) >
75
+ ) -> Vec < GroupedMoveError < ' tcx > > {
70
76
let mut grouped_errors = Vec :: new ( ) ;
71
- for error in errors {
72
- self . append_to_grouped_errors ( & mut grouped_errors, error) ;
77
+ for ( original_path , error) in errors {
78
+ self . append_to_grouped_errors ( & mut grouped_errors, original_path , error) ;
73
79
}
74
80
grouped_errors
75
81
}
76
82
77
83
fn append_to_grouped_errors (
78
84
& self ,
79
85
grouped_errors : & mut Vec < GroupedMoveError < ' tcx > > ,
86
+ original_path : Place < ' tcx > ,
80
87
error : MoveError < ' tcx > ,
81
88
) {
82
89
match error {
@@ -116,6 +123,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
116
123
self . append_binding_error (
117
124
grouped_errors,
118
125
kind,
126
+ original_path,
119
127
move_from,
120
128
* local,
121
129
opt_match_place,
@@ -127,6 +135,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
127
135
}
128
136
grouped_errors. push ( GroupedMoveError :: OtherIllegalMove {
129
137
span : stmt_source_info. span ,
138
+ original_path,
130
139
kind,
131
140
} ) ;
132
141
}
@@ -137,6 +146,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
137
146
& self ,
138
147
grouped_errors : & mut Vec < GroupedMoveError < ' tcx > > ,
139
148
kind : IllegalMoveOriginKind < ' tcx > ,
149
+ original_path : Place < ' tcx > ,
140
150
move_from : & Place < ' tcx > ,
141
151
bind_to : Local ,
142
152
match_place : & Option < Place < ' tcx > > ,
@@ -176,6 +186,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
176
186
grouped_errors. push ( GroupedMoveError :: MovesFromMatchPlace {
177
187
span,
178
188
move_from : match_place. clone ( ) ,
189
+ original_path,
179
190
kind,
180
191
binds_to,
181
192
} ) ;
@@ -206,6 +217,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
206
217
grouped_errors. push ( GroupedMoveError :: MovesFromPattern {
207
218
span : match_span,
208
219
move_from : mpi,
220
+ original_path,
209
221
kind,
210
222
binds_to : vec ! [ bind_to] ,
211
223
} ) ;
@@ -215,13 +227,23 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
215
227
216
228
fn report ( & mut self , error : GroupedMoveError < ' tcx > ) {
217
229
let ( mut err, err_span) = {
218
- let ( span, kind) : ( Span , & IllegalMoveOriginKind ) = match error {
219
- GroupedMoveError :: MovesFromMatchPlace { span, ref kind, .. }
220
- | GroupedMoveError :: MovesFromPattern { span, ref kind, .. }
221
- | GroupedMoveError :: OtherIllegalMove { span, ref kind } => ( span, kind) ,
222
- } ;
230
+ let ( span, original_path, kind) : ( Span , & Place < ' tcx > , & IllegalMoveOriginKind ) =
231
+ match error {
232
+ GroupedMoveError :: MovesFromMatchPlace {
233
+ span,
234
+ ref original_path,
235
+ ref kind,
236
+ ..
237
+ } |
238
+ GroupedMoveError :: MovesFromPattern { span, ref original_path, ref kind, .. } |
239
+ GroupedMoveError :: OtherIllegalMove { span, ref original_path, ref kind } => {
240
+ ( span, original_path, kind)
241
+ } ,
242
+ } ;
223
243
let origin = Origin :: Mir ;
224
- debug ! ( "report: span={:?}, kind={:?}" , span, kind) ;
244
+ debug ! ( "report: original_path={:?} span={:?}, kind={:?} \
245
+ original_path.is_upvar_field_projection={:?}", original_path, span, kind,
246
+ original_path. is_upvar_field_projection( self . mir, & self . tcx) ) ;
225
247
(
226
248
match kind {
227
249
IllegalMoveOriginKind :: Static => {
@@ -237,17 +259,11 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
237
259
. tcx
238
260
. cannot_move_out_of_interior_noncopy ( span, ty, None , origin) ,
239
261
ty:: TyClosure ( def_id, closure_substs)
240
- if !self . mir . upvar_decls . is_empty ( )
241
- && {
242
- match place {
243
- Place :: Projection ( ref proj) => {
244
- proj. base == Place :: Local ( Local :: new ( 1 ) )
245
- }
246
- Place :: Promoted ( _) |
247
- Place :: Local ( _) | Place :: Static ( _) => unreachable ! ( ) ,
248
- }
249
- } =>
250
- {
262
+ if !self . mir . upvar_decls . is_empty ( ) &&
263
+ original_path. strip_deref_projections ( )
264
+ . is_upvar_field_projection ( self . mir , & self . tcx )
265
+ . is_some ( )
266
+ => {
251
267
let closure_kind_ty =
252
268
closure_substs. closure_kind_ty ( def_id, self . tcx ) ;
253
269
let closure_kind = closure_kind_ty. to_opt_closure_kind ( ) ;
@@ -267,7 +283,19 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
267
283
place_description={:?}", closure_kind_ty, closure_kind,
268
284
place_description) ;
269
285
270
- self . tcx . cannot_move_out_of ( span, place_description, origin)
286
+ let mut diag = self . tcx . cannot_move_out_of (
287
+ span, place_description, origin) ;
288
+
289
+ if let Some ( field) = original_path. is_upvar_field_projection (
290
+ self . mir , & self . tcx ) {
291
+ let upvar_decl = & self . mir . upvar_decls [ field. index ( ) ] ;
292
+ let upvar_hir_id = upvar_decl. var_hir_id . assert_crate_local ( ) ;
293
+ let upvar_node_id = self . tcx . hir . hir_to_node_id ( upvar_hir_id) ;
294
+ let upvar_span = self . tcx . hir . span ( upvar_node_id) ;
295
+ diag. span_label ( upvar_span, "captured outer variable" ) ;
296
+ }
297
+
298
+ diag
271
299
}
272
300
_ => self
273
301
. tcx
0 commit comments