@@ -242,12 +242,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
242
242
let ( mut err, err_span) = {
243
243
let ( span, original_path, kind) : ( Span , & Place < ' tcx > , & IllegalMoveOriginKind < ' _ > ) =
244
244
match error {
245
- GroupedMoveError :: MovesFromPlace {
246
- span,
247
- ref original_path,
248
- ref kind,
249
- ..
250
- } |
245
+ GroupedMoveError :: MovesFromPlace { span, ref original_path, ref kind, .. } |
251
246
GroupedMoveError :: MovesFromValue { span, ref original_path, ref kind, .. } |
252
247
GroupedMoveError :: OtherIllegalMove { span, ref original_path, ref kind } => {
253
248
( span, original_path, kind)
@@ -257,81 +252,99 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
257
252
debug ! ( "report: original_path={:?} span={:?}, kind={:?} \
258
253
original_path.is_upvar_field_projection={:?}", original_path, span, kind,
259
254
self . is_upvar_field_projection( original_path) ) ;
260
- (
261
- match kind {
262
- IllegalMoveOriginKind :: Static => {
263
- self . infcx . tcx . cannot_move_out_of ( span, "static item" , origin)
264
- }
265
- IllegalMoveOriginKind :: BorrowedContent { target_place : place } => {
266
- // Inspect the type of the content behind the
267
- // borrow to provide feedback about why this
268
- // was a move rather than a copy.
269
- let ty = place. ty ( self . mir , self . infcx . tcx ) . ty ;
270
- let is_upvar_field_projection =
271
- self . prefixes ( & original_path, PrefixSet :: All )
272
- . any ( |p| self . is_upvar_field_projection ( p) . is_some ( ) ) ;
273
- debug ! ( "report: ty={:?}" , ty) ;
274
- match ty. sty {
275
- ty:: Array ( ..) | ty:: Slice ( ..) =>
276
- self . infcx . tcx . cannot_move_out_of_interior_noncopy (
277
- span, ty, None , origin
278
- ) ,
279
- ty:: Closure ( def_id, closure_substs)
280
- if def_id == self . mir_def_id && is_upvar_field_projection
281
- => {
282
- let closure_kind_ty =
283
- closure_substs. closure_kind_ty ( def_id, self . infcx . tcx ) ;
284
- let closure_kind = closure_kind_ty. to_opt_closure_kind ( ) ;
285
- let place_description = match closure_kind {
286
- Some ( ty:: ClosureKind :: Fn ) => {
287
- "captured variable in an `Fn` closure"
288
- }
289
- Some ( ty:: ClosureKind :: FnMut ) => {
290
- "captured variable in an `FnMut` closure"
291
- }
292
- Some ( ty:: ClosureKind :: FnOnce ) => {
293
- bug ! ( "closure kind does not match first argument type" )
294
- }
295
- None => bug ! ( "closure kind not inferred by borrowck" ) ,
296
- } ;
297
- debug ! ( "report: closure_kind_ty={:?} closure_kind={:?} \
298
- place_description={:?}", closure_kind_ty, closure_kind,
299
- place_description) ;
300
-
301
- let mut diag = self . infcx . tcx . cannot_move_out_of (
302
- span, place_description, origin) ;
303
-
304
- for prefix in self . prefixes ( & original_path, PrefixSet :: All ) {
305
- if let Some ( field) = self . is_upvar_field_projection ( prefix) {
306
- let upvar_hir_id = self . upvars [ field. index ( ) ] . var_hir_id ;
307
- let upvar_span = self . infcx . tcx . hir ( ) . span_by_hir_id (
308
- upvar_hir_id) ;
309
- diag. span_label ( upvar_span, "captured outer variable" ) ;
310
- break ;
311
- }
255
+ let err = match kind {
256
+ IllegalMoveOriginKind :: Static => {
257
+ self . infcx . tcx . cannot_move_out_of ( span, "static item" , origin)
258
+ }
259
+ IllegalMoveOriginKind :: BorrowedContent { target_place : place } => {
260
+ // Inspect the type of the content behind the
261
+ // borrow to provide feedback about why this
262
+ // was a move rather than a copy.
263
+ let ty = place. ty ( self . mir , self . infcx . tcx ) . ty ;
264
+ let is_upvar_field_projection =
265
+ self . prefixes ( & original_path, PrefixSet :: All )
266
+ . any ( |p| self . is_upvar_field_projection ( p) . is_some ( ) ) ;
267
+ debug ! ( "report: ty={:?}" , ty) ;
268
+ let mut err = match ty. sty {
269
+ ty:: Array ( ..) | ty:: Slice ( ..) =>
270
+ self . infcx . tcx . cannot_move_out_of_interior_noncopy (
271
+ span, ty, None , origin
272
+ ) ,
273
+ ty:: Closure ( def_id, closure_substs)
274
+ if def_id == self . mir_def_id && is_upvar_field_projection
275
+ => {
276
+ let closure_kind_ty =
277
+ closure_substs. closure_kind_ty ( def_id, self . infcx . tcx ) ;
278
+ let closure_kind = closure_kind_ty. to_opt_closure_kind ( ) ;
279
+ let place_description = match closure_kind {
280
+ Some ( ty:: ClosureKind :: Fn ) => {
281
+ "captured variable in an `Fn` closure"
282
+ }
283
+ Some ( ty:: ClosureKind :: FnMut ) => {
284
+ "captured variable in an `FnMut` closure"
285
+ }
286
+ Some ( ty:: ClosureKind :: FnOnce ) => {
287
+ bug ! ( "closure kind does not match first argument type" )
288
+ }
289
+ None => bug ! ( "closure kind not inferred by borrowck" ) ,
290
+ } ;
291
+ debug ! ( "report: closure_kind_ty={:?} closure_kind={:?} \
292
+ place_description={:?}", closure_kind_ty, closure_kind,
293
+ place_description) ;
294
+
295
+ let mut diag = self . infcx . tcx . cannot_move_out_of (
296
+ span, place_description, origin) ;
297
+
298
+ for prefix in self . prefixes ( & original_path, PrefixSet :: All ) {
299
+ if let Some ( field) = self . is_upvar_field_projection ( prefix) {
300
+ let upvar_hir_id = self . upvars [ field. index ( ) ] . var_hir_id ;
301
+ let upvar_span = self . infcx . tcx . hir ( ) . span_by_hir_id (
302
+ upvar_hir_id) ;
303
+ diag. span_label ( upvar_span, "captured outer variable" ) ;
304
+ break ;
312
305
}
313
-
314
- diag
315
306
}
316
- _ => {
317
- let source = self . borrowed_content_source ( place) ;
318
- self . infcx . tcx . cannot_move_out_of (
319
- span, & source. to_string ( ) , origin
320
- )
321
- } ,
307
+
308
+ diag
322
309
}
310
+ _ => {
311
+ let source = self . borrowed_content_source ( place) ;
312
+ self . infcx . tcx . cannot_move_out_of (
313
+ span, & source. to_string ( ) , origin
314
+ )
315
+ } ,
316
+ } ;
317
+ let orig_path_ty = format ! (
318
+ "{:?}" ,
319
+ original_path. ty( self . mir, self . infcx. tcx) . ty,
320
+ ) ;
321
+ let snippet = self . infcx . tcx . sess . source_map ( ) . span_to_snippet ( span) . unwrap ( ) ;
322
+ let is_option = orig_path_ty. starts_with ( "std::option::Option" ) ;
323
+ let is_result = orig_path_ty. starts_with ( "std::result::Result" ) ;
324
+ if is_option || is_result {
325
+ err. span_suggestion (
326
+ span,
327
+ & format ! ( "consider borrowing the `{}`'s content" , if is_option {
328
+ "Option"
329
+ } else {
330
+ "Result"
331
+ } ) ,
332
+ format ! ( "{}.as_ref()" , snippet) ,
333
+ Applicability :: MaybeIncorrect ,
334
+ ) ;
323
335
}
324
- IllegalMoveOriginKind :: InteriorOfTypeWithDestructor { container_ty : ty } => {
325
- self . infcx . tcx
326
- . cannot_move_out_of_interior_of_drop ( span, ty, origin)
327
- }
328
- IllegalMoveOriginKind :: InteriorOfSliceOrArray { ty, is_index } =>
329
- self . infcx . tcx . cannot_move_out_of_interior_noncopy (
330
- span, ty, Some ( * is_index) , origin
331
- ) ,
332
- } ,
333
- span,
334
- )
336
+ err
337
+ }
338
+ IllegalMoveOriginKind :: InteriorOfTypeWithDestructor { container_ty : ty } => {
339
+ self . infcx . tcx
340
+ . cannot_move_out_of_interior_of_drop ( span, ty, origin)
341
+ }
342
+ IllegalMoveOriginKind :: InteriorOfSliceOrArray { ty, is_index } =>
343
+ self . infcx . tcx . cannot_move_out_of_interior_noncopy (
344
+ span, ty, Some ( * is_index) , origin
345
+ ) ,
346
+ } ;
347
+ ( err, span)
335
348
} ;
336
349
337
350
self . add_move_hints ( error, & mut err, err_span) ;
0 commit comments