Skip to content

Commit

Permalink
Rollup merge of rust-lang#135964 - ehuss:cenum_impl_drop_cast, r=Nadr…
Browse files Browse the repository at this point in the history
…ieril

Make cenum_impl_drop_cast a hard error

This changes the `cenum_impl_drop_cast` lint to be a hard error. This lint has been deny-by-default and warning in dependencies since rust-lang#97652 about 2.5 years ago.

Closes rust-lang#73333
  • Loading branch information
jieyouxu authored Feb 5, 2025
2 parents c2fbba6 + e0bbeb7 commit 8ee0052
Show file tree
Hide file tree
Showing 8 changed files with 12 additions and 181 deletions.
11 changes: 3 additions & 8 deletions compiler/rustc_hir_typeck/src/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -831,7 +831,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {

// prim -> prim
(Int(CEnum), Int(_)) => {
self.cenum_impl_drop_lint(fcx);
self.err_if_cenum_impl_drop(fcx);
Ok(CastKind::EnumCast)
}
(Int(Char) | Int(Bool), Int(_)) => Ok(CastKind::PrimIntCast),
Expand Down Expand Up @@ -1091,19 +1091,14 @@ impl<'a, 'tcx> CastCheck<'tcx> {
}
}

fn cenum_impl_drop_lint(&self, fcx: &FnCtxt<'a, 'tcx>) {
fn err_if_cenum_impl_drop(&self, fcx: &FnCtxt<'a, 'tcx>) {
if let ty::Adt(d, _) = self.expr_ty.kind()
&& d.has_dtor(fcx.tcx)
{
let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty);
let cast_ty = fcx.resolve_vars_if_possible(self.cast_ty);

fcx.tcx.emit_node_span_lint(
lint::builtin::CENUM_IMPL_DROP_CAST,
self.expr.hir_id,
self.span,
errors::CastEnumDrop { expr_ty, cast_ty },
);
fcx.dcx().emit_err(errors::CastEnumDrop { span: self.span, expr_ty, cast_ty });
}
}

Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_hir_typeck/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -677,9 +677,11 @@ pub(crate) struct CannotCastToBool<'tcx> {
pub help: CannotCastToBoolHelp,
}

#[derive(LintDiagnostic)]
#[derive(Diagnostic)]
#[diag(hir_typeck_cast_enum_drop)]
pub(crate) struct CastEnumDrop<'tcx> {
#[primary_span]
pub span: Span,
pub expr_ty: Ty<'tcx>,
pub cast_ty: Ty<'tcx>,
}
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_lint/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,11 @@ fn register_builtins(store: &mut LintStore) {
<https://github.com/rust-lang/rust/pull/125380> for more information",
);
store.register_removed("unsupported_calling_conventions", "converted into hard error");
store.register_removed(
"cenum_impl_drop_cast",
"converted into hard error, \
see <https://github.com/rust-lang/rust/issues/73333> for more information",
);
}

