@@ -30,7 +30,7 @@ use ty::subst::{Subst, Substs};
30
30
use ty:: walk:: TypeWalker ;
31
31
use util:: common:: MemoizationMap ;
32
32
use util:: nodemap:: NodeSet ;
33
- use util:: nodemap:: FxHashMap ;
33
+ use util:: nodemap:: { FxHashMap , FxHashSet } ;
34
34
35
35
use serialize:: { self , Encodable , Encoder } ;
36
36
use std:: borrow:: Cow ;
@@ -1390,6 +1390,22 @@ impl<'tcx> serialize::UseSpecializedEncodable for AdtDef<'tcx> {
1390
1390
1391
1391
impl < ' tcx > serialize:: UseSpecializedDecodable for AdtDef < ' tcx > { }
1392
1392
1393
+ impl < ' a , ' gcx , ' tcx > AdtDefData < ' tcx , ' static > {
1394
+ #[ inline]
1395
+ pub fn is_uninhabited_recurse ( & ' tcx self ,
1396
+ visited : & mut FxHashSet < ( DefId , & ' tcx Substs < ' tcx > ) > ,
1397
+ block : Option < NodeId > ,
1398
+ cx : TyCtxt < ' a , ' gcx , ' tcx > ,
1399
+ substs : & ' tcx Substs < ' tcx > ) -> bool {
1400
+ if !visited. insert ( ( self . did , substs) ) {
1401
+ return false ;
1402
+ } ;
1403
+ self . variants . iter ( ) . all ( |v| {
1404
+ v. is_uninhabited_recurse ( visited, block, cx, substs, self . is_union ( ) )
1405
+ } )
1406
+ }
1407
+ }
1408
+
1393
1409
#[ derive( Copy , Clone , Debug , Eq , PartialEq ) ]
1394
1410
pub enum AdtKind { Struct , Union , Enum }
1395
1411
@@ -1532,11 +1548,6 @@ impl<'a, 'gcx, 'tcx, 'container> AdtDefData<'gcx, 'container> {
1532
1548
self . variants . iter ( ) . flat_map ( VariantDefData :: fields_iter)
1533
1549
}
1534
1550
1535
- #[ inline]
1536
- pub fn is_empty ( & self ) -> bool {
1537
- self . variants . is_empty ( )
1538
- }
1539
-
1540
1551
#[ inline]
1541
1552
pub fn is_univariant ( & self ) -> bool {
1542
1553
self . variants . len ( ) == 1
@@ -1796,6 +1807,22 @@ impl<'tcx, 'container> VariantDefData<'tcx, 'container> {
1796
1807
}
1797
1808
}
1798
1809
1810
+ impl < ' a , ' gcx , ' tcx > VariantDefData < ' tcx , ' static > {
1811
+ #[ inline]
1812
+ pub fn is_uninhabited_recurse ( & ' tcx self ,
1813
+ visited : & mut FxHashSet < ( DefId , & ' tcx Substs < ' tcx > ) > ,
1814
+ block : Option < NodeId > ,
1815
+ cx : TyCtxt < ' a , ' gcx , ' tcx > ,
1816
+ substs : & ' tcx Substs < ' tcx > ,
1817
+ is_union : bool ) -> bool {
1818
+ if is_union {
1819
+ self . fields . iter ( ) . all ( |f| f. is_uninhabited_recurse ( visited, block, cx, substs) )
1820
+ } else {
1821
+ self . fields . iter ( ) . any ( |f| f. is_uninhabited_recurse ( visited, block, cx, substs) )
1822
+ }
1823
+ }
1824
+ }
1825
+
1799
1826
impl < ' a , ' gcx , ' tcx , ' container > FieldDefData < ' tcx , ' container > {
1800
1827
pub fn new ( did : DefId ,
1801
1828
name : Name ,
@@ -1821,6 +1848,18 @@ impl<'a, 'gcx, 'tcx, 'container> FieldDefData<'tcx, 'container> {
1821
1848
}
1822
1849
}
1823
1850
1851
+ impl < ' a , ' gcx , ' tcx > FieldDefData < ' tcx , ' static > {
1852
+ #[ inline]
1853
+ pub fn is_uninhabited_recurse ( & ' tcx self ,
1854
+ visited : & mut FxHashSet < ( DefId , & ' tcx Substs < ' tcx > ) > ,
1855
+ block : Option < NodeId > ,
1856
+ tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
1857
+ substs : & ' tcx Substs < ' tcx > ) -> bool {
1858
+ block. map_or ( true , |b| self . vis . is_accessible_from ( b, & tcx. map ) ) &&
1859
+ self . ty ( tcx, substs) . is_uninhabited_recurse ( visited, block, tcx)
1860
+ }
1861
+ }
1862
+
1824
1863
/// Records the substitutions used to translate the polytype for an
1825
1864
/// item into the monotype of an item reference.
1826
1865
#[ derive( Clone , RustcEncodable , RustcDecodable ) ]
0 commit comments