@@ -166,6 +166,16 @@ pub struct ImplHeader<'tcx> {
166166 pub predicates : Vec < Predicate < ' tcx > > ,
167167}
168168
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+
169179#[ derive( Copy , Clone , Debug , PartialEq , HashStable ) ]
170180pub struct AssocItem {
171181 pub def_id : DefId ,
@@ -2892,11 +2902,24 @@ impl<'tcx> TyCtxt<'tcx> {
28922902 pub fn impls_are_allowed_to_overlap ( self , def_id1 : DefId , def_id2 : DefId )
28932903 -> Option < ImplOverlapKind >
28942904 {
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+ } ;
29002923
29012924 let is_marker_overlap = if self . features ( ) . overlapping_marker_traits {
29022925 let trait1_is_empty = self . impl_trait_ref ( def_id1)
@@ -2916,15 +2939,10 @@ impl<'tcx> TyCtxt<'tcx> {
29162939 is_marker_impl ( def_id1) && is_marker_impl ( def_id2)
29172940 } ;
29182941
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- } ;
29242942
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) ;
29282946 Some ( ImplOverlapKind :: Permitted )
29292947 } else {
29302948 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<'_>> {
33063324 debug ! ( "issue33140_self_ty({:?}), trait-ref={:?}" , def_id, trait_ref) ;
33073325
33083326 let is_marker_like =
3309- tcx. impl_polarity ( def_id) == hir :: ImplPolarity :: Positive &&
3327+ tcx. impl_polarity ( def_id) == ty :: ImplPolarity :: Positive &&
33103328 tcx. associated_item_def_ids ( trait_ref. def_id ) . is_empty ( ) ;
33113329
33123330 // Check whether these impls would be ok for a marker trait.
0 commit comments