@@ -13,6 +13,7 @@ use crate::traits::{
1313 self , FulfillmentContext , Normalized , Obligation , ObligationCause , PredicateObligation ,
1414 PredicateObligations , SelectionContext ,
1515} ;
16+ use rustc_ast:: Attribute ;
1617use rustc_hir:: def_id:: { DefId , LOCAL_CRATE } ;
1718use rustc_middle:: ty:: fast_reject:: { self , SimplifyParams , StripReferences } ;
1819use rustc_middle:: ty:: fold:: TypeFoldable ;
@@ -160,24 +161,30 @@ impl OverlapMode {
160161}
161162
162163fn overlap_mode < ' tcx > ( tcx : TyCtxt < ' tcx > , impl1_def_id : DefId , impl2_def_id : DefId ) -> OverlapMode {
163- if tcx. has_attr ( impl1_def_id, sym:: rustc_strict_coherence)
164- != tcx. has_attr ( impl2_def_id, sym:: rustc_strict_coherence)
165- {
166- bug ! ( "Use strict coherence on both impls" , ) ;
167- }
168-
169- if tcx. has_attr ( impl1_def_id, sym:: rustc_with_negative_coherence)
170- != tcx. has_attr ( impl2_def_id, sym:: rustc_with_negative_coherence)
171- {
172- bug ! ( "Use with negative coherence on both impls" , ) ;
173- }
174-
175- if tcx. has_attr ( impl1_def_id, sym:: rustc_strict_coherence) {
176- OverlapMode :: Strict
177- } else if tcx. has_attr ( impl1_def_id, sym:: rustc_with_negative_coherence) {
178- OverlapMode :: WithNegative
179- } else {
180- OverlapMode :: Stable
164+ // Find the possible coherence mode override opt-in attributes for each `DefId`
165+ let find_coherence_attr = |attr : & Attribute | {
166+ let name = attr. name_or_empty ( ) ;
167+ match name {
168+ sym:: rustc_with_negative_coherence | sym:: rustc_strict_coherence => Some ( name) ,
169+ _ => None ,
170+ }
171+ } ;
172+ let impl1_coherence_mode = tcx. get_attrs ( impl1_def_id) . iter ( ) . find_map ( find_coherence_attr) ;
173+ let impl2_coherence_mode = tcx. get_attrs ( impl2_def_id) . iter ( ) . find_map ( find_coherence_attr) ;
174+
175+ // If there are any (that currently happens in tests), they need to match. Otherwise, the
176+ // default 1.0 rules are used.
177+ match ( impl1_coherence_mode, impl2_coherence_mode) {
178+ ( None , None ) => OverlapMode :: Stable ,
179+ ( Some ( sym:: rustc_with_negative_coherence) , Some ( sym:: rustc_with_negative_coherence) ) => {
180+ OverlapMode :: WithNegative
181+ }
182+ ( Some ( sym:: rustc_strict_coherence) , Some ( sym:: rustc_strict_coherence) ) => {
183+ OverlapMode :: Strict
184+ }
185+ ( Some ( mode) , _) | ( _, Some ( mode) ) => {
186+ bug ! ( "Use the same coherence mode on both impls: {}" , mode)
187+ }
181188 }
182189}
183190
0 commit comments