@@ -198,13 +198,14 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
198
198
}
199
199
200
200
/// Like `pat_ty`, but ignores implicit `&` patterns.
201
+ #[ instrument( level = "debug" , skip( self ) , ret) ]
201
202
fn pat_ty_unadjusted ( & self , pat : & hir:: Pat < ' _ > ) -> McResult < Ty < ' tcx > > {
202
203
let base_ty = self . node_ty ( pat. hir_id ) ?;
203
- debug ! ( "pat_ty(pat={:?}) base_ty={:?}" , pat , base_ty) ;
204
+ trace ! ( ? base_ty) ;
204
205
205
206
// This code detects whether we are looking at a `ref x`,
206
207
// and if so, figures out what the type *being borrowed* is.
207
- let ret_ty = match pat. kind {
208
+ match pat. kind {
208
209
PatKind :: Binding ( ..) => {
209
210
let bm = * self
210
211
. typeck_results
@@ -217,21 +218,18 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
217
218
// but what we want here is the type of the underlying value being borrowed.
218
219
// So peel off one-level, turning the &T into T.
219
220
match base_ty. builtin_deref ( false ) {
220
- Some ( t) => t. ty ,
221
+ Some ( t) => Ok ( t. ty ) ,
221
222
None => {
222
- debug ! ( "By-ref binding of non-derefable type {:?}" , base_ty ) ;
223
- return Err ( ( ) ) ;
223
+ debug ! ( "By-ref binding of non-derefable type" ) ;
224
+ Err ( ( ) )
224
225
}
225
226
}
226
227
} else {
227
- base_ty
228
+ Ok ( base_ty)
228
229
}
229
230
}
230
- _ => base_ty,
231
- } ;
232
- debug ! ( "pat_ty(pat={:?}) ret_ty={:?}" , pat, ret_ty) ;
233
-
234
- Ok ( ret_ty)
231
+ _ => Ok ( base_ty) ,
232
+ }
235
233
}
236
234
237
235
pub ( crate ) fn cat_expr ( & self , expr : & hir:: Expr < ' _ > ) -> McResult < PlaceWithHirId < ' tcx > > {
@@ -299,13 +297,11 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
299
297
}
300
298
}
301
299
302
- #[ instrument( level = "debug" , skip( self ) ) ]
300
+ #[ instrument( level = "debug" , skip( self ) , ret ) ]
303
301
pub ( crate ) fn cat_expr_unadjusted (
304
302
& self ,
305
303
expr : & hir:: Expr < ' _ > ,
306
304
) -> McResult < PlaceWithHirId < ' tcx > > {
307
- debug ! ( "cat_expr: id={} expr={:?}" , expr. hir_id, expr) ;
308
-
309
305
let expr_ty = self . expr_ty ( expr) ?;
310
306
match expr. kind {
311
307
hir:: ExprKind :: Unary ( hir:: UnOp :: Deref , ref e_base) => {
@@ -319,7 +315,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
319
315
320
316
hir:: ExprKind :: Field ( ref base, _) => {
321
317
let base = self . cat_expr ( base) ?;
322
- debug ! ( "cat_expr(cat_field): id={} expr={:?} base={:?}" , expr . hir_id , expr , base) ;
318
+ debug ! ( ? base) ;
323
319
324
320
let field_idx = self
325
321
. typeck_results
@@ -389,7 +385,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
389
385
}
390
386
}
391
387
392
- #[ instrument( level = "debug" , skip( self , span) ) ]
388
+ #[ instrument( level = "debug" , skip( self , span) , ret ) ]
393
389
pub ( crate ) fn cat_res (
394
390
& self ,
395
391
hir_id : hir:: HirId ,
@@ -430,6 +426,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
430
426
/// Note: the actual upvar access contains invisible derefs of closure
431
427
/// environment and upvar reference as appropriate. Only regionck cares
432
428
/// about these dereferences, so we let it compute them as needed.
429
+ #[ instrument( level = "debug" , skip( self ) , ret) ]
433
430
fn cat_upvar ( & self , hir_id : hir:: HirId , var_id : hir:: HirId ) -> McResult < PlaceWithHirId < ' tcx > > {
434
431
let closure_expr_def_id = self . body_owner ;
435
432
@@ -439,41 +436,44 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
439
436
} ;
440
437
let var_ty = self . node_ty ( var_id) ?;
441
438
442
- let ret = PlaceWithHirId :: new ( hir_id, var_ty, PlaceBase :: Upvar ( upvar_id) , Vec :: new ( ) ) ;
443
-
444
- debug ! ( "cat_upvar ret={:?}" , ret) ;
445
- Ok ( ret)
439
+ Ok ( PlaceWithHirId :: new ( hir_id, var_ty, PlaceBase :: Upvar ( upvar_id) , Vec :: new ( ) ) )
446
440
}
447
441
442
+ #[ instrument( level = "debug" , skip( self ) , ret) ]
448
443
pub ( crate ) fn cat_rvalue (
449
444
& self ,
450
445
hir_id : hir:: HirId ,
451
446
span : Span ,
452
447
expr_ty : Ty < ' tcx > ,
453
448
) -> PlaceWithHirId < ' tcx > {
454
- debug ! ( "cat_rvalue hir_id={:?}, expr_ty={:?}, span={:?}" , hir_id, expr_ty, span) ;
455
- let ret = PlaceWithHirId :: new ( hir_id, expr_ty, PlaceBase :: Rvalue , Vec :: new ( ) ) ;
456
- debug ! ( "cat_rvalue ret={:?}" , ret) ;
457
- ret
449
+ PlaceWithHirId :: new ( hir_id, expr_ty, PlaceBase :: Rvalue , Vec :: new ( ) )
458
450
}
459
451
452
+ #[ instrument( level = "debug" , skip( self , node) , ret) ]
460
453
pub ( crate ) fn cat_projection < N : HirNode > (
461
454
& self ,
462
455
node : & N ,
463
456
base_place : PlaceWithHirId < ' tcx > ,
464
457
ty : Ty < ' tcx > ,
465
458
kind : ProjectionKind ,
466
459
) -> PlaceWithHirId < ' tcx > {
460
+ let place_ty = base_place. place . ty ( ) ;
467
461
let mut projections = base_place. place . projections ;
462
+
463
+ let node_ty = self . typeck_results . node_type ( node. hir_id ( ) ) ;
464
+ // Opaque types can't have field projections, but we can instead convert
465
+ // the current place in-place (heh) to the hidden type, and then apply all
466
+ // follow up projections on that.
467
+ if node_ty != place_ty && place_ty. has_opaque_types ( ) {
468
+ projections. push ( Projection { kind : ProjectionKind :: OpaqueCast , ty : node_ty } ) ;
469
+ }
468
470
projections. push ( Projection { kind, ty } ) ;
469
- let ret = PlaceWithHirId :: new (
471
+ PlaceWithHirId :: new (
470
472
node. hir_id ( ) ,
471
473
base_place. place . base_ty ,
472
474
base_place. place . base ,
473
475
projections,
474
- ) ;
475
- debug ! ( "cat_field ret {:?}" , ret) ;
476
- ret
476
+ )
477
477
}
478
478
479
479
#[ instrument( level = "debug" , skip( self ) ) ]
@@ -497,7 +497,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
497
497
self . cat_deref ( expr, base)
498
498
}
499
499
500
- #[ instrument( level = "debug" , skip( self , node) ) ]
500
+ #[ instrument( level = "debug" , skip( self , node) , ret ) ]
501
501
fn cat_deref (
502
502
& self ,
503
503
node : & impl HirNode ,
@@ -514,14 +514,12 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
514
514
let mut projections = base_place. place . projections ;
515
515
projections. push ( Projection { kind : ProjectionKind :: Deref , ty : deref_ty } ) ;
516
516
517
- let ret = PlaceWithHirId :: new (
517
+ Ok ( PlaceWithHirId :: new (
518
518
node. hir_id ( ) ,
519
519
base_place. place . base_ty ,
520
520
base_place. place . base ,
521
521
projections,
522
- ) ;
523
- debug ! ( "cat_deref ret {:?}" , ret) ;
524
- Ok ( ret)
522
+ ) )
525
523
}
526
524
527
525
pub ( crate ) fn cat_pattern < F > (
@@ -603,6 +601,13 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
603
601
}
604
602
}
605
603
604
+ /// Here, `place` is the `PlaceWithHirId` being matched and pat is the pattern it
605
+ /// is being matched against.
606
+ ///
607
+ /// In general, the way that this works is that we walk down the pattern,
608
+ /// constructing a `PlaceWithHirId` that represents the path that will be taken
609
+ /// to reach the value being matched.
610
+ #[ instrument( skip( self , op) , ret, level = "debug" ) ]
606
611
fn cat_pattern_ < F > (
607
612
& self ,
608
613
mut place_with_id : PlaceWithHirId < ' tcx > ,
@@ -612,15 +617,6 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
612
617
where
613
618
F : FnMut ( & PlaceWithHirId < ' tcx > , & hir:: Pat < ' _ > ) ,
614
619
{
615
- // Here, `place` is the `PlaceWithHirId` being matched and pat is the pattern it
616
- // is being matched against.
617
- //
618
- // In general, the way that this works is that we walk down the pattern,
619
- // constructing a `PlaceWithHirId` that represents the path that will be taken
620
- // to reach the value being matched.
621
-
622
- debug ! ( "cat_pattern(pat={:?}, place_with_id={:?})" , pat, place_with_id) ;
623
-
624
620
// If (pattern) adjustments are active for this pattern, adjust the `PlaceWithHirId` correspondingly.
625
621
// `PlaceWithHirId`s are constructed differently from patterns. For example, in
626
622
//
@@ -654,11 +650,11 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
654
650
// `deref { deref { place_foo }}` instead of `place_foo` since the pattern is now `Some(x,)`
655
651
// and not `&&Some(x,)`, even though its assigned type is that of `&&Some(x,)`.
656
652
for _ in 0 ..self . typeck_results . pat_adjustments ( ) . get ( pat. hir_id ) . map_or ( 0 , |v| v. len ( ) ) {
657
- debug ! ( "cat_pattern: applying adjustment to place_with_id={:?}" , place_with_id) ;
653
+ debug ! ( "applying adjustment to place_with_id={:?}" , place_with_id) ;
658
654
place_with_id = self . cat_deref ( pat, place_with_id) ?;
659
655
}
660
656
let place_with_id = place_with_id; // lose mutability
661
- debug ! ( "cat_pattern: applied adjustment derefs to get place_with_id={:?}" , place_with_id) ;
657
+ debug ! ( "applied adjustment derefs to get place_with_id={:?}" , place_with_id) ;
662
658
663
659
// Invoke the callback, but only now, after the `place_with_id` has adjusted.
664
660
//
0 commit comments