@@ -167,6 +167,16 @@ pub struct ImplHeader<'tcx> {
167167 pub predicates : Vec < Predicate < ' tcx > > ,
168168}
169169
170+ #[ derive( Copy , Clone , PartialEq , RustcEncodable , RustcDecodable , HashStable ) ]
171+ pub enum ImplPolarity {
172+ /// `impl Trait for Type`
173+ Positive ,
174+ /// `impl !Trait for Type`
175+ Negative ,
176+ /// `#[rustc_reservation_impl] impl Trait for Type`
177+ Reservation ,
178+ }
179+
170180#[ derive( Copy , Clone , Debug , PartialEq , HashStable ) ]
171181pub struct AssocItem {
172182 pub def_id : DefId ,
@@ -2911,11 +2921,24 @@ impl<'tcx> TyCtxt<'tcx> {
29112921 return Some ( ImplOverlapKind :: Permitted ) ;
29122922 }
29132923
2914- if self . impl_polarity ( def_id1) != self . impl_polarity ( def_id2) {
2915- debug ! ( "impls_are_allowed_to_overlap({:?}, {:?}) - different polarities, None" ,
2916- def_id1, def_id2) ;
2917- return None ;
2918- }
2924+ match ( self . impl_polarity ( def_id1) , self . impl_polarity ( def_id2) ) {
2925+ ( ImplPolarity :: Reservation , _) |
2926+ ( _, ImplPolarity :: Reservation ) => {
2927+ // `#[rustc_reservation_impl]` impls don't overlap with anything
2928+ debug ! ( "impls_are_allowed_to_overlap({:?}, {:?}) = Some(Permitted) (reservations)" ,
2929+ def_id1, def_id2) ;
2930+ return Some ( ImplOverlapKind :: Permitted ) ;
2931+ }
2932+ ( ImplPolarity :: Positive , ImplPolarity :: Negative ) |
2933+ ( ImplPolarity :: Negative , ImplPolarity :: Positive ) => {
2934+ // FIXME: when can this happen?
2935+ debug ! ( "impls_are_allowed_to_overlap({:?}, {:?}) - None (differing polarities)" ,
2936+ def_id1, def_id2) ;
2937+ return None ;
2938+ }
2939+ ( ImplPolarity :: Positive , ImplPolarity :: Positive ) |
2940+ ( ImplPolarity :: Negative , ImplPolarity :: Negative ) => { }
2941+ } ;
29192942
29202943 let is_marker_overlap = if self . features ( ) . overlapping_marker_traits {
29212944 let trait1_is_empty = self . impl_trait_ref ( def_id1)
@@ -2935,15 +2958,10 @@ impl<'tcx> TyCtxt<'tcx> {
29352958 is_marker_impl ( def_id1) && is_marker_impl ( def_id2)
29362959 } ;
29372960
2938- // `#[rustc_reservation_impl]` impls don't overlap with anything
2939- let is_reserve_overlap = {
2940- self . has_attr ( def_id1, sym:: rustc_reservation_impl) ||
2941- self . has_attr ( def_id2, sym:: rustc_reservation_impl)
2942- } ;
29432961
2944- if is_marker_overlap || is_reserve_overlap {
2945- debug ! ( "impls_are_allowed_to_overlap({:?}, {:?}) = Some(Permitted) ({:?}/{:?} )" ,
2946- def_id1, def_id2, is_marker_overlap , is_reserve_overlap ) ;
2962+ if is_marker_overlap {
2963+ debug ! ( "impls_are_allowed_to_overlap({:?}, {:?}) = Some(Permitted) (marker overlap )" ,
2964+ def_id1, def_id2) ;
29472965 Some ( ImplOverlapKind :: Permitted )
29482966 } else {
29492967 if let Some ( self_ty1) = self . issue33140_self_ty ( def_id1) {
@@ -3325,7 +3343,7 @@ fn issue33140_self_ty(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Ty<'_>> {
33253343 debug ! ( "issue33140_self_ty({:?}), trait-ref={:?}" , def_id, trait_ref) ;
33263344
33273345 let is_marker_like =
3328- tcx. impl_polarity ( def_id) == hir :: ImplPolarity :: Positive &&
3346+ tcx. impl_polarity ( def_id) == ty :: ImplPolarity :: Positive &&
33293347 tcx. associated_item_def_ids ( trait_ref. def_id ) . is_empty ( ) ;
33303348
33313349 // Check whether these impls would be ok for a marker trait.
0 commit comments