@@ -104,6 +104,7 @@ pub(crate) struct Candidate<'tcx> {
104
104
pub ( crate ) item : ty:: AssocItem ,
105
105
pub ( crate ) kind : CandidateKind < ' tcx > ,
106
106
pub ( crate ) import_ids : SmallVec < [ LocalDefId ; 1 ] > ,
107
+ receiver_trait_derefs : usize ,
107
108
}
108
109
109
110
#[ derive( Debug , Clone ) ]
@@ -157,6 +158,30 @@ impl AutorefOrPtrAdjustment {
157
158
}
158
159
}
159
160
161
+ /// Criteria to apply when searching for a given Pick. This is used during
162
+ /// the search for potentially shadowed methods to ensure we don't search
163
+ /// more candidates than strictly necessary.
164
+ #[ derive( Debug ) ]
165
+ struct PickConstraintsForShadowed {
166
+ autoderefs : usize ,
167
+ receiver_trait_derefs : usize ,
168
+ def_id : DefId ,
169
+ }
170
+
171
+ impl PickConstraintsForShadowed {
172
+ fn may_shadow_based_on_autoderefs ( & self , autoderefs : usize ) -> bool {
173
+ autoderefs == self . autoderefs
174
+ }
175
+
176
+ fn may_shadow_based_on_receiver_trait_derefs ( & self , receiver_trait_derefs : usize ) -> bool {
177
+ receiver_trait_derefs != self . receiver_trait_derefs
178
+ }
179
+
180
+ fn may_shadow_based_on_defid ( & self , def_id : DefId ) -> bool {
181
+ def_id != self . def_id
182
+ }
183
+ }
184
+
160
185
#[ derive( Debug , Clone ) ]
161
186
pub struct Pick < ' tcx > {
162
187
pub item : ty:: AssocItem ,
@@ -176,6 +201,10 @@ pub struct Pick<'tcx> {
176
201
177
202
/// Unstable candidates alongside the stable ones.
178
203
unstable_candidates : Vec < ( Candidate < ' tcx > , Symbol ) > ,
204
+
205
+ /// Number of jumps along the Receiver::target chain we followed
206
+ /// to identify this method. Used only for deshadowing errors.
207
+ pub receiver_trait_derefs : usize ,
179
208
}
180
209
181
210
#[ derive( Clone , Debug , PartialEq , Eq ) ]
@@ -497,6 +526,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
497
526
item,
498
527
kind : CandidateKind :: TraitCandidate ( ty:: Binder :: dummy ( trait_ref) ) ,
499
528
import_ids : smallvec ! [ ] ,
529
+ receiver_trait_derefs : 0usize ,
500
530
} ,
501
531
false ,
502
532
) ;
@@ -646,12 +676,16 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
646
676
647
677
fn assemble_inherent_candidates ( & mut self ) {
648
678
for step in self . steps . iter ( ) {
649
- self . assemble_probe ( & step. self_ty ) ;
679
+ self . assemble_probe ( & step. self_ty , step . autoderefs ) ;
650
680
}
651
681
}
652
682
653
683
#[ instrument( level = "debug" , skip( self ) ) ]
654
- fn assemble_probe ( & mut self , self_ty : & Canonical < ' tcx , QueryResponse < ' tcx , Ty < ' tcx > > > ) {
684
+ fn assemble_probe (
685
+ & mut self ,
686
+ self_ty : & Canonical < ' tcx , QueryResponse < ' tcx , Ty < ' tcx > > > ,
687
+ receiver_trait_derefs : usize ,
688
+ ) {
655
689
let raw_self_ty = self_ty. value . value ;
656
690
match * raw_self_ty. kind ( ) {
657
691
ty:: Dynamic ( data, ..) if let Some ( p) = data. principal ( ) => {
@@ -675,27 +709,39 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
675
709
let ( QueryResponse { value : generalized_self_ty, .. } , _ignored_var_values) =
676
710
self . fcx . instantiate_canonical ( self . span , self_ty) ;
677
711
678
- self . assemble_inherent_candidates_from_object ( generalized_self_ty) ;
679
- self . assemble_inherent_impl_candidates_for_type ( p. def_id ( ) ) ;
712
+ self . assemble_inherent_candidates_from_object (
713
+ generalized_self_ty,
714
+ receiver_trait_derefs,
715
+ ) ;
716
+ self . assemble_inherent_impl_candidates_for_type ( p. def_id ( ) , receiver_trait_derefs) ;
680
717
if self . tcx . has_attr ( p. def_id ( ) , sym:: rustc_has_incoherent_inherent_impls) {
681
- self . assemble_inherent_candidates_for_incoherent_ty ( raw_self_ty) ;
718
+ self . assemble_inherent_candidates_for_incoherent_ty (
719
+ raw_self_ty,
720
+ receiver_trait_derefs,
721
+ ) ;
682
722
}
683
723
}
684
724
ty:: Adt ( def, _) => {
685
725
let def_id = def. did ( ) ;
686
- self . assemble_inherent_impl_candidates_for_type ( def_id) ;
726
+ self . assemble_inherent_impl_candidates_for_type ( def_id, receiver_trait_derefs ) ;
687
727
if self . tcx . has_attr ( def_id, sym:: rustc_has_incoherent_inherent_impls) {
688
- self . assemble_inherent_candidates_for_incoherent_ty ( raw_self_ty) ;
728
+ self . assemble_inherent_candidates_for_incoherent_ty (
729
+ raw_self_ty,
730
+ receiver_trait_derefs,
731
+ ) ;
689
732
}
690
733
}
691
734
ty:: Foreign ( did) => {
692
- self . assemble_inherent_impl_candidates_for_type ( did) ;
735
+ self . assemble_inherent_impl_candidates_for_type ( did, receiver_trait_derefs ) ;
693
736
if self . tcx . has_attr ( did, sym:: rustc_has_incoherent_inherent_impls) {
694
- self . assemble_inherent_candidates_for_incoherent_ty ( raw_self_ty) ;
737
+ self . assemble_inherent_candidates_for_incoherent_ty (
738
+ raw_self_ty,
739
+ receiver_trait_derefs,
740
+ ) ;
695
741
}
696
742
}
697
743
ty:: Param ( p) => {
698
- self . assemble_inherent_candidates_from_param ( p) ;
744
+ self . assemble_inherent_candidates_from_param ( p, receiver_trait_derefs ) ;
699
745
}
700
746
ty:: Bool
701
747
| ty:: Char
@@ -708,29 +754,38 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
708
754
| ty:: RawPtr ( _, _)
709
755
| ty:: Ref ( ..)
710
756
| ty:: Never
711
- | ty:: Tuple ( ..) => self . assemble_inherent_candidates_for_incoherent_ty ( raw_self_ty) ,
757
+ | ty:: Tuple ( ..) => self
758
+ . assemble_inherent_candidates_for_incoherent_ty ( raw_self_ty, receiver_trait_derefs) ,
712
759
_ => { }
713
760
}
714
761
}
715
762
716
- fn assemble_inherent_candidates_for_incoherent_ty ( & mut self , self_ty : Ty < ' tcx > ) {
763
+ fn assemble_inherent_candidates_for_incoherent_ty (
764
+ & mut self ,
765
+ self_ty : Ty < ' tcx > ,
766
+ receiver_trait_derefs : usize ,
767
+ ) {
717
768
let Some ( simp) = simplify_type ( self . tcx , self_ty, TreatParams :: AsCandidateKey ) else {
718
769
bug ! ( "unexpected incoherent type: {:?}" , self_ty)
719
770
} ;
720
771
for & impl_def_id in self . tcx . incoherent_impls ( simp) . into_iter ( ) . flatten ( ) {
721
- self . assemble_inherent_impl_probe ( impl_def_id) ;
772
+ self . assemble_inherent_impl_probe ( impl_def_id, receiver_trait_derefs ) ;
722
773
}
723
774
}
724
775
725
- fn assemble_inherent_impl_candidates_for_type ( & mut self , def_id : DefId ) {
776
+ fn assemble_inherent_impl_candidates_for_type (
777
+ & mut self ,
778
+ def_id : DefId ,
779
+ receiver_trait_derefs : usize ,
780
+ ) {
726
781
let impl_def_ids = self . tcx . at ( self . span ) . inherent_impls ( def_id) . into_iter ( ) . flatten ( ) ;
727
782
for & impl_def_id in impl_def_ids {
728
- self . assemble_inherent_impl_probe ( impl_def_id) ;
783
+ self . assemble_inherent_impl_probe ( impl_def_id, receiver_trait_derefs ) ;
729
784
}
730
785
}
731
786
732
787
#[ instrument( level = "debug" , skip( self ) ) ]
733
- fn assemble_inherent_impl_probe ( & mut self , impl_def_id : DefId ) {
788
+ fn assemble_inherent_impl_probe ( & mut self , impl_def_id : DefId , receiver_trait_derefs : usize ) {
734
789
if !self . impl_dups . insert ( impl_def_id) {
735
790
return ; // already visited
736
791
}
@@ -746,14 +801,19 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
746
801
item,
747
802
kind : InherentImplCandidate ( impl_def_id) ,
748
803
import_ids : smallvec ! [ ] ,
804
+ receiver_trait_derefs,
749
805
} ,
750
806
true ,
751
807
) ;
752
808
}
753
809
}
754
810
755
811
#[ instrument( level = "debug" , skip( self ) ) ]
756
- fn assemble_inherent_candidates_from_object ( & mut self , self_ty : Ty < ' tcx > ) {
812
+ fn assemble_inherent_candidates_from_object (
813
+ & mut self ,
814
+ self_ty : Ty < ' tcx > ,
815
+ receiver_trait_derefs : usize ,
816
+ ) {
757
817
let principal = match self_ty. kind ( ) {
758
818
ty:: Dynamic ( ref data, ..) => Some ( data) ,
759
819
_ => None ,
@@ -782,6 +842,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
782
842
item,
783
843
kind : ObjectCandidate ( new_trait_ref) ,
784
844
import_ids : smallvec ! [ ] ,
845
+ receiver_trait_derefs,
785
846
} ,
786
847
true ,
787
848
) ;
@@ -790,7 +851,11 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
790
851
}
791
852
792
853
#[ instrument( level = "debug" , skip( self ) ) ]
793
- fn assemble_inherent_candidates_from_param ( & mut self , param_ty : ty:: ParamTy ) {
854
+ fn assemble_inherent_candidates_from_param (
855
+ & mut self ,
856
+ param_ty : ty:: ParamTy ,
857
+ receiver_trait_derefs : usize ,
858
+ ) {
794
859
let bounds = self . param_env . caller_bounds ( ) . iter ( ) . filter_map ( |predicate| {
795
860
let bound_predicate = predicate. kind ( ) ;
796
861
match bound_predicate. skip_binder ( ) {
@@ -817,6 +882,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
817
882
item,
818
883
kind : WhereClauseCandidate ( poly_trait_ref) ,
819
884
import_ids : smallvec ! [ ] ,
885
+ receiver_trait_derefs,
820
886
} ,
821
887
true ,
822
888
) ;
@@ -910,6 +976,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
910
976
item,
911
977
import_ids : import_ids. clone ( ) ,
912
978
kind : TraitCandidate ( bound_trait_ref) ,
979
+ receiver_trait_derefs : 0usize ,
913
980
} ,
914
981
false ,
915
982
) ;
@@ -933,6 +1000,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
933
1000
item,
934
1001
import_ids : import_ids. clone ( ) ,
935
1002
kind : TraitCandidate ( ty:: Binder :: dummy ( trait_ref) ) ,
1003
+ receiver_trait_derefs : 0usize ,
936
1004
} ,
937
1005
false ,
938
1006
) ;
@@ -1075,33 +1143,152 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1075
1143
. unwrap_or_else ( |_| {
1076
1144
span_bug ! ( self . span, "{:?} was applicable but now isn't?" , step. self_ty)
1077
1145
} ) ;
1078
- self . pick_by_value_method ( step, self_ty, unstable_candidates. as_deref_mut ( ) )
1079
- . or_else ( || {
1080
- self . pick_autorefd_method (
1081
- step,
1082
- self_ty,
1083
- hir:: Mutability :: Not ,
1084
- unstable_candidates. as_deref_mut ( ) ,
1085
- )
1086
- . or_else ( || {
1087
- self . pick_autorefd_method (
1146
+
1147
+ let by_value_pick =
1148
+ self . pick_by_value_method ( step, self_ty, unstable_candidates. as_deref_mut ( ) ) ;
1149
+
1150
+ // Check for shadowing of a by-reference method by a by-value method (see comments on check_for_shadowing)
1151
+ if let Some ( by_value_pick) = by_value_pick {
1152
+ if let Ok ( by_value_pick) = by_value_pick. as_ref ( ) {
1153
+ if by_value_pick. kind == PickKind :: InherentImplPick {
1154
+ if let Err ( e) = self . check_for_shadowed_autorefd_method (
1155
+ by_value_pick,
1156
+ step,
1157
+ self_ty,
1158
+ hir:: Mutability :: Not ,
1159
+ unstable_candidates. is_some ( ) ,
1160
+ ) {
1161
+ return Some ( Err ( e) ) ;
1162
+ }
1163
+ if let Err ( e) = self . check_for_shadowed_autorefd_method (
1164
+ by_value_pick,
1088
1165
step,
1089
1166
self_ty,
1090
1167
hir:: Mutability :: Mut ,
1091
- unstable_candidates. as_deref_mut ( ) ,
1092
- )
1093
- } )
1094
- . or_else ( || {
1095
- self . pick_const_ptr_method (
1168
+ unstable_candidates. is_some ( ) ,
1169
+ ) {
1170
+ return Some ( Err ( e) ) ;
1171
+ }
1172
+ }
1173
+ }
1174
+ return Some ( by_value_pick) ;
1175
+ }
1176
+
1177
+ let autoref_pick = self . pick_autorefd_method (
1178
+ step,
1179
+ self_ty,
1180
+ hir:: Mutability :: Not ,
1181
+ unstable_candidates. as_deref_mut ( ) ,
1182
+ None ,
1183
+ ) ;
1184
+ // Check for shadowing of a by-mut-ref method by a by-reference method (see comments on check_for_shadowing)
1185
+ if let Some ( autoref_pick) = autoref_pick {
1186
+ if let Ok ( autoref_pick) = autoref_pick. as_ref ( ) {
1187
+ // Check we're not shadowing others
1188
+ if autoref_pick. kind == PickKind :: InherentImplPick {
1189
+ if let Err ( e) = self . check_for_shadowed_autorefd_method (
1190
+ autoref_pick,
1096
1191
step,
1097
1192
self_ty,
1098
- unstable_candidates. as_deref_mut ( ) ,
1099
- )
1100
- } )
1101
- } )
1193
+ hir:: Mutability :: Mut ,
1194
+ unstable_candidates. is_some ( ) ,
1195
+ ) {
1196
+ return Some ( Err ( e) ) ;
1197
+ }
1198
+ }
1199
+ }
1200
+ return Some ( autoref_pick) ;
1201
+ }
1202
+
1203
+ // Note that no shadowing errors are produced from here on,
1204
+ // as we consider const ptr methods.
1205
+ // We allow new methods that take *mut T to shadow
1206
+ // methods which took *const T, so there is no entry in
1207
+ // this list for the results of `pick_const_ptr_method`.
1208
+ // The reason is that the standard pointer cast method
1209
+ // (on a mutable pointer) always already shadows the
1210
+ // cast method (on a const pointer). So, if we added
1211
+ // `pick_const_ptr_method` to this method, the anti-
1212
+ // shadowing algorithm would always complain about
1213
+ // the conflict between *const::cast and *mut::cast.
1214
+ // In practice therefore this does constrain us:
1215
+ // we cannot add new
1216
+ // self: *mut Self
1217
+ // methods to types such as NonNull or anything else
1218
+ // which implements Receiver, because this might in future
1219
+ // shadow existing methods taking
1220
+ // self: *const NonNull<Self>
1221
+ // in the pointee. In practice, methods taking raw pointers
1222
+ // are rare, and it seems that it should be easily possible
1223
+ // to avoid such compatibility breaks.
1224
+ self . pick_autorefd_method (
1225
+ step,
1226
+ self_ty,
1227
+ hir:: Mutability :: Mut ,
1228
+ unstable_candidates. as_deref_mut ( ) ,
1229
+ None ,
1230
+ )
1231
+ . or_else ( || {
1232
+ self . pick_const_ptr_method ( step, self_ty, unstable_candidates. as_deref_mut ( ) )
1233
+ } )
1102
1234
} )
1103
1235
}
1104
1236
1237
+ /// Check for cases where arbitrary self types allows shadowing
1238
+ /// of methods that might be a compatibility break. Specifically,
1239
+ /// we have something like:
1240
+ /// ```compile_fail
1241
+ /// # use std::ptr::NonNull;
1242
+ /// struct A;
1243
+ /// impl A {
1244
+ /// fn foo(self: &NonNull<A>) {}
1245
+ /// // note this is by reference
1246
+ /// }
1247
+ /// ```
1248
+ /// then we've come along and added this method to `NonNull`:
1249
+ /// ```
1250
+ /// # struct NonNull;
1251
+ /// # impl NonNull {
1252
+ /// fn foo(self) {} // note this is by value
1253
+ /// # }
1254
+ /// ```
1255
+ /// Report an error in this case.
1256
+ fn check_for_shadowed_autorefd_method (
1257
+ & self ,
1258
+ possible_shadower : & Pick < ' tcx > ,
1259
+ step : & CandidateStep < ' tcx > ,
1260
+ self_ty : Ty < ' tcx > ,
1261
+ mutbl : hir:: Mutability ,
1262
+ tracking_unstable_candidates : bool ,
1263
+ ) -> Result < ( ) , MethodError < ' tcx > > {
1264
+ let mut empty_vec = vec ! [ ] ;
1265
+ let unstable_candidates_for_shadow_probe =
1266
+ if tracking_unstable_candidates { Some ( & mut empty_vec) } else { None } ;
1267
+ // Set criteria for how we find methods possibly shadowed by 'possible_shadower'
1268
+ let pick_constraints = PickConstraintsForShadowed {
1269
+ // It's the same `self` type, other than any autoreffing...
1270
+ autoderefs : possible_shadower. autoderefs ,
1271
+ // ... but the method was found in an impl block determined
1272
+ // by searching further along the Receiver chain than the other,
1273
+ // showing that it's arbitrary self types causing the problem...
1274
+ receiver_trait_derefs : possible_shadower. receiver_trait_derefs ,
1275
+ // ... and they don't end up pointing to the same item in the
1276
+ // first place (could happen with things like blanket impls for T)
1277
+ def_id : possible_shadower. item . def_id ,
1278
+ } ;
1279
+ let _potentially_shadowed_pick = self . pick_autorefd_method (
1280
+ step,
1281
+ self_ty,
1282
+ mutbl,
1283
+ unstable_candidates_for_shadow_probe,
1284
+ Some ( & pick_constraints) ,
1285
+ ) ;
1286
+
1287
+ // At the moment, this function does no checks. A future
1288
+ // commit will fill out the body here.
1289
+ Ok ( ( ) )
1290
+ }
1291
+
1105
1292
/// For each type `T` in the step list, this attempts to find a method where
1106
1293
/// the (transformed) self type is exactly `T`. We do however do one
1107
1294
/// transformation on the adjustment: if we are passing a region pointer in,
@@ -1118,7 +1305,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1118
1305
return None ;
1119
1306
}
1120
1307
1121
- self . pick_method ( self_ty, unstable_candidates) . map ( |r| {
1308
+ self . pick_method ( self_ty, unstable_candidates, None ) . map ( |r| {
1122
1309
r. map ( |mut pick| {
1123
1310
pick. autoderefs = step. autoderefs ;
1124
1311
@@ -1142,14 +1329,21 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1142
1329
self_ty : Ty < ' tcx > ,
1143
1330
mutbl : hir:: Mutability ,
1144
1331
unstable_candidates : Option < & mut Vec < ( Candidate < ' tcx > , Symbol ) > > ,
1332
+ pick_constraints : Option < & PickConstraintsForShadowed > ,
1145
1333
) -> Option < PickResult < ' tcx > > {
1146
1334
let tcx = self . tcx ;
1147
1335
1336
+ if let Some ( pick_constraints) = pick_constraints {
1337
+ if !pick_constraints. may_shadow_based_on_autoderefs ( step. autoderefs ) {
1338
+ return None ;
1339
+ }
1340
+ }
1341
+
1148
1342
// In general, during probing we erase regions.
1149
1343
let region = tcx. lifetimes . re_erased ;
1150
1344
1151
1345
let autoref_ty = Ty :: new_ref ( tcx, region, self_ty, mutbl) ;
1152
- self . pick_method ( autoref_ty, unstable_candidates) . map ( |r| {
1346
+ self . pick_method ( autoref_ty, unstable_candidates, pick_constraints ) . map ( |r| {
1153
1347
r. map ( |mut pick| {
1154
1348
pick. autoderefs = step. autoderefs ;
1155
1349
pick. autoref_or_ptr_adjustment =
@@ -1178,7 +1372,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1178
1372
} ;
1179
1373
1180
1374
let const_ptr_ty = Ty :: new_imm_ptr ( self . tcx , ty) ;
1181
- self . pick_method ( const_ptr_ty, unstable_candidates) . map ( |r| {
1375
+ self . pick_method ( const_ptr_ty, unstable_candidates, None ) . map ( |r| {
1182
1376
r. map ( |mut pick| {
1183
1377
pick. autoderefs = step. autoderefs ;
1184
1378
pick. autoref_or_ptr_adjustment = Some ( AutorefOrPtrAdjustment :: ToConstPtr ) ;
@@ -1191,6 +1385,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1191
1385
& self ,
1192
1386
self_ty : Ty < ' tcx > ,
1193
1387
mut unstable_candidates : Option < & mut Vec < ( Candidate < ' tcx > , Symbol ) > > ,
1388
+ pick_constraints : Option < & PickConstraintsForShadowed > ,
1194
1389
) -> Option < PickResult < ' tcx > > {
1195
1390
debug ! ( "pick_method(self_ty={})" , self . ty_to_string( self_ty) ) ;
1196
1391
@@ -1205,6 +1400,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1205
1400
candidates,
1206
1401
& mut possibly_unsatisfied_predicates,
1207
1402
unstable_candidates. as_deref_mut ( ) ,
1403
+ pick_constraints,
1208
1404
) ;
1209
1405
if let Some ( pick) = res {
1210
1406
return Some ( pick) ;
@@ -1213,15 +1409,16 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1213
1409
1214
1410
if self . private_candidate . get ( ) . is_none ( ) {
1215
1411
if let Some ( Ok ( pick) ) =
1216
- self . consider_candidates ( self_ty, & self . private_candidates , & mut vec ! [ ] , None )
1412
+ self . consider_candidates ( self_ty, & self . private_candidates , & mut vec ! [ ] , None , None )
1217
1413
{
1218
1414
self . private_candidate . set ( Some ( ( pick. item . kind . as_def_kind ( ) , pick. item . def_id ) ) ) ;
1219
1415
}
1220
1416
}
1221
1417
1222
1418
// `pick_method` may be called twice for the same self_ty if no stable methods
1223
- // match. Only extend once.
1224
- if unstable_candidates. is_some ( ) {
1419
+ // match. Only extend once. And don't extend if we're just doing a search for
1420
+ // shadowed methods, which will result in a Some pick_constraints.
1421
+ if unstable_candidates. is_some ( ) && pick_constraints. is_none ( ) {
1225
1422
self . unsatisfied_predicates . borrow_mut ( ) . extend ( possibly_unsatisfied_predicates) ;
1226
1423
}
1227
1424
None
@@ -1237,9 +1434,20 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1237
1434
Option < ObligationCause < ' tcx > > ,
1238
1435
) > ,
1239
1436
mut unstable_candidates : Option < & mut Vec < ( Candidate < ' tcx > , Symbol ) > > ,
1437
+ pick_constraints : Option < & PickConstraintsForShadowed > ,
1240
1438
) -> Option < PickResult < ' tcx > > {
1241
1439
let mut applicable_candidates: Vec < _ > = candidates
1242
1440
. iter ( )
1441
+ . filter ( |candidate| {
1442
+ pick_constraints
1443
+ . map ( |pick_constraints| {
1444
+ pick_constraints. may_shadow_based_on_defid ( candidate. item . def_id )
1445
+ && pick_constraints. may_shadow_based_on_receiver_trait_derefs (
1446
+ candidate. receiver_trait_derefs ,
1447
+ )
1448
+ } )
1449
+ . unwrap_or ( true )
1450
+ } )
1243
1451
. map ( |probe| {
1244
1452
( probe, self . consider_probe ( self_ty, probe, possibly_unsatisfied_predicates) )
1245
1453
} )
@@ -1307,6 +1515,7 @@ impl<'tcx> Pick<'tcx> {
1307
1515
autoref_or_ptr_adjustment : _,
1308
1516
self_ty,
1309
1517
unstable_candidates : _,
1518
+ receiver_trait_derefs : _,
1310
1519
} = * self ;
1311
1520
self_ty != other. self_ty || def_id != other. item . def_id
1312
1521
}
@@ -1676,6 +1885,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1676
1885
autoref_or_ptr_adjustment : None ,
1677
1886
self_ty,
1678
1887
unstable_candidates : vec ! [ ] ,
1888
+ receiver_trait_derefs : 0 ,
1679
1889
} )
1680
1890
}
1681
1891
@@ -1969,6 +2179,7 @@ impl<'tcx> Candidate<'tcx> {
1969
2179
autoref_or_ptr_adjustment : None ,
1970
2180
self_ty,
1971
2181
unstable_candidates,
2182
+ receiver_trait_derefs : self . receiver_trait_derefs ,
1972
2183
}
1973
2184
}
1974
2185
}
0 commit comments