@@ -85,11 +85,6 @@ pub(crate) struct ProbeContext<'a, 'tcx> {
85
85
/// machinery, since we don't particularly care about, for example, similarly named
86
86
/// candidates if we're *reporting* similarly named candidates.
87
87
is_suggestion : IsSuggestion ,
88
-
89
- /// Number of times we've hopped along the chain of `Receiver::Target`.
90
- /// Used to spot cases where an "outer" method in a smart pointer might
91
- /// "shadow" a pre-existing method in the pointee.
92
- receiver_trait_derefs : usize ,
93
88
}
94
89
95
90
impl < ' a , ' tcx > Deref for ProbeContext < ' a , ' tcx > {
@@ -104,12 +99,11 @@ pub(crate) struct Candidate<'tcx> {
104
99
pub ( crate ) item : ty:: AssocItem ,
105
100
pub ( crate ) kind : CandidateKind < ' tcx > ,
106
101
pub ( crate ) import_ids : SmallVec < [ LocalDefId ; 1 ] > ,
107
- receiver_trait_derefs : usize ,
108
102
}
109
103
110
104
#[ derive( Debug , Clone ) ]
111
105
pub ( crate ) enum CandidateKind < ' tcx > {
112
- InherentImplCandidate ( DefId ) ,
106
+ InherentImplCandidate ( DefId , usize ) ,
113
107
ObjectCandidate ( ty:: PolyTraitRef < ' tcx > ) ,
114
108
TraitCandidate ( ty:: PolyTraitRef < ' tcx > ) ,
115
109
WhereClauseCandidate ( ty:: PolyTraitRef < ' tcx > ) ,
@@ -183,7 +177,7 @@ struct PickDiagHints<'a, 'tcx> {
183
177
#[ derive( Debug ) ]
184
178
struct PickConstraintsForShadowed {
185
179
autoderefs : usize ,
186
- receiver_trait_derefs : usize ,
180
+ receiver_trait_derefs : Option < usize > ,
187
181
def_id : DefId ,
188
182
}
189
183
@@ -192,8 +186,17 @@ impl PickConstraintsForShadowed {
192
186
autoderefs == self . autoderefs
193
187
}
194
188
195
- fn may_shadow_based_on_receiver_trait_derefs ( & self , receiver_trait_derefs : usize ) -> bool {
196
- receiver_trait_derefs != self . receiver_trait_derefs
189
+ fn may_shadow_based_on_kind ( & self , kind : & CandidateKind < ' _ > ) -> bool {
190
+ if let Some ( receiver_trait_derefs) = self . receiver_trait_derefs {
191
+ match kind {
192
+ CandidateKind :: InherentImplCandidate ( _, other_derefs) => {
193
+ * other_derefs != receiver_trait_derefs
194
+ }
195
+ _ => false ,
196
+ }
197
+ } else {
198
+ false
199
+ }
197
200
}
198
201
199
202
fn may_shadow_based_on_defid ( & self , def_id : DefId ) -> bool {
@@ -223,7 +226,8 @@ pub(crate) struct Pick<'tcx> {
223
226
224
227
/// Number of jumps along the `Receiver::Target` chain we followed
225
228
/// to identify this method. Used only for deshadowing errors.
226
- pub receiver_trait_derefs : usize ,
229
+ /// Only applies for inherent impls.
230
+ pub receiver_trait_derefs : Option < usize > ,
227
231
}
228
232
229
233
#[ derive( Clone , Debug , PartialEq , Eq ) ]
@@ -708,7 +712,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
708
712
static_candidates : RefCell :: new ( Vec :: new ( ) ) ,
709
713
scope_expr_id,
710
714
is_suggestion,
711
- receiver_trait_derefs : 0usize ,
712
715
}
713
716
}
714
717
@@ -741,8 +744,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
741
744
import_ids : SmallVec < [ LocalDefId ; 1 ] > ,
742
745
is_inherent : bool ,
743
746
) {
744
- let candidate =
745
- Candidate { item, kind, import_ids, receiver_trait_derefs : self . receiver_trait_derefs } ;
747
+ let candidate = Candidate { item, kind, import_ids } ;
746
748
let is_accessible = if let Some ( name) = self . method_name {
747
749
let item = candidate. item ;
748
750
let hir_id = self . tcx . local_def_id_to_hir_id ( self . body_id ) ;
@@ -765,13 +767,16 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
765
767
766
768
fn assemble_inherent_candidates ( & mut self ) {
767
769
for step in self . steps . iter ( ) {
768
- self . receiver_trait_derefs = step. autoderefs ;
769
- self . assemble_probe ( & step. self_ty ) ;
770
+ self . assemble_probe ( & step. self_ty , step. autoderefs ) ;
770
771
}
771
772
}
772
773
773
774
#[ instrument( level = "debug" , skip( self ) ) ]
774
- fn assemble_probe ( & mut self , self_ty : & Canonical < ' tcx , QueryResponse < ' tcx , Ty < ' tcx > > > ) {
775
+ fn assemble_probe (
776
+ & mut self ,
777
+ self_ty : & Canonical < ' tcx , QueryResponse < ' tcx , Ty < ' tcx > > > ,
778
+ receiver_steps : usize ,
779
+ ) {
775
780
let raw_self_ty = self_ty. value . value ;
776
781
match * raw_self_ty. kind ( ) {
777
782
ty:: Dynamic ( data, ..) if let Some ( p) = data. principal ( ) => {
@@ -796,22 +801,31 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
796
801
self . fcx . instantiate_canonical ( self . span , self_ty) ;
797
802
798
803
self . assemble_inherent_candidates_from_object ( generalized_self_ty) ;
799
- self . assemble_inherent_impl_candidates_for_type ( p. def_id ( ) ) ;
804
+ self . assemble_inherent_impl_candidates_for_type ( p. def_id ( ) , receiver_steps ) ;
800
805
if self . tcx . has_attr ( p. def_id ( ) , sym:: rustc_has_incoherent_inherent_impls) {
801
- self . assemble_inherent_candidates_for_incoherent_ty ( raw_self_ty) ;
806
+ self . assemble_inherent_candidates_for_incoherent_ty (
807
+ raw_self_ty,
808
+ receiver_steps,
809
+ ) ;
802
810
}
803
811
}
804
812
ty:: Adt ( def, _) => {
805
813
let def_id = def. did ( ) ;
806
- self . assemble_inherent_impl_candidates_for_type ( def_id) ;
814
+ self . assemble_inherent_impl_candidates_for_type ( def_id, receiver_steps ) ;
807
815
if self . tcx . has_attr ( def_id, sym:: rustc_has_incoherent_inherent_impls) {
808
- self . assemble_inherent_candidates_for_incoherent_ty ( raw_self_ty) ;
816
+ self . assemble_inherent_candidates_for_incoherent_ty (
817
+ raw_self_ty,
818
+ receiver_steps,
819
+ ) ;
809
820
}
810
821
}
811
822
ty:: Foreign ( did) => {
812
- self . assemble_inherent_impl_candidates_for_type ( did) ;
823
+ self . assemble_inherent_impl_candidates_for_type ( did, receiver_steps ) ;
813
824
if self . tcx . has_attr ( did, sym:: rustc_has_incoherent_inherent_impls) {
814
- self . assemble_inherent_candidates_for_incoherent_ty ( raw_self_ty) ;
825
+ self . assemble_inherent_candidates_for_incoherent_ty (
826
+ raw_self_ty,
827
+ receiver_steps,
828
+ ) ;
815
829
}
816
830
}
817
831
ty:: Param ( p) => {
@@ -828,29 +842,35 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
828
842
| ty:: RawPtr ( _, _)
829
843
| ty:: Ref ( ..)
830
844
| ty:: Never
831
- | ty:: Tuple ( ..) => self . assemble_inherent_candidates_for_incoherent_ty ( raw_self_ty) ,
845
+ | ty:: Tuple ( ..) => {
846
+ self . assemble_inherent_candidates_for_incoherent_ty ( raw_self_ty, receiver_steps)
847
+ }
832
848
_ => { }
833
849
}
834
850
}
835
851
836
- fn assemble_inherent_candidates_for_incoherent_ty ( & mut self , self_ty : Ty < ' tcx > ) {
852
+ fn assemble_inherent_candidates_for_incoherent_ty (
853
+ & mut self ,
854
+ self_ty : Ty < ' tcx > ,
855
+ receiver_steps : usize ,
856
+ ) {
837
857
let Some ( simp) = simplify_type ( self . tcx , self_ty, TreatParams :: InstantiateWithInfer ) else {
838
858
bug ! ( "unexpected incoherent type: {:?}" , self_ty)
839
859
} ;
840
860
for & impl_def_id in self . tcx . incoherent_impls ( simp) . into_iter ( ) {
841
- self . assemble_inherent_impl_probe ( impl_def_id) ;
861
+ self . assemble_inherent_impl_probe ( impl_def_id, receiver_steps ) ;
842
862
}
843
863
}
844
864
845
- fn assemble_inherent_impl_candidates_for_type ( & mut self , def_id : DefId ) {
865
+ fn assemble_inherent_impl_candidates_for_type ( & mut self , def_id : DefId , receiver_steps : usize ) {
846
866
let impl_def_ids = self . tcx . at ( self . span ) . inherent_impls ( def_id) . into_iter ( ) ;
847
867
for & impl_def_id in impl_def_ids {
848
- self . assemble_inherent_impl_probe ( impl_def_id) ;
868
+ self . assemble_inherent_impl_probe ( impl_def_id, receiver_steps ) ;
849
869
}
850
870
}
851
871
852
872
#[ instrument( level = "debug" , skip( self ) ) ]
853
- fn assemble_inherent_impl_probe ( & mut self , impl_def_id : DefId ) {
873
+ fn assemble_inherent_impl_probe ( & mut self , impl_def_id : DefId , receiver_steps : usize ) {
854
874
if !self . impl_dups . insert ( impl_def_id) {
855
875
return ; // already visited
856
876
}
@@ -861,7 +881,12 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
861
881
self . record_static_candidate ( CandidateSource :: Impl ( impl_def_id) ) ;
862
882
continue ;
863
883
}
864
- self . push_candidate ( item, InherentImplCandidate ( impl_def_id) , smallvec ! [ ] , true ) ;
884
+ self . push_candidate (
885
+ item,
886
+ InherentImplCandidate ( impl_def_id, receiver_steps) ,
887
+ smallvec ! [ ] ,
888
+ true ,
889
+ ) ;
865
890
}
866
891
}
867
892
@@ -1569,9 +1594,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1569
1594
pick_constraints
1570
1595
. map ( |pick_constraints| {
1571
1596
pick_constraints. may_shadow_based_on_defid ( candidate. item . def_id )
1572
- && pick_constraints. may_shadow_based_on_receiver_trait_derefs (
1573
- candidate. receiver_trait_derefs ,
1574
- )
1597
+ && pick_constraints. may_shadow_based_on_kind ( & candidate. kind )
1575
1598
} )
1576
1599
. unwrap_or ( true )
1577
1600
} )
@@ -1724,7 +1747,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1724
1747
/// so do not use to make a decision that may lead to a successful compilation.
1725
1748
fn candidate_source ( & self , candidate : & Candidate < ' tcx > , self_ty : Ty < ' tcx > ) -> CandidateSource {
1726
1749
match candidate. kind {
1727
- InherentImplCandidate ( _ ) => {
1750
+ InherentImplCandidate ( .. ) => {
1728
1751
CandidateSource :: Impl ( candidate. item . container_id ( self . tcx ) )
1729
1752
}
1730
1753
ObjectCandidate ( _) | WhereClauseCandidate ( _) => {
@@ -1787,7 +1810,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1787
1810
let ( mut xform_self_ty, mut xform_ret_ty) ;
1788
1811
1789
1812
match probe. kind {
1790
- InherentImplCandidate ( impl_def_id) => {
1813
+ InherentImplCandidate ( impl_def_id, _ ) => {
1791
1814
let impl_args = self . fresh_args_for_item ( self . span , impl_def_id) ;
1792
1815
let impl_ty = self . tcx . type_of ( impl_def_id) . instantiate ( self . tcx , impl_args) ;
1793
1816
( xform_self_ty, xform_ret_ty) =
@@ -1956,7 +1979,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1956
1979
// We don't normalize the other candidates for perf/backwards-compat reasons...
1957
1980
// but `self.return_type` is only set on the diagnostic-path, so we
1958
1981
// should be okay doing it here.
1959
- if !matches ! ( probe. kind, InherentImplCandidate ( _ ) ) {
1982
+ if !matches ! ( probe. kind, InherentImplCandidate ( .. ) ) {
1960
1983
xform_ret_ty = ocx. normalize ( & cause, self . param_env , xform_ret_ty) ;
1961
1984
}
1962
1985
@@ -2030,11 +2053,11 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
2030
2053
item : probes[ 0 ] . 0 . item ,
2031
2054
kind : TraitPick ,
2032
2055
import_ids : probes[ 0 ] . 0 . import_ids . clone ( ) ,
2033
- autoderefs : probes [ 0 ] . 0 . receiver_trait_derefs ,
2056
+ autoderefs : 0 ,
2034
2057
autoref_or_ptr_adjustment : None ,
2035
2058
self_ty,
2036
2059
unstable_candidates : vec ! [ ] ,
2037
- receiver_trait_derefs : 0 ,
2060
+ receiver_trait_derefs : None ,
2038
2061
} )
2039
2062
}
2040
2063
@@ -2306,7 +2329,7 @@ impl<'tcx> Candidate<'tcx> {
2306
2329
Pick {
2307
2330
item : self . item ,
2308
2331
kind : match self . kind {
2309
- InherentImplCandidate ( _ ) => InherentImplPick ,
2332
+ InherentImplCandidate ( .. ) => InherentImplPick ,
2310
2333
ObjectCandidate ( _) => ObjectPick ,
2311
2334
TraitCandidate ( _) => TraitPick ,
2312
2335
WhereClauseCandidate ( trait_ref) => {
@@ -2328,7 +2351,10 @@ impl<'tcx> Candidate<'tcx> {
2328
2351
autoref_or_ptr_adjustment : None ,
2329
2352
self_ty,
2330
2353
unstable_candidates,
2331
- receiver_trait_derefs : self . receiver_trait_derefs ,
2354
+ receiver_trait_derefs : match self . kind {
2355
+ InherentImplCandidate ( _, receiver_steps) => Some ( receiver_steps) ,
2356
+ _ => None ,
2357
+ } ,
2332
2358
}
2333
2359
}
2334
2360
}
0 commit comments