Skip to content

Commit

Permalink
Auto merge of rust-lang#95065 - matthiaskrgr:rollup-75i6oz5, r=matthi…
Browse files Browse the repository at this point in the history
…askrgr

Rollup of 4 pull requests

Successful merges:

 - rust-lang#95013 (Update browser-ui-test version to 0.8.2)
 - rust-lang#95039 (Make negative coherence work when there's impl negative on super predicates)
 - rust-lang#95047 (Refactor: remove an unnecessary pattern for ignoring all parts)
 - rust-lang#95048 (update Miri)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Mar 18, 2022
2 parents d6f3a4e + d3dc65b commit 691d1c1
Show file tree
Hide file tree
Showing 10 changed files with 101 additions and 48 deletions.
7 changes: 7 additions & 0 deletions compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_resolve/src/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
90 changes: 58 additions & 32 deletions compiler/rustc_trait_selection/src/traits/coherence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -353,49 +353,75 @@ 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>,
region_context: DefId,
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>(
Expand Down
2 changes: 1 addition & 1 deletion src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -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 [email protected].1 --unsafe-perm=true
RUN npm install -g [email protected].3 --unsafe-perm=true

ENV RUST_CONFIGURE_ARGS \
--build=x86_64-unknown-linux-gnu \
Expand Down
1 change: 1 addition & 0 deletions src/ci/scripts/should-skip-this.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
12 changes: 12 additions & 0 deletions src/test/ui/coherence/coherence-overlap-double-negative.rs
Original file line number Diff line number Diff line change
@@ -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() {}
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// check-pass

#![feature(negative_impls)]
#![feature(rustc_attrs)]
#![feature(trait_alias)]
Expand All @@ -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() {}
11 changes: 0 additions & 11 deletions src/test/ui/coherence/coherence-overlap-negate-alias-strict.stderr

This file was deleted.

18 changes: 18 additions & 0 deletions src/test/ui/coherence/coherence-overlap-super-negative.rs
Original file line number Diff line number Diff line change
@@ -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() {}

0 comments on commit 691d1c1

Please sign in to comment.