@@ -154,6 +154,27 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
154154 Attribute :: Parsed ( AttributeKind :: AsPtr ( attr_span) ) => {
155155 self . check_applied_to_fn_or_method ( hir_id, * attr_span, span, target)
156156 }
157+ & Attribute :: Parsed ( AttributeKind :: MayDangle ( attr_span) ) => {
158+ // Check if `#[may_dangle]` is applied to a lifetime or type generic parameter in `Drop` impl.
159+ if let hir:: Node :: GenericParam ( param) = self . tcx . hir_node ( hir_id)
160+ && matches ! (
161+ param. kind,
162+ hir:: GenericParamKind :: Lifetime { .. }
163+ | hir:: GenericParamKind :: Type { .. }
164+ )
165+ && matches ! ( param. source, hir:: GenericParamSource :: Generics )
166+ && let parent_hir_id = self . tcx . parent_hir_id ( hir_id)
167+ && let hir:: Node :: Item ( item) = self . tcx . hir_node ( parent_hir_id)
168+ && let hir:: ItemKind :: Impl ( impl_) = item. kind
169+ && let Some ( trait_) = impl_. of_trait
170+ && let Some ( def_id) = trait_. trait_def_id ( )
171+ && self . tcx . is_lang_item ( def_id, hir:: LangItem :: Drop )
172+ {
173+ // OK
174+ } else {
175+ self . dcx ( ) . emit_err ( errors:: InvalidMayDangle { attr_span } ) ;
176+ }
177+ }
157178 Attribute :: Unparsed ( _) => {
158179 match attr. path ( ) . as_slice ( ) {
159180 [ sym:: diagnostic, sym:: do_not_recommend, ..] => {
@@ -228,7 +249,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
228249 [ sym:: collapse_debuginfo, ..] => self . check_collapse_debuginfo ( attr, span, target) ,
229250 [ sym:: must_not_suspend, ..] => self . check_must_not_suspend ( attr, span, target) ,
230251 [ sym:: must_use, ..] => self . check_must_use ( hir_id, attr, target) ,
231- [ sym:: may_dangle, ..] => self . check_may_dangle ( hir_id, attr) ,
232252 [ sym:: rustc_pass_by_value, ..] => self . check_pass_by_value ( attr, span, target) ,
233253 [ sym:: rustc_allow_incoherent_impl, ..] => {
234254 self . check_allow_incoherent_impl ( attr, span, target)
@@ -1606,27 +1626,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
16061626 }
16071627 }
16081628
1609- /// Checks if `#[may_dangle]` is applied to a lifetime or type generic parameter in `Drop` impl.
1610- fn check_may_dangle ( & self , hir_id : HirId , attr : & Attribute ) {
1611- if let hir:: Node :: GenericParam ( param) = self . tcx . hir_node ( hir_id)
1612- && matches ! (
1613- param. kind,
1614- hir:: GenericParamKind :: Lifetime { .. } | hir:: GenericParamKind :: Type { .. }
1615- )
1616- && matches ! ( param. source, hir:: GenericParamSource :: Generics )
1617- && let parent_hir_id = self . tcx . parent_hir_id ( hir_id)
1618- && let hir:: Node :: Item ( item) = self . tcx . hir_node ( parent_hir_id)
1619- && let hir:: ItemKind :: Impl ( impl_) = item. kind
1620- && let Some ( trait_) = impl_. of_trait
1621- && let Some ( def_id) = trait_. trait_def_id ( )
1622- && self . tcx . is_lang_item ( def_id, hir:: LangItem :: Drop )
1623- {
1624- return ;
1625- }
1626-
1627- self . dcx ( ) . emit_err ( errors:: InvalidMayDangle { attr_span : attr. span ( ) } ) ;
1628- }
1629-
16301629 /// Checks if `#[cold]` is applied to a non-function.
16311630 fn check_cold ( & self , hir_id : HirId , attr : & Attribute , span : Span , target : Target ) {
16321631 match target {
0 commit comments