@@ -62,11 +62,14 @@ mod def_id_forest;
6262// This code should only compile in modules where the uninhabitedness of Foo is
6363// visible.
6464
65+ const ARBITRARY_RECURSION_LIMIT : u32 = 24 ;
66+
6567impl < ' a , ' gcx , ' tcx > AdtDef {
6668 /// Calculate the forest of DefIds from which this adt is visibly uninhabited.
6769 pub fn uninhabited_from (
6870 & self ,
6971 visited : & mut FxHashSet < ( DefId , & ' tcx Substs < ' tcx > ) > ,
72+ recursion_depth : u32 ,
7073 tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
7174 substs : & ' tcx Substs < ' tcx > ) -> DefIdForest
7275 {
@@ -75,7 +78,7 @@ impl<'a, 'gcx, 'tcx> AdtDef {
7578 }
7679
7780 let ret = DefIdForest :: intersection ( tcx, self . variants . iter ( ) . map ( |v| {
78- v. uninhabited_from ( visited, tcx, substs, self . adt_kind ( ) )
81+ v. uninhabited_from ( visited, recursion_depth , tcx, substs, self . adt_kind ( ) )
7982 } ) ) ;
8083 visited. remove ( & ( self . did , substs) ) ;
8184 ret
@@ -87,24 +90,25 @@ impl<'a, 'gcx, 'tcx> VariantDef {
8790 pub fn uninhabited_from (
8891 & self ,
8992 visited : & mut FxHashSet < ( DefId , & ' tcx Substs < ' tcx > ) > ,
93+ recursion_depth : u32 ,
9094 tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
9195 substs : & ' tcx Substs < ' tcx > ,
9296 adt_kind : AdtKind ) -> DefIdForest
9397 {
9498 match adt_kind {
9599 AdtKind :: Union => {
96100 DefIdForest :: intersection ( tcx, self . fields . iter ( ) . map ( |f| {
97- f. uninhabited_from ( visited, tcx, substs, false )
101+ f. uninhabited_from ( visited, recursion_depth , tcx, substs, false )
98102 } ) )
99103 } ,
100104 AdtKind :: Struct => {
101105 DefIdForest :: union ( tcx, self . fields . iter ( ) . map ( |f| {
102- f. uninhabited_from ( visited, tcx, substs, false )
106+ f. uninhabited_from ( visited, recursion_depth , tcx, substs, false )
103107 } ) )
104108 } ,
105109 AdtKind :: Enum => {
106110 DefIdForest :: union ( tcx, self . fields . iter ( ) . map ( |f| {
107- f. uninhabited_from ( visited, tcx, substs, true )
111+ f. uninhabited_from ( visited, recursion_depth , tcx, substs, true )
108112 } ) )
109113 } ,
110114 }
@@ -116,11 +120,14 @@ impl<'a, 'gcx, 'tcx> FieldDef {
116120 pub fn uninhabited_from (
117121 & self ,
118122 visited : & mut FxHashSet < ( DefId , & ' tcx Substs < ' tcx > ) > ,
123+ recursion_depth : u32 ,
119124 tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
120125 substs : & ' tcx Substs < ' tcx > ,
121126 is_enum : bool ) -> DefIdForest
122127 {
123- let mut data_uninhabitedness = move || self . ty ( tcx, substs) . uninhabited_from ( visited, tcx) ;
128+ let mut data_uninhabitedness = move || {
129+ self . ty ( tcx, substs) . uninhabited_from ( visited, recursion_depth, tcx)
130+ } ;
124131 // FIXME(canndrew): Currently enum fields are (incorrectly) stored with
125132 // Visibility::Invisible so we need to override self.vis if we're
126133 // dealing with an enum.
@@ -145,8 +152,14 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
145152 pub fn uninhabited_from (
146153 & self ,
147154 visited : & mut FxHashSet < ( DefId , & ' tcx Substs < ' tcx > ) > ,
155+ mut recursion_depth : u32 ,
148156 tcx : TyCtxt < ' a , ' gcx , ' tcx > ) -> DefIdForest
149157 {
158+ recursion_depth += 1 ;
159+ if recursion_depth >= ARBITRARY_RECURSION_LIMIT {
160+ return DefIdForest :: empty ( ) ;
161+ }
162+
150163 match tcx. lift_to_global ( & self ) {
151164 Some ( global_ty) => {
152165 {
@@ -155,13 +168,13 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
155168 return forest. clone ( ) ;
156169 }
157170 }
158- let forest = global_ty. uninhabited_from_inner ( visited, tcx) ;
171+ let forest = global_ty. uninhabited_from_inner ( visited, recursion_depth , tcx) ;
159172 let mut cache = tcx. inhabitedness_cache . borrow_mut ( ) ;
160173 cache. insert ( global_ty, forest. clone ( ) ) ;
161174 forest
162175 } ,
163176 None => {
164- let forest = self . uninhabited_from_inner ( visited, tcx) ;
177+ let forest = self . uninhabited_from_inner ( visited, recursion_depth , tcx) ;
165178 forest
166179 } ,
167180 }
@@ -170,28 +183,29 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
170183 fn uninhabited_from_inner (
171184 & self ,
172185 visited : & mut FxHashSet < ( DefId , & ' tcx Substs < ' tcx > ) > ,
186+ recursion_depth : u32 ,
173187 tcx : TyCtxt < ' a , ' gcx , ' tcx > ) -> DefIdForest
174188 {
175189 match self . sty {
176190 TyAdt ( def, substs) => {
177- def. uninhabited_from ( visited, tcx, substs)
191+ def. uninhabited_from ( visited, recursion_depth , tcx, substs)
178192 } ,
179193
180194 TyNever => DefIdForest :: full ( tcx) ,
181195 TyTuple ( ref tys, _) => {
182196 DefIdForest :: union ( tcx, tys. iter ( ) . map ( |ty| {
183- ty. uninhabited_from ( visited, tcx)
197+ ty. uninhabited_from ( visited, recursion_depth , tcx)
184198 } ) )
185199 } ,
186200 TyArray ( ty, len) => {
187201 if len == 0 {
188202 DefIdForest :: empty ( )
189203 } else {
190- ty. uninhabited_from ( visited, tcx)
204+ ty. uninhabited_from ( visited, recursion_depth , tcx)
191205 }
192206 }
193207 TyRef ( _, ref tm) => {
194- tm. ty . uninhabited_from ( visited, tcx)
208+ tm. ty . uninhabited_from ( visited, recursion_depth , tcx)
195209 }
196210
197211 _ => DefIdForest :: empty ( ) ,
0 commit comments