Normalize types when applying uninhabited predicate.
This commit is contained in:
parent
e0ba2d038d
commit
6f3f878351
@ -62,7 +62,18 @@ fn apply_inner<E>(
|
|||||||
Some(1..) => Ok(false),
|
Some(1..) => Ok(false),
|
||||||
},
|
},
|
||||||
Self::NotInModule(id) => in_module(id).map(|in_mod| !in_mod),
|
Self::NotInModule(id) => in_module(id).map(|in_mod| !in_mod),
|
||||||
Self::GenericType(_) => Ok(true),
|
// `t` may be a projection, for which `inhabited_predicate` returns a `GenericType`. As
|
||||||
|
// we have a param_env available, we can do better.
|
||||||
|
Self::GenericType(t) => {
|
||||||
|
let normalized_pred = tcx
|
||||||
|
.try_normalize_erasing_regions(param_env, t)
|
||||||
|
.map_or(self, |t| t.inhabited_predicate(tcx));
|
||||||
|
match normalized_pred {
|
||||||
|
// We don't have more information than we started with, so consider inhabited.
|
||||||
|
Self::GenericType(_) => Ok(true),
|
||||||
|
pred => pred.apply_inner(tcx, param_env, in_module),
|
||||||
|
}
|
||||||
|
}
|
||||||
Self::And([a, b]) => try_and(a, b, |x| x.apply_inner(tcx, param_env, in_module)),
|
Self::And([a, b]) => try_and(a, b, |x| x.apply_inner(tcx, param_env, in_module)),
|
||||||
Self::Or([a, b]) => try_or(a, b, |x| x.apply_inner(tcx, param_env, in_module)),
|
Self::Or([a, b]) => try_or(a, b, |x| x.apply_inner(tcx, param_env, in_module)),
|
||||||
}
|
}
|
||||||
|
32
tests/ui/uninhabited/projection.rs
Normal file
32
tests/ui/uninhabited/projection.rs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// check-pass
|
||||||
|
|
||||||
|
#![feature(never_type, exhaustive_patterns)]
|
||||||
|
|
||||||
|
trait Tag {
|
||||||
|
type TagType;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Keep {}
|
||||||
|
enum Erase {}
|
||||||
|
|
||||||
|
impl Tag for Keep {
|
||||||
|
type TagType = ();
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Tag for Erase {
|
||||||
|
type TagType = !;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum TagInt<T: Tag> {
|
||||||
|
Untagged(i32),
|
||||||
|
Tagged(T::TagType, i32)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test(keep: TagInt<Keep>, erase: TagInt<Erase>) {
|
||||||
|
match erase {
|
||||||
|
TagInt::Untagged(_) => (),
|
||||||
|
TagInt::Tagged(_, _) => ()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
Loading…
Reference in New Issue
Block a user