@@ -214,76 +214,69 @@ fn overlap<'tcx>(
214
214
let mut obligations = equate_impl_headers ( selcx. infcx , & impl1_header, & impl2_header) ?;
215
215
debug ! ( "overlap: unification check succeeded" ) ;
216
216
217
- if !overlap_mode. use_implicit_negative ( ) {
218
- let impl_header = selcx. infcx . resolve_vars_if_possible ( impl1_header) ;
219
- return Some ( OverlapResult {
220
- impl_header,
221
- intercrate_ambiguity_causes : Default :: default ( ) ,
222
- involves_placeholder : false ,
223
- } ) ;
224
- } ;
225
-
226
217
obligations. extend (
227
218
[ & impl1_header. predicates , & impl2_header. predicates ] . into_iter ( ) . flatten ( ) . map (
228
219
|& predicate| Obligation :: new ( infcx. tcx , ObligationCause :: dummy ( ) , param_env, predicate) ,
229
220
) ,
230
221
) ;
231
222
232
- for mode in [ TreatInductiveCycleAs :: Ambig , TreatInductiveCycleAs :: Recur ] {
233
- if let Some ( failing_obligation) = selcx. with_treat_inductive_cycle_as ( mode, |selcx| {
234
- impl_intersection_has_impossible_obligation ( selcx, & obligations)
235
- } ) {
236
- if matches ! ( mode, TreatInductiveCycleAs :: Recur ) {
237
- let first_local_impl = impl1_header
238
- . impl_def_id
239
- . as_local ( )
240
- . or ( impl2_header. impl_def_id . as_local ( ) )
241
- . expect ( "expected one of the impls to be local" ) ;
242
- infcx. tcx . struct_span_lint_hir (
243
- COINDUCTIVE_OVERLAP_IN_COHERENCE ,
244
- infcx. tcx . local_def_id_to_hir_id ( first_local_impl) ,
245
- infcx. tcx . def_span ( first_local_impl) ,
246
- format ! (
247
- "implementations {} will conflict in the future" ,
248
- match impl1_header. trait_ref {
249
- Some ( trait_ref) => {
250
- let trait_ref = infcx. resolve_vars_if_possible( trait_ref) ;
251
- format!(
252
- "of `{}` for `{}`" ,
253
- trait_ref. print_only_trait_path( ) ,
254
- trait_ref. self_ty( )
255
- )
256
- }
257
- None => format!(
258
- "for `{}`" ,
259
- infcx. resolve_vars_if_possible( impl1_header. self_ty)
260
- ) ,
223
+ if overlap_mode. use_implicit_negative ( ) {
224
+ for mode in [ TreatInductiveCycleAs :: Ambig , TreatInductiveCycleAs :: Recur ] {
225
+ if let Some ( failing_obligation) = selcx. with_treat_inductive_cycle_as ( mode, |selcx| {
226
+ impl_intersection_has_impossible_obligation ( selcx, & obligations)
227
+ } ) {
228
+ if matches ! ( mode, TreatInductiveCycleAs :: Recur ) {
229
+ let first_local_impl = impl1_header
230
+ . impl_def_id
231
+ . as_local ( )
232
+ . or ( impl2_header. impl_def_id . as_local ( ) )
233
+ . expect ( "expected one of the impls to be local" ) ;
234
+ infcx. tcx . struct_span_lint_hir (
235
+ COINDUCTIVE_OVERLAP_IN_COHERENCE ,
236
+ infcx. tcx . local_def_id_to_hir_id ( first_local_impl) ,
237
+ infcx. tcx . def_span ( first_local_impl) ,
238
+ format ! (
239
+ "implementations {} will conflict in the future" ,
240
+ match impl1_header. trait_ref {
241
+ Some ( trait_ref) => {
242
+ let trait_ref = infcx. resolve_vars_if_possible( trait_ref) ;
243
+ format!(
244
+ "of `{}` for `{}`" ,
245
+ trait_ref. print_only_trait_path( ) ,
246
+ trait_ref. self_ty( )
247
+ )
248
+ }
249
+ None => format!(
250
+ "for `{}`" ,
251
+ infcx. resolve_vars_if_possible( impl1_header. self_ty)
252
+ ) ,
253
+ } ,
254
+ ) ,
255
+ |lint| {
256
+ lint. note (
257
+ "impls that are not considered to overlap may be considered to \
258
+ overlap in the future",
259
+ )
260
+ . span_label (
261
+ infcx. tcx . def_span ( impl1_header. impl_def_id ) ,
262
+ "the first impl is here" ,
263
+ )
264
+ . span_label (
265
+ infcx. tcx . def_span ( impl2_header. impl_def_id ) ,
266
+ "the second impl is here" ,
267
+ ) ;
268
+ lint. note ( format ! (
269
+ "`{}` may be considered to hold in future releases, \
270
+ causing the impls to overlap",
271
+ infcx. resolve_vars_if_possible( failing_obligation. predicate)
272
+ ) ) ;
273
+ lint
261
274
} ,
262
- ) ,
263
- |lint| {
264
- lint. note (
265
- "impls that are not considered to overlap may be considered to \
266
- overlap in the future",
267
- )
268
- . span_label (
269
- infcx. tcx . def_span ( impl1_header. impl_def_id ) ,
270
- "the first impl is here" ,
271
- )
272
- . span_label (
273
- infcx. tcx . def_span ( impl2_header. impl_def_id ) ,
274
- "the second impl is here" ,
275
- ) ;
276
- lint. note ( format ! (
277
- "`{}` may be considered to hold in future releases, \
278
- causing the impls to overlap",
279
- infcx. resolve_vars_if_possible( failing_obligation. predicate)
280
- ) ) ;
281
- lint
282
- } ,
283
- ) ;
284
- }
275
+ ) ;
276
+ }
285
277
286
- return None ;
278
+ return None ;
279
+ }
287
280
}
288
281
}
289
282
@@ -294,7 +287,9 @@ fn overlap<'tcx>(
294
287
return None ;
295
288
}
296
289
297
- let intercrate_ambiguity_causes = if infcx. next_trait_solver ( ) {
290
+ let intercrate_ambiguity_causes = if !overlap_mode. use_implicit_negative ( ) {
291
+ Default :: default ( )
292
+ } else if infcx. next_trait_solver ( ) {
298
293
compute_intercrate_ambiguity_causes ( & infcx, & obligations)
299
294
} else {
300
295
selcx. take_intercrate_ambiguity_causes ( )
@@ -932,6 +927,8 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a> {
932
927
933
928
let Goal { param_env, predicate } = goal. goal ( ) ;
934
929
930
+ // For bound predicates we simply call `infcx.replace_bound_vars_with_placeholders`
931
+ // and then prove the resulting predicate as a nested goal.
935
932
let trait_ref = match predicate. kind ( ) . no_bound_vars ( ) {
936
933
Some ( ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Trait ( tr) ) ) => tr. trait_ref ,
937
934
Some ( ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Projection ( proj) ) ) => {
@@ -942,21 +939,6 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a> {
942
939
943
940
let mut ambiguity_cause = None ;
944
941
for cand in goal. candidates ( ) {
945
- match cand. result ( ) {
946
- Ok ( Certainty :: Maybe ( _) ) => { }
947
- // We only add intercrate ambiguity causes if the goal would
948
- // otherwise result in an error.
949
- //
950
- // FIXME: this isn't quite right. Changing a goal from YES with
951
- // inference contraints to AMBIGUOUS can also cause a goal to not
952
- // fail.
953
- Ok ( Certainty :: Yes ) => {
954
- ambiguity_cause = None ;
955
- break ;
956
- }
957
- Err ( NoSolution ) => continue ,
958
- }
959
-
960
942
// FIXME: boiiii, using string comparisions here sure is scuffed.
961
943
if let inspect:: ProbeKind :: MiscCandidate { name : "coherence unknowable" , result : _ } =
962
944
cand. kind ( )
@@ -1011,6 +993,21 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a> {
1011
993
}
1012
994
}
1013
995
} )
996
+ } else {
997
+ match cand. result ( ) {
998
+ // We only add an ambiguity cause if the goal would otherwise
999
+ // result in an error.
1000
+ //
1001
+ // FIXME: While this matches the behavior of the
1002
+ // old solver, it is not the only way in which the unknowable
1003
+ // candidates *weaken* coherence, they can also force otherwise
1004
+ // sucessful normalization to be ambiguous.
1005
+ Ok ( Certainty :: Maybe ( _) | Certainty :: Yes ) => {
1006
+ ambiguity_cause = None ;
1007
+ break ;
1008
+ }
1009
+ Err ( NoSolution ) => continue ,
1010
+ }
1014
1011
}
1015
1012
}
1016
1013
0 commit comments