fn register_internals(store: &mut LintStore) {
Expand Down
53 changes: 0 additions & 53 deletions compiler/rustc_lint_defs/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ declare_lint_pass! {
BARE_TRAIT_OBJECTS,
BINDINGS_WITH_VARIANT_NAME,
BREAK_WITH_LABEL_AND_LOOP,
CENUM_IMPL_DROP_CAST,
COHERENCE_LEAK_CHECK,
CONFLICTING_REPR_HINTS,
CONST_EVALUATABLE_UNCHECKED,
Expand Down Expand Up @@ -2612,58 +2611,6 @@ declare_lint! {
@edition Edition2024 => Warn;
}

declare_lint! {
/// The `cenum_impl_drop_cast` lint detects an `as` cast of a field-less
/// `enum` that implements [`Drop`].
///
/// [`Drop`]: https://doc.rust-lang.org/std/ops/trait.Drop.html
///
/// ### Example
///
/// ```rust,compile_fail
/// # #![allow(unused)]
/// enum E {
/// A,
/// }
///
/// impl Drop for E {
/// fn drop(&mut self) {
/// println!("Drop");
/// }
/// }
///
/// fn main() {
/// let e = E::A;
/// let i = e as u32;
/// }
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// Casting a field-less `enum` that does not implement [`Copy`] to an
/// integer moves the value without calling `drop`. This can result in
/// surprising behavior if it was expected that `drop` should be called.
/// Calling `drop` automatically would be inconsistent with other move
/// operations. Since neither behavior is clear or consistent, it was
/// decided that a cast of this nature will no longer be allowed.
///
/// This is a [future-incompatible] lint to transition this to a hard error
/// in the future. See [issue #73333] for more details.
///
/// [future-incompatible]: ../index.md#future-incompatible-lints
/// [issue #73333]: https://github.com/rust-lang/rust/issues/73333
/// [`Copy`]: https://doc.rust-lang.org/std/marker/trait.Copy.html
pub CENUM_IMPL_DROP_CAST,
Deny,
"a C-like enum implementing Drop is cast",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps,
reference: "issue #73333 <https://github.com/rust-lang/rust/issues/73333>",
};
}

declare_lint! {
/// The `fuzzy_provenance_casts` lint detects an `as` cast between an integer
/// and a pointer.
Expand Down
71 changes: 0 additions & 71 deletions tests/mir-opt/building/enum_cast.droppy.built.after.mir

This file was deleted.

21 changes: 0 additions & 21 deletions tests/mir-opt/building/enum_cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,27 +41,6 @@ fn far(far: Far) -> isize {
far as isize
}

// EMIT_MIR enum_cast.droppy.built.after.mir
enum Droppy {
A,
B,
C,
}

impl Drop for Droppy {
fn drop(&mut self) {}
}

fn droppy() {
{
let x = Droppy::C;
// remove this entire test once `cenum_impl_drop_cast` becomes a hard error
#[allow(cenum_impl_drop_cast)]
let y = x as usize;
}
let z = Droppy::B;
}

#[repr(i16)]
enum SignedAroundZero {
A = -2,
Expand Down
3 changes: 0 additions & 3 deletions tests/ui/cenum_impl_drop_cast.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#![deny(cenum_impl_drop_cast)]

enum E {
A = 0,
}
Expand All @@ -14,5 +12,4 @@ fn main() {
let e = E::A;
let i = e as u32;
//~^ ERROR cannot cast enum `E` into integer `u32` because it implements `Drop`
//~| WARN this was previously accepted
}
25 changes: 1 addition & 24 deletions tests/ui/cenum_impl_drop_cast.stderr
Original file line number Diff line number Diff line change
@@ -1,31 +1,8 @@
error: cannot cast enum `E` into integer `u32` because it implements `Drop`
--> $DIR/cenum_impl_drop_cast.rs:15:13
--> $DIR/cenum_impl_drop_cast.rs:13:13
|
LL | let i = e as u32;
| ^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #73333 <https://github.com/rust-lang/rust/issues/73333>
note: the lint level is defined here
--> $DIR/cenum_impl_drop_cast.rs:1:9
|
LL | #![deny(cenum_impl_drop_cast)]
| ^^^^^^^^^^^^^^^^^^^^

error: aborting due to 1 previous error

Future incompatibility report: Future breakage diagnostic:
error: cannot cast enum `E` into integer `u32` because it implements `Drop`
--> $DIR/cenum_impl_drop_cast.rs:15:13
|
LL | let i = e as u32;
| ^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #73333 <https://github.com/rust-lang/rust/issues/73333>
note: the lint level is defined here
--> $DIR/cenum_impl_drop_cast.rs:1:9
|
LL | #![deny(cenum_impl_drop_cast)]
| ^^^^^^^^^^^^^^^^^^^^

0 comments on commit 8ee0052

Please sign in to comment.