Skip to content

Commit d5ea0e9

Browse files
committed
Report error when casting an C-like enum implementing Drop
1 parent 1fb612b commit d5ea0e9

File tree

2 files changed

+38
-3
lines changed

2 files changed

+38
-3
lines changed

src/librustc_session/lint/builtin.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,16 @@ declare_lint! {
534534
@feature_gate = sym::unsafe_block_in_unsafe_fn;
535535
}
536536

537+
declare_lint! {
538+
pub CENUM_IMPL_DROP_CAST,
539+
Warn,
540+
"a C-like enum implementing Drop is cast",
541+
@future_incompatible = FutureIncompatibleInfo {
542+
reference: "issue #73333 <https://github.com/rust-lang/rust/issues/73333>",
543+
edition: None,
544+
};
545+
}
546+
537547
declare_lint_pass! {
538548
/// Does nothing as a lint pass, but registers some `Lint`s
539549
/// that are used by other parts of the compiler.
@@ -607,6 +617,7 @@ declare_lint_pass! {
607617
ASM_SUB_REGISTER,
608618
UNSAFE_OP_IN_UNSAFE_FN,
609619
INCOMPLETE_INCLUDE,
620+
CENUM_IMPL_DROP_CAST,
610621
]
611622
}
612623

src/librustc_typeck/check/cast.rs

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -609,7 +609,10 @@ impl<'a, 'tcx> CastCheck<'tcx> {
609609
(FnPtr, Ptr(mt)) => self.check_fptr_ptr_cast(fcx, mt),
610610

611611
// prim -> prim
612-
(Int(CEnum), Int(_)) => Ok(CastKind::EnumCast),
612+
(Int(CEnum), Int(_)) => {
613+
self.cenum_impl_drop_lint(fcx);
614+
Ok(CastKind::EnumCast)
615+
}
613616
(Int(Char) | Int(Bool), Int(_)) => Ok(CastKind::PrimIntCast),
614617

615618
(Int(_) | Float, Int(_) | Float) => Ok(CastKind::NumericCast),
@@ -706,11 +709,13 @@ impl<'a, 'tcx> CastCheck<'tcx> {
706709
// Coerce to a raw pointer so that we generate AddressOf in MIR.
707710
let array_ptr_type = fcx.tcx.mk_ptr(m_expr);
708711
fcx.try_coerce(self.expr, self.expr_ty, array_ptr_type, AllowTwoPhase::No)
709-
.unwrap_or_else(|_| bug!(
712+
.unwrap_or_else(|_| {
713+
bug!(
710714
"could not cast from reference to array to pointer to array ({:?} to {:?})",
711715
self.expr_ty,
712716
array_ptr_type,
713-
));
717+
)
718+
});
714719

715720
// this will report a type mismatch if needed
716721
fcx.demand_eqtype(self.span, ety, m_cast.ty);
@@ -740,6 +745,25 @@ impl<'a, 'tcx> CastCheck<'tcx> {
740745
Err(err) => Err(err),
741746
}
742747
}
748+
749+
fn cenum_impl_drop_lint(&self, fcx: &FnCtxt<'a, 'tcx>) {
750+
if let ty::Adt(d, _) = self.expr_ty.kind {
751+
if d.has_dtor(fcx.tcx) {
752+
fcx.tcx.struct_span_lint_hir(
753+
lint::builtin::CENUM_IMPL_DROP_CAST,
754+
self.expr.hir_id,
755+
self.span,
756+
|err| {
757+
err.build(&format!(
758+
"Cast `enum` implementing `Drop` `{}` to integer `{}`",
759+
self.expr_ty, self.cast_ty
760+
))
761+
.emit();
762+
},
763+
);
764+
}
765+
}
766+
}
743767
}
744768

745769
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

0 commit comments

Comments
 (0)