@@ -229,61 +229,63 @@ fn overlap<'tcx>(
229229 ) ,
230230 ) ;
231231
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
261283 } ,
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+ }
285286
286- return None ;
287+ return None ;
288+ }
287289 }
288290 }
289291
@@ -294,7 +296,9 @@ fn overlap<'tcx>(
294296 return None ;
295297 }
296298
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 ( ) {
298302 compute_intercrate_ambiguity_causes ( & infcx, & obligations)
299303 } else {
300304 selcx. take_intercrate_ambiguity_causes ( )
@@ -932,6 +936,8 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a> {
932936
933937 let Goal { param_env, predicate } = goal. goal ( ) ;
934938
939+ // For bound predicates we simply call `infcx.replace_bound_vars_with_placeholders`
940+ // and then prove the resulting predicate as a nested goal.
935941 let trait_ref = match predicate. kind ( ) . no_bound_vars ( ) {
936942 Some ( ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Trait ( tr) ) ) => tr. trait_ref ,
937943 Some ( ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Projection ( proj) ) ) => {
@@ -942,21 +948,6 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a> {
942948
943949 let mut ambiguity_cause = None ;
944950 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-
960951 // FIXME: boiiii, using string comparisions here sure is scuffed.
961952 if let inspect:: ProbeKind :: MiscCandidate { name : "coherence unknowable" , result : _ } =
962953 cand. kind ( )
@@ -1011,6 +1002,21 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a> {
10111002 }
10121003 }
10131004 } )
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+ }
10141020 }
10151021 }
10161022
0 commit comments