@@ -166,6 +166,16 @@ pub struct ImplHeader<'tcx> {
166
166
pub predicates : Vec < Predicate < ' tcx > > ,
167
167
}
168
168
169
+ #[ derive( Copy , Clone , PartialEq , RustcEncodable , RustcDecodable , HashStable ) ]
170
+ pub enum ImplPolarity {
171
+ /// `impl Trait for Type`
172
+ Positive ,
173
+ /// `impl !Trait for Type`
174
+ Negative ,
175
+ /// `#[rustc_reservation_impl] impl Trait for Type`
176
+ Reservation ,
177
+ }
178
+
169
179
#[ derive( Copy , Clone , Debug , PartialEq , HashStable ) ]
170
180
pub struct AssocItem {
171
181
pub def_id : DefId ,
@@ -2892,11 +2902,24 @@ impl<'tcx> TyCtxt<'tcx> {
2892
2902
pub fn impls_are_allowed_to_overlap ( self , def_id1 : DefId , def_id2 : DefId )
2893
2903
-> Option < ImplOverlapKind >
2894
2904
{
2895
- if self . impl_polarity ( def_id1) != self . impl_polarity ( def_id2) {
2896
- debug ! ( "impls_are_allowed_to_overlap({:?}, {:?}) - different polarities, None" ,
2897
- def_id1, def_id2) ;
2898
- return None ;
2899
- }
2905
+ match ( self . impl_polarity ( def_id1) , self . impl_polarity ( def_id2) ) {
2906
+ ( ImplPolarity :: Reservation , _) |
2907
+ ( _, ImplPolarity :: Reservation ) => {
2908
+ // `#[rustc_reservation_impl]` impls don't overlap with anything
2909
+ debug ! ( "impls_are_allowed_to_overlap({:?}, {:?}) = Some(Permitted) (reservations)" ,
2910
+ def_id1, def_id2) ;
2911
+ return Some ( ImplOverlapKind :: Permitted ) ;
2912
+ }
2913
+ ( ImplPolarity :: Positive , ImplPolarity :: Negative ) |
2914
+ ( ImplPolarity :: Negative , ImplPolarity :: Positive ) => {
2915
+ // FIXME: when can this happen?
2916
+ debug ! ( "impls_are_allowed_to_overlap({:?}, {:?}) - None (differing polarities)" ,
2917
+ def_id1, def_id2) ;
2918
+ return None ;
2919
+ }
2920
+ ( ImplPolarity :: Positive , ImplPolarity :: Positive ) |
2921
+ ( ImplPolarity :: Negative , ImplPolarity :: Negative ) => { }
2922
+ } ;
2900
2923
2901
2924
let is_marker_overlap = if self . features ( ) . overlapping_marker_traits {
2902
2925
let trait1_is_empty = self . impl_trait_ref ( def_id1)
@@ -2916,15 +2939,10 @@ impl<'tcx> TyCtxt<'tcx> {
2916
2939
is_marker_impl ( def_id1) && is_marker_impl ( def_id2)
2917
2940
} ;
2918
2941
2919
- // `#[rustc_reservation_impl]` impls don't overlap with anything
2920
- let is_reserve_overlap = {
2921
- self . has_attr ( def_id1, sym:: rustc_reservation_impl) ||
2922
- self . has_attr ( def_id2, sym:: rustc_reservation_impl)
2923
- } ;
2924
2942
2925
- if is_marker_overlap || is_reserve_overlap {
2926
- debug ! ( "impls_are_allowed_to_overlap({:?}, {:?}) = Some(Permitted) ({:?}/{:?} )" ,
2927
- def_id1, def_id2, is_marker_overlap , is_reserve_overlap ) ;
2943
+ if is_marker_overlap {
2944
+ debug ! ( "impls_are_allowed_to_overlap({:?}, {:?}) = Some(Permitted) (marker overlap )" ,
2945
+ def_id1, def_id2) ;
2928
2946
Some ( ImplOverlapKind :: Permitted )
2929
2947
} else {
2930
2948
if let Some ( self_ty1) = self . issue33140_self_ty ( def_id1) {
@@ -3306,7 +3324,7 @@ fn issue33140_self_ty(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Ty<'_>> {
3306
3324
debug ! ( "issue33140_self_ty({:?}), trait-ref={:?}" , def_id, trait_ref) ;
3307
3325
3308
3326
let is_marker_like =
3309
- tcx. impl_polarity ( def_id) == hir :: ImplPolarity :: Positive &&
3327
+ tcx. impl_polarity ( def_id) == ty :: ImplPolarity :: Positive &&
3310
3328
tcx. associated_item_def_ids ( trait_ref. def_id ) . is_empty ( ) ;
3311
3329
3312
3330
// Check whether these impls would be ok for a marker trait.
0 commit comments