@@ -135,6 +135,25 @@ fn with_fresh_ty_vars<'cx, 'tcx>(
135
135
header
136
136
}
137
137
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
+
138
157
/// Can both impl `a` and impl `b` be satisfied by a common type (including
139
158
/// where-clauses)? If so, returns an `ImplHeader` that unifies the two impls.
140
159
fn overlap < ' cx , ' tcx > (
@@ -169,10 +188,8 @@ fn overlap_within_probe<'cx, 'tcx>(
169
188
let impl1_header = with_fresh_ty_vars ( selcx, param_env, impl1_def_id) ;
170
189
let impl2_header = with_fresh_ty_vars ( selcx, param_env, impl2_def_id) ;
171
190
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) {
176
193
return None ;
177
194
}
178
195
@@ -200,7 +217,7 @@ fn stable_disjoint<'cx, 'tcx>(
200
217
param_env : ty:: ParamEnv < ' tcx > ,
201
218
impl1_header : & ty:: ImplHeader < ' tcx > ,
202
219
impl2_header : ty:: ImplHeader < ' tcx > ,
203
- strict_coherence : bool ,
220
+ overlap_mode : OverlapMode ,
204
221
) -> bool {
205
222
debug ! ( "overlap: impl1_header={:?}" , impl1_header) ;
206
223
debug ! ( "overlap: impl2_header={:?}" , impl2_header) ;
@@ -258,10 +275,11 @@ fn stable_disjoint<'cx, 'tcx>(
258
275
. find ( |o| {
259
276
// if both impl headers are set to strict coherence it means that this will be accepted
260
277
// 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) ,
265
283
}
266
284
} ) ;
267
285
// FIXME: the call to `selcx.predicate_may_hold_fatal` above should be ported
0 commit comments