1
Fork 0

Rollup merge of #135466 - compiler-errors:leak-check-impossible, r=lcnr

Leak check in `impossible_predicates` to avoid monomorphizing impossible instances

Fixes #135462

r? lcnr
This commit is contained in:
Matthias Krüger 2025-01-14 19:25:06 +01:00 committed by GitHub
commit 866e61aae0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 91 additions and 3 deletions

View file

@ -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>(

View file

@ -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> = &();
}

View file

@ -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(&())> = &();
}