diff options
| author | oddg <odegevigney@gmail.com> | 2020-05-14 19:58:43 -0700 |
|---|---|---|
| committer | oddg <odegevigney@gmail.com> | 2020-06-13 17:35:31 -0700 |
| commit | d5ea0e9f8def9a3ec0eb2dd88f0465d4d1a81c21 (patch) | |
| tree | 5a45f946c1a71c435de04f6a7dcc0119271cc46b | |
| parent | 1fb612bd15bb3ef098fd24c20d0727de573b4410 (diff) | |
| download | rust-d5ea0e9f8def9a3ec0eb2dd88f0465d4d1a81c21.tar.gz rust-d5ea0e9f8def9a3ec0eb2dd88f0465d4d1a81c21.zip | |
Report error when casting an C-like enum implementing Drop
| -rw-r--r-- | src/librustc_session/lint/builtin.rs | 11 | ||||
| -rw-r--r-- | src/librustc_typeck/check/cast.rs | 30 |
2 files changed, 38 insertions, 3 deletions
diff --git a/src/librustc_session/lint/builtin.rs b/src/librustc_session/lint/builtin.rs index 58388bafbed..5a8f5c1b9fb 100644 --- a/src/librustc_session/lint/builtin.rs +++ b/src/librustc_session/lint/builtin.rs @@ -534,6 +534,16 @@ declare_lint! { @feature_gate = sym::unsafe_block_in_unsafe_fn; } +declare_lint! { + pub CENUM_IMPL_DROP_CAST, + Warn, + "a C-like enum implementing Drop is cast", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #73333 <https://github.com/rust-lang/rust/issues/73333>", + edition: None, + }; +} + declare_lint_pass! { /// Does nothing as a lint pass, but registers some `Lint`s /// that are used by other parts of the compiler. @@ -607,6 +617,7 @@ declare_lint_pass! { ASM_SUB_REGISTER, UNSAFE_OP_IN_UNSAFE_FN, INCOMPLETE_INCLUDE, + CENUM_IMPL_DROP_CAST, ] } diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs index 46d6706cbf4..bea5e0e9966 100644 --- a/src/librustc_typeck/check/cast.rs +++ b/src/librustc_typeck/check/cast.rs @@ -609,7 +609,10 @@ impl<'a, 'tcx> CastCheck<'tcx> { (FnPtr, Ptr(mt)) => self.check_fptr_ptr_cast(fcx, mt), // prim -> prim - (Int(CEnum), Int(_)) => Ok(CastKind::EnumCast), + (Int(CEnum), Int(_)) => { + self.cenum_impl_drop_lint(fcx); + Ok(CastKind::EnumCast) + } (Int(Char) | Int(Bool), Int(_)) => Ok(CastKind::PrimIntCast), (Int(_) | Float, Int(_) | Float) => Ok(CastKind::NumericCast), @@ -706,11 +709,13 @@ impl<'a, 'tcx> CastCheck<'tcx> { // Coerce to a raw pointer so that we generate AddressOf in MIR. let array_ptr_type = fcx.tcx.mk_ptr(m_expr); fcx.try_coerce(self.expr, self.expr_ty, array_ptr_type, AllowTwoPhase::No) - .unwrap_or_else(|_| bug!( + .unwrap_or_else(|_| { + bug!( "could not cast from reference to array to pointer to array ({:?} to {:?})", self.expr_ty, array_ptr_type, - )); + ) + }); // this will report a type mismatch if needed fcx.demand_eqtype(self.span, ety, m_cast.ty); @@ -740,6 +745,25 @@ impl<'a, 'tcx> CastCheck<'tcx> { Err(err) => Err(err), } } + + fn cenum_impl_drop_lint(&self, fcx: &FnCtxt<'a, 'tcx>) { + if let ty::Adt(d, _) = self.expr_ty.kind { + if d.has_dtor(fcx.tcx) { + fcx.tcx.struct_span_lint_hir( + lint::builtin::CENUM_IMPL_DROP_CAST, + self.expr.hir_id, + self.span, + |err| { + err.build(&format!( + "Cast `enum` implementing `Drop` `{}` to integer `{}`", + self.expr_ty, self.cast_ty + )) + .emit(); + }, + ); + } + } + } } impl<'a, 'tcx> FnCtxt<'a, 'tcx> { |
