@@ -242,12 +242,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
242242 let ( mut err, err_span) = {
243243 let ( span, original_path, kind) : ( Span , & Place < ' tcx > , & IllegalMoveOriginKind < ' _ > ) =
244244 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, .. } |
251246 GroupedMoveError :: MovesFromValue { span, ref original_path, ref kind, .. } |
252247 GroupedMoveError :: OtherIllegalMove { span, ref original_path, ref kind } => {
253248 ( span, original_path, kind)
@@ -257,81 +252,99 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
257252 debug ! ( "report: original_path={:?} span={:?}, kind={:?} \
258253 original_path.is_upvar_field_projection={:?}", original_path, span, kind,
259254 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 ;
312305 }
313-
314- diag
315306 }
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
322309 }
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+ ) ;
323335 }
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)
335348 } ;
336349
337350 self . add_move_hints ( error, & mut err, err_span) ;
0 commit comments