Migration lint

Rustfix remains TODO
This commit is contained in:
Jules Bertholet 2024-04-05 23:28:34 -04:00
parent ef1d084c0b
commit 83f330fbd4
No known key found for this signature in database
GPG Key ID: 32034DAFC38C1BFC
6 changed files with 108 additions and 0 deletions

View File

@ -46,6 +46,10 @@ hir_typeck_ctor_is_private = tuple struct constructor `{$def}` is private
hir_typeck_deref_is_empty = this expression `Deref`s to `{$deref_ty}` which implements `is_empty`
hir_typeck_dereferencing_mut_binding = dereferencing `mut` binding
.label = `mut` dereferences the type of this binding
.help = this will change in edition 2024
hir_typeck_expected_default_return_type = expected `()` because of default return type
hir_typeck_expected_return_type = expected `{$expected}` because of return type

View File

@ -632,3 +632,11 @@ pub enum SuggestBoxingForReturnImplTrait {
ends: Vec<Span>,
},
}
#[derive(LintDiagnostic)]
#[diag(hir_typeck_dereferencing_mut_binding)]
pub struct DereferencingMutBinding {
#[label]
#[help]
pub span: Span,
}

View File

@ -10,6 +10,7 @@ use rustc_hir::pat_util::EnumerateAndAdjustIterator;
use rustc_hir::{self as hir, BindingAnnotation, ByRef, HirId, Mutability, Pat, PatKind};
use rustc_infer::infer;
use rustc_infer::infer::type_variable::TypeVariableOrigin;
use rustc_lint as lint;
use rustc_middle::mir::interpret::ErrorHandled;
use rustc_middle::ty::{self, Adt, Ty, TypeVisitableExt};
use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS;
@ -639,6 +640,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&& matches!(def_br, ByRef::Yes(_)) =>
{
// `mut x` resets the binding mode in edition <= 2021.
self.tcx.emit_node_span_lint(
lint::builtin::DEREFERENCING_MUT_BINDING,
pat.hir_id,
pat.span,
errors::DereferencingMutBinding { span: pat.span },
);
BindingAnnotation(ByRef::No, Mutability::Mut)
}
BindingAnnotation(ByRef::No, mutbl) => BindingAnnotation(def_br, mutbl),

View File

@ -38,6 +38,7 @@ declare_lint_pass! {
DEPRECATED_CFG_ATTR_CRATE_TYPE_NAME,
DEPRECATED_IN_FUTURE,
DEPRECATED_WHERE_CLAUSE_LOCATION,
DEREFERENCING_MUT_BINDING,
DUPLICATE_MACRO_ATTRIBUTES,
ELIDED_LIFETIMES_IN_ASSOCIATED_CONSTANT,
ELIDED_LIFETIMES_IN_PATHS,
@ -1627,6 +1628,41 @@ declare_lint! {
"detect mut variables which don't need to be mutable"
}
declare_lint! {
/// The `dereferencing_mut_binding` lint detects a `mut x` pattern that resets the binding mode,
/// as this behavior will change in rust 2024.
///
/// ### Example
///
/// ```rust
/// # #![warn(dereferencing_mut_binding)]
/// let x = Some(123u32);
/// let _y = match &x {
/// Some(mut x) => {
/// x += 1;
/// x
/// }
/// None => 0,
/// };
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// Without the `mut`, `x` would have type `&u32`. Pre-2024, adding `mut` makes `x` have type
/// `u32`, which was deeped surprising. After edition 2024, adding `mut` will not change the
/// type of `x`. This lint warns users of editions before 2024 to update their code.
pub DEREFERENCING_MUT_BINDING,
Allow,
"detects `mut x` bindings that change the type of `x`",
@feature_gate = sym::mut_dont_reset_binding_mode_2024;
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024),
reference: "123076",
};
}
declare_lint! {
/// The `unconditional_recursion` lint detects functions that cannot
/// return without calling themselves.

View File

@ -0,0 +1,18 @@
//@ edition: 2021
#![feature(mut_dont_reset_binding_mode_2024)]
#![allow(unused)]
#![forbid(dereferencing_mut_binding)]
struct Foo(u8);
fn main() {
let Foo(mut a) = &Foo(0);
//~^ ERROR: dereferencing `mut` binding
//~| WARN: this changes meaning in Rust 2024
a = 42;
let Foo(mut a) = &mut Foo(0);
//~^ ERROR: dereferencing `mut` binding
//~| WARN: this changes meaning in Rust 2024
a = 42;
}

View File

@ -0,0 +1,35 @@
error: dereferencing `mut` binding
--> $DIR/mut_dont_reset_binding_mode_2024_lint.rs:9:13
|
LL | let Foo(mut a) = &Foo(0);
| ^^^^^ `mut` dereferences the type of this binding
|
= warning: this changes meaning in Rust 2024
= note: for more information, see 123076
help: this will change in edition 2024
--> $DIR/mut_dont_reset_binding_mode_2024_lint.rs:9:13
|
LL | let Foo(mut a) = &Foo(0);
| ^^^^^
note: the lint level is defined here
--> $DIR/mut_dont_reset_binding_mode_2024_lint.rs:4:11
|
LL | #![forbid(dereferencing_mut_binding)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: dereferencing `mut` binding
--> $DIR/mut_dont_reset_binding_mode_2024_lint.rs:14:13
|
LL | let Foo(mut a) = &mut Foo(0);
| ^^^^^ `mut` dereferences the type of this binding
|
= warning: this changes meaning in Rust 2024
= note: for more information, see 123076
help: this will change in edition 2024
--> $DIR/mut_dont_reset_binding_mode_2024_lint.rs:14:13
|
LL | let Foo(mut a) = &mut Foo(0);
| ^^^^^
error: aborting due to 2 previous errors