@@ -62,88 +62,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
62
62
self . check_binop_assign ( expr, op, lhs, rhs)
63
63
}
64
64
ExprKind :: Unary ( unop, ref oprnd) => {
65
- let expected_inner = match unop {
66
- hir:: UnNot | hir:: UnNeg => {
67
- expected
68
- }
69
- hir:: UnDeref => {
70
- NoExpectation
71
- }
72
- } ;
73
- let needs = match unop {
74
- hir:: UnDeref => needs,
75
- _ => Needs :: None
76
- } ;
77
- let mut oprnd_t = self . check_expr_with_expectation_and_needs ( & oprnd,
78
- expected_inner,
79
- needs) ;
80
-
81
- if !oprnd_t. references_error ( ) {
82
- oprnd_t = self . structurally_resolved_type ( expr. span , oprnd_t) ;
83
- match unop {
84
- hir:: UnDeref => {
85
- if let Some ( mt) = oprnd_t. builtin_deref ( true ) {
86
- oprnd_t = mt. ty ;
87
- } else if let Some ( ok) = self . try_overloaded_deref (
88
- expr. span , oprnd_t, needs) {
89
- let method = self . register_infer_ok_obligations ( ok) ;
90
- if let ty:: Ref ( region, _, mutbl) = method. sig . inputs ( ) [ 0 ] . sty {
91
- let mutbl = match mutbl {
92
- hir:: MutImmutable => AutoBorrowMutability :: Immutable ,
93
- hir:: MutMutable => AutoBorrowMutability :: Mutable {
94
- // (It shouldn't actually matter for unary ops whether
95
- // we enable two-phase borrows or not, since a unary
96
- // op has no additional operands.)
97
- allow_two_phase_borrow : AllowTwoPhase :: No ,
98
- }
99
- } ;
100
- self . apply_adjustments ( oprnd, vec ! [ Adjustment {
101
- kind: Adjust :: Borrow ( AutoBorrow :: Ref ( region, mutbl) ) ,
102
- target: method. sig. inputs( ) [ 0 ]
103
- } ] ) ;
104
- }
105
- oprnd_t = self . make_overloaded_place_return_type ( method) . ty ;
106
- self . write_method_call ( expr. hir_id , method) ;
107
- } else {
108
- let mut err = type_error_struct ! (
109
- tcx. sess,
110
- expr. span,
111
- oprnd_t,
112
- E0614 ,
113
- "type `{}` cannot be dereferenced" ,
114
- oprnd_t,
115
- ) ;
116
- let sp = tcx. sess . source_map ( ) . start_point ( expr. span ) ;
117
- if let Some ( sp) = tcx. sess . parse_sess . ambiguous_block_expr_parse
118
- . borrow ( ) . get ( & sp)
119
- {
120
- tcx. sess . parse_sess . expr_parentheses_needed (
121
- & mut err,
122
- * sp,
123
- None ,
124
- ) ;
125
- }
126
- err. emit ( ) ;
127
- oprnd_t = tcx. types . err ;
128
- }
129
- }
130
- hir:: UnNot => {
131
- let result = self . check_user_unop ( expr, oprnd_t, unop) ;
132
- // If it's builtin, we can reuse the type, this helps inference.
133
- if !( oprnd_t. is_integral ( ) || oprnd_t. sty == ty:: Bool ) {
134
- oprnd_t = result;
135
- }
136
- }
137
- hir:: UnNeg => {
138
- let result = self . check_user_unop ( expr, oprnd_t, unop) ;
139
- // If it's builtin, we can reuse the type, this helps inference.
140
- if !oprnd_t. is_numeric ( ) {
141
- oprnd_t = result;
142
- }
143
- }
144
- }
145
- }
146
- oprnd_t
65
+ self . check_expr_unary ( unop, oprnd, expected, needs, expr)
147
66
}
148
67
ExprKind :: AddrOf ( mutbl, ref oprnd) => {
149
68
let hint = expected. only_has_type ( self ) . map_or ( NoExpectation , |ty| {
@@ -706,4 +625,91 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
706
625
let referent_ty = self . check_expr_with_expectation ( expr, expected_inner) ;
707
626
self . tcx . mk_box ( referent_ty)
708
627
}
628
+
629
+ fn check_expr_unary (
630
+ & self ,
631
+ unop : hir:: UnOp ,
632
+ oprnd : & ' tcx hir:: Expr ,
633
+ expected : Expectation < ' tcx > ,
634
+ needs : Needs ,
635
+ expr : & ' tcx hir:: Expr ,
636
+ ) -> Ty < ' tcx > {
637
+ let tcx = self . tcx ;
638
+ let expected_inner = match unop {
639
+ hir:: UnNot | hir:: UnNeg => expected,
640
+ hir:: UnDeref => NoExpectation ,
641
+ } ;
642
+ let needs = match unop {
643
+ hir:: UnDeref => needs,
644
+ _ => Needs :: None
645
+ } ;
646
+ let mut oprnd_t = self . check_expr_with_expectation_and_needs ( & oprnd, expected_inner, needs) ;
647
+
648
+ if !oprnd_t. references_error ( ) {
649
+ oprnd_t = self . structurally_resolved_type ( expr. span , oprnd_t) ;
650
+ match unop {
651
+ hir:: UnDeref => {
652
+ if let Some ( mt) = oprnd_t. builtin_deref ( true ) {
653
+ oprnd_t = mt. ty ;
654
+ } else if let Some ( ok) = self . try_overloaded_deref (
655
+ expr. span , oprnd_t, needs) {
656
+ let method = self . register_infer_ok_obligations ( ok) ;
657
+ if let ty:: Ref ( region, _, mutbl) = method. sig . inputs ( ) [ 0 ] . sty {
658
+ let mutbl = match mutbl {
659
+ hir:: MutImmutable => AutoBorrowMutability :: Immutable ,
660
+ hir:: MutMutable => AutoBorrowMutability :: Mutable {
661
+ // (It shouldn't actually matter for unary ops whether
662
+ // we enable two-phase borrows or not, since a unary
663
+ // op has no additional operands.)
664
+ allow_two_phase_borrow : AllowTwoPhase :: No ,
665
+ }
666
+ } ;
667
+ self . apply_adjustments ( oprnd, vec ! [ Adjustment {
668
+ kind: Adjust :: Borrow ( AutoBorrow :: Ref ( region, mutbl) ) ,
669
+ target: method. sig. inputs( ) [ 0 ]
670
+ } ] ) ;
671
+ }
672
+ oprnd_t = self . make_overloaded_place_return_type ( method) . ty ;
673
+ self . write_method_call ( expr. hir_id , method) ;
674
+ } else {
675
+ let mut err = type_error_struct ! (
676
+ tcx. sess,
677
+ expr. span,
678
+ oprnd_t,
679
+ E0614 ,
680
+ "type `{}` cannot be dereferenced" ,
681
+ oprnd_t,
682
+ ) ;
683
+ let sp = tcx. sess . source_map ( ) . start_point ( expr. span ) ;
684
+ if let Some ( sp) = tcx. sess . parse_sess . ambiguous_block_expr_parse
685
+ . borrow ( ) . get ( & sp)
686
+ {
687
+ tcx. sess . parse_sess . expr_parentheses_needed (
688
+ & mut err,
689
+ * sp,
690
+ None ,
691
+ ) ;
692
+ }
693
+ err. emit ( ) ;
694
+ oprnd_t = tcx. types . err ;
695
+ }
696
+ }
697
+ hir:: UnNot => {
698
+ let result = self . check_user_unop ( expr, oprnd_t, unop) ;
699
+ // If it's builtin, we can reuse the type, this helps inference.
700
+ if !( oprnd_t. is_integral ( ) || oprnd_t. sty == ty:: Bool ) {
701
+ oprnd_t = result;
702
+ }
703
+ }
704
+ hir:: UnNeg => {
705
+ let result = self . check_user_unop ( expr, oprnd_t, unop) ;
706
+ // If it's builtin, we can reuse the type, this helps inference.
707
+ if !oprnd_t. is_numeric ( ) {
708
+ oprnd_t = result;
709
+ }
710
+ }
711
+ }
712
+ }
713
+ oprnd_t
714
+ }
709
715
}
0 commit comments