@@ -189,6 +189,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
189189 [ sym:: collapse_debuginfo, ..] => self . check_collapse_debuginfo ( attr, span, target) ,
190190 [ sym:: must_not_suspend, ..] => self . check_must_not_suspend ( attr, span, target) ,
191191 [ sym:: must_use, ..] => self . check_must_use ( hir_id, attr, target) ,
192+ [ sym:: may_dangle, ..] => self . check_may_dangle ( hir_id, attr) ,
192193 [ sym:: rustc_pass_by_value, ..] => self . check_pass_by_value ( attr, span, target) ,
193194 [ sym:: rustc_allow_incoherent_impl, ..] => {
194195 self . check_allow_incoherent_impl ( attr, span, target)
@@ -255,7 +256,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
255256 | sym:: cfg_attr
256257 // need to be fixed
257258 | sym:: cfi_encoding // FIXME(cfi_encoding)
258- | sym:: may_dangle // FIXME(dropck_eyepatch)
259259 | sym:: pointee // FIXME(derive_smart_pointer)
260260 | sym:: omit_gdb_pretty_printer_section // FIXME(omit_gdb_pretty_printer_section)
261261 | sym:: used // handled elsewhere to restrict to static items
@@ -1363,7 +1363,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
13631363 }
13641364 }
13651365
1366- /// Checks if `#[must_not_suspend]` is applied to a function .
1366+ /// Checks if `#[must_not_suspend]` is applied to a struct, enum, union, or trait .
13671367 fn check_must_not_suspend ( & self , attr : & Attribute , span : Span , target : Target ) {
13681368 match target {
13691369 Target :: Struct | Target :: Enum | Target :: Union | Target :: Trait => { }
@@ -1373,6 +1373,27 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
13731373 }
13741374 }
13751375
1376+ /// Checks if `#[may_dangle]` is applied to a lifetime or type generic parameter in `Drop` impl.
1377+ fn check_may_dangle ( & self , hir_id : HirId , attr : & Attribute ) {
1378+ if let hir:: Node :: GenericParam ( param) = self . tcx . hir_node ( hir_id)
1379+ && matches ! (
1380+ param. kind,
1381+ hir:: GenericParamKind :: Lifetime { .. } | hir:: GenericParamKind :: Type { .. }
1382+ )
1383+ && matches ! ( param. source, hir:: GenericParamSource :: Generics )
1384+ && let parent_hir_id = self . tcx . parent_hir_id ( hir_id)
1385+ && let hir:: Node :: Item ( item) = self . tcx . hir_node ( parent_hir_id)
1386+ && let hir:: ItemKind :: Impl ( impl_) = item. kind
1387+ && let Some ( trait_) = impl_. of_trait
1388+ && let Some ( def_id) = trait_. trait_def_id ( )
1389+ && self . tcx . is_lang_item ( def_id, hir:: LangItem :: Drop )
1390+ {
1391+ return ;
1392+ }
1393+
1394+ self . dcx ( ) . emit_err ( errors:: InvalidMayDangle { attr_span : attr. span } ) ;
1395+ }
1396+
13761397 /// Checks if `#[cold]` is applied to a non-function.
13771398 fn check_cold ( & self , hir_id : HirId , attr : & Attribute , span : Span , target : Target ) {
13781399 match target {
0 commit comments