@@ -1187,6 +1187,10 @@ impl Struct {
11871187 fn variant_data ( self , db : & dyn HirDatabase ) -> Arc < VariantData > {
11881188 db. struct_data ( self . id ) . variant_data . clone ( )
11891189 }
1190+
1191+ pub fn is_unstable ( self , db : & dyn HirDatabase ) -> bool {
1192+ db. attrs ( self . id . into ( ) ) . is_unstable ( )
1193+ }
11901194}
11911195
11921196impl HasVisibility for Struct {
@@ -1229,6 +1233,10 @@ impl Union {
12291233 fn variant_data ( self , db : & dyn HirDatabase ) -> Arc < VariantData > {
12301234 db. union_data ( self . id ) . variant_data . clone ( )
12311235 }
1236+
1237+ pub fn is_unstable ( self , db : & dyn HirDatabase ) -> bool {
1238+ db. attrs ( self . id . into ( ) ) . is_unstable ( )
1239+ }
12321240}
12331241
12341242impl HasVisibility for Union {
@@ -1318,6 +1326,10 @@ impl Enum {
13181326 pub fn layout ( self , db : & dyn HirDatabase ) -> Result < Layout , LayoutError > {
13191327 Adt :: from ( self ) . layout ( db)
13201328 }
1329+
1330+ pub fn is_unstable ( self , db : & dyn HirDatabase ) -> bool {
1331+ db. attrs ( self . id . into ( ) ) . is_unstable ( )
1332+ }
13211333}
13221334
13231335impl HasVisibility for Enum {
@@ -1393,6 +1405,10 @@ impl Variant {
13931405 _ => parent_layout,
13941406 } )
13951407 }
1408+
1409+ pub fn is_unstable ( self , db : & dyn HirDatabase ) -> bool {
1410+ db. attrs ( self . id . into ( ) ) . is_unstable ( )
1411+ }
13961412}
13971413
13981414/// Variants inherit visibility from the parent enum.
@@ -2912,7 +2928,7 @@ impl GenericDef {
29122928 . collect ( )
29132929 }
29142930
2915- pub fn type_params ( self , db : & dyn HirDatabase ) -> Vec < TypeOrConstParam > {
2931+ pub fn type_or_const_params ( self , db : & dyn HirDatabase ) -> Vec < TypeOrConstParam > {
29162932 let generics = db. generic_params ( self . into ( ) ) ;
29172933 generics
29182934 . type_or_consts
@@ -2922,6 +2938,40 @@ impl GenericDef {
29222938 } )
29232939 . collect ( )
29242940 }
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+ }
29252975}
29262976
29272977/// A single local definition.
@@ -3284,12 +3334,16 @@ impl TypeParam {
32843334 let ty = generic_arg_from_param ( db, self . id . into ( ) ) ?;
32853335 let resolver = self . id . parent ( ) . resolver ( db. upcast ( ) ) ;
32863336 match ty. data ( Interner ) {
3287- GenericArgData :: Ty ( it) => {
3337+ GenericArgData :: Ty ( it) if * it . kind ( Interner ) != TyKind :: Error => {
32883338 Some ( Type :: new_with_resolver_inner ( db, & resolver, it. clone ( ) ) )
32893339 }
32903340 _ => None ,
32913341 }
32923342 }
3343+
3344+ pub fn is_unstable ( self , db : & dyn HirDatabase ) -> bool {
3345+ db. attrs ( GenericParamId :: from ( self . id ) . into ( ) ) . is_unstable ( )
3346+ }
32933347}
32943348
32953349#[ derive( Clone , Copy , Debug , PartialEq , Eq , Hash ) ]
@@ -3773,6 +3827,50 @@ impl Type {
37733827 matches ! ( self . ty. kind( Interner ) , TyKind :: Ref ( ..) )
37743828 }
37753829
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+
37763874 pub fn as_reference ( & self ) -> Option < ( Type , Mutability ) > {
37773875 let ( ty, _lt, m) = self . ty . as_reference ( ) ?;
37783876 let m = Mutability :: from_mutable ( matches ! ( m, hir_ty:: Mutability :: Mut ) ) ;
0 commit comments