Skip to content

Commit d756f61

Browse files
committed
Make is_uninhabited respect privacy
1 parent a6cc398 commit d756f61

File tree

3 files changed

+21
-14
lines changed

3 files changed

+21
-14
lines changed

src/librustc/ty/mod.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -1394,13 +1394,16 @@ impl<'a, 'gcx, 'tcx> AdtDefData<'tcx, 'static> {
13941394
#[inline]
13951395
pub fn is_uninhabited_recurse(&'tcx self,
13961396
visited: &mut HashMap<(DefId, &'tcx Substs<'tcx>), ()>,
1397+
block: Option<NodeId>,
13971398
cx: TyCtxt<'a, 'gcx, 'tcx>,
13981399
substs: &'tcx Substs<'tcx>) -> bool {
13991400
match visited.entry((self.did, substs)) {
14001401
hash_map::Entry::Occupied(_) => return false,
14011402
hash_map::Entry::Vacant(ve) => ve.insert(()),
14021403
};
1403-
self.variants.iter().all(|v| v.is_uninhabited_recurse(visited, cx, substs, self.is_union()))
1404+
self.variants.iter().all(|v| {
1405+
v.is_uninhabited_recurse(visited, block, cx, substs, self.is_union())
1406+
})
14041407
}
14051408
}
14061409

@@ -1809,13 +1812,14 @@ impl<'a, 'gcx, 'tcx> VariantDefData<'tcx, 'static> {
18091812
#[inline]
18101813
pub fn is_uninhabited_recurse(&'tcx self,
18111814
visited: &mut HashMap<(DefId, &'tcx Substs<'tcx>), ()>,
1815+
block: Option<NodeId>,
18121816
cx: TyCtxt<'a, 'gcx, 'tcx>,
18131817
substs: &'tcx Substs<'tcx>,
18141818
is_union: bool) -> bool {
18151819
if is_union {
1816-
self.fields.iter().all(|f| f.is_uninhabited_recurse(visited, cx, substs))
1820+
self.fields.iter().all(|f| f.is_uninhabited_recurse(visited, block, cx, substs))
18171821
} else {
1818-
self.fields.iter().any(|f| f.is_uninhabited_recurse(visited, cx, substs))
1822+
self.fields.iter().any(|f| f.is_uninhabited_recurse(visited, block, cx, substs))
18191823
}
18201824
}
18211825
}
@@ -1849,9 +1853,11 @@ impl<'a, 'gcx, 'tcx> FieldDefData<'tcx, 'static> {
18491853
#[inline]
18501854
pub fn is_uninhabited_recurse(&'tcx self,
18511855
visited: &mut HashMap<(DefId, &'tcx Substs<'tcx>), ()>,
1856+
block: Option<NodeId>,
18521857
tcx: TyCtxt<'a, 'gcx, 'tcx>,
18531858
substs: &'tcx Substs<'tcx>) -> bool {
1854-
self.ty(tcx, substs).is_uninhabited_recurse(visited, tcx)
1859+
block.map_or(true, |b| self.vis.is_accessible_from(b, &tcx.map)) &&
1860+
self.ty(tcx, substs).is_uninhabited_recurse(visited, block, tcx)
18551861
}
18561862
}
18571863

src/librustc/ty/sty.rs

+10-9
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use std::fmt;
2323
use std::ops;
2424
use std::collections::HashMap;
2525
use syntax::abi;
26-
use syntax::ast::{self, Name};
26+
use syntax::ast::{self, Name, NodeId};
2727
use syntax::symbol::{keywords, InternedString};
2828

2929
use serialize;
@@ -930,25 +930,26 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
930930
}
931931
}
932932

933-
pub fn is_uninhabited(&self, cx: TyCtxt<'a, 'gcx, 'tcx>) -> bool {
933+
/// Checks whether a type is uninhabited.
934+
/// If `block` is `Some(id)` it also checks that the uninhabited-ness is visible from `id`.
935+
pub fn is_uninhabited(&self, block: Option<NodeId>, cx: TyCtxt<'a, 'gcx, 'tcx>) -> bool {
934936
let mut visited = HashMap::new();
935-
self.is_uninhabited_recurse(&mut visited, cx)
937+
self.is_uninhabited_recurse(&mut visited, block, cx)
936938
}
937939

938940
pub fn is_uninhabited_recurse(&self,
939941
visited: &mut HashMap<(DefId, &'tcx Substs<'tcx>), ()>,
942+
block: Option<NodeId>,
940943
cx: TyCtxt<'a, 'gcx, 'tcx>) -> bool {
941-
// FIXME(#24885): be smarter here, the AdtDefData::is_empty method could easily be made
942-
// more complete.
943944
match self.sty {
944945
TyAdt(def, substs) => {
945-
def.is_uninhabited_recurse(visited, cx, substs)
946+
def.is_uninhabited_recurse(visited, block, cx, substs)
946947
},
947948

948949
TyNever => true,
949-
TyTuple(ref tys) => tys.iter().any(|ty| ty.is_uninhabited_recurse(visited, cx)),
950-
TyArray(ty, len) => len > 0 && ty.is_uninhabited_recurse(visited, cx),
951-
TyRef(_, ref tm) => tm.ty.is_uninhabited_recurse(visited, cx),
950+
TyTuple(ref tys) => tys.iter().any(|ty| ty.is_uninhabited_recurse(visited, block, cx)),
951+
TyArray(ty, len) => len > 0 && ty.is_uninhabited_recurse(visited, block, cx),
952+
TyRef(_, ref tm) => tm.ty.is_uninhabited_recurse(visited, block, cx),
952953

953954
_ => false,
954955
}

src/librustc_const_eval/check_match.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> {
204204
// Check for empty enum, because is_useful only works on inhabited types.
205205
let pat_ty = self.tcx.tables().node_id_to_type(scrut.id);
206206
if inlined_arms.is_empty() {
207-
if !pat_ty.is_uninhabited(self.tcx) {
207+
if !pat_ty.is_uninhabited(Some(scrut.id), self.tcx) {
208208
// We know the type is inhabited, so this must be wrong
209209
let mut err = create_e0004(self.tcx.sess, span,
210210
format!("non-exhaustive patterns: type {} \

0 commit comments

Comments
 (0)