diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2022-08-23 06:55:26 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-08-23 06:55:26 +0200 |
| commit | 579dfa42be707acd0e2fa378b505ed18ad7b5c75 (patch) | |
| tree | 3f02274667716f1e0e51f6cc8d8a998f34a9603e | |
| parent | 44aa866488fd3524be7aafd1db0269ad4d59c2af (diff) | |
| parent | ba7272959df7447c7393a14f475663de1f250f8f (diff) | |
| download | rust-579dfa42be707acd0e2fa378b505ed18ad7b5c75.tar.gz rust-579dfa42be707acd0e2fa378b505ed18ad7b5c75.zip | |
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``
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/coherence.rs | 21 | ||||
| -rw-r--r-- | src/test/ui/coherence/coherence-negative-outlives-lifetimes.rs | 7 | ||||
| -rw-r--r-- | src/test/ui/coherence/coherence-negative-outlives-lifetimes.stock.stderr (renamed from src/test/ui/coherence/coherence-negative-outlives-lifetimes.stderr) | 2 | ||||
| -rw-r--r-- | src/test/ui/coherence/coherence-negative-outlives-lifetimes.with_negative_coherence.stderr | 11 |
4 files changed, 26 insertions, 15 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 985600d9ebc..3bc08fba91a 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -342,10 +342,8 @@ fn equate<'cx, 'tcx>( }; let selcx = &mut SelectionContext::new(&infcx); - let opt_failing_obligation = obligations - .into_iter() - .chain(more_obligations) - .find(|o| negative_impl_exists(selcx, impl_env, o)); + let opt_failing_obligation = + obligations.into_iter().chain(more_obligations).find(|o| negative_impl_exists(selcx, o)); if let Some(failing_obligation) = opt_failing_obligation { debug!("overlap: obligation unsatisfiable {:?}", failing_obligation); @@ -359,18 +357,15 @@ fn equate<'cx, 'tcx>( #[instrument(level = "debug", skip(selcx))] fn negative_impl_exists<'cx, 'tcx>( selcx: &SelectionContext<'cx, 'tcx>, - param_env: ty::ParamEnv<'tcx>, o: &PredicateObligation<'tcx>, ) -> bool { - let infcx = &selcx.infcx().fork(); - - if resolve_negative_obligation(infcx, param_env, o) { + if resolve_negative_obligation(selcx.infcx().fork(), o) { return true; } // Try to prove a negative obligation exists for super predicates - for o in util::elaborate_predicates(infcx.tcx, iter::once(o.predicate)) { - if resolve_negative_obligation(infcx, param_env, &o) { + for o in util::elaborate_predicates(selcx.tcx(), iter::once(o.predicate)) { + if resolve_negative_obligation(selcx.infcx().fork(), &o) { return true; } } @@ -380,8 +375,7 @@ fn negative_impl_exists<'cx, 'tcx>( #[instrument(level = "debug", skip(infcx))] fn resolve_negative_obligation<'cx, 'tcx>( - infcx: &InferCtxt<'cx, 'tcx>, - param_env: ty::ParamEnv<'tcx>, + infcx: InferCtxt<'cx, 'tcx>, o: &PredicateObligation<'tcx>, ) -> bool { let tcx = infcx.tcx; @@ -390,7 +384,8 @@ fn resolve_negative_obligation<'cx, 'tcx>( return false; }; - let errors = super::fully_solve_obligation(infcx, o); + let param_env = o.param_env; + let errors = super::fully_solve_obligation(&infcx, o); if !errors.is_empty() { return false; } diff --git a/src/test/ui/coherence/coherence-negative-outlives-lifetimes.rs b/src/test/ui/coherence/coherence-negative-outlives-lifetimes.rs index 159788b1b77..221c1bc23b3 100644 --- a/src/test/ui/coherence/coherence-negative-outlives-lifetimes.rs +++ b/src/test/ui/coherence/coherence-negative-outlives-lifetimes.rs @@ -1,10 +1,15 @@ +// revisions: stock with_negative_coherence #![feature(negative_impls)] +#![cfg_attr(with_negative_coherence, feature(with_negative_coherence))] // FIXME: this should compile trait MyPredicate<'a> {} -impl<'a, T> !MyPredicate<'a> for &T where T: 'a {} + +impl<'a, T> !MyPredicate<'a> for &'a T where T: 'a {} + trait MyTrait<'a> {} + impl<'a, T: MyPredicate<'a>> MyTrait<'a> for T {} impl<'a, T> MyTrait<'a> for &'a T {} //~^ ERROR: conflicting implementations of trait `MyTrait<'_>` for type `&_` diff --git a/src/test/ui/coherence/coherence-negative-outlives-lifetimes.stderr b/src/test/ui/coherence/coherence-negative-outlives-lifetimes.stock.stderr index 263bd19b424..097cc4e0fe3 100644 --- a/src/test/ui/coherence/coherence-negative-outlives-lifetimes.stderr +++ b/src/test/ui/coherence/coherence-negative-outlives-lifetimes.stock.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `MyTrait<'_>` for type `&_` - --> $DIR/coherence-negative-outlives-lifetimes.rs:9:1 + --> $DIR/coherence-negative-outlives-lifetimes.rs:14:1 | LL | impl<'a, T: MyPredicate<'a>> MyTrait<'a> for T {} | ---------------------------------------------- first implementation here diff --git a/src/test/ui/coherence/coherence-negative-outlives-lifetimes.with_negative_coherence.stderr b/src/test/ui/coherence/coherence-negative-outlives-lifetimes.with_negative_coherence.stderr new file mode 100644 index 00000000000..097cc4e0fe3 --- /dev/null +++ b/src/test/ui/coherence/coherence-negative-outlives-lifetimes.with_negative_coherence.stderr @@ -0,0 +1,11 @@ +error[E0119]: conflicting implementations of trait `MyTrait<'_>` for type `&_` + --> $DIR/coherence-negative-outlives-lifetimes.rs:14:1 + | +LL | impl<'a, T: MyPredicate<'a>> MyTrait<'a> for T {} + | ---------------------------------------------- first implementation here +LL | impl<'a, T> MyTrait<'a> for &'a T {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `&_` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0119`. |
