@@ -1191,6 +1191,10 @@ impl Struct {
1191
1191
fn variant_data ( self , db : & dyn HirDatabase ) -> Arc < VariantData > {
1192
1192
db. struct_data ( self . id ) . variant_data . clone ( )
1193
1193
}
1194
+
1195
+ pub fn is_unstable ( self , db : & dyn HirDatabase ) -> bool {
1196
+ db. attrs ( self . id . into ( ) ) . is_unstable ( )
1197
+ }
1194
1198
}
1195
1199
1196
1200
impl HasVisibility for Struct {
@@ -1233,6 +1237,10 @@ impl Union {
1233
1237
fn variant_data ( self , db : & dyn HirDatabase ) -> Arc < VariantData > {
1234
1238
db. union_data ( self . id ) . variant_data . clone ( )
1235
1239
}
1240
+
1241
+ pub fn is_unstable ( self , db : & dyn HirDatabase ) -> bool {
1242
+ db. attrs ( self . id . into ( ) ) . is_unstable ( )
1243
+ }
1236
1244
}
1237
1245
1238
1246
impl HasVisibility for Union {
@@ -1322,6 +1330,10 @@ impl Enum {
1322
1330
pub fn layout ( self , db : & dyn HirDatabase ) -> Result < Layout , LayoutError > {
1323
1331
Adt :: from ( self ) . layout ( db)
1324
1332
}
1333
+
1334
+ pub fn is_unstable ( self , db : & dyn HirDatabase ) -> bool {
1335
+ db. attrs ( self . id . into ( ) ) . is_unstable ( )
1336
+ }
1325
1337
}
1326
1338
1327
1339
impl HasVisibility for Enum {
@@ -1397,6 +1409,10 @@ impl Variant {
1397
1409
_ => parent_layout,
1398
1410
} )
1399
1411
}
1412
+
1413
+ pub fn is_unstable ( self , db : & dyn HirDatabase ) -> bool {
1414
+ db. variants_attrs ( self . parent . into ( ) ) [ self . id ] . is_unstable ( )
1415
+ }
1400
1416
}
1401
1417
1402
1418
/// Variants inherit visibility from the parent enum.
@@ -3143,7 +3159,7 @@ impl GenericDef {
3143
3159
. collect ( )
3144
3160
}
3145
3161
3146
- pub fn type_params ( self , db : & dyn HirDatabase ) -> Vec < TypeOrConstParam > {
3162
+ pub fn type_or_const_params ( self , db : & dyn HirDatabase ) -> Vec < TypeOrConstParam > {
3147
3163
let generics = db. generic_params ( self . into ( ) ) ;
3148
3164
generics
3149
3165
. type_or_consts
@@ -3153,6 +3169,40 @@ impl GenericDef {
3153
3169
} )
3154
3170
. collect ( )
3155
3171
}
3172
+
3173
+ pub fn type_params ( self , db : & dyn HirDatabase ) -> Vec < TypeParam > {
3174
+ let generics = db. generic_params ( self . into ( ) ) ;
3175
+ generics
3176
+ . type_or_consts
3177
+ . iter ( )
3178
+ . filter_map ( |( local_id, data) | match data {
3179
+ hir_def:: generics:: TypeOrConstParamData :: TypeParamData ( _) => Some ( TypeParam {
3180
+ id : TypeParamId :: from_unchecked ( TypeOrConstParamId {
3181
+ parent : self . into ( ) ,
3182
+ local_id,
3183
+ } ) ,
3184
+ } ) ,
3185
+ hir_def:: generics:: TypeOrConstParamData :: ConstParamData ( _) => None ,
3186
+ } )
3187
+ . collect ( )
3188
+ }
3189
+
3190
+ pub fn const_params ( self , db : & dyn HirDatabase ) -> Vec < ConstParam > {
3191
+ let generics = db. generic_params ( self . into ( ) ) ;
3192
+ generics
3193
+ . type_or_consts
3194
+ . iter ( )
3195
+ . filter_map ( |( local_id, data) | match data {
3196
+ hir_def:: generics:: TypeOrConstParamData :: TypeParamData ( _) => None ,
3197
+ hir_def:: generics:: TypeOrConstParamData :: ConstParamData ( _) => Some ( ConstParam {
3198
+ id : ConstParamId :: from_unchecked ( TypeOrConstParamId {
3199
+ parent : self . into ( ) ,
3200
+ local_id,
3201
+ } ) ,
3202
+ } ) ,
3203
+ } )
3204
+ . collect ( )
3205
+ }
3156
3206
}
3157
3207
3158
3208
/// A single local definition.
@@ -3515,12 +3565,16 @@ impl TypeParam {
3515
3565
let ty = generic_arg_from_param ( db, self . id . into ( ) ) ?;
3516
3566
let resolver = self . id . parent ( ) . resolver ( db. upcast ( ) ) ;
3517
3567
match ty. data ( Interner ) {
3518
- GenericArgData :: Ty ( it) => {
3568
+ GenericArgData :: Ty ( it) if * it . kind ( Interner ) != TyKind :: Error => {
3519
3569
Some ( Type :: new_with_resolver_inner ( db, & resolver, it. clone ( ) ) )
3520
3570
}
3521
3571
_ => None ,
3522
3572
}
3523
3573
}
3574
+
3575
+ pub fn is_unstable ( self , db : & dyn HirDatabase ) -> bool {
3576
+ db. attrs ( GenericParamId :: from ( self . id ) . into ( ) ) . is_unstable ( )
3577
+ }
3524
3578
}
3525
3579
3526
3580
#[ derive( Clone , Copy , Debug , PartialEq , Eq , Hash ) ]
@@ -4004,6 +4058,50 @@ impl Type {
4004
4058
matches ! ( self . ty. kind( Interner ) , TyKind :: Ref ( ..) )
4005
4059
}
4006
4060
4061
+ pub fn contains_reference ( & self , db : & dyn HirDatabase ) -> bool {
4062
+ return go ( db, self . env . krate , & self . ty ) ;
4063
+
4064
+ fn go ( db : & dyn HirDatabase , krate : CrateId , ty : & Ty ) -> bool {
4065
+ match ty. kind ( Interner ) {
4066
+ // Reference itself
4067
+ TyKind :: Ref ( _, _, _) => true ,
4068
+
4069
+ // For non-phantom_data adts we check variants/fields as well as generic parameters
4070
+ TyKind :: Adt ( adt_id, substitution)
4071
+ if !db. struct_datum ( krate, * adt_id) . flags . phantom_data =>
4072
+ {
4073
+ let adt_datum = & db. struct_datum ( krate, * adt_id) ;
4074
+ let adt_datum_bound =
4075
+ adt_datum. binders . clone ( ) . substitute ( Interner , substitution) ;
4076
+ adt_datum_bound
4077
+ . variants
4078
+ . into_iter ( )
4079
+ . flat_map ( |variant| variant. fields . into_iter ( ) )
4080
+ . any ( |ty| go ( db, krate, & ty) )
4081
+ || substitution
4082
+ . iter ( Interner )
4083
+ . filter_map ( |x| x. ty ( Interner ) )
4084
+ . any ( |ty| go ( db, krate, ty) )
4085
+ }
4086
+ // And for `PhantomData<T>`, we check `T`.
4087
+ TyKind :: Adt ( _, substitution)
4088
+ | TyKind :: Tuple ( _, substitution)
4089
+ | TyKind :: OpaqueType ( _, substitution)
4090
+ | TyKind :: AssociatedType ( _, substitution)
4091
+ | TyKind :: FnDef ( _, substitution) => substitution
4092
+ . iter ( Interner )
4093
+ . filter_map ( |x| x. ty ( Interner ) )
4094
+ . any ( |ty| go ( db, krate, ty) ) ,
4095
+
4096
+ // For `[T]` or `*T` we check `T`
4097
+ TyKind :: Array ( ty, _) | TyKind :: Slice ( ty) | TyKind :: Raw ( _, ty) => go ( db, krate, ty) ,
4098
+
4099
+ // Consider everything else as not reference
4100
+ _ => false ,
4101
+ }
4102
+ }
4103
+ }
4104
+
4007
4105
pub fn as_reference ( & self ) -> Option < ( Type , Mutability ) > {
4008
4106
let ( ty, _lt, m) = self . ty . as_reference ( ) ?;
4009
4107
let m = Mutability :: from_mutable ( matches ! ( m, hir_ty:: Mutability :: Mut ) ) ;
0 commit comments