mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
Auto merge of #103454 - camsteffen:remove-conservatively-uninhabited, r=oli-obk
Factor out `conservative_is_privately_uninhabited` After #102660 there is no more need for `conservative_is_privately_uninhabited`. r? `@oli-obk`
This commit is contained in:
commit
736c675d2a
@ -1564,10 +1564,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
if !self
|
if !sig.output().is_privately_uninhabited(self.tcx(), self.param_env) {
|
||||||
.tcx()
|
|
||||||
.conservative_is_privately_uninhabited(self.param_env.and(sig.output()))
|
|
||||||
{
|
|
||||||
span_mirbug!(self, term, "call to converging function {:?} w/o dest", sig);
|
span_mirbug!(self, term, "call to converging function {:?} w/o dest", sig);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -217,7 +217,7 @@ impl<'a, 'tcx> DropRangeVisitor<'a, 'tcx> {
|
|||||||
let ty = self.tcx.erase_regions(ty);
|
let ty = self.tcx.erase_regions(ty);
|
||||||
let m = self.tcx.parent_module(expr.hir_id).to_def_id();
|
let m = self.tcx.parent_module(expr.hir_id).to_def_id();
|
||||||
let param_env = self.tcx.param_env(m.expect_local());
|
let param_env = self.tcx.param_env(m.expect_local());
|
||||||
if self.tcx.is_ty_uninhabited_from(m, ty, param_env) {
|
if !ty.is_inhabited_from(self.tcx, m, param_env) {
|
||||||
// This function will not return. We model this fact as an infinite loop.
|
// This function will not return. We model this fact as an infinite loop.
|
||||||
self.drop_ranges.add_control_edge(self.expr_index + 1, self.expr_index + 1);
|
self.drop_ranges.add_control_edge(self.expr_index + 1, self.expr_index + 1);
|
||||||
}
|
}
|
||||||
|
@ -542,10 +542,10 @@ fn check_must_not_suspend_ty<'tcx>(
|
|||||||
data: SuspendCheckData<'_, 'tcx>,
|
data: SuspendCheckData<'_, 'tcx>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
if ty.is_unit()
|
if ty.is_unit()
|
||||||
// FIXME: should this check `is_ty_uninhabited_from`. This query is not available in this stage
|
// FIXME: should this check `Ty::is_inhabited_from`. This query is not available in this stage
|
||||||
// of typeck (before ReVar and RePlaceholder are removed), but may remove noise, like in
|
// of typeck (before ReVar and RePlaceholder are removed), but may remove noise, like in
|
||||||
// `must_use`
|
// `must_use`
|
||||||
// || fcx.tcx.is_ty_uninhabited_from(fcx.tcx.parent_module(hir_id).to_def_id(), ty, fcx.param_env)
|
// || !ty.is_inhabited_from(fcx.tcx, fcx.tcx.parent_module(hir_id).to_def_id(), fcx.param_env)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -201,9 +201,9 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
|
|||||||
plural_len: usize,
|
plural_len: usize,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
if ty.is_unit()
|
if ty.is_unit()
|
||||||
|| cx.tcx.is_ty_uninhabited_from(
|
|| !ty.is_inhabited_from(
|
||||||
|
cx.tcx,
|
||||||
cx.tcx.parent_module(expr.hir_id).to_def_id(),
|
cx.tcx.parent_module(expr.hir_id).to_def_id(),
|
||||||
ty,
|
|
||||||
cx.param_env,
|
cx.param_env,
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
@ -2078,17 +2078,6 @@ rustc_queries! {
|
|||||||
desc { "normalizing opaque types in `{:?}`", key }
|
desc { "normalizing opaque types in `{:?}`", key }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks whether a type is definitely uninhabited. This is
|
|
||||||
/// conservative: for some types that are uninhabited we return `false`,
|
|
||||||
/// but we only return `true` for types that are definitely uninhabited.
|
|
||||||
/// `ty.conservative_is_privately_uninhabited` implies that any value of type `ty`
|
|
||||||
/// will be `Abi::Uninhabited`. (Note that uninhabited types may have nonzero
|
|
||||||
/// size, to account for partial initialisation. See #49298 for details.)
|
|
||||||
query conservative_is_privately_uninhabited(key: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
|
|
||||||
desc { "conservatively checking if `{}` is privately uninhabited", key.value }
|
|
||||||
remap_env_constness
|
|
||||||
}
|
|
||||||
|
|
||||||
query limits(key: ()) -> Limits {
|
query limits(key: ()) -> Limits {
|
||||||
desc { "looking up limits" }
|
desc { "looking up limits" }
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,13 @@ impl<'tcx> InhabitedPredicate<'tcx> {
|
|||||||
self.apply_inner(tcx, param_env, &|_| Err(())).ok()
|
self.apply_inner(tcx, param_env, &|_| Err(())).ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Same as `apply`, but `NotInModule(_)` predicates yield `false`. That is,
|
||||||
|
/// privately uninhabited types are considered always uninhabited.
|
||||||
|
pub fn apply_ignore_module(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> bool {
|
||||||
|
let Ok(result) = self.apply_inner::<!>(tcx, param_env, &|_| Ok(true));
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
fn apply_inner<E>(
|
fn apply_inner<E>(
|
||||||
self,
|
self,
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
//! }
|
//! }
|
||||||
//! ```
|
//! ```
|
||||||
//! In this code, the type `Foo` will only be visibly uninhabited inside the
|
//! 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)`.
|
//! return `NotInModule(b) AND NotInModule(c)`.
|
||||||
//!
|
//!
|
||||||
//! We need this information for pattern-matching on `Foo` or types that contain
|
//! We need this information for pattern-matching on `Foo` or types that contain
|
||||||
@ -57,57 +57,6 @@ pub(crate) fn provide(providers: &mut ty::query::Providers) {
|
|||||||
ty::query::Providers { inhabited_predicate_adt, inhabited_predicate_type, ..*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
|
/// Returns an `InhabitedPredicate` that is generic over type parameters and
|
||||||
/// requires calling [`InhabitedPredicate::subst`]
|
/// requires calling [`InhabitedPredicate::subst`]
|
||||||
fn inhabited_predicate_adt(tcx: TyCtxt<'_>, def_id: DefId) -> InhabitedPredicate<'_> {
|
fn inhabited_predicate_adt(tcx: TyCtxt<'_>, def_id: DefId) -> InhabitedPredicate<'_> {
|
||||||
@ -171,6 +120,64 @@ impl<'tcx> Ty<'tcx> {
|
|||||||
_ => InhabitedPredicate::True,
|
_ => 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`
|
/// N.B. this query should only be called through `Ty::inhabited_predicate`
|
||||||
|
@ -271,15 +271,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||||||
// MIR checks and ultimately whether code is accepted or not. We can only
|
// MIR checks and ultimately whether code is accepted or not. We can only
|
||||||
// omit the return edge if a return type is visibly uninhabited to a module
|
// omit the return edge if a return type is visibly uninhabited to a module
|
||||||
// that makes the call.
|
// that makes the call.
|
||||||
target: if this.tcx.is_ty_uninhabited_from(
|
target: expr
|
||||||
this.parent_module,
|
.ty
|
||||||
expr.ty,
|
.is_inhabited_from(this.tcx, this.parent_module, this.param_env)
|
||||||
this.param_env,
|
.then_some(success),
|
||||||
) {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(success)
|
|
||||||
},
|
|
||||||
from_hir_call,
|
from_hir_call,
|
||||||
fn_span,
|
fn_span,
|
||||||
},
|
},
|
||||||
|
@ -264,10 +264,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||||||
let irrefutable = adt_def.variants().iter_enumerated().all(|(i, v)| {
|
let irrefutable = adt_def.variants().iter_enumerated().all(|(i, v)| {
|
||||||
i == variant_index || {
|
i == variant_index || {
|
||||||
self.tcx.features().exhaustive_patterns
|
self.tcx.features().exhaustive_patterns
|
||||||
&& v.inhabited_predicate(self.tcx, adt_def)
|
&& !v
|
||||||
|
.inhabited_predicate(self.tcx, adt_def)
|
||||||
.subst(self.tcx, substs)
|
.subst(self.tcx, substs)
|
||||||
.apply_any_module(self.tcx, self.param_env)
|
.apply_ignore_module(self.tcx, self.param_env)
|
||||||
!= Some(true)
|
|
||||||
}
|
}
|
||||||
}) && (adt_def.did().is_local()
|
}) && (adt_def.did().is_local()
|
||||||
|| !adt_def.is_variant_list_non_exhaustive());
|
|| !adt_def.is_variant_list_non_exhaustive());
|
||||||
|
@ -818,7 +818,7 @@ fn non_exhaustive_match<'p, 'tcx>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let ty::Ref(_, sub_ty, _) = scrut_ty.kind() {
|
if let ty::Ref(_, sub_ty, _) = scrut_ty.kind() {
|
||||||
if cx.tcx.is_ty_uninhabited_from(cx.module, *sub_ty, cx.param_env) {
|
if !sub_ty.is_inhabited_from(cx.tcx, cx.module, cx.param_env) {
|
||||||
err.note("references are always considered inhabited");
|
err.note("references are always considered inhabited");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -324,7 +324,7 @@ pub(crate) struct MatchCheckCtxt<'p, 'tcx> {
|
|||||||
impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> {
|
impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> {
|
||||||
pub(super) fn is_uninhabited(&self, ty: Ty<'tcx>) -> bool {
|
pub(super) fn is_uninhabited(&self, ty: Ty<'tcx>) -> bool {
|
||||||
if self.tcx.features().exhaustive_patterns {
|
if self.tcx.features().exhaustive_patterns {
|
||||||
self.tcx.is_ty_uninhabited_from(self.module, ty, self.param_env)
|
!ty.is_inhabited_from(self.tcx, self.module, self.param_env)
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
@ -1015,7 +1015,7 @@ fn insert_panic_block<'tcx>(
|
|||||||
|
|
||||||
fn can_return<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool {
|
fn can_return<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool {
|
||||||
// Returning from a function with an uninhabited return type is undefined behavior.
|
// Returning from a function with an uninhabited return type is undefined behavior.
|
||||||
if tcx.conservative_is_privately_uninhabited(param_env.and(body.return_ty())) {
|
if body.return_ty().is_privately_uninhabited(tcx, param_env) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1284,7 +1284,9 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
|||||||
fn check_is_ty_uninhabited(&mut self, expr: &Expr<'_>, succ: LiveNode) -> LiveNode {
|
fn check_is_ty_uninhabited(&mut self, expr: &Expr<'_>, succ: LiveNode) -> LiveNode {
|
||||||
let ty = self.typeck_results.expr_ty(expr);
|
let ty = self.typeck_results.expr_ty(expr);
|
||||||
let m = self.ir.tcx.parent_module(expr.hir_id).to_def_id();
|
let m = self.ir.tcx.parent_module(expr.hir_id).to_def_id();
|
||||||
if self.ir.tcx.is_ty_uninhabited_from(m, ty, self.param_env) {
|
if ty.is_inhabited_from(self.ir.tcx, m, self.param_env) {
|
||||||
|
return succ;
|
||||||
|
}
|
||||||
match self.ir.lnks[succ] {
|
match self.ir.lnks[succ] {
|
||||||
LiveNodeKind::ExprNode(succ_span, succ_id) => {
|
LiveNodeKind::ExprNode(succ_span, succ_id) => {
|
||||||
self.warn_about_unreachable(expr.span, ty, succ_span, succ_id, "expression");
|
self.warn_about_unreachable(expr.span, ty, succ_span, succ_id, "expression");
|
||||||
@ -1295,9 +1297,6 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
|||||||
_ => {}
|
_ => {}
|
||||||
};
|
};
|
||||||
self.exit_ln
|
self.exit_ln
|
||||||
} else {
|
|
||||||
succ
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn warn_about_unreachable(
|
fn warn_about_unreachable(
|
||||||
|
@ -442,8 +442,7 @@ fn layout_of_uncached<'tcx>(
|
|||||||
let element = cx.layout_of(element)?;
|
let element = cx.layout_of(element)?;
|
||||||
let size = element.size.checked_mul(count, dl).ok_or(LayoutError::SizeOverflow(ty))?;
|
let size = element.size.checked_mul(count, dl).ok_or(LayoutError::SizeOverflow(ty))?;
|
||||||
|
|
||||||
let abi = if count != 0 && tcx.conservative_is_privately_uninhabited(param_env.and(ty))
|
let abi = if count != 0 && ty.is_privately_uninhabited(tcx, param_env) {
|
||||||
{
|
|
||||||
Abi::Uninhabited
|
Abi::Uninhabited
|
||||||
} else {
|
} else {
|
||||||
Abi::Aggregate { sized: true }
|
Abi::Aggregate { sized: true }
|
||||||
|
@ -12,7 +12,7 @@ pub(super) fn sanity_check_layout<'tcx>(
|
|||||||
layout: &TyAndLayout<'tcx>,
|
layout: &TyAndLayout<'tcx>,
|
||||||
) {
|
) {
|
||||||
// Type-level uninhabitedness should always imply ABI uninhabitedness.
|
// Type-level uninhabitedness should always imply ABI uninhabitedness.
|
||||||
if cx.tcx.conservative_is_privately_uninhabited(cx.param_env.and(layout.ty)) {
|
if layout.ty.is_privately_uninhabited(cx.tcx, cx.param_env) {
|
||||||
assert!(layout.abi.is_uninhabited());
|
assert!(layout.abi.is_uninhabited());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -416,62 +416,6 @@ fn asyncness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::IsAsync {
|
|||||||
node.fn_sig().map_or(hir::IsAsync::NotAsync, |sig| sig.header.asyncness)
|
node.fn_sig().map_or(hir::IsAsync::NotAsync, |sig| sig.header.asyncness)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Don't call this directly: use ``tcx.conservative_is_privately_uninhabited`` instead.
|
|
||||||
pub fn conservative_is_privately_uninhabited_raw<'tcx>(
|
|
||||||
tcx: TyCtxt<'tcx>,
|
|
||||||
param_env_and: ty::ParamEnvAnd<'tcx, Ty<'tcx>>,
|
|
||||||
) -> bool {
|
|
||||||
let (param_env, ty) = param_env_and.into_parts();
|
|
||||||
match ty.kind() {
|
|
||||||
ty::Never => {
|
|
||||||
debug!("ty::Never =>");
|
|
||||||
true
|
|
||||||
}
|
|
||||||
ty::Adt(def, _) if def.is_union() => {
|
|
||||||
debug!("ty::Adt(def, _) if def.is_union() =>");
|
|
||||||
// For now, `union`s are never considered uninhabited.
|
|
||||||
false
|
|
||||||
}
|
|
||||||
ty::Adt(def, substs) => {
|
|
||||||
debug!("ty::Adt(def, _) if def.is_not_union() =>");
|
|
||||||
// Any ADT is uninhabited if either:
|
|
||||||
// (a) It has no variants (i.e. an empty `enum`);
|
|
||||||
// (b) Each of its variants (a single one in the case of a `struct`) has at least
|
|
||||||
// one uninhabited field.
|
|
||||||
def.variants().iter().all(|var| {
|
|
||||||
var.fields.iter().any(|field| {
|
|
||||||
let ty = tcx.bound_type_of(field.did).subst(tcx, substs);
|
|
||||||
tcx.conservative_is_privately_uninhabited(param_env.and(ty))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
ty::Tuple(fields) => {
|
|
||||||
debug!("ty::Tuple(..) =>");
|
|
||||||
fields.iter().any(|ty| tcx.conservative_is_privately_uninhabited(param_env.and(ty)))
|
|
||||||
}
|
|
||||||
ty::Array(ty, len) => {
|
|
||||||
debug!("ty::Array(ty, len) =>");
|
|
||||||
match len.try_eval_usize(tcx, param_env) {
|
|
||||||
Some(0) | None => false,
|
|
||||||
// If the array is definitely non-empty, it's uninhabited if
|
|
||||||
// the type of its elements is uninhabited.
|
|
||||||
Some(1..) => tcx.conservative_is_privately_uninhabited(param_env.and(*ty)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ty::Ref(..) => {
|
|
||||||
debug!("ty::Ref(..) =>");
|
|
||||||
// References to uninitialised memory is valid for any type, including
|
|
||||||
// uninhabited types, in unsafe code, so we treat all references as
|
|
||||||
// inhabited.
|
|
||||||
false
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
debug!("_ =>");
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn provide(providers: &mut ty::query::Providers) {
|
pub fn provide(providers: &mut ty::query::Providers) {
|
||||||
*providers = ty::query::Providers {
|
*providers = ty::query::Providers {
|
||||||
asyncness,
|
asyncness,
|
||||||
@ -481,7 +425,6 @@ pub fn provide(providers: &mut ty::query::Providers) {
|
|||||||
instance_def_size_estimate,
|
instance_def_size_estimate,
|
||||||
issue33140_self_ty,
|
issue33140_self_ty,
|
||||||
impl_defaultness,
|
impl_defaultness,
|
||||||
conservative_is_privately_uninhabited: conservative_is_privately_uninhabited_raw,
|
|
||||||
..*providers
|
..*providers
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#![feature(generic_const_exprs)]
|
#![feature(generic_const_exprs)]
|
||||||
#![allow(incomplete_features)]
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
// This tests that the `conservative_is_privately_uninhabited` fn doesn't cause
|
// This tests that the inhabited check doesn't cause
|
||||||
// ICEs by trying to evaluate `T::ASSOC` with an incorrect `ParamEnv`.
|
// ICEs by trying to evaluate `T::ASSOC` with an incorrect `ParamEnv`.
|
||||||
|
|
||||||
trait Foo {
|
trait Foo {
|
@ -2,7 +2,7 @@
|
|||||||
#![feature(generic_const_exprs)]
|
#![feature(generic_const_exprs)]
|
||||||
#![allow(incomplete_features)]
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
// This tests that the `conservative_is_privately_uninhabited` fn doesn't cause
|
// This tests that the inhabited check doesn't cause
|
||||||
// ICEs by trying to evaluate `T::ASSOC` with an incorrect `ParamEnv`.
|
// ICEs by trying to evaluate `T::ASSOC` with an incorrect `ParamEnv`.
|
||||||
|
|
||||||
trait Foo {
|
trait Foo {
|
@ -2,7 +2,7 @@
|
|||||||
// aux-build:empty.rs
|
// aux-build:empty.rs
|
||||||
//
|
//
|
||||||
// This tests plays with matching and uninhabited types. This also serves as a test for the
|
// This tests plays with matching and uninhabited types. This also serves as a test for the
|
||||||
// `tcx.is_ty_uninhabited_from()` function.
|
// `Ty::is_inhabited_from` function.
|
||||||
#![feature(never_type)]
|
#![feature(never_type)]
|
||||||
#![feature(never_type_fallback)]
|
#![feature(never_type_fallback)]
|
||||||
#![feature(exhaustive_patterns)]
|
#![feature(exhaustive_patterns)]
|
||||||
|
Loading…
Reference in New Issue
Block a user