@@ -1186,6 +1186,10 @@ impl Struct {
1186
1186
fn variant_data ( self , db : & dyn HirDatabase ) -> Arc < VariantData > {
1187
1187
db. struct_data ( self . id ) . variant_data . clone ( )
1188
1188
}
1189
+
1190
+ pub fn is_unstable ( self , db : & dyn HirDatabase ) -> bool {
1191
+ db. attrs ( self . id . into ( ) ) . is_unstable ( )
1192
+ }
1189
1193
}
1190
1194
1191
1195
impl HasVisibility for Struct {
@@ -1228,6 +1232,10 @@ impl Union {
1228
1232
fn variant_data ( self , db : & dyn HirDatabase ) -> Arc < VariantData > {
1229
1233
db. union_data ( self . id ) . variant_data . clone ( )
1230
1234
}
1235
+
1236
+ pub fn is_unstable ( self , db : & dyn HirDatabase ) -> bool {
1237
+ db. attrs ( self . id . into ( ) ) . is_unstable ( )
1238
+ }
1231
1239
}
1232
1240
1233
1241
impl HasVisibility for Union {
@@ -1317,6 +1325,10 @@ impl Enum {
1317
1325
pub fn layout ( self , db : & dyn HirDatabase ) -> Result < Layout , LayoutError > {
1318
1326
Adt :: from ( self ) . layout ( db)
1319
1327
}
1328
+
1329
+ pub fn is_unstable ( self , db : & dyn HirDatabase ) -> bool {
1330
+ db. attrs ( self . id . into ( ) ) . is_unstable ( )
1331
+ }
1320
1332
}
1321
1333
1322
1334
impl HasVisibility for Enum {
@@ -1392,6 +1404,10 @@ impl Variant {
1392
1404
_ => parent_layout,
1393
1405
} )
1394
1406
}
1407
+
1408
+ pub fn is_unstable ( self , db : & dyn HirDatabase ) -> bool {
1409
+ db. attrs ( self . id . into ( ) ) . is_unstable ( )
1410
+ }
1395
1411
}
1396
1412
1397
1413
/// Variants inherit visibility from the parent enum.
@@ -2900,7 +2916,7 @@ impl GenericDef {
2900
2916
. collect ( )
2901
2917
}
2902
2918
2903
- pub fn type_params ( self , db : & dyn HirDatabase ) -> Vec < TypeOrConstParam > {
2919
+ pub fn type_or_const_params ( self , db : & dyn HirDatabase ) -> Vec < TypeOrConstParam > {
2904
2920
let generics = db. generic_params ( self . into ( ) ) ;
2905
2921
generics
2906
2922
. type_or_consts
@@ -2910,6 +2926,40 @@ impl GenericDef {
2910
2926
} )
2911
2927
. collect ( )
2912
2928
}
2929
+
2930
+ pub fn type_params ( self , db : & dyn HirDatabase ) -> Vec < TypeParam > {
2931
+ let generics = db. generic_params ( self . into ( ) ) ;
2932
+ generics
2933
+ . type_or_consts
2934
+ . iter ( )
2935
+ . filter_map ( |( local_id, data) | match data {
2936
+ hir_def:: generics:: TypeOrConstParamData :: TypeParamData ( _) => Some ( TypeParam {
2937
+ id : TypeParamId :: from_unchecked ( TypeOrConstParamId {
2938
+ parent : self . into ( ) ,
2939
+ local_id,
2940
+ } ) ,
2941
+ } ) ,
2942
+ hir_def:: generics:: TypeOrConstParamData :: ConstParamData ( _) => None ,
2943
+ } )
2944
+ . collect ( )
2945
+ }
2946
+
2947
+ pub fn const_params ( self , db : & dyn HirDatabase ) -> Vec < ConstParam > {
2948
+ let generics = db. generic_params ( self . into ( ) ) ;
2949
+ generics
2950
+ . type_or_consts
2951
+ . iter ( )
2952
+ . filter_map ( |( local_id, data) | match data {
2953
+ hir_def:: generics:: TypeOrConstParamData :: TypeParamData ( _) => None ,
2954
+ hir_def:: generics:: TypeOrConstParamData :: ConstParamData ( _) => Some ( ConstParam {
2955
+ id : ConstParamId :: from_unchecked ( TypeOrConstParamId {
2956
+ parent : self . into ( ) ,
2957
+ local_id,
2958
+ } ) ,
2959
+ } ) ,
2960
+ } )
2961
+ . collect ( )
2962
+ }
2913
2963
}
2914
2964
2915
2965
/// A single local definition.
@@ -3272,12 +3322,16 @@ impl TypeParam {
3272
3322
let ty = generic_arg_from_param ( db, self . id . into ( ) ) ?;
3273
3323
let resolver = self . id . parent ( ) . resolver ( db. upcast ( ) ) ;
3274
3324
match ty. data ( Interner ) {
3275
- GenericArgData :: Ty ( it) => {
3325
+ GenericArgData :: Ty ( it) if * it . kind ( Interner ) != TyKind :: Error => {
3276
3326
Some ( Type :: new_with_resolver_inner ( db, & resolver, it. clone ( ) ) )
3277
3327
}
3278
3328
_ => None ,
3279
3329
}
3280
3330
}
3331
+
3332
+ pub fn is_unstable ( self , db : & dyn HirDatabase ) -> bool {
3333
+ db. attrs ( GenericParamId :: from ( self . id ) . into ( ) ) . is_unstable ( )
3334
+ }
3281
3335
}
3282
3336
3283
3337
#[ derive( Clone , Copy , Debug , PartialEq , Eq , Hash ) ]
@@ -3761,6 +3815,50 @@ impl Type {
3761
3815
matches ! ( self . ty. kind( Interner ) , TyKind :: Ref ( ..) )
3762
3816
}
3763
3817
3818
+ pub fn contains_reference ( & self , db : & dyn HirDatabase ) -> bool {
3819
+ return go ( db, self . env . krate , & self . ty ) ;
3820
+
3821
+ fn go ( db : & dyn HirDatabase , krate : CrateId , ty : & Ty ) -> bool {
3822
+ match ty. kind ( Interner ) {
3823
+ // Reference itself
3824
+ TyKind :: Ref ( _, _, _) => true ,
3825
+
3826
+ // For non-phantom_data adts we check variants/fields as well as generic parameters
3827
+ TyKind :: Adt ( adt_id, substitution)
3828
+ if !db. struct_datum ( krate, * adt_id) . flags . phantom_data =>
3829
+ {
3830
+ let adt_datum = & db. struct_datum ( krate, * adt_id) ;
3831
+ let adt_datum_bound =
3832
+ adt_datum. binders . clone ( ) . substitute ( Interner , substitution) ;
3833
+ adt_datum_bound
3834
+ . variants
3835
+ . into_iter ( )
3836
+ . flat_map ( |variant| variant. fields . into_iter ( ) )
3837
+ . any ( |ty| go ( db, krate, & ty) )
3838
+ || substitution
3839
+ . iter ( Interner )
3840
+ . filter_map ( |x| x. ty ( Interner ) )
3841
+ . any ( |ty| go ( db, krate, ty) )
3842
+ }
3843
+ // And for `PhantomData<T>`, we check `T`.
3844
+ TyKind :: Adt ( _, substitution)
3845
+ | TyKind :: Tuple ( _, substitution)
3846
+ | TyKind :: OpaqueType ( _, substitution)
3847
+ | TyKind :: AssociatedType ( _, substitution)
3848
+ | TyKind :: FnDef ( _, substitution) => substitution
3849
+ . iter ( Interner )
3850
+ . filter_map ( |x| x. ty ( Interner ) )
3851
+ . any ( |ty| go ( db, krate, ty) ) ,
3852
+
3853
+ // For `[T]` or `*T` we check `T`
3854
+ TyKind :: Array ( ty, _) | TyKind :: Slice ( ty) | TyKind :: Raw ( _, ty) => go ( db, krate, ty) ,
3855
+
3856
+ // Consider everything else as not reference
3857
+ _ => false ,
3858
+ }
3859
+ }
3860
+ }
3861
+
3764
3862
pub fn as_reference ( & self ) -> Option < ( Type , Mutability ) > {
3765
3863
let ( ty, _lt, m) = self . ty . as_reference ( ) ?;
3766
3864
let m = Mutability :: from_mutable ( matches ! ( m, hir_ty:: Mutability :: Mut ) ) ;
0 commit comments