summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_middle/src/ty/inhabitedness/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_middle/src/ty/inhabitedness/mod.rs')
-rw-r--r--compiler/rustc_middle/src/ty/inhabitedness/mod.rs116
1 files changed, 62 insertions, 54 deletions
diff --git a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs
index 279a728ea..ace81bc4f 100644
--- a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs
+++ b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs
@@ -5,7 +5,7 @@
//!
//! # Example
//! ```rust
-//! enum Void {}
+//! #![feature(never_type)]
//! mod a {
//! pub mod b {
//! pub struct SecretlyUninhabited {
@@ -15,6 +15,7 @@
//! }
//!
//! mod c {
+//! enum Void {}
//! pub struct AlsoSecretlyUninhabited {
//! _priv: Void,
//! }
@@ -28,14 +29,14 @@
//! }
//! ```
//! In this code, the type `Foo` will only be visibly uninhabited inside the
-//! modules `b`, `c` and `d`. Calling `uninhabited_predicate` on `Foo` will
+//! modules `b`, `c` and `d`. Calling `inhabited_predicate` on `Foo` will
//! return `NotInModule(b) AND NotInModule(c)`.
//!
//! We need this information for pattern-matching on `Foo` or types that contain
//! `Foo`.
//!
//! # Example
-//! ```rust
+//! ```ignore(illustrative)
//! let foo_result: Result<T, Foo> = ... ;
//! let Ok(t) = foo_result;
//! ```
@@ -56,57 +57,6 @@ pub(crate) fn provide(providers: &mut ty::query::Providers) {
ty::query::Providers { inhabited_predicate_adt, inhabited_predicate_type, ..*providers };
}
-impl<'tcx> TyCtxt<'tcx> {
- /// Checks whether a type is visibly uninhabited from a particular module.
- ///
- /// # Example
- /// ```
- /// #![feature(never_type)]
- /// # fn main() {}
- /// enum Void {}
- /// mod a {
- /// pub mod b {
- /// pub struct SecretlyUninhabited {
- /// _priv: !,
- /// }
- /// }
- /// }
- ///
- /// mod c {
- /// use super::Void;
- /// pub struct AlsoSecretlyUninhabited {
- /// _priv: Void,
- /// }
- /// mod d {
- /// }
- /// }
- ///
- /// struct Foo {
- /// x: a::b::SecretlyUninhabited,
- /// y: c::AlsoSecretlyUninhabited,
- /// }
- /// ```
- /// In this code, the type `Foo` will only be visibly uninhabited inside the
- /// modules b, c and d. This effects pattern-matching on `Foo` or types that
- /// contain `Foo`.
- ///
- /// # Example
- /// ```ignore (illustrative)
- /// let foo_result: Result<T, Foo> = ... ;
- /// let Ok(t) = foo_result;
- /// ```
- /// This code should only compile in modules where the uninhabitedness of Foo is
- /// visible.
- pub fn is_ty_uninhabited_from(
- self,
- module: DefId,
- ty: Ty<'tcx>,
- param_env: ty::ParamEnv<'tcx>,
- ) -> bool {
- !ty.inhabited_predicate(self).apply(self, param_env, module)
- }
-}
-
/// Returns an `InhabitedPredicate` that is generic over type parameters and
/// requires calling [`InhabitedPredicate::subst`]
fn inhabited_predicate_adt(tcx: TyCtxt<'_>, def_id: DefId) -> InhabitedPredicate<'_> {
@@ -170,6 +120,64 @@ impl<'tcx> Ty<'tcx> {
_ => InhabitedPredicate::True,
}
}
+
+ /// Checks whether a type is visibly uninhabited from a particular module.
+ ///
+ /// # Example
+ /// ```
+ /// #![feature(never_type)]
+ /// # fn main() {}
+ /// enum Void {}
+ /// mod a {
+ /// pub mod b {
+ /// pub struct SecretlyUninhabited {
+ /// _priv: !,
+ /// }
+ /// }
+ /// }
+ ///
+ /// mod c {
+ /// use super::Void;
+ /// pub struct AlsoSecretlyUninhabited {
+ /// _priv: Void,
+ /// }
+ /// mod d {
+ /// }
+ /// }
+ ///
+ /// struct Foo {
+ /// x: a::b::SecretlyUninhabited,
+ /// y: c::AlsoSecretlyUninhabited,
+ /// }
+ /// ```
+ /// In this code, the type `Foo` will only be visibly uninhabited inside the
+ /// modules b, c and d. This effects pattern-matching on `Foo` or types that
+ /// contain `Foo`.
+ ///
+ /// # Example
+ /// ```ignore (illustrative)
+ /// let foo_result: Result<T, Foo> = ... ;
+ /// let Ok(t) = foo_result;
+ /// ```
+ /// This code should only compile in modules where the uninhabitedness of Foo is
+ /// visible.
+ pub fn is_inhabited_from(
+ self,
+ tcx: TyCtxt<'tcx>,
+ module: DefId,
+ param_env: ty::ParamEnv<'tcx>,
+ ) -> bool {
+ self.inhabited_predicate(tcx).apply(tcx, param_env, module)
+ }
+
+ /// Returns true if the type is uninhabited without regard to visibility
+ pub fn is_privately_uninhabited(
+ self,
+ tcx: TyCtxt<'tcx>,
+ param_env: ty::ParamEnv<'tcx>,
+ ) -> bool {
+ !self.inhabited_predicate(tcx).apply_ignore_module(tcx, param_env)
+ }
}
/// N.B. this query should only be called through `Ty::inhabited_predicate`