1
1
//! Type inhabitedness logic.
2
- use std:: {
3
- collections:: HashMap ,
4
- ops:: ControlFlow :: { self , Break , Continue } ,
5
- } ;
2
+ use std:: ops:: ControlFlow :: { self , Break , Continue } ;
6
3
7
4
use chalk_ir:: {
8
5
visit:: { TypeSuperVisitable , TypeVisitable , TypeVisitor } ,
@@ -12,7 +9,7 @@ use hir_def::{
12
9
adt:: VariantData , attr:: Attrs , visibility:: Visibility , AdtId , EnumVariantId , HasModule , Lookup ,
13
10
ModuleId , VariantId ,
14
11
} ;
15
- use rustc_hash:: FxHashMap ;
12
+ use rustc_hash:: FxHashSet ;
16
13
17
14
use crate :: {
18
15
consteval:: try_const_usize, db:: HirDatabase , Binders , Interner , Substitution , Ty , TyKind ,
@@ -21,7 +18,7 @@ use crate::{
21
18
/// Checks whether a type is visibly uninhabited from a particular module.
22
19
pub ( crate ) fn is_ty_uninhabited_from ( ty : & Ty , target_mod : ModuleId , db : & dyn HirDatabase ) -> bool {
23
20
let mut uninhabited_from =
24
- UninhabitedFrom { target_mod, db, max_depth : 500 , recursive_ty : HashMap :: default ( ) } ;
21
+ UninhabitedFrom { target_mod, db, max_depth : 500 , recursive_ty : FxHashSet :: default ( ) } ;
25
22
let inhabitedness = ty. visit_with ( & mut uninhabited_from, DebruijnIndex :: INNERMOST ) ;
26
23
inhabitedness == BREAK_VISIBLY_UNINHABITED
27
24
}
@@ -38,7 +35,7 @@ pub(crate) fn is_enum_variant_uninhabited_from(
38
35
let is_local = variant. parent . lookup ( db. upcast ( ) ) . container . krate ( ) == target_mod. krate ( ) ;
39
36
40
37
let mut uninhabited_from =
41
- UninhabitedFrom { target_mod, db, max_depth : 500 , recursive_ty : HashMap :: default ( ) } ;
38
+ UninhabitedFrom { target_mod, db, max_depth : 500 , recursive_ty : FxHashSet :: default ( ) } ;
42
39
let inhabitedness = uninhabited_from. visit_variant (
43
40
variant. into ( ) ,
44
41
& enum_data. variants [ variant. local_id ] . variant_data ,
@@ -51,7 +48,7 @@ pub(crate) fn is_enum_variant_uninhabited_from(
51
48
52
49
struct UninhabitedFrom < ' a > {
53
50
target_mod : ModuleId ,
54
- recursive_ty : FxHashMap < Ty , ( ) > ,
51
+ recursive_ty : FxHashSet < Ty > ,
55
52
// guard for preventing stack overflow in non trivial non terminating types
56
53
max_depth : usize ,
57
54
db : & ' a dyn HirDatabase ,
@@ -74,12 +71,12 @@ impl TypeVisitor<Interner> for UninhabitedFrom<'_> {
74
71
ty : & Ty ,
75
72
outer_binder : DebruijnIndex ,
76
73
) -> ControlFlow < VisiblyUninhabited > {
77
- if self . recursive_ty . contains_key ( ty) || self . max_depth == 0 {
74
+ if self . recursive_ty . contains ( ty) || self . max_depth == 0 {
78
75
// rustc considers recursive types always inhabited. I think it is valid to consider
79
76
// recursive types as always uninhabited, but we should do what rustc is doing.
80
77
return CONTINUE_OPAQUELY_INHABITED ;
81
78
}
82
- self . recursive_ty . insert ( ty. clone ( ) , ( ) ) ;
79
+ self . recursive_ty . insert ( ty. clone ( ) ) ;
83
80
self . max_depth -= 1 ;
84
81
let r = match ty. kind ( Interner ) {
85
82
TyKind :: Adt ( adt, subst) => self . visit_adt ( adt. 0 , subst) ,
0 commit comments