@@ -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