diff options
| author | bors <bors@rust-lang.org> | 2022-03-18 05:26:14 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-03-18 05:26:14 +0000 |
| commit | 691d1c1e12602c57237e9ccddac406ebd0c54082 (patch) | |
| tree | 058231f5b253bd4aed04b991c28bf3300ce962b7 /compiler | |
| parent | d6f3a4ecb48ead838638e902f2fa4e5f3059779b (diff) | |
| parent | d3dc65be66d5abac5f017ce673d5aa600e46e55e (diff) | |
| download | rust-691d1c1e12602c57237e9ccddac406ebd0c54082.tar.gz rust-691d1c1e12602c57237e9ccddac406ebd0c54082.zip | |
Auto merge of #95065 - matthiaskrgr:rollup-75i6oz5, r=matthiaskrgr
Rollup of 4 pull requests Successful merges: - #95013 (Update browser-ui-test version to 0.8.2) - #95039 (Make negative coherence work when there's impl negative on super predicates) - #95047 (Refactor: remove an unnecessary pattern for ignoring all parts) - #95048 (update Miri) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_middle/src/ty/mod.rs | 7 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/late.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/coherence.rs | 90 |
3 files changed, 66 insertions, 33 deletions
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index e7cef9e198b..83ab761aa55 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -748,6 +748,13 @@ pub struct TraitPredicate<'tcx> { pub constness: BoundConstness, + /// If polarity is Positive: we are proving that the trait is implemented. + /// + /// If polarity is Negative: we are proving that a negative impl of this trait + /// exists. (Note that coherence also checks whether negative impls of supertraits + /// exist via a series of predicates.) + /// + /// If polarity is Reserved: that's a bug. pub polarity: ImplPolarity, } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 91695257137..d5b1aa00e52 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1129,7 +1129,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { } for param in &generics.params { - if let GenericParamKind::Lifetime { .. } = param.kind { + if let GenericParamKind::Lifetime = param.kind { continue; } diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index a3d32acc6fb..94a4001bbb9 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -17,8 +17,8 @@ use crate::traits::{ use rustc_errors::Diagnostic; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_hir::CRATE_HIR_ID; -use rustc_infer::infer::TyCtxtInferExt; -use rustc_infer::traits::TraitEngine; +use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; +use rustc_infer::traits::{util, TraitEngine}; use rustc_middle::traits::specialization_graph::OverlapMode; use rustc_middle::ty::fast_reject::{self, TreatParams}; use rustc_middle::ty::fold::TypeFoldable; @@ -353,6 +353,8 @@ fn negative_impl<'cx, 'tcx>( }) } +/// Try to prove that a negative impl exist for the given obligation and their super predicates. +#[instrument(level = "debug", skip(selcx))] fn negative_impl_exists<'cx, 'tcx>( selcx: &SelectionContext<'cx, 'tcx>, param_env: ty::ParamEnv<'tcx>, @@ -360,42 +362,66 @@ fn negative_impl_exists<'cx, 'tcx>( o: &PredicateObligation<'tcx>, ) -> bool { let infcx = &selcx.infcx().fork(); + + if resolve_negative_obligation(infcx, param_env, region_context, o) { + return true; + } + + // Try to prove a negative obligation exist for super predicates + for o in util::elaborate_predicates(infcx.tcx, iter::once(o.predicate)) { + if resolve_negative_obligation(infcx, param_env, region_context, &o) { + return true; + } + } + + false +} + +#[instrument(level = "debug", skip(infcx))] +fn resolve_negative_obligation<'cx, 'tcx>( + infcx: &InferCtxt<'cx, 'tcx>, + param_env: ty::ParamEnv<'tcx>, + region_context: DefId, + o: &PredicateObligation<'tcx>, +) -> bool { let tcx = infcx.tcx; - o.flip_polarity(tcx) - .map(|o| { - let mut fulfillment_cx = FulfillmentContext::new(); - fulfillment_cx.register_predicate_obligation(infcx, o); - - let errors = fulfillment_cx.select_all_or_error(infcx); - if !errors.is_empty() { - return false; - } - let mut outlives_env = OutlivesEnvironment::new(param_env); - // FIXME -- add "assumed to be well formed" types into the `outlives_env` + let Some(o) = o.flip_polarity(tcx) else { + return false; + }; - // "Save" the accumulated implied bounds into the outlives environment - // (due to the FIXME above, there aren't any, but this step is still needed). - // The "body id" is given as `CRATE_HIR_ID`, which is the same body-id used - // by the "dummy" causes elsewhere (body-id is only relevant when checking - // function bodies with closures). - outlives_env.save_implied_bounds(CRATE_HIR_ID); + let mut fulfillment_cx = FulfillmentContext::new(); + fulfillment_cx.register_predicate_obligation(infcx, o); - infcx.process_registered_region_obligations( - outlives_env.region_bound_pairs_map(), - Some(tcx.lifetimes.re_root_empty), - param_env, - ); + let errors = fulfillment_cx.select_all_or_error(infcx); - let errors = - infcx.resolve_regions(region_context, &outlives_env, RegionckMode::default()); - if !errors.is_empty() { - return false; - } + if !errors.is_empty() { + return false; + } - true - }) - .unwrap_or(false) + let mut outlives_env = OutlivesEnvironment::new(param_env); + // FIXME -- add "assumed to be well formed" types into the `outlives_env` + + // "Save" the accumulated implied bounds into the outlives environment + // (due to the FIXME above, there aren't any, but this step is still needed). + // The "body id" is given as `CRATE_HIR_ID`, which is the same body-id used + // by the "dummy" causes elsewhere (body-id is only relevant when checking + // function bodies with closures). + outlives_env.save_implied_bounds(CRATE_HIR_ID); + + infcx.process_registered_region_obligations( + outlives_env.region_bound_pairs_map(), + Some(tcx.lifetimes.re_root_empty), + param_env, + ); + + let errors = infcx.resolve_regions(region_context, &outlives_env, RegionckMode::default()); + + if !errors.is_empty() { + return false; + } + + true } pub fn trait_ref_is_knowable<'tcx>( |
