@@ -2107,3 +2107,57 @@ impl LintPass for UnstableFeatures {
21072107 }
21082108 }
21092109}
2110+
2111+ /// Lints for attempts to impl Drop on types that have `#[repr(C)]`
2112+ /// attribute (see issue #24585).
2113+ #[ derive( Copy , Clone ) ]
2114+ pub struct DropWithReprExtern ;
2115+
2116+ declare_lint ! {
2117+ DROP_WITH_REPR_EXTERN ,
2118+ Warn ,
2119+ "use of #[repr(C)] on a type that implements Drop"
2120+ }
2121+
2122+ impl LintPass for DropWithReprExtern {
2123+ fn get_lints ( & self ) -> LintArray {
2124+ lint_array ! ( DROP_WITH_REPR_EXTERN )
2125+ }
2126+ fn check_crate ( & mut self , ctx : & Context , _: & ast:: Crate ) {
2127+ for dtor_did in ctx. tcx . destructors . borrow ( ) . iter ( ) {
2128+ let ( drop_impl_did, dtor_self_type) =
2129+ if dtor_did. krate == ast:: LOCAL_CRATE {
2130+ let impl_did = ctx. tcx . map . get_parent_did ( dtor_did. node ) ;
2131+ let ty = ty:: lookup_item_type ( ctx. tcx , impl_did) . ty ;
2132+ ( impl_did, ty)
2133+ } else {
2134+ continue ;
2135+ } ;
2136+
2137+ match dtor_self_type. sty {
2138+ ty:: ty_enum( self_type_did, _) |
2139+ ty:: ty_struct( self_type_did, _) |
2140+ ty:: ty_closure( self_type_did, _) => {
2141+ let hints = ty:: lookup_repr_hints ( ctx. tcx , self_type_did) ;
2142+ if hints. iter ( ) . any ( |attr| * attr == attr:: ReprExtern ) &&
2143+ ty:: ty_dtor ( ctx. tcx , self_type_did) . has_drop_flag ( ) {
2144+ let drop_impl_span = ctx. tcx . map . def_id_span ( drop_impl_did,
2145+ codemap:: DUMMY_SP ) ;
2146+ let self_defn_span = ctx. tcx . map . def_id_span ( self_type_did,
2147+ codemap:: DUMMY_SP ) ;
2148+ ctx. span_lint ( DROP_WITH_REPR_EXTERN ,
2149+ drop_impl_span,
2150+ "implementing Drop adds hidden state to types, \
2151+ possibly conflicting with `#[repr(C)]`") ;
2152+ // FIXME #19668: could be span_lint_note instead of manual guard.
2153+ if ctx. current_level ( DROP_WITH_REPR_EXTERN ) != Level :: Allow {
2154+ ctx. sess ( ) . span_note ( self_defn_span,
2155+ "the `#[repr(C)]` attribute is attached here" ) ;
2156+ }
2157+ }
2158+ }
2159+ _ => { }
2160+ }
2161+ }
2162+ }
2163+ }
0 commit comments