diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2023-06-27 22:10:16 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-06-27 22:10:16 +0200 |
| commit | 4b1d0682a6ff9ced8a5a224c96dadd4ac5a500e0 (patch) | |
| tree | 38e8e2a8dee9843f7a7894c752712d13ae5c3add | |
| parent | d505582ce2ec8f015180175acf41391d17324af8 (diff) | |
| parent | 6f3f8783517f939c1646eecc705872b7f18fe353 (diff) | |
| download | rust-4b1d0682a6ff9ced8a5a224c96dadd4ac5a500e0.tar.gz rust-4b1d0682a6ff9ced8a5a224c96dadd4ac5a500e0.zip | |
Rollup merge of #113103 - cjgillot:normalize-inhabited, r=compiler-errors
Normalize types when applying uninhabited predicate. Fixes https://github.com/rust-lang/rust/issues/112997
| -rw-r--r-- | compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs | 13 | ||||
| -rw-r--r-- | tests/ui/uninhabited/projection.rs | 32 |
2 files changed, 44 insertions, 1 deletions
diff --git a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs index d48672b2baa..018fa227154 100644 --- a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs +++ b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs @@ -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)), } diff --git a/tests/ui/uninhabited/projection.rs b/tests/ui/uninhabited/projection.rs new file mode 100644 index 00000000000..be0d3ff7da7 --- /dev/null +++ b/tests/ui/uninhabited/projection.rs @@ -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() {} |
