@@ -157,6 +157,9 @@ fn overlap_within_probe<'cx, 'tcx>(
157
157
impl2_def_id : DefId ,
158
158
snapshot : & CombinedSnapshot < ' _ , ' tcx > ,
159
159
) -> Option < OverlapResult < ' tcx > > {
160
+ let infcx = selcx. infcx ( ) ;
161
+ let tcx = infcx. tcx ;
162
+
160
163
// For the purposes of this check, we don't bring any placeholder
161
164
// types into scope; instead, we replace the generic types with
162
165
// fresh type variables, and hence we do our evaluations in an
@@ -166,6 +169,39 @@ fn overlap_within_probe<'cx, 'tcx>(
166
169
let impl1_header = with_fresh_ty_vars ( selcx, param_env, impl1_def_id) ;
167
170
let impl2_header = with_fresh_ty_vars ( selcx, param_env, impl2_def_id) ;
168
171
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) {
176
+ return None ;
177
+ }
178
+
179
+ if !skip_leak_check. is_yes ( ) {
180
+ if infcx. leak_check ( true , snapshot) . is_err ( ) {
181
+ debug ! ( "overlap: leak check failed" ) ;
182
+ return None ;
183
+ }
184
+ }
185
+
186
+ let intercrate_ambiguity_causes = selcx. take_intercrate_ambiguity_causes ( ) ;
187
+ debug ! ( "overlap: intercrate_ambiguity_causes={:#?}" , intercrate_ambiguity_causes) ;
188
+
189
+ let involves_placeholder =
190
+ matches ! ( selcx. infcx( ) . region_constraints_added_in_snapshot( snapshot) , Some ( true ) ) ;
191
+
192
+ let impl_header = selcx. infcx ( ) . resolve_vars_if_possible ( impl1_header) ;
193
+ Some ( OverlapResult { impl_header, intercrate_ambiguity_causes, involves_placeholder } )
194
+ }
195
+
196
+ /// Given impl1 and impl2 check if both impls can be satisfied by a common type (including
197
+ /// where-clauses) If so, return false, otherwise return true, they are disjoint.
198
+ fn stable_disjoint < ' cx , ' tcx > (
199
+ selcx : & mut SelectionContext < ' cx , ' tcx > ,
200
+ param_env : ty:: ParamEnv < ' tcx > ,
201
+ impl1_header : & ty:: ImplHeader < ' tcx > ,
202
+ impl2_header : ty:: ImplHeader < ' tcx > ,
203
+ strict_coherence : bool ,
204
+ ) -> bool {
169
205
debug ! ( "overlap: impl1_header={:?}" , impl1_header) ;
170
206
debug ! ( "overlap: impl2_header={:?}" , impl2_header) ;
171
207
@@ -177,7 +213,7 @@ fn overlap_within_probe<'cx, 'tcx>(
177
213
{
178
214
Ok ( InferOk { obligations, value : ( ) } ) => obligations,
179
215
Err ( _) => {
180
- return None ;
216
+ return true ;
181
217
}
182
218
} ;
183
219
@@ -222,9 +258,7 @@ fn overlap_within_probe<'cx, 'tcx>(
222
258
. find ( |o| {
223
259
// if both impl headers are set to strict coherence it means that this will be accepted
224
260
// only if it's stated that T: !Trait. So only prove that the negated obligation holds.
225
- if tcx. has_attr ( impl1_def_id, sym:: rustc_strict_coherence)
226
- && tcx. has_attr ( impl2_def_id, sym:: rustc_strict_coherence)
227
- {
261
+ if strict_coherence {
228
262
strict_check ( selcx, o)
229
263
} else {
230
264
loose_check ( selcx, o) || tcx. features ( ) . negative_impls && strict_check ( selcx, o)
@@ -236,24 +270,10 @@ fn overlap_within_probe<'cx, 'tcx>(
236
270
237
271
if let Some ( failing_obligation) = opt_failing_obligation {
238
272
debug ! ( "overlap: obligation unsatisfiable {:?}" , failing_obligation) ;
239
- return None ;
240
- }
241
-
242
- if !skip_leak_check. is_yes ( ) {
243
- if infcx. leak_check ( true , snapshot) . is_err ( ) {
244
- debug ! ( "overlap: leak check failed" ) ;
245
- return None ;
246
- }
273
+ true
274
+ } else {
275
+ false
247
276
}
248
-
249
- let impl_header = selcx. infcx ( ) . resolve_vars_if_possible ( impl1_header) ;
250
- let intercrate_ambiguity_causes = selcx. take_intercrate_ambiguity_causes ( ) ;
251
- debug ! ( "overlap: intercrate_ambiguity_causes={:#?}" , intercrate_ambiguity_causes) ;
252
-
253
- let involves_placeholder =
254
- matches ! ( selcx. infcx( ) . region_constraints_added_in_snapshot( snapshot) , Some ( true ) ) ;
255
-
256
- Some ( OverlapResult { impl_header, intercrate_ambiguity_causes, involves_placeholder } )
257
277
}
258
278
259
279
fn loose_check < ' cx , ' tcx > (
0 commit comments