@@ -551,6 +551,16 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
551551}
552552
553553impl < ' a , ' tcx > Visitor < ' tcx > for TypeChecker < ' a , ' tcx > {
554+ fn visit_assign ( & mut self , place : & Place < ' tcx > , rvalue : & Rvalue < ' tcx > , location : Location ) {
555+ // check rvalue is Reborrow
556+ if let Rvalue :: Reborrow ( mutability, rvalue) = rvalue {
557+ self . add_generic_reborrow_constraint ( * mutability, location, place, rvalue) ;
558+ } else {
559+ // rest of the cases
560+ self . super_assign ( place, rvalue, location) ;
561+ }
562+ }
563+
554564 fn visit_span ( & mut self , span : Span ) {
555565 if !span. is_dummy ( ) {
556566 debug ! ( ?span) ;
@@ -628,8 +638,11 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
628638 debug ! ( ?rv_ty) ;
629639 let rv_ty = self . normalize ( rv_ty, location) ;
630640 debug ! ( "normalized rv_ty: {:?}" , rv_ty) ;
631- if let Err ( terr) =
632- self . sub_types ( rv_ty, place_ty, location. to_locations ( ) , category)
641+ // Note: we've checked Reborrow/CoerceShared type matches
642+ // separately in fn visit_assign.
643+ if !matches ! ( rv, Rvalue :: Reborrow ( _, _) )
644+ && let Err ( terr) =
645+ self . sub_types ( rv_ty, place_ty, location. to_locations ( ) , category)
633646 {
634647 span_mirbug ! (
635648 self ,
@@ -1582,6 +1595,12 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
15821595 self . add_reborrow_constraint ( location, * region, borrowed_place) ;
15831596 }
15841597
1598+ Rvalue :: Reborrow ( ..) => {
1599+ // Reborrow needs to produce a relation between the source and destination fields,
1600+ // which means that we have had to already handle this in visit_assign.
1601+ unreachable ! ( )
1602+ }
1603+
15851604 Rvalue :: BinaryOp (
15861605 BinOp :: Eq | BinOp :: Ne | BinOp :: Lt | BinOp :: Le | BinOp :: Gt | BinOp :: Ge ,
15871606 box ( left, right) ,
@@ -2218,6 +2237,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
22182237 | Rvalue :: ThreadLocalRef ( _)
22192238 | Rvalue :: Repeat ( ..)
22202239 | Rvalue :: Ref ( ..)
2240+ | Rvalue :: Reborrow ( ..)
22212241 | Rvalue :: RawPtr ( ..)
22222242 | Rvalue :: Cast ( ..)
22232243 | Rvalue :: BinaryOp ( ..)
@@ -2422,6 +2442,121 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
24222442 }
24232443 }
24242444
2445+ fn add_generic_reborrow_constraint (
2446+ & mut self ,
2447+ mutability : Mutability ,
2448+ location : Location ,
2449+ dest : & Place < ' tcx > ,
2450+ borrowed_place : & Place < ' tcx > ,
2451+ ) {
2452+ // These constraints are only meaningful during borrowck:
2453+ let Self { borrow_set, location_table, polonius_facts, constraints, infcx, body, .. } =
2454+ self ;
2455+
2456+ // If we are reborrowing the referent of another reference, we
2457+ // need to add outlives relationships. In a case like `&mut
2458+ // *p`, where the `p` has type `&'b mut Foo`, for example, we
2459+ // need to ensure that `'b: 'a`.
2460+
2461+ debug ! (
2462+ "add_generic_reborrow_constraint({:?}, {:?}, {:?}, {:?})" ,
2463+ mutability, location, dest, borrowed_place
2464+ ) ;
2465+
2466+ let tcx = infcx. tcx ;
2467+ let def = body. source . def_id ( ) . expect_local ( ) ;
2468+ let upvars = tcx. closure_captures ( def) ;
2469+ let field =
2470+ path_utils:: is_upvar_field_projection ( tcx, upvars, borrowed_place. as_ref ( ) , body) ;
2471+ let category = if let Some ( field) = field {
2472+ ConstraintCategory :: ClosureUpvar ( field)
2473+ } else {
2474+ ConstraintCategory :: Boring
2475+ } ;
2476+
2477+ let dest_ty = dest. ty ( self . body , tcx) . ty ;
2478+ let borrowed_ty = borrowed_place. ty ( self . body , tcx) . ty ;
2479+ let ty:: Adt ( _, args) = dest_ty. kind ( ) else { bug ! ( ) } ;
2480+ let [ arg, ..] = * * * args else { bug ! ( ) } ;
2481+ let ty:: GenericArgKind :: Lifetime ( reborrow_region) = arg. kind ( ) else { bug ! ( ) } ;
2482+ constraints. liveness_constraints . add_location ( reborrow_region. as_var ( ) , location) ;
2483+
2484+ // In Polonius mode, we also push a `loan_issued_at` fact
2485+ // linking the loan to the region.
2486+ if let Some ( polonius_facts) = polonius_facts {
2487+ let _prof_timer = infcx. tcx . prof . generic_activity ( "polonius_fact_generation" ) ;
2488+ if let Some ( borrow_index) = borrow_set. get_index_of ( & location) {
2489+ let region_vid = reborrow_region. as_var ( ) ;
2490+ polonius_facts. loan_issued_at . push ( (
2491+ region_vid. into ( ) ,
2492+ borrow_index,
2493+ location_table. mid_index ( location) ,
2494+ ) ) ;
2495+ }
2496+ }
2497+
2498+ if mutability. is_not ( ) {
2499+ // FIXME: for shared reborrow we need to relate the types manually,
2500+ // field by field with CoerceShared drilling down and down and down.
2501+ // We cannot just attempt to relate T and <T as CoerceShared>::Target
2502+ // by calling relate_types.
2503+ let ty:: Adt ( dest_adt, dest_args) = dest_ty. kind ( ) else { unreachable ! ( ) } ;
2504+ let ty:: Adt ( borrowed_adt, borrowed_args) = borrowed_ty. kind ( ) else { unreachable ! ( ) } ;
2505+ let borrowed_fields = borrowed_adt. all_fields ( ) . collect :: < Vec < _ > > ( ) ;
2506+ for dest_field in dest_adt. all_fields ( ) {
2507+ let Some ( borrowed_field) =
2508+ borrowed_fields. iter ( ) . find ( |f| f. name == dest_field. name )
2509+ else {
2510+ continue ;
2511+ } ;
2512+ let dest_ty = dest_field. ty ( tcx, dest_args) ;
2513+ let borrowed_ty = borrowed_field. ty ( tcx, borrowed_args) ;
2514+ if let (
2515+ ty:: Ref ( borrow_region, _, Mutability :: Mut ) ,
2516+ ty:: Ref ( ref_region, _, Mutability :: Not ) ,
2517+ ) = ( borrowed_ty. kind ( ) , dest_ty. kind ( ) )
2518+ {
2519+ self . relate_types (
2520+ borrowed_ty. peel_refs ( ) ,
2521+ ty:: Variance :: Covariant ,
2522+ dest_ty. peel_refs ( ) ,
2523+ location. to_locations ( ) ,
2524+ category,
2525+ )
2526+ . unwrap ( ) ;
2527+ self . constraints . outlives_constraints . push ( OutlivesConstraint {
2528+ sup : ref_region. as_var ( ) ,
2529+ sub : borrow_region. as_var ( ) ,
2530+ locations : location. to_locations ( ) ,
2531+ span : location. to_locations ( ) . span ( self . body ) ,
2532+ category,
2533+ variance_info : ty:: VarianceDiagInfo :: default ( ) ,
2534+ from_closure : false ,
2535+ } ) ;
2536+ } else {
2537+ self . relate_types (
2538+ borrowed_ty,
2539+ ty:: Variance :: Covariant ,
2540+ dest_ty,
2541+ location. to_locations ( ) ,
2542+ category,
2543+ )
2544+ . unwrap ( ) ;
2545+ }
2546+ }
2547+ } else {
2548+ // Exclusive reborrow
2549+ self . relate_types (
2550+ borrowed_ty,
2551+ ty:: Variance :: Covariant ,
2552+ dest_ty,
2553+ location. to_locations ( ) ,
2554+ category,
2555+ )
2556+ . unwrap ( ) ;
2557+ }
2558+ }
2559+
24252560 fn prove_aggregate_predicates (
24262561 & mut self ,
24272562 aggregate_kind : & AggregateKind < ' tcx > ,
0 commit comments