@@ -158,6 +158,27 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
158158 Attribute :: Parsed ( AttributeKind :: AsPtr ( attr_span) ) => {
159159 self . check_applied_to_fn_or_method ( hir_id, * attr_span, span, target)
160160 }
161+ & Attribute :: Parsed ( AttributeKind :: MayDangle ( attr_span) ) => {
162+ // Check if `#[may_dangle]` is applied to a lifetime or type generic parameter in `Drop` impl.
163+ if let hir:: Node :: GenericParam ( param) = self . tcx . hir_node ( hir_id)
164+ && matches ! (
165+ param. kind,
166+ hir:: GenericParamKind :: Lifetime { .. }
167+ | hir:: GenericParamKind :: Type { .. }
168+ )
169+ && matches ! ( param. source, hir:: GenericParamSource :: Generics )
170+ && let parent_hir_id = self . tcx . parent_hir_id ( hir_id)
171+ && let hir:: Node :: Item ( item) = self . tcx . hir_node ( parent_hir_id)
172+ && let hir:: ItemKind :: Impl ( impl_) = item. kind
173+ && let Some ( trait_) = impl_. of_trait
174+ && let Some ( def_id) = trait_. trait_def_id ( )
175+ && self . tcx . is_lang_item ( def_id, hir:: LangItem :: Drop )
176+ {
177+ // OK
178+ } else {
179+ self . dcx ( ) . emit_err ( errors:: InvalidMayDangle { attr_span } ) ;
180+ }
181+ }
161182 Attribute :: Unparsed ( _) => {
162183 match attr. path ( ) . as_slice ( ) {
163184 [ sym:: diagnostic, sym:: do_not_recommend, ..] => {
@@ -232,7 +253,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
232253 [ sym:: collapse_debuginfo, ..] => self . check_collapse_debuginfo ( attr, span, target) ,
233254 [ sym:: must_not_suspend, ..] => self . check_must_not_suspend ( attr, span, target) ,
234255 [ sym:: must_use, ..] => self . check_must_use ( hir_id, attr, target) ,
235- [ sym:: may_dangle, ..] => self . check_may_dangle ( hir_id, attr) ,
236256 [ sym:: rustc_pass_by_value, ..] => self . check_pass_by_value ( attr, span, target) ,
237257 [ sym:: rustc_allow_incoherent_impl, ..] => {
238258 self . check_allow_incoherent_impl ( attr, span, target)
@@ -1613,27 +1633,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
16131633 }
16141634 }
16151635
1616- /// Checks if `#[may_dangle]` is applied to a lifetime or type generic parameter in `Drop` impl.
1617- fn check_may_dangle ( & self , hir_id : HirId , attr : & Attribute ) {
1618- if let hir:: Node :: GenericParam ( param) = self . tcx . hir_node ( hir_id)
1619- && matches ! (
1620- param. kind,
1621- hir:: GenericParamKind :: Lifetime { .. } | hir:: GenericParamKind :: Type { .. }
1622- )
1623- && matches ! ( param. source, hir:: GenericParamSource :: Generics )
1624- && let parent_hir_id = self . tcx . parent_hir_id ( hir_id)
1625- && let hir:: Node :: Item ( item) = self . tcx . hir_node ( parent_hir_id)
1626- && let hir:: ItemKind :: Impl ( impl_) = item. kind
1627- && let Some ( trait_) = impl_. of_trait
1628- && let Some ( def_id) = trait_. trait_def_id ( )
1629- && self . tcx . is_lang_item ( def_id, hir:: LangItem :: Drop )
1630- {
1631- return ;
1632- }
1633-
1634- self . dcx ( ) . emit_err ( errors:: InvalidMayDangle { attr_span : attr. span ( ) } ) ;
1635- }
1636-
16371636 /// Checks if `#[cold]` is applied to a non-function.
16381637 fn check_cold ( & self , hir_id : HirId , attr : & Attribute , span : Span , target : Target ) {
16391638 match target {
0 commit comments