@@ -1170,6 +1170,10 @@ impl Struct {
1170
1170
fn variant_data ( self , db : & dyn HirDatabase ) -> Arc < VariantData > {
1171
1171
db. struct_data ( self . id ) . variant_data . clone ( )
1172
1172
}
1173
+
1174
+ pub fn is_unstable ( self , db : & dyn HirDatabase ) -> bool {
1175
+ db. attrs ( self . id . into ( ) ) . is_unstable ( )
1176
+ }
1173
1177
}
1174
1178
1175
1179
impl HasVisibility for Struct {
@@ -1212,6 +1216,10 @@ impl Union {
1212
1216
fn variant_data ( self , db : & dyn HirDatabase ) -> Arc < VariantData > {
1213
1217
db. union_data ( self . id ) . variant_data . clone ( )
1214
1218
}
1219
+
1220
+ pub fn is_unstable ( self , db : & dyn HirDatabase ) -> bool {
1221
+ db. attrs ( self . id . into ( ) ) . is_unstable ( )
1222
+ }
1215
1223
}
1216
1224
1217
1225
impl HasVisibility for Union {
@@ -1301,6 +1309,10 @@ impl Enum {
1301
1309
pub fn layout ( self , db : & dyn HirDatabase ) -> Result < Layout , LayoutError > {
1302
1310
Adt :: from ( self ) . layout ( db)
1303
1311
}
1312
+
1313
+ pub fn is_unstable ( self , db : & dyn HirDatabase ) -> bool {
1314
+ db. attrs ( self . id . into ( ) ) . is_unstable ( )
1315
+ }
1304
1316
}
1305
1317
1306
1318
impl HasVisibility for Enum {
@@ -1373,6 +1385,10 @@ impl Variant {
1373
1385
_ => parent_layout,
1374
1386
} )
1375
1387
}
1388
+
1389
+ pub fn is_unstable ( self , db : & dyn HirDatabase ) -> bool {
1390
+ db. variants_attrs ( self . parent . into ( ) ) [ self . id ] . is_unstable ( )
1391
+ }
1376
1392
}
1377
1393
1378
1394
/// Variants inherit visibility from the parent enum.
@@ -3081,7 +3097,7 @@ impl GenericDef {
3081
3097
. collect ( )
3082
3098
}
3083
3099
3084
- pub fn type_params ( self , db : & dyn HirDatabase ) -> Vec < TypeOrConstParam > {
3100
+ pub fn type_or_const_params ( self , db : & dyn HirDatabase ) -> Vec < TypeOrConstParam > {
3085
3101
let generics = db. generic_params ( self . into ( ) ) ;
3086
3102
generics
3087
3103
. type_or_consts
@@ -3091,6 +3107,40 @@ impl GenericDef {
3091
3107
} )
3092
3108
. collect ( )
3093
3109
}
3110
+
3111
+ pub fn type_params ( self , db : & dyn HirDatabase ) -> Vec < TypeParam > {
3112
+ let generics = db. generic_params ( self . into ( ) ) ;
3113
+ generics
3114
+ . type_or_consts
3115
+ . iter ( )
3116
+ . filter_map ( |( local_id, data) | match data {
3117
+ hir_def:: generics:: TypeOrConstParamData :: TypeParamData ( _) => Some ( TypeParam {
3118
+ id : TypeParamId :: from_unchecked ( TypeOrConstParamId {
3119
+ parent : self . into ( ) ,
3120
+ local_id,
3121
+ } ) ,
3122
+ } ) ,
3123
+ hir_def:: generics:: TypeOrConstParamData :: ConstParamData ( _) => None ,
3124
+ } )
3125
+ . collect ( )
3126
+ }
3127
+
3128
+ pub fn const_params ( self , db : & dyn HirDatabase ) -> Vec < ConstParam > {
3129
+ let generics = db. generic_params ( self . into ( ) ) ;
3130
+ generics
3131
+ . type_or_consts
3132
+ . iter ( )
3133
+ . filter_map ( |( local_id, data) | match data {
3134
+ hir_def:: generics:: TypeOrConstParamData :: TypeParamData ( _) => None ,
3135
+ hir_def:: generics:: TypeOrConstParamData :: ConstParamData ( _) => Some ( ConstParam {
3136
+ id : ConstParamId :: from_unchecked ( TypeOrConstParamId {
3137
+ parent : self . into ( ) ,
3138
+ local_id,
3139
+ } ) ,
3140
+ } ) ,
3141
+ } )
3142
+ . collect ( )
3143
+ }
3094
3144
}
3095
3145
3096
3146
/// A single local definition.
@@ -3452,12 +3502,16 @@ impl TypeParam {
3452
3502
let ty = generic_arg_from_param ( db, self . id . into ( ) ) ?;
3453
3503
let resolver = self . id . parent ( ) . resolver ( db. upcast ( ) ) ;
3454
3504
match ty. data ( Interner ) {
3455
- GenericArgData :: Ty ( it) => {
3505
+ GenericArgData :: Ty ( it) if * it . kind ( Interner ) != TyKind :: Error => {
3456
3506
Some ( Type :: new_with_resolver_inner ( db, & resolver, it. clone ( ) ) )
3457
3507
}
3458
3508
_ => None ,
3459
3509
}
3460
3510
}
3511
+
3512
+ pub fn is_unstable ( self , db : & dyn HirDatabase ) -> bool {
3513
+ db. attrs ( GenericParamId :: from ( self . id ) . into ( ) ) . is_unstable ( )
3514
+ }
3461
3515
}
3462
3516
3463
3517
#[ derive( Clone , Copy , Debug , PartialEq , Eq , Hash ) ]
@@ -3940,6 +3994,50 @@ impl Type {
3940
3994
matches ! ( self . ty. kind( Interner ) , TyKind :: Ref ( ..) )
3941
3995
}
3942
3996
3997
+ pub fn contains_reference ( & self , db : & dyn HirDatabase ) -> bool {
3998
+ return go ( db, self . env . krate , & self . ty ) ;
3999
+
4000
+ fn go ( db : & dyn HirDatabase , krate : CrateId , ty : & Ty ) -> bool {
4001
+ match ty. kind ( Interner ) {
4002
+ // Reference itself
4003
+ TyKind :: Ref ( _, _, _) => true ,
4004
+
4005
+ // For non-phantom_data adts we check variants/fields as well as generic parameters
4006
+ TyKind :: Adt ( adt_id, substitution)
4007
+ if !db. struct_datum ( krate, * adt_id) . flags . phantom_data =>
4008
+ {
4009
+ let adt_datum = & db. struct_datum ( krate, * adt_id) ;
4010
+ let adt_datum_bound =
4011
+ adt_datum. binders . clone ( ) . substitute ( Interner , substitution) ;
4012
+ adt_datum_bound
4013
+ . variants
4014
+ . into_iter ( )
4015
+ . flat_map ( |variant| variant. fields . into_iter ( ) )
4016
+ . any ( |ty| go ( db, krate, & ty) )
4017
+ || substitution
4018
+ . iter ( Interner )
4019
+ . filter_map ( |x| x. ty ( Interner ) )
4020
+ . any ( |ty| go ( db, krate, ty) )
4021
+ }
4022
+ // And for `PhantomData<T>`, we check `T`.
4023
+ TyKind :: Adt ( _, substitution)
4024
+ | TyKind :: Tuple ( _, substitution)
4025
+ | TyKind :: OpaqueType ( _, substitution)
4026
+ | TyKind :: AssociatedType ( _, substitution)
4027
+ | TyKind :: FnDef ( _, substitution) => substitution
4028
+ . iter ( Interner )
4029
+ . filter_map ( |x| x. ty ( Interner ) )
4030
+ . any ( |ty| go ( db, krate, ty) ) ,
4031
+
4032
+ // For `[T]` or `*T` we check `T`
4033
+ TyKind :: Array ( ty, _) | TyKind :: Slice ( ty) | TyKind :: Raw ( _, ty) => go ( db, krate, ty) ,
4034
+
4035
+ // Consider everything else as not reference
4036
+ _ => false ,
4037
+ }
4038
+ }
4039
+ }
4040
+
3943
4041
pub fn as_reference ( & self ) -> Option < ( Type , Mutability ) > {
3944
4042
let ( ty, _lt, m) = self . ty . as_reference ( ) ?;
3945
4043
let m = Mutability :: from_mutable ( matches ! ( m, hir_ty:: Mutability :: Mut ) ) ;
0 commit comments