@@ -25,7 +25,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
25
25
26
26
let ty =
27
27
if !lhs_ty. is_ty_var ( ) && !rhs_ty. is_ty_var ( ) && is_builtin_binop ( lhs_ty, rhs_ty, op) {
28
- self . enforce_builtin_binop_types ( lhs, lhs_ty, rhs, rhs_ty, op) ;
28
+ self . enforce_builtin_binop_types ( & lhs. span , lhs_ty, & rhs. span , rhs_ty, op) ;
29
29
self . tcx . mk_unit ( )
30
30
} else {
31
31
return_ty
@@ -86,8 +86,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
86
86
&& !rhs_ty. is_ty_var ( )
87
87
&& is_builtin_binop ( lhs_ty, rhs_ty, op)
88
88
{
89
- let builtin_return_ty =
90
- self . enforce_builtin_binop_types ( lhs_expr, lhs_ty, rhs_expr, rhs_ty, op) ;
89
+ let builtin_return_ty = self . enforce_builtin_binop_types (
90
+ & lhs_expr. span ,
91
+ lhs_ty,
92
+ & rhs_expr. span ,
93
+ rhs_ty,
94
+ op,
95
+ ) ;
91
96
self . demand_suptype ( expr. span , builtin_return_ty, return_ty) ;
92
97
}
93
98
@@ -98,19 +103,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
98
103
99
104
fn enforce_builtin_binop_types (
100
105
& self ,
101
- lhs_expr : & ' tcx hir :: Expr < ' tcx > ,
106
+ lhs_span : & Span ,
102
107
lhs_ty : Ty < ' tcx > ,
103
- rhs_expr : & ' tcx hir :: Expr < ' tcx > ,
108
+ rhs_span : & Span ,
104
109
rhs_ty : Ty < ' tcx > ,
105
110
op : hir:: BinOp ,
106
111
) -> Ty < ' tcx > {
107
112
debug_assert ! ( is_builtin_binop( lhs_ty, rhs_ty, op) ) ;
108
113
114
+ // Special-case a single layer of referencing, so that things like `5.0 + &6.0f32` work.
115
+ // (See https://github.com/rust-lang/rust/issues/57447.)
116
+ let ( lhs_ty, rhs_ty) = ( deref_ty_if_possible ( lhs_ty) , deref_ty_if_possible ( rhs_ty) ) ;
117
+
109
118
let tcx = self . tcx ;
110
119
match BinOpCategory :: from ( op) {
111
120
BinOpCategory :: Shortcircuit => {
112
- self . demand_suptype ( lhs_expr . span , tcx. mk_bool ( ) , lhs_ty) ;
113
- self . demand_suptype ( rhs_expr . span , tcx. mk_bool ( ) , rhs_ty) ;
121
+ self . demand_suptype ( * lhs_span , tcx. mk_bool ( ) , lhs_ty) ;
122
+ self . demand_suptype ( * rhs_span , tcx. mk_bool ( ) , rhs_ty) ;
114
123
tcx. mk_bool ( )
115
124
}
116
125
@@ -121,13 +130,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
121
130
122
131
BinOpCategory :: Math | BinOpCategory :: Bitwise => {
123
132
// both LHS and RHS and result will have the same type
124
- self . demand_suptype ( rhs_expr . span , lhs_ty, rhs_ty) ;
133
+ self . demand_suptype ( * rhs_span , lhs_ty, rhs_ty) ;
125
134
lhs_ty
126
135
}
127
136
128
137
BinOpCategory :: Comparison => {
129
138
// both LHS and RHS and result will have the same type
130
- self . demand_suptype ( rhs_expr . span , lhs_ty, rhs_ty) ;
139
+ self . demand_suptype ( * rhs_span , lhs_ty, rhs_ty) ;
131
140
tcx. mk_bool ( )
132
141
}
133
142
}
@@ -862,6 +871,14 @@ enum Op {
862
871
Unary ( hir:: UnOp , Span ) ,
863
872
}
864
873
874
+ /// Dereferences a single level of immutable referencing.
875
+ fn deref_ty_if_possible < ' tcx > ( ty : Ty < ' tcx > ) -> Ty < ' tcx > {
876
+ match ty. kind {
877
+ ty:: Ref ( _, ty, hir:: Mutability :: Not ) => ty,
878
+ _ => ty,
879
+ }
880
+ }
881
+
865
882
/// Returns `true` if this is a built-in arithmetic operation (e.g., u32
866
883
/// + u32, i16x4 == i16x4) and false if these types would have to be
867
884
/// overloaded to be legal. There are two reasons that we distinguish
@@ -878,7 +895,11 @@ enum Op {
878
895
/// Reason #2 is the killer. I tried for a while to always use
879
896
/// overloaded logic and just check the types in constants/codegen after
880
897
/// the fact, and it worked fine, except for SIMD types. -nmatsakis
881
- fn is_builtin_binop ( lhs : Ty < ' _ > , rhs : Ty < ' _ > , op : hir:: BinOp ) -> bool {
898
+ fn is_builtin_binop < ' tcx > ( lhs : Ty < ' tcx > , rhs : Ty < ' tcx > , op : hir:: BinOp ) -> bool {
899
+ // Special-case a single layer of referencing, so that things like `5.0 + &6.0f32` work.
900
+ // (See https://github.com/rust-lang/rust/issues/57447.)
901
+ let ( lhs, rhs) = ( deref_ty_if_possible ( lhs) , deref_ty_if_possible ( rhs) ) ;
902
+
882
903
match BinOpCategory :: from ( op) {
883
904
BinOpCategory :: Shortcircuit => true ,
884
905
0 commit comments