@@ -229,61 +229,63 @@ fn overlap<'tcx>(
229
229
) ,
230
230
) ;
231
231
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
- ) ,
232
+ if overlap_mode. use_implicit_negative ( ) {
233
+ for mode in [ TreatInductiveCycleAs :: Ambig , TreatInductiveCycleAs :: Recur ] {
234
+ if let Some ( failing_obligation) = selcx. with_treat_inductive_cycle_as ( mode, |selcx| {
235
+ impl_intersection_has_impossible_obligation ( selcx, & obligations)
236
+ } ) {
237
+ if matches ! ( mode, TreatInductiveCycleAs :: Recur ) {
238
+ let first_local_impl = impl1_header
239
+ . impl_def_id
240
+ . as_local ( )
241
+ . or ( impl2_header. impl_def_id . as_local ( ) )
242
+ . expect ( "expected one of the impls to be local" ) ;
243
+ infcx. tcx . struct_span_lint_hir (
244
+ COINDUCTIVE_OVERLAP_IN_COHERENCE ,
245
+ infcx. tcx . local_def_id_to_hir_id ( first_local_impl) ,
246
+ infcx. tcx . def_span ( first_local_impl) ,
247
+ format ! (
248
+ "implementations {} will conflict in the future" ,
249
+ match impl1_header. trait_ref {
250
+ Some ( trait_ref) => {
251
+ let trait_ref = infcx. resolve_vars_if_possible( trait_ref) ;
252
+ format!(
253
+ "of `{}` for `{}`" ,
254
+ trait_ref. print_only_trait_path( ) ,
255
+ trait_ref. self_ty( )
256
+ )
257
+ }
258
+ None => format!(
259
+ "for `{}`" ,
260
+ infcx. resolve_vars_if_possible( impl1_header. self_ty)
261
+ ) ,
262
+ } ,
263
+ ) ,
264
+ |lint| {
265
+ lint. note (
266
+ "impls that are not considered to overlap may be considered to \
267
+ overlap in the future",
268
+ )
269
+ . span_label (
270
+ infcx. tcx . def_span ( impl1_header. impl_def_id ) ,
271
+ "the first impl is here" ,
272
+ )
273
+ . span_label (
274
+ infcx. tcx . def_span ( impl2_header. impl_def_id ) ,
275
+ "the second impl is here" ,
276
+ ) ;
277
+ lint. note ( format ! (
278
+ "`{}` may be considered to hold in future releases, \
279
+ causing the impls to overlap",
280
+ infcx. resolve_vars_if_possible( failing_obligation. predicate)
281
+ ) ) ;
282
+ lint
261
283
} ,
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
- }
284
+ ) ;
285
+ }
285
286
286
- return None ;
287
+ return None ;
288
+ }
287
289
}
288
290
}
289
291
@@ -294,7 +296,9 @@ fn overlap<'tcx>(
294
296
return None ;
295
297
}
296
298
297
- let intercrate_ambiguity_causes = if infcx. next_trait_solver ( ) {
299
+ let intercrate_ambiguity_causes = if !overlap_mode. use_implicit_negative ( ) {
300
+ Default :: default ( )
301
+ } else if infcx. next_trait_solver ( ) {
298
302
compute_intercrate_ambiguity_causes ( & infcx, & obligations)
299
303
} else {
300
304
selcx. take_intercrate_ambiguity_causes ( )
@@ -932,6 +936,8 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a> {
932
936
933
937
let Goal { param_env, predicate } = goal. goal ( ) ;
934
938
939
+ // For bound predicates we simply call `infcx.replace_bound_vars_with_placeholders`
940
+ // and then prove the resulting predicate as a nested goal.
935
941
let trait_ref = match predicate. kind ( ) . no_bound_vars ( ) {
936
942
Some ( ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Trait ( tr) ) ) => tr. trait_ref ,
937
943
Some ( ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Projection ( proj) ) ) => {
@@ -942,21 +948,6 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a> {
942
948
943
949
let mut ambiguity_cause = None ;
944
950
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
951
// FIXME: boiiii, using string comparisions here sure is scuffed.
961
952
if let inspect:: ProbeKind :: MiscCandidate { name : "coherence unknowable" , result : _ } =
962
953
cand. kind ( )
@@ -1011,6 +1002,21 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a> {
1011
1002
}
1012
1003
}
1013
1004
} )
1005
+ } else {
1006
+ match cand. result ( ) {
1007
+ // We only add an ambiguity cause if the goal would otherwise
1008
+ // result in an error.
1009
+ //
1010
+ // FIXME: While this matches the behavior of the
1011
+ // old solver, it is not the only way in which the unknowable
1012
+ // candidates *weaken* coherence, they can also force otherwise
1013
+ // sucessful normalization to be ambiguous.
1014
+ Ok ( Certainty :: Maybe ( _) | Certainty :: Yes ) => {
1015
+ ambiguity_cause = None ;
1016
+ break ;
1017
+ }
1018
+ Err ( NoSolution ) => continue ,
1019
+ }
1014
1020
}
1015
1021
}
1016
1022
0 commit comments