@@ -111,39 +111,42 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
111
111
// If that ever stops being the case, then the ever initialized
112
112
// flow could be used.
113
113
if let Some ( StatementKind :: Assign (
114
- Place :: Local ( local ) ,
114
+ place ,
115
115
box Rvalue :: Use ( Operand :: Move ( move_from) ) ,
116
116
) ) = self . mir . basic_blocks ( ) [ location. block ]
117
117
. statements
118
118
. get ( location. statement_index )
119
119
. map ( |stmt| & stmt. kind )
120
120
{
121
- let local_decl = & self . mir . local_decls [ * local] ;
122
- // opt_match_place is the
123
- // match_span is the span of the expression being matched on
124
- // match *x.y { ... } match_place is Some(*x.y)
125
- // ^^^^ match_span is the span of *x.y
126
- //
127
- // opt_match_place is None for let [mut] x = ... statements,
128
- // whether or not the right-hand side is a place expression
129
- if let Some ( ClearCrossCrate :: Set ( BindingForm :: Var ( VarBindingForm {
130
- opt_match_place : Some ( ( ref opt_match_place, match_span) ) ,
131
- binding_mode : _,
132
- opt_ty_info : _,
133
- pat_span : _,
134
- } ) ) ) = local_decl. is_user_variable
135
- {
136
- self . append_binding_error (
137
- grouped_errors,
138
- kind,
139
- original_path,
140
- move_from,
141
- * local,
142
- opt_match_place,
143
- match_span,
144
- stmt_source_info. span ,
145
- ) ;
146
- return ;
121
+ let neo_place = self . infcx . tcx . as_new_place ( & place) ;
122
+ if let Some ( PlaceBase :: Local ( local) ) = neo_place. as_place_base ( ) {
123
+ let local_decl = & self . mir . local_decls [ * local] ;
124
+ // opt_match_place is the
125
+ // match_span is the span of the expression being matched on
126
+ // match *x.y { ... } match_place is Some(*x.y)
127
+ // ^^^^ match_span is the span of *x.y
128
+ //
129
+ // opt_match_place is None for let [mut] x = ... statements,
130
+ // whether or not the right-hand side is a place expression
131
+ if let Some ( ClearCrossCrate :: Set ( BindingForm :: Var ( VarBindingForm {
132
+ opt_match_place : Some ( ( ref opt_match_place, match_span) ) ,
133
+ binding_mode : _,
134
+ opt_ty_info : _,
135
+ pat_span : _,
136
+ } ) ) ) = local_decl. is_user_variable
137
+ {
138
+ self . append_binding_error (
139
+ grouped_errors,
140
+ kind,
141
+ original_path,
142
+ move_from,
143
+ * local,
144
+ opt_match_place,
145
+ match_span,
146
+ stmt_source_info. span ,
147
+ ) ;
148
+ return ;
149
+ }
147
150
}
148
151
}
149
152
grouped_errors. push ( GroupedMoveError :: OtherIllegalMove {
@@ -269,12 +272,15 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
269
272
// Inspect the type of the content behind the
270
273
// borrow to provide feedback about why this
271
274
// was a move rather than a copy.
272
- let ty = place. ty ( self . mir , self . infcx . tcx ) . to_ty ( self . infcx . tcx ) ;
275
+ let neo_place = self . infcx . tcx . as_new_place ( & place) ;
276
+ let ty = neo_place. ty ( self . mir , self . infcx . tcx ) . to_ty ( self . infcx . tcx ) ;
277
+
273
278
let is_upvar_field_projection =
274
279
self . prefixes ( & original_path, PrefixSet :: All )
275
280
. map ( |p| self . infcx . tcx . as_new_place ( & p) )
276
281
. any ( |p| p. is_upvar_field_projection ( self . mir , & self . infcx . tcx )
277
- . is_some ( ) ) ;
282
+ . is_some ( )
283
+ ) ;
278
284
debug ! ( "report: ty={:?}" , ty) ;
279
285
match ty. sty {
280
286
ty:: Array ( ..) | ty:: Slice ( ..) =>
@@ -354,52 +360,54 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
354
360
err : & mut DiagnosticBuilder < ' a > ,
355
361
span : Span ,
356
362
) {
357
- let snippet = self . infcx . tcx . sess . source_map ( ) . span_to_snippet ( span) . unwrap ( ) ;
358
- match error {
359
- GroupedMoveError :: MovesFromPlace {
360
- mut binds_to,
361
- move_from,
362
- ..
363
- } => {
364
- let try_remove_deref = match move_from {
365
- Place :: Projection ( box PlaceProjection {
366
- elem : ProjectionElem :: Deref ,
367
- ..
368
- } ) => true ,
369
- _ => false ,
370
- } ;
371
- if try_remove_deref && snippet. starts_with ( '*' ) {
372
- // The snippet doesn't start with `*` in (e.g.) index
373
- // expressions `a[b]`, which roughly desugar to
374
- // `*Index::index(&a, b)` or
375
- // `*IndexMut::index_mut(&mut a, b)`.
376
- err. span_suggestion (
377
- span,
378
- "consider removing the `*`" ,
379
- snippet[ 1 ..] . to_owned ( ) ,
380
- Applicability :: Unspecified ,
381
- ) ;
382
- } else {
383
- err. span_suggestion (
384
- span,
385
- "consider borrowing here" ,
386
- format ! ( "&{}" , snippet) ,
387
- Applicability :: Unspecified ,
388
- ) ;
389
- }
363
+ if let Ok ( snippet) = self . infcx . tcx . sess
364
+ . source_map ( ) . span_to_snippet ( span) {
365
+ match error {
366
+ GroupedMoveError :: MovesFromPlace {
367
+ mut binds_to,
368
+ move_from,
369
+ ..
370
+ } => {
371
+ let try_remove_deref = match move_from {
372
+ Place :: Projection ( box PlaceProjection {
373
+ elem : ProjectionElem :: Deref ,
374
+ ..
375
+ } ) => true ,
376
+ _ => false ,
377
+ } ;
378
+ if try_remove_deref && snippet. starts_with ( '*' ) {
379
+ // The snippet doesn't start with `*` in (e.g.) index
380
+ // expressions `a[b]`, which roughly desugar to
381
+ // `*Index::index(&a, b)` or
382
+ // `*IndexMut::index_mut(&mut a, b)`.
383
+ err. span_suggestion (
384
+ span,
385
+ "consider removing the `*`" ,
386
+ snippet[ 1 ..] . to_owned ( ) ,
387
+ Applicability :: Unspecified ,
388
+ ) ;
389
+ } else {
390
+ err. span_suggestion (
391
+ span,
392
+ "consider borrowing here" ,
393
+ format ! ( "&{}" , snippet) ,
394
+ Applicability :: Unspecified ,
395
+ ) ;
396
+ }
390
397
391
- binds_to. sort ( ) ;
392
- binds_to. dedup ( ) ;
393
- self . add_move_error_details ( err, & binds_to) ;
394
- }
395
- GroupedMoveError :: MovesFromValue { mut binds_to, .. } => {
396
- binds_to. sort ( ) ;
397
- binds_to. dedup ( ) ;
398
- self . add_move_error_suggestions ( err, & binds_to) ;
399
- self . add_move_error_details ( err, & binds_to) ;
398
+ binds_to. sort ( ) ;
399
+ binds_to. dedup ( ) ;
400
+ self . add_move_error_details ( err, & binds_to) ;
401
+ }
402
+ GroupedMoveError :: MovesFromValue { mut binds_to, .. } => {
403
+ binds_to. sort ( ) ;
404
+ binds_to. dedup ( ) ;
405
+ self . add_move_error_suggestions ( err, & binds_to) ;
406
+ self . add_move_error_details ( err, & binds_to) ;
407
+ }
408
+ // No binding. Nothing to suggest.
409
+ GroupedMoveError :: OtherIllegalMove { .. } => ( ) ,
400
410
}
401
- // No binding. Nothing to suggest.
402
- GroupedMoveError :: OtherIllegalMove { .. } => ( ) ,
403
411
}
404
412
}
405
413
@@ -417,27 +425,28 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
417
425
..
418
426
} ) )
419
427
) = bind_to. is_user_variable {
420
- let pat_snippet = self . infcx . tcx . sess . source_map ( )
421
- . span_to_snippet ( pat_span)
422
- . unwrap ( ) ;
423
- if pat_snippet. starts_with ( '&' ) {
424
- let pat_snippet = pat_snippet[ 1 ..] . trim_start ( ) ;
425
- let suggestion;
426
- let to_remove;
427
- if pat_snippet. starts_with ( "mut" )
428
- && pat_snippet[ "mut" . len ( ) ..] . starts_with ( Pattern_White_Space )
429
- {
430
- suggestion = pat_snippet[ "mut" . len ( ) ..] . trim_start ( ) ;
431
- to_remove = "&mut" ;
432
- } else {
433
- suggestion = pat_snippet;
434
- to_remove = "&" ;
428
+ if let Ok ( pat_snippet) = self . infcx . tcx . sess
429
+ . source_map ( )
430
+ . span_to_snippet ( pat_span) {
431
+ if pat_snippet. starts_with ( '&' ) {
432
+ let pat_snippet = pat_snippet[ 1 ..] . trim_start ( ) ;
433
+ let suggestion;
434
+ let to_remove;
435
+ if pat_snippet. starts_with ( "mut" )
436
+ && pat_snippet[ "mut" . len ( ) ..] . starts_with ( Pattern_White_Space )
437
+ {
438
+ suggestion = pat_snippet[ "mut" . len ( ) ..] . trim_start ( ) ;
439
+ to_remove = "&mut" ;
440
+ } else {
441
+ suggestion = pat_snippet;
442
+ to_remove = "&" ;
443
+ }
444
+ suggestions. push ( (
445
+ pat_span,
446
+ to_remove,
447
+ suggestion. to_owned ( ) ,
448
+ ) ) ;
435
449
}
436
- suggestions. push ( (
437
- pat_span,
438
- to_remove,
439
- suggestion. to_owned ( ) ,
440
- ) ) ;
441
450
}
442
451
}
443
452
}
@@ -536,7 +545,8 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
536
545
// We're only interested in assignments (in particular, where the
537
546
// assignment came from - was it an `Rc` or `Arc`?).
538
547
if let StatementKind :: Assign ( _, box Rvalue :: Ref ( _, _, source) ) = & stmt. kind {
539
- let ty = source. ty ( self . mir , self . infcx . tcx ) . to_ty ( self . infcx . tcx ) ;
548
+ let neo_place = self . infcx . tcx . as_new_place ( source) ;
549
+ let ty = neo_place. ty ( self . mir , self . infcx . tcx ) . to_ty ( self . infcx . tcx ) ;
540
550
let ty = match ty. sty {
541
551
ty:: TyKind :: Ref ( _, ty, _) => ty,
542
552
_ => ty,
@@ -560,8 +570,8 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
560
570
Operand :: Copy ( place) | Operand :: Move ( place) => place,
561
571
_ => continue ,
562
572
} ;
563
-
564
- let ty = source . ty ( self . mir , self . infcx . tcx ) . to_ty ( self . infcx . tcx ) ;
573
+ let neo_place = self . infcx . tcx . as_new_place ( & source ) ;
574
+ let ty = neo_place . ty ( self . mir , self . infcx . tcx ) . to_ty ( self . infcx . tcx ) ;
565
575
let ty = match ty. sty {
566
576
ty:: TyKind :: Ref ( _, ty, _) => ty,
567
577
_ => ty,
@@ -583,11 +593,14 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
583
593
// If we didn't find an `Arc` or an `Rc`, then check specifically for
584
594
// a dereference of a place that has the type of a raw pointer.
585
595
// We can't use `place.ty(..).to_ty(..)` here as that strips away the raw pointer.
586
- if let Place :: Projection ( box Projection {
587
- base,
588
- elem : ProjectionElem :: Deref ,
589
- } ) = place {
590
- if base. ty ( self . mir , self . infcx . tcx ) . to_ty ( self . infcx . tcx ) . is_unsafe_ptr ( ) {
596
+ let neo_place = self . infcx . tcx . as_new_place ( & place) ;
597
+ let place_tys = neo_place. place_tys ( & self . mir , self . infcx . tcx ) ;
598
+ if let Some ( & ProjectionElem :: Deref ) = neo_place. elems . last ( ) {
599
+ // Given place
600
+ // base.[a, b, c]
601
+ // ^-- deref
602
+ // ^^^^^^^^^^
603
+ if place_tys[ place_tys. len ( ) - 2 ] . to_ty ( self . infcx . tcx ) . is_unsafe_ptr ( ) {
591
604
return BorrowedContentSource :: DerefRawPointer ;
592
605
}
593
606
}
0 commit comments