@@ -1190,6 +1190,10 @@ impl Struct {
1190
1190
fn variant_data ( self , db : & dyn HirDatabase ) -> Arc < VariantData > {
1191
1191
db. struct_data ( self . id ) . variant_data . clone ( )
1192
1192
}
1193
+
1194
+ pub fn is_unstable ( self , db : & dyn HirDatabase ) -> bool {
1195
+ db. attrs ( self . id . into ( ) ) . is_unstable ( )
1196
+ }
1193
1197
}
1194
1198
1195
1199
impl HasVisibility for Struct {
@@ -1232,6 +1236,10 @@ impl Union {
1232
1236
fn variant_data ( self , db : & dyn HirDatabase ) -> Arc < VariantData > {
1233
1237
db. union_data ( self . id ) . variant_data . clone ( )
1234
1238
}
1239
+
1240
+ pub fn is_unstable ( self , db : & dyn HirDatabase ) -> bool {
1241
+ db. attrs ( self . id . into ( ) ) . is_unstable ( )
1242
+ }
1235
1243
}
1236
1244
1237
1245
impl HasVisibility for Union {
@@ -1321,6 +1329,10 @@ impl Enum {
1321
1329
pub fn layout ( self , db : & dyn HirDatabase ) -> Result < Layout , LayoutError > {
1322
1330
Adt :: from ( self ) . layout ( db)
1323
1331
}
1332
+
1333
+ pub fn is_unstable ( self , db : & dyn HirDatabase ) -> bool {
1334
+ db. attrs ( self . id . into ( ) ) . is_unstable ( )
1335
+ }
1324
1336
}
1325
1337
1326
1338
impl HasVisibility for Enum {
@@ -1396,6 +1408,10 @@ impl Variant {
1396
1408
_ => parent_layout,
1397
1409
} )
1398
1410
}
1411
+
1412
+ pub fn is_unstable ( self , db : & dyn HirDatabase ) -> bool {
1413
+ db. attrs ( self . id . into ( ) ) . is_unstable ( )
1414
+ }
1399
1415
}
1400
1416
1401
1417
/// Variants inherit visibility from the parent enum.
@@ -3099,7 +3115,7 @@ impl GenericDef {
3099
3115
. collect ( )
3100
3116
}
3101
3117
3102
- pub fn type_params ( self , db : & dyn HirDatabase ) -> Vec < TypeOrConstParam > {
3118
+ pub fn type_or_const_params ( self , db : & dyn HirDatabase ) -> Vec < TypeOrConstParam > {
3103
3119
let generics = db. generic_params ( self . into ( ) ) ;
3104
3120
generics
3105
3121
. type_or_consts
@@ -3109,6 +3125,40 @@ impl GenericDef {
3109
3125
} )
3110
3126
. collect ( )
3111
3127
}
3128
+
3129
+ pub fn type_params ( self , db : & dyn HirDatabase ) -> Vec < TypeParam > {
3130
+ let generics = db. generic_params ( self . into ( ) ) ;
3131
+ generics
3132
+ . type_or_consts
3133
+ . iter ( )
3134
+ . filter_map ( |( local_id, data) | match data {
3135
+ hir_def:: generics:: TypeOrConstParamData :: TypeParamData ( _) => Some ( TypeParam {
3136
+ id : TypeParamId :: from_unchecked ( TypeOrConstParamId {
3137
+ parent : self . into ( ) ,
3138
+ local_id,
3139
+ } ) ,
3140
+ } ) ,
3141
+ hir_def:: generics:: TypeOrConstParamData :: ConstParamData ( _) => None ,
3142
+ } )
3143
+ . collect ( )
3144
+ }
3145
+
3146
+ pub fn const_params ( self , db : & dyn HirDatabase ) -> Vec < ConstParam > {
3147
+ let generics = db. generic_params ( self . into ( ) ) ;
3148
+ generics
3149
+ . type_or_consts
3150
+ . iter ( )
3151
+ . filter_map ( |( local_id, data) | match data {
3152
+ hir_def:: generics:: TypeOrConstParamData :: TypeParamData ( _) => None ,
3153
+ hir_def:: generics:: TypeOrConstParamData :: ConstParamData ( _) => Some ( ConstParam {
3154
+ id : ConstParamId :: from_unchecked ( TypeOrConstParamId {
3155
+ parent : self . into ( ) ,
3156
+ local_id,
3157
+ } ) ,
3158
+ } ) ,
3159
+ } )
3160
+ . collect ( )
3161
+ }
3112
3162
}
3113
3163
3114
3164
/// A single local definition.
@@ -3471,12 +3521,16 @@ impl TypeParam {
3471
3521
let ty = generic_arg_from_param ( db, self . id . into ( ) ) ?;
3472
3522
let resolver = self . id . parent ( ) . resolver ( db. upcast ( ) ) ;
3473
3523
match ty. data ( Interner ) {
3474
- GenericArgData :: Ty ( it) => {
3524
+ GenericArgData :: Ty ( it) if * it . kind ( Interner ) != TyKind :: Error => {
3475
3525
Some ( Type :: new_with_resolver_inner ( db, & resolver, it. clone ( ) ) )
3476
3526
}
3477
3527
_ => None ,
3478
3528
}
3479
3529
}
3530
+
3531
+ pub fn is_unstable ( self , db : & dyn HirDatabase ) -> bool {
3532
+ db. attrs ( GenericParamId :: from ( self . id ) . into ( ) ) . is_unstable ( )
3533
+ }
3480
3534
}
3481
3535
3482
3536
#[ derive( Clone , Copy , Debug , PartialEq , Eq , Hash ) ]
@@ -3960,6 +4014,50 @@ impl Type {
3960
4014
matches ! ( self . ty. kind( Interner ) , TyKind :: Ref ( ..) )
3961
4015
}
3962
4016
4017
+ pub fn contains_reference ( & self , db : & dyn HirDatabase ) -> bool {
4018
+ return go ( db, self . env . krate , & self . ty ) ;
4019
+
4020
+ fn go ( db : & dyn HirDatabase , krate : CrateId , ty : & Ty ) -> bool {
4021
+ match ty. kind ( Interner ) {
4022
+ // Reference itself
4023
+ TyKind :: Ref ( _, _, _) => true ,
4024
+
4025
+ // For non-phantom_data adts we check variants/fields as well as generic parameters
4026
+ TyKind :: Adt ( adt_id, substitution)
4027
+ if !db. struct_datum ( krate, * adt_id) . flags . phantom_data =>
4028
+ {
4029
+ let adt_datum = & db. struct_datum ( krate, * adt_id) ;
4030
+ let adt_datum_bound =
4031
+ adt_datum. binders . clone ( ) . substitute ( Interner , substitution) ;
4032
+ adt_datum_bound
4033
+ . variants
4034
+ . into_iter ( )
4035
+ . flat_map ( |variant| variant. fields . into_iter ( ) )
4036
+ . any ( |ty| go ( db, krate, & ty) )
4037
+ || substitution
4038
+ . iter ( Interner )
4039
+ . filter_map ( |x| x. ty ( Interner ) )
4040
+ . any ( |ty| go ( db, krate, ty) )
4041
+ }
4042
+ // And for `PhantomData<T>`, we check `T`.
4043
+ TyKind :: Adt ( _, substitution)
4044
+ | TyKind :: Tuple ( _, substitution)
4045
+ | TyKind :: OpaqueType ( _, substitution)
4046
+ | TyKind :: AssociatedType ( _, substitution)
4047
+ | TyKind :: FnDef ( _, substitution) => substitution
4048
+ . iter ( Interner )
4049
+ . filter_map ( |x| x. ty ( Interner ) )
4050
+ . any ( |ty| go ( db, krate, ty) ) ,
4051
+
4052
+ // For `[T]` or `*T` we check `T`
4053
+ TyKind :: Array ( ty, _) | TyKind :: Slice ( ty) | TyKind :: Raw ( _, ty) => go ( db, krate, ty) ,
4054
+
4055
+ // Consider everything else as not reference
4056
+ _ => false ,
4057
+ }
4058
+ }
4059
+ }
4060
+
3963
4061
pub fn as_reference ( & self ) -> Option < ( Type , Mutability ) > {
3964
4062
let ( ty, _lt, m) = self . ty . as_reference ( ) ?;
3965
4063
let m = Mutability :: from_mutable ( matches ! ( m, hir_ty:: Mutability :: Mut ) ) ;
0 commit comments