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
This commit is contained in:
commit
691d1c1e12
10 changed files with 100 additions and 47 deletions
|
@ -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,
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 Some(o) = o.flip_polarity(tcx) else {
|
||||
return false;
|
||||
};
|
||||
|
||||
let mut outlives_env = OutlivesEnvironment::new(param_env);
|
||||
// FIXME -- add "assumed to be well formed" types into the `outlives_env`
|
||||
let mut fulfillment_cx = FulfillmentContext::new();
|
||||
fulfillment_cx.register_predicate_obligation(infcx, o);
|
||||
|
||||
// "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 errors = fulfillment_cx.select_all_or_error(infcx);
|
||||
|
||||
infcx.process_registered_region_obligations(
|
||||
outlives_env.region_bound_pairs_map(),
|
||||
Some(tcx.lifetimes.re_root_empty),
|
||||
param_env,
|
||||
);
|
||||
if !errors.is_empty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
let errors =
|
||||
infcx.resolve_regions(region_context, &outlives_env, RegionckMode::default());
|
||||
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`
|
||||
|
||||
true
|
||||
})
|
||||
.unwrap_or(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);
|
||||
|
||||
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>(
|
||||
|
|
|
@ -72,7 +72,7 @@ ENV PATH="/node-v14.4.0-linux-x64/bin:${PATH}"
|
|||
# https://github.com/puppeteer/puppeteer/issues/375
|
||||
#
|
||||
# We also specify the version in case we need to update it to go around cache limitations.
|
||||
RUN npm install -g browser-ui-test@0.8.1 --unsafe-perm=true
|
||||
RUN npm install -g browser-ui-test@0.8.3 --unsafe-perm=true
|
||||
|
||||
ENV RUST_CONFIGURE_ARGS \
|
||||
--build=x86_64-unknown-linux-gnu \
|
||||
|
|
|
@ -25,6 +25,7 @@ if [[ -n "${CI_ONLY_WHEN_SUBMODULES_CHANGED-}" ]]; then
|
|||
elif ! (git diff --quiet "$BASE_COMMIT" -- \
|
||||
src/test/rustdoc-gui \
|
||||
src/librustdoc \
|
||||
src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile \
|
||||
src/tools/rustdoc-gui); then
|
||||
# There was a change in either rustdoc or in its GUI tests.
|
||||
echo "Rustdoc was updated"
|
||||
|
|
12
src/test/ui/coherence/coherence-overlap-double-negative.rs
Normal file
12
src/test/ui/coherence/coherence-overlap-double-negative.rs
Normal file
|
@ -0,0 +1,12 @@
|
|||
// check-pass
|
||||
|
||||
#![feature(negative_impls)]
|
||||
#![feature(with_negative_coherence)]
|
||||
|
||||
trait A {}
|
||||
trait B: A {}
|
||||
|
||||
impl !A for u32 {}
|
||||
impl !B for u32 {}
|
||||
|
||||
fn main() {}
|
|
@ -1,3 +1,5 @@
|
|||
// check-pass
|
||||
|
||||
#![feature(negative_impls)]
|
||||
#![feature(rustc_attrs)]
|
||||
#![feature(trait_alias)]
|
||||
|
@ -13,7 +15,5 @@ impl !A for u32 {}
|
|||
trait C {}
|
||||
impl<T: AB> C for T {}
|
||||
impl C for u32 {}
|
||||
//~^ ERROR: conflicting implementations of trait `C` for type `u32` [E0119]
|
||||
// FIXME this should work, we should implement an `assemble_neg_candidates` fn
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
error[E0119]: conflicting implementations of trait `C` for type `u32`
|
||||
--> $DIR/coherence-overlap-negate-alias-strict.rs:15:1
|
||||
|
|
||||
LL | impl<T: AB> C for T {}
|
||||
| ------------------- first implementation here
|
||||
LL | impl C for u32 {}
|
||||
| ^^^^^^^^^^^^^^ conflicting implementation for `u32`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0119`.
|
18
src/test/ui/coherence/coherence-overlap-super-negative.rs
Normal file
18
src/test/ui/coherence/coherence-overlap-super-negative.rs
Normal file
|
@ -0,0 +1,18 @@
|
|||
// check-pass
|
||||
|
||||
#![feature(negative_impls)]
|
||||
#![feature(rustc_attrs)]
|
||||
#![feature(with_negative_coherence)]
|
||||
|
||||
trait Trait1: Trait2 {}
|
||||
trait Trait2 {}
|
||||
|
||||
struct MyType {}
|
||||
impl !Trait2 for MyType {}
|
||||
|
||||
#[rustc_strict_coherence]
|
||||
trait Foo {}
|
||||
impl<T: Trait1> Foo for T {}
|
||||
impl Foo for MyType {}
|
||||
|
||||
fn main() {}
|
|
@ -1 +1 @@
|
|||
Subproject commit 7bc0c986217629e6c831edcb133532023a5aec63
|
||||
Subproject commit 8e818ffa1b85f4e740c4096fd38c62b2b73f4d83
|
Loading…
Add table
Reference in a new issue