Leak check in impossible_predicates to avoid monomorphizing impossible instances
This commit is contained in:
parent
2ae9916816
commit
377dbc96a6
3 changed files with 91 additions and 3 deletions
|
@ -714,9 +714,18 @@ pub fn impossible_predicates<'tcx>(tcx: TyCtxt<'tcx>, predicates: Vec<ty::Clause
|
||||||
}
|
}
|
||||||
let errors = ocx.select_all_or_error();
|
let errors = ocx.select_all_or_error();
|
||||||
|
|
||||||
let result = !errors.is_empty();
|
if !errors.is_empty() {
|
||||||
debug!("impossible_predicates = {:?}", result);
|
return true;
|
||||||
result
|
}
|
||||||
|
|
||||||
|
// 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>(
|
fn instantiate_and_check_impossible_predicates<'tcx>(
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
//@ build-pass
|
||||||
|
//@ revisions: current next
|
||||||
|
//@ ignore-compare-mode-next-solver (explicit revisions)
|
||||||
|
//@[next] compile-flags: -Znext-solver
|
||||||
|
|
||||||
|
#![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> = &();
|
||||||
|
}
|
|
@ -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(&())> = &();
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue