1 pub use self::def_id_forest
::DefIdForest
;
4 use crate::ty
::context
::TyCtxt
;
5 use crate::ty
::TyKind
::*;
6 use crate::ty
::{AdtDef, FieldDef, Ty, TyS, VariantDef}
;
7 use crate::ty
::{AdtKind, Visibility}
;
8 use crate::ty
::{DefId, SubstsRef}
;
9 use rustc_data_structures
::stack
::ensure_sufficient_stack
;
13 // The methods in this module calculate `DefIdForest`s of modules in which a
14 // `AdtDef`/`VariantDef`/`FieldDef` is visibly uninhabited.
21 // pub struct SecretlyUninhabited {
28 // pub struct AlsoSecretlyUninhabited {
36 // x: a::b::SecretlyUninhabited,
37 // y: c::AlsoSecretlyUninhabited,
40 // In this code, the type `Foo` will only be visibly uninhabited inside the
41 // modules `b`, `c` and `d`. Calling `uninhabited_from` on `Foo` or its `AdtDef` will
42 // return the forest of modules {`b`, `c`->`d`} (represented in a `DefIdForest` by the
45 // We need this information for pattern-matching on `Foo` or types that contain
50 // let foo_result: Result<T, Foo> = ... ;
51 // let Ok(t) = foo_result;
53 // This code should only compile in modules where the uninhabitedness of `Foo` is
56 impl<'tcx
> TyCtxt
<'tcx
> {
57 /// Checks whether a type is visibly uninhabited from a particular module.
64 /// pub struct SecretlyUninhabited {
71 /// pub struct AlsoSecretlyUninhabited {
79 /// x: a::b::SecretlyUninhabited,
80 /// y: c::AlsoSecretlyUninhabited,
83 /// In this code, the type `Foo` will only be visibly uninhabited inside the
84 /// modules b, c and d. This effects pattern-matching on `Foo` or types that
89 /// let foo_result: Result<T, Foo> = ... ;
90 /// let Ok(t) = foo_result;
92 /// This code should only compile in modules where the uninhabitedness of Foo is
94 pub fn is_ty_uninhabited_from(
98 param_env
: ty
::ParamEnv
<'tcx
>,
100 // To check whether this type is uninhabited at all (not just from the
101 // given node), you could check whether the forest is empty.
105 ty
.uninhabited_from(self, param_env
).contains(self, module
)
108 pub fn is_ty_uninhabited_from_any_module(
111 param_env
: ty
::ParamEnv
<'tcx
>,
113 !ty
.uninhabited_from(self, param_env
).is_empty()
118 /// Calculates the forest of `DefId`s from which this ADT is visibly uninhabited.
122 substs
: SubstsRef
<'tcx
>,
123 param_env
: ty
::ParamEnv
<'tcx
>,
125 // Non-exhaustive ADTs from other crates are always considered inhabited.
126 if self.is_variant_list_non_exhaustive() && !self.did
.is_local() {
129 DefIdForest
::intersection(
133 .map(|v
| v
.uninhabited_from(tcx
, substs
, self.adt_kind(), param_env
)),
139 impl<'tcx
> VariantDef
{
140 /// Calculates the forest of `DefId`s from which this variant is visibly uninhabited.
141 pub fn uninhabited_from(
144 substs
: SubstsRef
<'tcx
>,
146 param_env
: ty
::ParamEnv
<'tcx
>,
148 let is_enum
= match adt_kind
{
149 // For now, `union`s are never considered uninhabited.
150 // The precise semantics of inhabitedness with respect to unions is currently undecided.
151 AdtKind
::Union
=> return DefIdForest
::empty(),
152 AdtKind
::Enum
=> true,
153 AdtKind
::Struct
=> false,
155 // Non-exhaustive variants from other crates are always considered inhabited.
156 if self.is_field_list_non_exhaustive() && !self.def_id
.is_local() {
161 self.fields
.iter().map(|f
| f
.uninhabited_from(tcx
, substs
, is_enum
, param_env
)),
167 impl<'tcx
> FieldDef
{
168 /// Calculates the forest of `DefId`s from which this field is visibly uninhabited.
172 substs
: SubstsRef
<'tcx
>,
174 param_env
: ty
::ParamEnv
<'tcx
>,
176 let data_uninhabitedness
= move || self.ty(tcx
, substs
).uninhabited_from(tcx
, param_env
);
177 // FIXME(canndrew): Currently enum fields are (incorrectly) stored with
178 // `Visibility::Invisible` so we need to override `self.vis` if we're
179 // dealing with an enum.
181 data_uninhabitedness()
184 Visibility
::Invisible
=> DefIdForest
::empty(),
185 Visibility
::Restricted(from
) => {
186 let forest
= DefIdForest
::from_id(from
);
187 let iter
= Some(forest
).into_iter().chain(Some(data_uninhabitedness()));
188 DefIdForest
::intersection(tcx
, iter
)
190 Visibility
::Public
=> data_uninhabitedness(),
196 impl<'tcx
> TyS
<'tcx
> {
197 /// Calculates the forest of `DefId`s from which this type is visibly uninhabited.
198 fn uninhabited_from(&self, tcx
: TyCtxt
<'tcx
>, param_env
: ty
::ParamEnv
<'tcx
>) -> DefIdForest
{
200 Adt(def
, substs
) => {
201 ensure_sufficient_stack(|| def
.uninhabited_from(tcx
, substs
, param_env
))
204 Never
=> DefIdForest
::full(tcx
),
206 Tuple(ref tys
) => DefIdForest
::union(
208 tys
.iter().map(|ty
| ty
.expect_ty().uninhabited_from(tcx
, param_env
)),
211 Array(ty
, len
) => match len
.try_eval_usize(tcx
, param_env
) {
212 // If the array is definitely non-empty, it's uninhabited if
213 // the type of its elements is uninhabited.
214 Some(n
) if n
!= 0 => ty
.uninhabited_from(tcx
, param_env
),
215 _
=> DefIdForest
::empty(),
218 // References to uninitialised memory is valid for any type, including
219 // uninhabited types, in unsafe code, so we treat all references as
221 // The precise semantics of inhabitedness with respect to references is currently
223 Ref(..) => DefIdForest
::empty(),
225 _
=> DefIdForest
::empty(),