@@ -25,13 +25,15 @@ use rustc::util::nodemap::FxHashSet;
25
25
use rustc:: infer:: { self , InferOk } ;
26
26
use syntax:: ast;
27
27
use syntax:: util:: lev_distance:: { lev_distance, find_best_match_for_name} ;
28
+ use syntax:: symbol:: Symbol ;
28
29
use syntax_pos:: Span ;
29
30
use rustc:: hir;
30
31
use std:: mem;
31
32
use std:: ops:: Deref ;
32
33
use std:: rc:: Rc ;
33
34
use std:: cmp:: max;
34
35
36
+
35
37
use self :: CandidateKind :: * ;
36
38
pub use self :: PickKind :: * ;
37
39
@@ -222,6 +224,99 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
222
224
|probe_cx| probe_cx. pick ( ) )
223
225
}
224
226
227
+ fn probe_for_operator ( & ' a self ,
228
+ span : Span ,
229
+ mode : Mode ,
230
+ operator : hir:: BinOp ,
231
+ is_assign : bool ,
232
+ return_type : Option < Ty < ' tcx > > ,
233
+ is_suggestion : IsSuggestion ,
234
+ self_ty : Ty < ' tcx > ,
235
+ scope_expr_id : ast:: NodeId )
236
+ -> PickResult < ' tcx >
237
+ {
238
+ let steps = if mode == Mode :: MethodCall {
239
+ match self . create_steps ( span, self_ty, is_suggestion) {
240
+ Some ( steps) => steps,
241
+ None => {
242
+ return Err ( MethodError :: NoMatch ( NoMatchData :: new ( Vec :: new ( ) ,
243
+ Vec :: new ( ) ,
244
+ Vec :: new ( ) ,
245
+ None ,
246
+ mode) ) )
247
+ }
248
+ }
249
+ } else {
250
+ vec ! [ CandidateStep {
251
+ self_ty,
252
+ autoderefs: 0 ,
253
+ unsize: false ,
254
+ } ]
255
+ } ;
256
+
257
+ debug ! ( "ProbeContext: steps for self_ty={:?} are {:?}" ,
258
+ self_ty,
259
+ steps) ;
260
+
261
+ // this creates one big transaction so that all type variables etc
262
+ // that we create during the probe process are removed later
263
+ self . probe ( |_| {
264
+ let lang = self . tcx . lang_items ( ) ;
265
+
266
+ let ( opname, trait_did) = if is_assign {
267
+ match operator. node {
268
+ hir:: BiAdd => ( "add_assign" , lang. add_assign_trait ( ) ) ,
269
+ hir:: BiSub => ( "sub_assign" , lang. sub_assign_trait ( ) ) ,
270
+ hir:: BiMul => ( "mul_assign" , lang. mul_assign_trait ( ) ) ,
271
+ hir:: BiDiv => ( "div_assign" , lang. div_assign_trait ( ) ) ,
272
+ hir:: BiRem => ( "rem_assign" , lang. rem_assign_trait ( ) ) ,
273
+ hir:: BiBitXor => ( "bitxor_assign" , lang. bitxor_assign_trait ( ) ) ,
274
+ hir:: BiBitAnd => ( "bitand_assign" , lang. bitand_assign_trait ( ) ) ,
275
+ hir:: BiBitOr => ( "bitor_assign" , lang. bitor_assign_trait ( ) ) ,
276
+ hir:: BiShl => ( "shl_assign" , lang. shl_assign_trait ( ) ) ,
277
+ hir:: BiShr => ( "shr_assign" , lang. shr_assign_trait ( ) ) ,
278
+ hir:: BiLt | hir:: BiLe |
279
+ hir:: BiGe | hir:: BiGt |
280
+ hir:: BiEq | hir:: BiNe |
281
+ hir:: BiAnd | hir:: BiOr => {
282
+ span_bug ! ( span,
283
+ "impossible assignment operation: {}=" ,
284
+ operator. node. as_str( ) )
285
+ }
286
+ }
287
+ } else {
288
+ match operator. node {
289
+ hir:: BiAdd => ( "add" , lang. add_trait ( ) ) ,
290
+ hir:: BiSub => ( "sub" , lang. sub_trait ( ) ) ,
291
+ hir:: BiMul => ( "mul" , lang. mul_trait ( ) ) ,
292
+ hir:: BiDiv => ( "div" , lang. div_trait ( ) ) ,
293
+ hir:: BiRem => ( "rem" , lang. rem_trait ( ) ) ,
294
+ hir:: BiBitXor => ( "bitxor" , lang. bitxor_trait ( ) ) ,
295
+ hir:: BiBitAnd => ( "bitand" , lang. bitand_trait ( ) ) ,
296
+ hir:: BiBitOr => ( "bitor" , lang. bitor_trait ( ) ) ,
297
+ hir:: BiShl => ( "shl" , lang. shl_trait ( ) ) ,
298
+ hir:: BiShr => ( "shr" , lang. shr_trait ( ) ) ,
299
+ hir:: BiLt => ( "lt" , lang. ord_trait ( ) ) ,
300
+ hir:: BiLe => ( "le" , lang. ord_trait ( ) ) ,
301
+ hir:: BiGe => ( "ge" , lang. ord_trait ( ) ) ,
302
+ hir:: BiGt => ( "gt" , lang. ord_trait ( ) ) ,
303
+ hir:: BiEq => ( "eq" , lang. eq_trait ( ) ) ,
304
+ hir:: BiNe => ( "ne" , lang. eq_trait ( ) ) ,
305
+ hir:: BiAnd | hir:: BiOr => {
306
+ span_bug ! ( span, "&& and || are not overloadable" )
307
+ }
308
+ }
309
+ } ;
310
+
311
+ let mut probe_cx =
312
+ ProbeContext :: new ( self , span, mode, Some ( Symbol :: intern ( opname) ) , return_type, Rc :: new ( steps) ) ;
313
+
314
+ probe_cx. assemble_extension_candidates_for_trait ( Some ( scope_expr_id) , trait_did. unwrap ( ) ) ?;
315
+
316
+ probe_cx. pick_core ( ) . unwrap ( )
317
+ } )
318
+ }
319
+
225
320
fn probe_op < OP , R > ( & ' a self ,
226
321
span : Span ,
227
322
mode : Mode ,
0 commit comments