@@ -65,44 +65,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
65
65
self . check_expr_unary ( unop, oprnd, expected, needs, expr)
66
66
}
67
67
ExprKind :: AddrOf ( mutbl, ref oprnd) => {
68
- let hint = expected. only_has_type ( self ) . map_or ( NoExpectation , |ty| {
69
- match ty. sty {
70
- ty:: Ref ( _, ty, _) | ty:: RawPtr ( ty:: TypeAndMut { ty, .. } ) => {
71
- if oprnd. is_place_expr ( ) {
72
- // Places may legitimately have unsized types.
73
- // For example, dereferences of a fat pointer and
74
- // the last field of a struct can be unsized.
75
- ExpectHasType ( ty)
76
- } else {
77
- Expectation :: rvalue_hint ( self , ty)
78
- }
79
- }
80
- _ => NoExpectation
81
- }
82
- } ) ;
83
- let needs = Needs :: maybe_mut_place ( mutbl) ;
84
- let ty = self . check_expr_with_expectation_and_needs ( & oprnd, hint, needs) ;
85
-
86
- let tm = ty:: TypeAndMut { ty : ty, mutbl : mutbl } ;
87
- if tm. ty . references_error ( ) {
88
- tcx. types . err
89
- } else {
90
- // Note: at this point, we cannot say what the best lifetime
91
- // is to use for resulting pointer. We want to use the
92
- // shortest lifetime possible so as to avoid spurious borrowck
93
- // errors. Moreover, the longest lifetime will depend on the
94
- // precise details of the value whose address is being taken
95
- // (and how long it is valid), which we don't know yet until type
96
- // inference is complete.
97
- //
98
- // Therefore, here we simply generate a region variable. The
99
- // region inferencer will then select the ultimate value.
100
- // Finally, borrowck is charged with guaranteeing that the
101
- // value whose address was taken can actually be made to live
102
- // as long as it needs to live.
103
- let region = self . next_region_var ( infer:: AddrOfRegion ( expr. span ) ) ;
104
- tcx. mk_ref ( region, tm)
105
- }
68
+ self . check_expr_addr_of ( mutbl, oprnd, expected, expr)
106
69
}
107
70
ExprKind :: Path ( ref qpath) => {
108
71
let ( res, opt_ty, segs) = self . resolve_ty_and_res_ufcs ( qpath, expr. hir_id ,
@@ -712,4 +675,51 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
712
675
}
713
676
oprnd_t
714
677
}
678
+
679
+ fn check_expr_addr_of (
680
+ & self ,
681
+ mutbl : hir:: Mutability ,
682
+ oprnd : & ' tcx hir:: Expr ,
683
+ expected : Expectation < ' tcx > ,
684
+ expr : & ' tcx hir:: Expr ,
685
+ ) -> Ty < ' tcx > {
686
+ let hint = expected. only_has_type ( self ) . map_or ( NoExpectation , |ty| {
687
+ match ty. sty {
688
+ ty:: Ref ( _, ty, _) | ty:: RawPtr ( ty:: TypeAndMut { ty, .. } ) => {
689
+ if oprnd. is_place_expr ( ) {
690
+ // Places may legitimately have unsized types.
691
+ // For example, dereferences of a fat pointer and
692
+ // the last field of a struct can be unsized.
693
+ ExpectHasType ( ty)
694
+ } else {
695
+ Expectation :: rvalue_hint ( self , ty)
696
+ }
697
+ }
698
+ _ => NoExpectation
699
+ }
700
+ } ) ;
701
+ let needs = Needs :: maybe_mut_place ( mutbl) ;
702
+ let ty = self . check_expr_with_expectation_and_needs ( & oprnd, hint, needs) ;
703
+
704
+ let tm = ty:: TypeAndMut { ty : ty, mutbl : mutbl } ;
705
+ if tm. ty . references_error ( ) {
706
+ self . tcx . types . err
707
+ } else {
708
+ // Note: at this point, we cannot say what the best lifetime
709
+ // is to use for resulting pointer. We want to use the
710
+ // shortest lifetime possible so as to avoid spurious borrowck
711
+ // errors. Moreover, the longest lifetime will depend on the
712
+ // precise details of the value whose address is being taken
713
+ // (and how long it is valid), which we don't know yet until type
714
+ // inference is complete.
715
+ //
716
+ // Therefore, here we simply generate a region variable. The
717
+ // region inferencer will then select the ultimate value.
718
+ // Finally, borrowck is charged with guaranteeing that the
719
+ // value whose address was taken can actually be made to live
720
+ // as long as it needs to live.
721
+ let region = self . next_region_var ( infer:: AddrOfRegion ( expr. span ) ) ;
722
+ self . tcx . mk_ref ( region, tm)
723
+ }
724
+ }
715
725
}
0 commit comments