@@ -135,6 +135,25 @@ fn with_fresh_ty_vars<'cx, 'tcx>(
135135 header
136136}
137137
138+ enum OverlapMode {
139+ Stable ,
140+ Strict ,
141+ }
142+
143+ fn overlap_mode < ' tcx > ( tcx : TyCtxt < ' tcx > , impl1_def_id : DefId , impl2_def_id : DefId ) -> OverlapMode {
144+ if tcx. has_attr ( impl1_def_id, sym:: rustc_strict_coherence)
145+ != tcx. has_attr ( impl2_def_id, sym:: rustc_strict_coherence)
146+ {
147+ bug ! ( "Use strict coherence on both impls" , ) ;
148+ }
149+
150+ if tcx. has_attr ( impl1_def_id, sym:: rustc_strict_coherence) {
151+ OverlapMode :: Strict
152+ } else {
153+ OverlapMode :: Stable
154+ }
155+ }
156+
138157/// Can both impl `a` and impl `b` be satisfied by a common type (including
139158/// where-clauses)? If so, returns an `ImplHeader` that unifies the two impls.
140159fn overlap < ' cx , ' tcx > (
@@ -169,10 +188,8 @@ fn overlap_within_probe<'cx, 'tcx>(
169188 let impl1_header = with_fresh_ty_vars ( selcx, param_env, impl1_def_id) ;
170189 let impl2_header = with_fresh_ty_vars ( selcx, param_env, impl2_def_id) ;
171190
172- let strict_coherence = tcx. has_attr ( impl1_def_id, sym:: rustc_strict_coherence)
173- && tcx. has_attr ( impl2_def_id, sym:: rustc_strict_coherence) ;
174-
175- if stable_disjoint ( selcx, param_env, & impl1_header, impl2_header, strict_coherence) {
191+ let overlap_mode = overlap_mode ( tcx, impl1_def_id, impl2_def_id) ;
192+ if stable_disjoint ( selcx, param_env, & impl1_header, impl2_header, overlap_mode) {
176193 return None ;
177194 }
178195
@@ -200,7 +217,7 @@ fn stable_disjoint<'cx, 'tcx>(
200217 param_env : ty:: ParamEnv < ' tcx > ,
201218 impl1_header : & ty:: ImplHeader < ' tcx > ,
202219 impl2_header : ty:: ImplHeader < ' tcx > ,
203- strict_coherence : bool ,
220+ overlap_mode : OverlapMode ,
204221) -> bool {
205222 debug ! ( "overlap: impl1_header={:?}" , impl1_header) ;
206223 debug ! ( "overlap: impl2_header={:?}" , impl2_header) ;
@@ -258,10 +275,11 @@ fn stable_disjoint<'cx, 'tcx>(
258275 . find ( |o| {
259276 // if both impl headers are set to strict coherence it means that this will be accepted
260277 // only if it's stated that T: !Trait. So only prove that the negated obligation holds.
261- if strict_coherence {
262- strict_check ( selcx, o)
263- } else {
264- loose_check ( selcx, o) || tcx. features ( ) . negative_impls && strict_check ( selcx, o)
278+ match overlap_mode {
279+ OverlapMode :: Stable => {
280+ loose_check ( selcx, o) || tcx. features ( ) . negative_impls && strict_check ( selcx, o)
281+ }
282+ OverlapMode :: Strict => strict_check ( selcx, o) ,
265283 }
266284 } ) ;
267285 // FIXME: the call to `selcx.predicate_may_hold_fatal` above should be ported
0 commit comments