Skip to content

Commit 858a0d8

Browse files
committed
method-style lookup for operator trait method
1 parent 0a2e9ad commit 858a0d8

File tree

1 file changed

+95
-0
lines changed
  • src/librustc_typeck/check/method

1 file changed

+95
-0
lines changed

src/librustc_typeck/check/method/probe.rs

+95
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,15 @@ use rustc::util::nodemap::FxHashSet;
2525
use rustc::infer::{self, InferOk};
2626
use syntax::ast;
2727
use syntax::util::lev_distance::{lev_distance, find_best_match_for_name};
28+
use syntax::symbol::Symbol;
2829
use syntax_pos::Span;
2930
use rustc::hir;
3031
use std::mem;
3132
use std::ops::Deref;
3233
use std::rc::Rc;
3334
use std::cmp::max;
3435

36+
3537
use self::CandidateKind::*;
3638
pub use self::PickKind::*;
3739

@@ -222,6 +224,99 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
222224
|probe_cx| probe_cx.pick())
223225
}
224226

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+
225320
fn probe_op<OP,R>(&'a self,
226321
span: Span,
227322
mode: Mode,

0 commit comments

Comments
 (0)