@@ -214,76 +214,69 @@ fn overlap<'tcx>(
214214 let mut obligations = equate_impl_headers ( selcx. infcx , & impl1_header, & impl2_header) ?;
215215 debug ! ( "overlap: unification check succeeded" ) ;
216216
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-
226217 obligations. extend (
227218 [ & impl1_header. predicates , & impl2_header. predicates ] . into_iter ( ) . flatten ( ) . map (
228219 |& predicate| Obligation :: new ( infcx. tcx , ObligationCause :: dummy ( ) , param_env, predicate) ,
229220 ) ,
230221 ) ;
231222
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
261274 } ,
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+ }
285277
286- return None ;
278+ return None ;
279+ }
287280 }
288281 }
289282
@@ -294,7 +287,9 @@ fn overlap<'tcx>(
294287 return None ;
295288 }
296289
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 ( ) {
298293 compute_intercrate_ambiguity_causes ( & infcx, & obligations)
299294 } else {
300295 selcx. take_intercrate_ambiguity_causes ( )
@@ -932,6 +927,8 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a> {
932927
933928 let Goal { param_env, predicate } = goal. goal ( ) ;
934929
930+ // For bound predicates we simply call `infcx.replace_bound_vars_with_placeholders`
931+ // and then prove the resulting predicate as a nested goal.
935932 let trait_ref = match predicate. kind ( ) . no_bound_vars ( ) {
936933 Some ( ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Trait ( tr) ) ) => tr. trait_ref ,
937934 Some ( ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Projection ( proj) ) ) => {
@@ -942,21 +939,6 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a> {
942939
943940 let mut ambiguity_cause = None ;
944941 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-
960942 // FIXME: boiiii, using string comparisions here sure is scuffed.
961943 if let inspect:: ProbeKind :: MiscCandidate { name : "coherence unknowable" , result : _ } =
962944 cand. kind ( )
@@ -1011,6 +993,21 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a> {
1011993 }
1012994 }
1013995 } )
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+ }
10141011 }
10151012 }
10161013
0 commit comments