Skip to content

Commit

Permalink
Normalize types when applying uninhabited predicate.
Browse files Browse the repository at this point in the history
  • Loading branch information
cjgillot committed Jun 27, 2023
1 parent e0ba2d0 commit 6f3f878
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,18 @@ impl<'tcx> InhabitedPredicate<'tcx> {
Some(1..) => Ok(false),
},
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::Or([a, b]) => try_or(a, b, |x| x.apply_inner(tcx, param_env, in_module)),
}
Expand Down
32 changes: 32 additions & 0 deletions tests/ui/uninhabited/projection.rs
Original file line number Diff line number Diff line change
@@ -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() {}

0 comments on commit 6f3f878

Please sign in to comment.