Skip to content

Commit 34cbe72

Browse files
committed
Change to Ty::is_inhabited_from
1 parent a6d96f9 commit 34cbe72

File tree

9 files changed

+73
-81
lines changed

9 files changed

+73
-81
lines changed

compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ impl<'a, 'tcx> DropRangeVisitor<'a, 'tcx> {
217217
let ty = self.tcx.erase_regions(ty);
218218
let m = self.tcx.parent_module(expr.hir_id).to_def_id();
219219
let param_env = self.tcx.param_env(m.expect_local());
220-
if self.tcx.is_ty_uninhabited_from(m, ty, param_env) {
220+
if !ty.is_inhabited_from(self.tcx, m, param_env) {
221221
// This function will not return. We model this fact as an infinite loop.
222222
self.drop_ranges.add_control_edge(self.expr_index + 1, self.expr_index + 1);
223223
}

compiler/rustc_hir_typeck/src/generator_interior/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -542,10 +542,10 @@ fn check_must_not_suspend_ty<'tcx>(
542542
data: SuspendCheckData<'_, 'tcx>,
543543
) -> bool {
544544
if ty.is_unit()
545-
// FIXME: should this check `is_ty_uninhabited_from`. This query is not available in this stage
545+
// FIXME: should this check `Ty::is_inhabited_from`. This query is not available in this stage
546546
// of typeck (before ReVar and RePlaceholder are removed), but may remove noise, like in
547547
// `must_use`
548-
// || fcx.tcx.is_ty_uninhabited_from(fcx.tcx.parent_module(hir_id).to_def_id(), ty, fcx.param_env)
548+
// || !ty.is_inhabited_from(fcx.tcx, fcx.tcx.parent_module(hir_id).to_def_id(), fcx.param_env)
549549
{
550550
return false;
551551
}

compiler/rustc_lint/src/unused.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -201,9 +201,9 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
201201
plural_len: usize,
202202
) -> bool {
203203
if ty.is_unit()
204-
|| cx.tcx.is_ty_uninhabited_from(
204+
|| !ty.is_inhabited_from(
205+
cx.tcx,
205206
cx.tcx.parent_module(expr.hir_id).to_def_id(),
206-
ty,
207207
cx.param_env,
208208
)
209209
{

compiler/rustc_middle/src/ty/inhabitedness/mod.rs

+49-51
Original file line numberDiff line numberDiff line change
@@ -57,57 +57,6 @@ pub(crate) fn provide(providers: &mut ty::query::Providers) {
5757
ty::query::Providers { inhabited_predicate_adt, inhabited_predicate_type, ..*providers };
5858
}
5959

60-
impl<'tcx> TyCtxt<'tcx> {
61-
/// Checks whether a type is visibly uninhabited from a particular module.
62-
///
63-
/// # Example
64-
/// ```
65-
/// #![feature(never_type)]
66-
/// # fn main() {}
67-
/// enum Void {}
68-
/// mod a {
69-
/// pub mod b {
70-
/// pub struct SecretlyUninhabited {
71-
/// _priv: !,
72-
/// }
73-
/// }
74-
/// }
75-
///
76-
/// mod c {
77-
/// use super::Void;
78-
/// pub struct AlsoSecretlyUninhabited {
79-
/// _priv: Void,
80-
/// }
81-
/// mod d {
82-
/// }
83-
/// }
84-
///
85-
/// struct Foo {
86-
/// x: a::b::SecretlyUninhabited,
87-
/// y: c::AlsoSecretlyUninhabited,
88-
/// }
89-
/// ```
90-
/// In this code, the type `Foo` will only be visibly uninhabited inside the
91-
/// modules b, c and d. This effects pattern-matching on `Foo` or types that
92-
/// contain `Foo`.
93-
///
94-
/// # Example
95-
/// ```ignore (illustrative)
96-
/// let foo_result: Result<T, Foo> = ... ;
97-
/// let Ok(t) = foo_result;
98-
/// ```
99-
/// This code should only compile in modules where the uninhabitedness of Foo is
100-
/// visible.
101-
pub fn is_ty_uninhabited_from(
102-
self,
103-
module: DefId,
104-
ty: Ty<'tcx>,
105-
param_env: ty::ParamEnv<'tcx>,
106-
) -> bool {
107-
!ty.inhabited_predicate(self).apply(self, param_env, module)
108-
}
109-
}
110-
11160
/// Returns an `InhabitedPredicate` that is generic over type parameters and
11261
/// requires calling [`InhabitedPredicate::subst`]
11362
fn inhabited_predicate_adt(tcx: TyCtxt<'_>, def_id: DefId) -> InhabitedPredicate<'_> {
@@ -171,6 +120,55 @@ impl<'tcx> Ty<'tcx> {
171120
_ => InhabitedPredicate::True,
172121
}
173122
}
123+
124+
/// Checks whether a type is visibly uninhabited from a particular module.
125+
///
126+
/// # Example
127+
/// ```
128+
/// #![feature(never_type)]
129+
/// # fn main() {}
130+
/// enum Void {}
131+
/// mod a {
132+
/// pub mod b {
133+
/// pub struct SecretlyUninhabited {
134+
/// _priv: !,
135+
/// }
136+
/// }
137+
/// }
138+
///
139+
/// mod c {
140+
/// use super::Void;
141+
/// pub struct AlsoSecretlyUninhabited {
142+
/// _priv: Void,
143+
/// }
144+
/// mod d {
145+
/// }
146+
/// }
147+
///
148+
/// struct Foo {
149+
/// x: a::b::SecretlyUninhabited,
150+
/// y: c::AlsoSecretlyUninhabited,
151+
/// }
152+
/// ```
153+
/// In this code, the type `Foo` will only be visibly uninhabited inside the
154+
/// modules b, c and d. This effects pattern-matching on `Foo` or types that
155+
/// contain `Foo`.
156+
///
157+
/// # Example
158+
/// ```ignore (illustrative)
159+
/// let foo_result: Result<T, Foo> = ... ;
160+
/// let Ok(t) = foo_result;
161+
/// ```
162+
/// This code should only compile in modules where the uninhabitedness of Foo is
163+
/// visible.
164+
pub fn is_inhabited_from(
165+
self,
166+
tcx: TyCtxt<'tcx>,
167+
module: DefId,
168+
param_env: ty::ParamEnv<'tcx>,
169+
) -> bool {
170+
self.inhabited_predicate(tcx).apply(tcx, param_env, module)
171+
}
174172
}
175173

176174
/// N.B. this query should only be called through `Ty::inhabited_predicate`

compiler/rustc_mir_build/src/build/expr/into.rs

+4-9
Original file line numberDiff line numberDiff line change
@@ -271,15 +271,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
271271
// MIR checks and ultimately whether code is accepted or not. We can only
272272
// omit the return edge if a return type is visibly uninhabited to a module
273273
// that makes the call.
274-
target: if this.tcx.is_ty_uninhabited_from(
275-
this.parent_module,
276-
expr.ty,
277-
this.param_env,
278-
) {
279-
None
280-
} else {
281-
Some(success)
282-
},
274+
target: expr
275+
.ty
276+
.is_inhabited_from(this.tcx, this.parent_module, this.param_env)
277+
.then_some(success),
283278
from_hir_call,
284279
fn_span,
285280
},

compiler/rustc_mir_build/src/thir/pattern/check_match.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -818,7 +818,7 @@ fn non_exhaustive_match<'p, 'tcx>(
818818
}
819819
}
820820
if let ty::Ref(_, sub_ty, _) = scrut_ty.kind() {
821-
if cx.tcx.is_ty_uninhabited_from(cx.module, *sub_ty, cx.param_env) {
821+
if !sub_ty.is_inhabited_from(cx.tcx, cx.module, cx.param_env) {
822822
err.note("references are always considered inhabited");
823823
}
824824
}

compiler/rustc_mir_build/src/thir/pattern/usefulness.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ pub(crate) struct MatchCheckCtxt<'p, 'tcx> {
324324
impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> {
325325
pub(super) fn is_uninhabited(&self, ty: Ty<'tcx>) -> bool {
326326
if self.tcx.features().exhaustive_patterns {
327-
self.tcx.is_ty_uninhabited_from(self.module, ty, self.param_env)
327+
!ty.is_inhabited_from(self.tcx, self.module, self.param_env)
328328
} else {
329329
false
330330
}

compiler/rustc_passes/src/liveness.rs

+12-13
Original file line numberDiff line numberDiff line change
@@ -1284,20 +1284,19 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
12841284
fn check_is_ty_uninhabited(&mut self, expr: &Expr<'_>, succ: LiveNode) -> LiveNode {
12851285
let ty = self.typeck_results.expr_ty(expr);
12861286
let m = self.ir.tcx.parent_module(expr.hir_id).to_def_id();
1287-
if self.ir.tcx.is_ty_uninhabited_from(m, ty, self.param_env) {
1288-
match self.ir.lnks[succ] {
1289-
LiveNodeKind::ExprNode(succ_span, succ_id) => {
1290-
self.warn_about_unreachable(expr.span, ty, succ_span, succ_id, "expression");
1291-
}
1292-
LiveNodeKind::VarDefNode(succ_span, succ_id) => {
1293-
self.warn_about_unreachable(expr.span, ty, succ_span, succ_id, "definition");
1294-
}
1295-
_ => {}
1296-
};
1297-
self.exit_ln
1298-
} else {
1299-
succ
1287+
if ty.is_inhabited_from(self.ir.tcx, m, self.param_env) {
1288+
return succ;
13001289
}
1290+
match self.ir.lnks[succ] {
1291+
LiveNodeKind::ExprNode(succ_span, succ_id) => {
1292+
self.warn_about_unreachable(expr.span, ty, succ_span, succ_id, "expression");
1293+
}
1294+
LiveNodeKind::VarDefNode(succ_span, succ_id) => {
1295+
self.warn_about_unreachable(expr.span, ty, succ_span, succ_id, "definition");
1296+
}
1297+
_ => {}
1298+
};
1299+
self.exit_ln
13011300
}
13021301

13031302
fn warn_about_unreachable(

src/test/ui/pattern/usefulness/uninhabited.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// aux-build:empty.rs
33
//
44
// This tests plays with matching and uninhabited types. This also serves as a test for the
5-
// `tcx.is_ty_uninhabited_from()` function.
5+
// `Ty::is_inhabited_from` function.
66
#![feature(never_type)]
77
#![feature(never_type_fallback)]
88
#![feature(exhaustive_patterns)]

0 commit comments

Comments
 (0)