Skip to content

Commit

Permalink
Rollup merge of rust-lang#135466 - compiler-errors:leak-check-impossi…
Browse files Browse the repository at this point in the history
…ble, r=lcnr

Leak check in `impossible_predicates` to avoid monomorphizing impossible instances

Fixes rust-lang#135462

r? lcnr
  • Loading branch information
GuillaumeGomez authored Jan 14, 2025
2 parents 47af387 + 94ffced commit 614de1e
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 3 deletions.
15 changes: 12 additions & 3 deletions compiler/rustc_trait_selection/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -714,9 +714,18 @@ pub fn impossible_predicates<'tcx>(tcx: TyCtxt<'tcx>, predicates: Vec<ty::Clause
}
let errors = ocx.select_all_or_error();

let result = !errors.is_empty();
debug!("impossible_predicates = {:?}", result);
result
if !errors.is_empty() {
return true;
}

// Leak check for any higher-ranked trait mismatches.
// We only need to do this in the old solver, since the new solver already
// leak-checks.
if !infcx.next_trait_solver() && infcx.leak_check(ty::UniverseIndex::ROOT, None).is_err() {
return true;
}

false
}

fn instantiate_and_check_impossible_predicates<'tcx>(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//@ build-pass
//@ revisions: current next
//@ ignore-compare-mode-next-solver (explicit revisions)
//@[next] compile-flags: -Znext-solver
// Regression test for #135462.
#![allow(coherence_leak_check)]

type A = fn(&'static ());
type B = fn(&());

trait Bound<P: WithAssoc>: From<GetAssoc<P>> {
}
impl Bound<B> for String {}

trait Trt<T> {
fn __(&self, x: T) where T: Bound<A> {
T::from(());
}
}

impl<T, S> Trt<T> for S {}

type GetAssoc<T> = <T as WithAssoc>::Ty;

trait WithAssoc {
type Ty;
}

impl WithAssoc for B {
type Ty = String;
}

impl WithAssoc for A {
type Ty = ();
}

fn main() {
let x: &'static dyn Trt<String> = &();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//@ build-pass
//@ revisions: current next
//@ ignore-compare-mode-next-solver (explicit revisions)
//@[next] compile-flags: -Znext-solver

trait Foo {}
impl Foo for fn(&'static ()) {}

trait Bar {
type Assoc: Default;
}
impl<T: Foo> Bar for T {
type Assoc = usize;
}
impl Bar for fn(&()) {
type Assoc = ();
}

fn needs_foo<T: Foo>() -> usize {
needs_bar::<T>()
}

fn needs_bar<T: Bar>() -> <T as Bar>::Assoc {
Default::default()
}

trait Evil<T> {
fn bad(&self)
where
T: Foo,
{
needs_foo::<T>();
}
}

impl Evil<fn(&())> for () {}

fn main() {
let x: &dyn Evil<fn(&())> = &();
}

0 comments on commit 614de1e

Please sign in to comment.