diff options
Diffstat (limited to 'compiler/rustc_middle/src/ty/inhabitedness/mod.rs')
-rw-r--r-- | compiler/rustc_middle/src/ty/inhabitedness/mod.rs | 116 |
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` |