Skip to content

Commit 579dfa4

Browse files
authored
Rollup merge of #100789 - compiler-errors:issue-99662, r=spastorino
Use separate infcx to solve obligations during negative coherence I feel like I fixed this already but I may have fixed it then forgot to push the branch... Also fixes up some redundant param-envs being passed around (since they're already passed around in the `Obligation`) Fixes #99662 r? ``@spastorino``
2 parents 44aa866 + ba72729 commit 579dfa4

File tree

4 files changed

+26
-15
lines changed

4 files changed

+26
-15
lines changed

compiler/rustc_trait_selection/src/traits/coherence.rs

+8-13
Original file line numberDiff line numberDiff line change
@@ -342,10 +342,8 @@ fn equate<'cx, 'tcx>(
342342
};
343343

344344
let selcx = &mut SelectionContext::new(&infcx);
345-
let opt_failing_obligation = obligations
346-
.into_iter()
347-
.chain(more_obligations)
348-
.find(|o| negative_impl_exists(selcx, impl_env, o));
345+
let opt_failing_obligation =
346+
obligations.into_iter().chain(more_obligations).find(|o| negative_impl_exists(selcx, o));
349347

350348
if let Some(failing_obligation) = opt_failing_obligation {
351349
debug!("overlap: obligation unsatisfiable {:?}", failing_obligation);
@@ -359,18 +357,15 @@ fn equate<'cx, 'tcx>(
359357
#[instrument(level = "debug", skip(selcx))]
360358
fn negative_impl_exists<'cx, 'tcx>(
361359
selcx: &SelectionContext<'cx, 'tcx>,
362-
param_env: ty::ParamEnv<'tcx>,
363360
o: &PredicateObligation<'tcx>,
364361
) -> bool {
365-
let infcx = &selcx.infcx().fork();
366-
367-
if resolve_negative_obligation(infcx, param_env, o) {
362+
if resolve_negative_obligation(selcx.infcx().fork(), o) {
368363
return true;
369364
}
370365

371366
// Try to prove a negative obligation exists for super predicates
372-
for o in util::elaborate_predicates(infcx.tcx, iter::once(o.predicate)) {
373-
if resolve_negative_obligation(infcx, param_env, &o) {
367+
for o in util::elaborate_predicates(selcx.tcx(), iter::once(o.predicate)) {
368+
if resolve_negative_obligation(selcx.infcx().fork(), &o) {
374369
return true;
375370
}
376371
}
@@ -380,8 +375,7 @@ fn negative_impl_exists<'cx, 'tcx>(
380375

381376
#[instrument(level = "debug", skip(infcx))]
382377
fn resolve_negative_obligation<'cx, 'tcx>(
383-
infcx: &InferCtxt<'cx, 'tcx>,
384-
param_env: ty::ParamEnv<'tcx>,
378+
infcx: InferCtxt<'cx, 'tcx>,
385379
o: &PredicateObligation<'tcx>,
386380
) -> bool {
387381
let tcx = infcx.tcx;
@@ -390,7 +384,8 @@ fn resolve_negative_obligation<'cx, 'tcx>(
390384
return false;
391385
};
392386

393-
let errors = super::fully_solve_obligation(infcx, o);
387+
let param_env = o.param_env;
388+
let errors = super::fully_solve_obligation(&infcx, o);
394389
if !errors.is_empty() {
395390
return false;
396391
}

src/test/ui/coherence/coherence-negative-outlives-lifetimes.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
1+
// revisions: stock with_negative_coherence
12
#![feature(negative_impls)]
3+
#![cfg_attr(with_negative_coherence, feature(with_negative_coherence))]
24

35
// FIXME: this should compile
46

57
trait MyPredicate<'a> {}
6-
impl<'a, T> !MyPredicate<'a> for &T where T: 'a {}
8+
9+
impl<'a, T> !MyPredicate<'a> for &'a T where T: 'a {}
10+
711
trait MyTrait<'a> {}
12+
813
impl<'a, T: MyPredicate<'a>> MyTrait<'a> for T {}
914
impl<'a, T> MyTrait<'a> for &'a T {}
1015
//~^ ERROR: conflicting implementations of trait `MyTrait<'_>` for type `&_`

src/test/ui/coherence/coherence-negative-outlives-lifetimes.stderr renamed to src/test/ui/coherence/coherence-negative-outlives-lifetimes.stock.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0119]: conflicting implementations of trait `MyTrait<'_>` for type `&_`
2-
--> $DIR/coherence-negative-outlives-lifetimes.rs:9:1
2+
--> $DIR/coherence-negative-outlives-lifetimes.rs:14:1
33
|
44
LL | impl<'a, T: MyPredicate<'a>> MyTrait<'a> for T {}
55
| ---------------------------------------------- first implementation here
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error[E0119]: conflicting implementations of trait `MyTrait<'_>` for type `&_`
2+
--> $DIR/coherence-negative-outlives-lifetimes.rs:14:1
3+
|
4+
LL | impl<'a, T: MyPredicate<'a>> MyTrait<'a> for T {}
5+
| ---------------------------------------------- first implementation here
6+
LL | impl<'a, T> MyTrait<'a> for &'a T {}
7+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `&_`
8+
9+
error: aborting due to previous error
10+
11+
For more information about this error, try `rustc --explain E0119`.

0 commit comments

Comments
 (0)