@@ -1187,6 +1187,10 @@ impl Struct {
1187
1187
fn variant_data ( self , db : & dyn HirDatabase ) -> Arc < VariantData > {
1188
1188
db. struct_data ( self . id ) . variant_data . clone ( )
1189
1189
}
1190
+
1191
+ pub fn is_unstable ( self , db : & dyn HirDatabase ) -> bool {
1192
+ db. attrs ( self . id . into ( ) ) . is_unstable ( )
1193
+ }
1190
1194
}
1191
1195
1192
1196
impl HasVisibility for Struct {
@@ -1229,6 +1233,10 @@ impl Union {
1229
1233
fn variant_data ( self , db : & dyn HirDatabase ) -> Arc < VariantData > {
1230
1234
db. union_data ( self . id ) . variant_data . clone ( )
1231
1235
}
1236
+
1237
+ pub fn is_unstable ( self , db : & dyn HirDatabase ) -> bool {
1238
+ db. attrs ( self . id . into ( ) ) . is_unstable ( )
1239
+ }
1232
1240
}
1233
1241
1234
1242
impl HasVisibility for Union {
@@ -1318,6 +1326,10 @@ impl Enum {
1318
1326
pub fn layout ( self , db : & dyn HirDatabase ) -> Result < Layout , LayoutError > {
1319
1327
Adt :: from ( self ) . layout ( db)
1320
1328
}
1329
+
1330
+ pub fn is_unstable ( self , db : & dyn HirDatabase ) -> bool {
1331
+ db. attrs ( self . id . into ( ) ) . is_unstable ( )
1332
+ }
1321
1333
}
1322
1334
1323
1335
impl HasVisibility for Enum {
@@ -1393,6 +1405,10 @@ impl Variant {
1393
1405
_ => parent_layout,
1394
1406
} )
1395
1407
}
1408
+
1409
+ pub fn is_unstable ( self , db : & dyn HirDatabase ) -> bool {
1410
+ db. attrs ( self . id . into ( ) ) . is_unstable ( )
1411
+ }
1396
1412
}
1397
1413
1398
1414
/// Variants inherit visibility from the parent enum.
@@ -2912,7 +2928,7 @@ impl GenericDef {
2912
2928
. collect ( )
2913
2929
}
2914
2930
2915
- pub fn type_params ( self , db : & dyn HirDatabase ) -> Vec < TypeOrConstParam > {
2931
+ pub fn type_or_const_params ( self , db : & dyn HirDatabase ) -> Vec < TypeOrConstParam > {
2916
2932
let generics = db. generic_params ( self . into ( ) ) ;
2917
2933
generics
2918
2934
. type_or_consts
@@ -2922,6 +2938,40 @@ impl GenericDef {
2922
2938
} )
2923
2939
. collect ( )
2924
2940
}
2941
+
2942
+ pub fn type_params ( self , db : & dyn HirDatabase ) -> Vec < TypeParam > {
2943
+ let generics = db. generic_params ( self . into ( ) ) ;
2944
+ generics
2945
+ . type_or_consts
2946
+ . iter ( )
2947
+ . filter_map ( |( local_id, data) | match data {
2948
+ hir_def:: generics:: TypeOrConstParamData :: TypeParamData ( _) => Some ( TypeParam {
2949
+ id : TypeParamId :: from_unchecked ( TypeOrConstParamId {
2950
+ parent : self . into ( ) ,
2951
+ local_id,
2952
+ } ) ,
2953
+ } ) ,
2954
+ hir_def:: generics:: TypeOrConstParamData :: ConstParamData ( _) => None ,
2955
+ } )
2956
+ . collect ( )
2957
+ }
2958
+
2959
+ pub fn const_params ( self , db : & dyn HirDatabase ) -> Vec < ConstParam > {
2960
+ let generics = db. generic_params ( self . into ( ) ) ;
2961
+ generics
2962
+ . type_or_consts
2963
+ . iter ( )
2964
+ . filter_map ( |( local_id, data) | match data {
2965
+ hir_def:: generics:: TypeOrConstParamData :: TypeParamData ( _) => None ,
2966
+ hir_def:: generics:: TypeOrConstParamData :: ConstParamData ( _) => Some ( ConstParam {
2967
+ id : ConstParamId :: from_unchecked ( TypeOrConstParamId {
2968
+ parent : self . into ( ) ,
2969
+ local_id,
2970
+ } ) ,
2971
+ } ) ,
2972
+ } )
2973
+ . collect ( )
2974
+ }
2925
2975
}
2926
2976
2927
2977
/// A single local definition.
@@ -3284,12 +3334,16 @@ impl TypeParam {
3284
3334
let ty = generic_arg_from_param ( db, self . id . into ( ) ) ?;
3285
3335
let resolver = self . id . parent ( ) . resolver ( db. upcast ( ) ) ;
3286
3336
match ty. data ( Interner ) {
3287
- GenericArgData :: Ty ( it) => {
3337
+ GenericArgData :: Ty ( it) if * it . kind ( Interner ) != TyKind :: Error => {
3288
3338
Some ( Type :: new_with_resolver_inner ( db, & resolver, it. clone ( ) ) )
3289
3339
}
3290
3340
_ => None ,
3291
3341
}
3292
3342
}
3343
+
3344
+ pub fn is_unstable ( self , db : & dyn HirDatabase ) -> bool {
3345
+ db. attrs ( GenericParamId :: from ( self . id ) . into ( ) ) . is_unstable ( )
3346
+ }
3293
3347
}
3294
3348
3295
3349
#[ derive( Clone , Copy , Debug , PartialEq , Eq , Hash ) ]
@@ -3773,6 +3827,50 @@ impl Type {
3773
3827
matches ! ( self . ty. kind( Interner ) , TyKind :: Ref ( ..) )
3774
3828
}
3775
3829
3830
+ pub fn contains_reference ( & self , db : & dyn HirDatabase ) -> bool {
3831
+ return go ( db, self . env . krate , & self . ty ) ;
3832
+
3833
+ fn go ( db : & dyn HirDatabase , krate : CrateId , ty : & Ty ) -> bool {
3834
+ match ty. kind ( Interner ) {
3835
+ // Reference itself
3836
+ TyKind :: Ref ( _, _, _) => true ,
3837
+
3838
+ // For non-phantom_data adts we check variants/fields as well as generic parameters
3839
+ TyKind :: Adt ( adt_id, substitution)
3840
+ if !db. struct_datum ( krate, * adt_id) . flags . phantom_data =>
3841
+ {
3842
+ let adt_datum = & db. struct_datum ( krate, * adt_id) ;
3843
+ let adt_datum_bound =
3844
+ adt_datum. binders . clone ( ) . substitute ( Interner , substitution) ;
3845
+ adt_datum_bound
3846
+ . variants
3847
+ . into_iter ( )
3848
+ . flat_map ( |variant| variant. fields . into_iter ( ) )
3849
+ . any ( |ty| go ( db, krate, & ty) )
3850
+ || substitution
3851
+ . iter ( Interner )
3852
+ . filter_map ( |x| x. ty ( Interner ) )
3853
+ . any ( |ty| go ( db, krate, ty) )
3854
+ }
3855
+ // And for `PhantomData<T>`, we check `T`.
3856
+ TyKind :: Adt ( _, substitution)
3857
+ | TyKind :: Tuple ( _, substitution)
3858
+ | TyKind :: OpaqueType ( _, substitution)
3859
+ | TyKind :: AssociatedType ( _, substitution)
3860
+ | TyKind :: FnDef ( _, substitution) => substitution
3861
+ . iter ( Interner )
3862
+ . filter_map ( |x| x. ty ( Interner ) )
3863
+ . any ( |ty| go ( db, krate, ty) ) ,
3864
+
3865
+ // For `[T]` or `*T` we check `T`
3866
+ TyKind :: Array ( ty, _) | TyKind :: Slice ( ty) | TyKind :: Raw ( _, ty) => go ( db, krate, ty) ,
3867
+
3868
+ // Consider everything else as not reference
3869
+ _ => false ,
3870
+ }
3871
+ }
3872
+ }
3873
+
3776
3874
pub fn as_reference ( & self ) -> Option < ( Type , Mutability ) > {
3777
3875
let ( ty, _lt, m) = self . ty . as_reference ( ) ?;
3778
3876
let m = Mutability :: from_mutable ( matches ! ( m, hir_ty:: Mutability :: Mut ) ) ;
0 commit comments