@@ -96,6 +96,27 @@ pub(crate) struct ProbeContext<'a, 'tcx> {
9696
9797 scope_expr_id : HirId ,
9898
99+ /// Delegation item can be expanded into method calls or fully qualified calls
100+ /// depending on the callee's signature. Method calls are used to allow
101+ /// autoref/autoderef for target expression. For example in:
102+ ///
103+ /// ```ignore (illustrative)
104+ /// trait Trait : Sized {
105+ /// fn by_value(self) -> i32 { 1 }
106+ /// fn by_mut_ref(&mut self) -> i32 { 2 }
107+ /// fn by_ref(&self) -> i32 { 3 }
108+ /// }
109+ ///
110+ /// struct NewType(SomeType);
111+ /// impl Trait for NewType {
112+ /// reuse Trait::* { self.0 }
113+ /// }
114+ /// ```
115+ ///
116+ /// `self.0` will automatically coerce. The difference with existing method lookup
117+ /// is that methods in delegation items are pre-resolved by callee path (`Trait::*`).
118+ expected_def_id : Option < DefId > ,
119+
99120 /// Is this probe being done for a diagnostic? This will skip some error reporting
100121 /// machinery, since we don't particularly care about, for example, similarly named
101122 /// candidates if we're *reporting* similarly named candidates.
@@ -248,6 +269,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
248269 IsSuggestion ( true ) ,
249270 self_ty,
250271 scope_expr_id,
272+ None ,
251273 ProbeScope :: AllTraits ,
252274 |probe_cx| Ok ( probe_cx. candidate_method_names ( candidate_filter) ) ,
253275 )
@@ -263,6 +285,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
263285 IsSuggestion ( true ) ,
264286 self_ty,
265287 scope_expr_id,
288+ None ,
266289 ProbeScope :: AllTraits ,
267290 |probe_cx| probe_cx. pick ( ) ,
268291 )
@@ -281,6 +304,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
281304 is_suggestion : IsSuggestion ,
282305 self_ty : Ty < ' tcx > ,
283306 scope_expr_id : HirId ,
307+ expected_def_id : Option < DefId > ,
284308 scope : ProbeScope ,
285309 ) -> PickResult < ' tcx > {
286310 self . probe_op (
@@ -291,6 +315,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
291315 is_suggestion,
292316 self_ty,
293317 scope_expr_id,
318+ expected_def_id,
294319 scope,
295320 |probe_cx| probe_cx. pick ( ) ,
296321 )
@@ -315,6 +340,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
315340 is_suggestion,
316341 self_ty,
317342 scope_expr_id,
343+ None ,
318344 scope,
319345 |probe_cx| {
320346 Ok ( probe_cx
@@ -335,6 +361,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
335361 is_suggestion : IsSuggestion ,
336362 self_ty : Ty < ' tcx > ,
337363 scope_expr_id : HirId ,
364+ expected_def_id : Option < DefId > ,
338365 scope : ProbeScope ,
339366 op : OP ,
340367 ) -> Result < R , MethodError < ' tcx > >
@@ -476,6 +503,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
476503 & orig_values,
477504 steps. steps ,
478505 scope_expr_id,
506+ expected_def_id,
479507 is_suggestion,
480508 ) ;
481509
@@ -571,6 +599,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
571599 orig_steps_var_values : & ' a OriginalQueryValues < ' tcx > ,
572600 steps : & ' tcx [ CandidateStep < ' tcx > ] ,
573601 scope_expr_id : HirId ,
602+ expected_def_id : Option < DefId > ,
574603 is_suggestion : IsSuggestion ,
575604 ) -> ProbeContext < ' a , ' tcx > {
576605 ProbeContext {
@@ -590,6 +619,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
590619 static_candidates : RefCell :: new ( Vec :: new ( ) ) ,
591620 unsatisfied_predicates : RefCell :: new ( Vec :: new ( ) ) ,
592621 scope_expr_id,
622+ expected_def_id,
593623 is_suggestion,
594624 }
595625 }
@@ -1220,6 +1250,9 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
12201250 ) -> Option < PickResult < ' tcx > > {
12211251 let mut applicable_candidates: Vec < _ > = candidates
12221252 . iter ( )
1253+ . filter ( |candidate| {
1254+ !matches ! ( self . expected_def_id, Some ( def_id) if def_id != candidate. item. def_id)
1255+ } )
12231256 . map ( |probe| {
12241257 ( probe, self . consider_probe ( self_ty, probe, possibly_unsatisfied_predicates) )
12251258 } )
@@ -1677,6 +1710,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
16771710 self . orig_steps_var_values ,
16781711 self . steps ,
16791712 self . scope_expr_id ,
1713+ None ,
16801714 IsSuggestion ( true ) ,
16811715 ) ;
16821716 pcx. allow_similar_names = true ;
0 commit comments