Skip to content

Commit 691d1c1

Browse files
committed
Auto merge of rust-lang#95065 - matthiaskrgr:rollup-75i6oz5, r=matthiaskrgr
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
2 parents d6f3a4e + d3dc65b commit 691d1c1

File tree

10 files changed

+101
-48
lines changed

10 files changed

+101
-48
lines changed

compiler/rustc_middle/src/ty/mod.rs

+7
Original file line numberDiff line numberDiff line change
@@ -748,6 +748,13 @@ pub struct TraitPredicate<'tcx> {
748748

749749
pub constness: BoundConstness,
750750

751+
/// If polarity is Positive: we are proving that the trait is implemented.
752+
///
753+
/// If polarity is Negative: we are proving that a negative impl of this trait
754+
/// exists. (Note that coherence also checks whether negative impls of supertraits
755+
/// exist via a series of predicates.)
756+
///
757+
/// If polarity is Reserved: that's a bug.
751758
pub polarity: ImplPolarity,
752759
}
753760

compiler/rustc_resolve/src/late.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1129,7 +1129,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
11291129
}
11301130

11311131
for param in &generics.params {
1132-
if let GenericParamKind::Lifetime { .. } = param.kind {
1132+
if let GenericParamKind::Lifetime = param.kind {
11331133
continue;
11341134
}
11351135

compiler/rustc_trait_selection/src/traits/coherence.rs

+58-32
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ use crate::traits::{
1717
use rustc_errors::Diagnostic;
1818
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
1919
use rustc_hir::CRATE_HIR_ID;
20-
use rustc_infer::infer::TyCtxtInferExt;
21-
use rustc_infer::traits::TraitEngine;
20+
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
21+
use rustc_infer::traits::{util, TraitEngine};
2222
use rustc_middle::traits::specialization_graph::OverlapMode;
2323
use rustc_middle::ty::fast_reject::{self, TreatParams};
2424
use rustc_middle::ty::fold::TypeFoldable;
@@ -353,49 +353,75 @@ fn negative_impl<'cx, 'tcx>(
353353
})
354354
}
355355

356+
/// Try to prove that a negative impl exist for the given obligation and their super predicates.
357+
#[instrument(level = "debug", skip(selcx))]
356358
fn negative_impl_exists<'cx, 'tcx>(
357359
selcx: &SelectionContext<'cx, 'tcx>,
358360
param_env: ty::ParamEnv<'tcx>,
359361
region_context: DefId,
360362
o: &PredicateObligation<'tcx>,
361363
) -> bool {
362364
let infcx = &selcx.infcx().fork();
365+
366+
if resolve_negative_obligation(infcx, param_env, region_context, o) {
367+
return true;
368+
}
369+
370+
// Try to prove a negative obligation exist for super predicates
371+
for o in util::elaborate_predicates(infcx.tcx, iter::once(o.predicate)) {
372+
if resolve_negative_obligation(infcx, param_env, region_context, &o) {
373+
return true;
374+
}
375+
}
376+
377+
false
378+
}
379+
380+
#[instrument(level = "debug", skip(infcx))]
381+
fn resolve_negative_obligation<'cx, 'tcx>(
382+
infcx: &InferCtxt<'cx, 'tcx>,
383+
param_env: ty::ParamEnv<'tcx>,
384+
region_context: DefId,
385+
o: &PredicateObligation<'tcx>,
386+
) -> bool {
363387
let tcx = infcx.tcx;
364-
o.flip_polarity(tcx)
365-
.map(|o| {
366-
let mut fulfillment_cx = FulfillmentContext::new();
367-
fulfillment_cx.register_predicate_obligation(infcx, o);
368-
369-
let errors = fulfillment_cx.select_all_or_error(infcx);
370-
if !errors.is_empty() {
371-
return false;
372-
}
373388

374-
let mut outlives_env = OutlivesEnvironment::new(param_env);
375-
// FIXME -- add "assumed to be well formed" types into the `outlives_env`
389+
let Some(o) = o.flip_polarity(tcx) else {
390+
return false;
391+
};
376392

377-
// "Save" the accumulated implied bounds into the outlives environment
378-
// (due to the FIXME above, there aren't any, but this step is still needed).
379-
// The "body id" is given as `CRATE_HIR_ID`, which is the same body-id used
380-
// by the "dummy" causes elsewhere (body-id is only relevant when checking
381-
// function bodies with closures).
382-
outlives_env.save_implied_bounds(CRATE_HIR_ID);
393+
let mut fulfillment_cx = FulfillmentContext::new();
394+
fulfillment_cx.register_predicate_obligation(infcx, o);
383395

384-
infcx.process_registered_region_obligations(
385-
outlives_env.region_bound_pairs_map(),
386-
Some(tcx.lifetimes.re_root_empty),
387-
param_env,
388-
);
396+
let errors = fulfillment_cx.select_all_or_error(infcx);
389397

390-
let errors =
391-
infcx.resolve_regions(region_context, &outlives_env, RegionckMode::default());
392-
if !errors.is_empty() {
393-
return false;
394-
}
398+
if !errors.is_empty() {
399+
return false;
400+
}
395401

396-
true
397-
})
398-
.unwrap_or(false)
402+
let mut outlives_env = OutlivesEnvironment::new(param_env);
403+
// FIXME -- add "assumed to be well formed" types into the `outlives_env`
404+
405+
// "Save" the accumulated implied bounds into the outlives environment
406+
// (due to the FIXME above, there aren't any, but this step is still needed).
407+
// The "body id" is given as `CRATE_HIR_ID`, which is the same body-id used
408+
// by the "dummy" causes elsewhere (body-id is only relevant when checking
409+
// function bodies with closures).
410+
outlives_env.save_implied_bounds(CRATE_HIR_ID);
411+
412+
infcx.process_registered_region_obligations(
413+
outlives_env.region_bound_pairs_map(),
414+
Some(tcx.lifetimes.re_root_empty),
415+
param_env,
416+
);
417+
418+
let errors = infcx.resolve_regions(region_context, &outlives_env, RegionckMode::default());
419+
420+
if !errors.is_empty() {
421+
return false;
422+
}
423+
424+
true
399425
}
400426

401427
pub fn trait_ref_is_knowable<'tcx>(

src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ ENV PATH="/node-v14.4.0-linux-x64/bin:${PATH}"
7272
# https://github.com/puppeteer/puppeteer/issues/375
7373
#
7474
# We also specify the version in case we need to update it to go around cache limitations.
75-
RUN npm install -g [email protected].1 --unsafe-perm=true
75+
RUN npm install -g [email protected].3 --unsafe-perm=true
7676

7777
ENV RUST_CONFIGURE_ARGS \
7878
--build=x86_64-unknown-linux-gnu \

src/ci/scripts/should-skip-this.sh

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ if [[ -n "${CI_ONLY_WHEN_SUBMODULES_CHANGED-}" ]]; then
2525
elif ! (git diff --quiet "$BASE_COMMIT" -- \
2626
src/test/rustdoc-gui \
2727
src/librustdoc \
28+
src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile \
2829
src/tools/rustdoc-gui); then
2930
# There was a change in either rustdoc or in its GUI tests.
3031
echo "Rustdoc was updated"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// check-pass
2+
3+
#![feature(negative_impls)]
4+
#![feature(with_negative_coherence)]
5+
6+
trait A {}
7+
trait B: A {}
8+
9+
impl !A for u32 {}
10+
impl !B for u32 {}
11+
12+
fn main() {}

src/test/ui/coherence/coherence-overlap-negate-alias-strict.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// check-pass
2+
13
#![feature(negative_impls)]
24
#![feature(rustc_attrs)]
35
#![feature(trait_alias)]
@@ -13,7 +15,5 @@ impl !A for u32 {}
1315
trait C {}
1416
impl<T: AB> C for T {}
1517
impl C for u32 {}
16-
//~^ ERROR: conflicting implementations of trait `C` for type `u32` [E0119]
17-
// FIXME this should work, we should implement an `assemble_neg_candidates` fn
1818

1919
fn main() {}

src/test/ui/coherence/coherence-overlap-negate-alias-strict.stderr

-11
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// check-pass
2+
3+
#![feature(negative_impls)]
4+
#![feature(rustc_attrs)]
5+
#![feature(with_negative_coherence)]
6+
7+
trait Trait1: Trait2 {}
8+
trait Trait2 {}
9+
10+
struct MyType {}
11+
impl !Trait2 for MyType {}
12+
13+
#[rustc_strict_coherence]
14+
trait Foo {}
15+
impl<T: Trait1> Foo for T {}
16+
impl Foo for MyType {}
17+
18+
fn main() {}

0 commit comments

Comments
 (0)