@@ -201,17 +201,17 @@ fn overlap_within_probe<'cx, 'tcx>(
201201
202202 match overlap_mode ( tcx, impl1_def_id, impl2_def_id) {
203203 OverlapMode :: Stable => {
204- if stable_disjoint ( selcx, param_env, & impl1_header, impl2_header, OverlapMode :: Stable ) {
204+ if stable_disjoint ( selcx, param_env, & impl1_header, impl2_header) {
205205 return None ;
206206 }
207207 }
208208 OverlapMode :: Strict => {
209- if stable_disjoint ( selcx, param_env, & impl1_header, impl2_header, OverlapMode :: Strict ) {
209+ if strict_disjoint ( selcx, param_env, & impl1_header, impl2_header) {
210210 return None ;
211211 }
212212 }
213213 OverlapMode :: WithNegative => {
214- if stable_disjoint ( selcx, param_env, & impl1_header, impl2_header, OverlapMode :: Stable )
214+ if stable_disjoint ( selcx, param_env, & impl1_header, impl2_header)
215215 || explicit_disjoint ( selcx, impl1_def_id, impl2_def_id)
216216 || explicit_disjoint ( selcx, impl2_def_id, impl1_def_id)
217217 {
@@ -244,7 +244,35 @@ fn stable_disjoint<'cx, 'tcx>(
244244 param_env : ty:: ParamEnv < ' tcx > ,
245245 impl1_header : & ty:: ImplHeader < ' tcx > ,
246246 impl2_header : ty:: ImplHeader < ' tcx > ,
247- overlap_mode : OverlapMode ,
247+ ) -> bool {
248+ let infcx = selcx. infcx ( ) ;
249+ let tcx = infcx. tcx ;
250+
251+ disjoint_with_filter ( selcx, param_env, impl1_header, impl2_header, |selcx, o| {
252+ loose_check ( selcx, o) || tcx. features ( ) . negative_impls && strict_check ( selcx, o)
253+ } )
254+ }
255+
256+ fn strict_disjoint < ' cx , ' tcx > (
257+ selcx : & mut SelectionContext < ' cx , ' tcx > ,
258+ param_env : ty:: ParamEnv < ' tcx > ,
259+ impl1_header : & ty:: ImplHeader < ' tcx > ,
260+ impl2_header : ty:: ImplHeader < ' tcx > ,
261+ ) -> bool {
262+ disjoint_with_filter ( selcx, param_env, impl1_header, impl2_header, |selcx, o| {
263+ strict_check ( selcx, o)
264+ } )
265+ }
266+
267+ fn disjoint_with_filter < ' cx , ' tcx > (
268+ selcx : & mut SelectionContext < ' cx , ' tcx > ,
269+ param_env : ty:: ParamEnv < ' tcx > ,
270+ impl1_header : & ty:: ImplHeader < ' tcx > ,
271+ impl2_header : ty:: ImplHeader < ' tcx > ,
272+ mut filter : impl FnMut (
273+ & mut SelectionContext < ' cx , ' tcx > ,
274+ & rustc_infer:: traits:: Obligation < ' tcx , rustc_middle:: ty:: Predicate < ' tcx > > ,
275+ ) -> bool ,
248276) -> bool {
249277 debug ! ( "overlap: impl1_header={:?}" , impl1_header) ;
250278 debug ! ( "overlap: impl2_header={:?}" , impl2_header) ;
@@ -285,7 +313,6 @@ fn stable_disjoint<'cx, 'tcx>(
285313 // hold we need to check if `&'?a str: !Error` holds, if doesn't hold there's overlap because
286314 // at some point an impl for `&'?a str: Error` could be added.
287315 let infcx = selcx. infcx ( ) ;
288- let tcx = infcx. tcx ;
289316 let opt_failing_obligation = impl1_header
290317 . predicates
291318 . iter ( )
@@ -299,17 +326,7 @@ fn stable_disjoint<'cx, 'tcx>(
299326 predicate : p,
300327 } )
301328 . chain ( obligations)
302- . find ( |o| {
303- // if both impl headers are set to strict coherence it means that this will be accepted
304- // only if it's stated that T: !Trait. So only prove that the negated obligation holds.
305- match overlap_mode {
306- OverlapMode :: Stable => {
307- loose_check ( selcx, o) || tcx. features ( ) . negative_impls && strict_check ( selcx, o)
308- }
309- OverlapMode :: Strict => strict_check ( selcx, o) ,
310- OverlapMode :: WithNegative => loose_check ( selcx, o) ,
311- }
312- } ) ;
329+ . find ( |o| filter ( selcx, o) ) ;
313330 // FIXME: the call to `selcx.predicate_may_hold_fatal` above should be ported
314331 // to the canonical trait query form, `infcx.predicate_may_hold`, once
315332 // the new system supports intercrate mode (which coherence needs).
0 commit comments