Skip to content

Commit d10e4e6

Browse files
committed
parametrisetheenvironment
1 parent d1206f9 commit d10e4e6

File tree

6 files changed

+81
-16
lines changed

6 files changed

+81
-16
lines changed

compiler/rustc_middle/src/ty/layout.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ fn layout_raw<'tcx>(
231231
let layout = cx.layout_raw_uncached(ty);
232232
// Type-level uninhabitedness should always imply ABI uninhabitedness.
233233
if let Ok(layout) = layout {
234-
if ty.conservative_is_privately_uninhabited(tcx) {
234+
if ty.conservative_is_privately_uninhabited(tcx, param_env) {
235235
assert!(layout.abi.is_uninhabited());
236236
}
237237
}
@@ -583,7 +583,8 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
583583
let size =
584584
element.size.checked_mul(count, dl).ok_or(LayoutError::SizeOverflow(ty))?;
585585

586-
let abi = if count != 0 && ty.conservative_is_privately_uninhabited(tcx) {
586+
let abi = if count != 0 && ty.conservative_is_privately_uninhabited(tcx, param_env)
587+
{
587588
Abi::Uninhabited
588589
} else {
589590
Abi::Aggregate { sized: true }

compiler/rustc_middle/src/ty/sty.rs

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1691,44 +1691,61 @@ impl<'tcx> TyS<'tcx> {
16911691
/// `ty.conservative_is_privately_uninhabited` implies that any value of type `ty`
16921692
/// will be `Abi::Uninhabited`. (Note that uninhabited types may have nonzero
16931693
/// size, to account for partial initialisation. See #49298 for details.)
1694-
pub fn conservative_is_privately_uninhabited(&self, tcx: TyCtxt<'tcx>) -> bool {
1695-
// FIXME(varkor): we can make this less conversative by substituting concrete
1696-
// type arguments.
1694+
#[instrument(level = "debug", skip(tcx))]
1695+
pub fn conservative_is_privately_uninhabited(
1696+
&self,
1697+
tcx: TyCtxt<'tcx>,
1698+
param_env: ty::ParamEnv<'tcx>,
1699+
) -> bool {
16971700
match self.kind() {
1698-
ty::Never => true,
1701+
ty::Never => {
1702+
debug!("ty::Never =>");
1703+
true
1704+
}
16991705
ty::Adt(def, _) if def.is_union() => {
1706+
debug!("ty::Adt(def, _) if def.is_union() =>");
17001707
// For now, `union`s are never considered uninhabited.
17011708
false
17021709
}
1703-
ty::Adt(def, _) => {
1710+
ty::Adt(def, substs) => {
1711+
debug!("ty::Adt(def, _) if def.is_not_union() =>");
17041712
// Any ADT is uninhabited if either:
17051713
// (a) It has no variants (i.e. an empty `enum`);
17061714
// (b) Each of its variants (a single one in the case of a `struct`) has at least
17071715
// one uninhabited field.
17081716
def.variants.iter().all(|var| {
17091717
var.fields.iter().any(|field| {
1710-
tcx.type_of(field.did).conservative_is_privately_uninhabited(tcx)
1718+
tcx.type_of(field.did)
1719+
.subst(tcx, substs)
1720+
.conservative_is_privately_uninhabited(tcx, param_env)
17111721
})
17121722
})
17131723
}
17141724
ty::Tuple(..) => {
1715-
self.tuple_fields().any(|ty| ty.conservative_is_privately_uninhabited(tcx))
1725+
debug!("ty::Tuple(..) =>");
1726+
self.tuple_fields()
1727+
.any(|ty| ty.conservative_is_privately_uninhabited(tcx, param_env))
17161728
}
17171729
ty::Array(ty, len) => {
1718-
match len.try_eval_usize(tcx, ParamEnv::empty()) {
1730+
debug!("ty::Array(ty, len) =>");
1731+
match len.try_eval_usize(tcx, param_env) {
17191732
Some(0) | None => false,
17201733
// If the array is definitely non-empty, it's uninhabited if
17211734
// the type of its elements is uninhabited.
1722-
Some(1..) => ty.conservative_is_privately_uninhabited(tcx),
1735+
Some(1..) => ty.conservative_is_privately_uninhabited(tcx, param_env),
17231736
}
17241737
}
17251738
ty::Ref(..) => {
1739+
debug!("ty::Ref(..) =>");
17261740
// References to uninitialised memory is valid for any type, including
17271741
// uninhabited types, in unsafe code, so we treat all references as
17281742
// inhabited.
17291743
false
17301744
}
1731-
_ => false,
1745+
_ => {
1746+
debug!("_ =>");
1747+
false
1748+
}
17321749
}
17331750
}
17341751

compiler/rustc_mir/src/borrow_check/type_check/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1730,7 +1730,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
17301730
}
17311731
}
17321732
None => {
1733-
if !sig.output().conservative_is_privately_uninhabited(self.tcx()) {
1733+
if !sig.output().conservative_is_privately_uninhabited(self.tcx(), self.param_env) {
17341734
span_mirbug!(self, term, "call to converging function {:?} w/o dest", sig);
17351735
}
17361736
}

compiler/rustc_mir/src/transform/generator.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,9 +1007,9 @@ fn insert_panic_block<'tcx>(
10071007
assert_block
10081008
}
10091009

1010-
fn can_return<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) -> bool {
1010+
fn can_return<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool {
10111011
// Returning from a function with an uninhabited return type is undefined behavior.
1012-
if body.return_ty().conservative_is_privately_uninhabited(tcx) {
1012+
if body.return_ty().conservative_is_privately_uninhabited(tcx, param_env) {
10131013
return false;
10141014
}
10151015

@@ -1320,7 +1320,7 @@ impl<'tcx> MirPass<'tcx> for StateTransform {
13201320
// `storage_liveness` tells us which locals have live storage at suspension points
13211321
let (remap, layout, storage_liveness) = compute_layout(liveness_info, body);
13221322

1323-
let can_return = can_return(tcx, body);
1323+
let can_return = can_return(tcx, body, tcx.param_env(body.source.def_id()));
13241324

13251325
// Run the transformation which converts Places from Local to generator struct
13261326
// accesses for locals in `remap`.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// run-pass
2+
#![feature(const_generics, const_evaluatable_checked)]
3+
#![allow(incomplete_features)]
4+
5+
// This tests that the `conservative_is_privately_uninhabited` fn doesn't cause
6+
// ices by trying to evaluate `T::ASSOC` with an incorrect `ParamEnv`
7+
8+
trait Foo {
9+
const ASSOC: usize = 1;
10+
}
11+
12+
struct Iced<T: Foo>(T, [(); T::ASSOC])
13+
where
14+
[(); T::ASSOC]: ;
15+
16+
impl Foo for u32 {}
17+
18+
fn foo<T: Foo>()
19+
where
20+
[(); T::ASSOC]: ,
21+
{
22+
let _iced: Iced<T> = return;
23+
}
24+
25+
fn main() {
26+
foo::<u32>();
27+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// run-pass
2+
#![feature(const_generics, const_evaluatable_checked)]
3+
#![allow(incomplete_features)]
4+
5+
// This tests that the `conservative_is_privately_uninhabited` fn doesn't cause
6+
// ices by trying to evaluate `T::ASSOC` with an incorrect `ParamEnv`
7+
8+
trait Foo {
9+
const ASSOC: usize = 1;
10+
}
11+
12+
struct Iced<T: Foo>(T, [(); T::ASSOC])
13+
where
14+
[(); T::ASSOC]: ;
15+
16+
impl Foo for u32 {}
17+
18+
fn main() {
19+
let _iced: Iced<u32> = return;
20+
}

0 commit comments

Comments
 (0)