-// ignore-tidy-filelength
-
//! Some lints that are built in to the compiler.
//!
//! These are the built-in lints that are emitted direct in the main
Warn,
"suggest using `dyn Trait` for trait objects",
@future_incompatible = FutureIncompatibleInfo {
- reference: "issue #80165 <https://github.com/rust-lang/rust/issues/80165>",
+ reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>",
reason: FutureIncompatibilityReason::EditionError(Edition::Edition2021),
};
}
"detects deprecation attributes with no effect",
}
+declare_lint! {
+ /// The `undefined_naked_function_abi` lint detects naked function definitions that
+ /// either do not specify an ABI or specify the Rust ABI.
+ ///
+ /// ### Example
+ ///
+ /// ```rust
+ /// #![feature(naked_functions)]
+ /// #![feature(asm)]
+ ///
+ /// #[naked]
+ /// pub fn default_abi() -> u32 {
+ /// unsafe { asm!("", options(noreturn)); }
+ /// }
+ ///
+ /// #[naked]
+ /// pub extern "Rust" fn rust_abi() -> u32 {
+ /// unsafe { asm!("", options(noreturn)); }
+ /// }
+ /// ```
+ ///
+ /// {{produces}}
+ ///
+ /// ### Explanation
+ ///
+ /// The Rust ABI is currently undefined. Therefore, naked functions should
+ /// specify a non-Rust ABI.
+ pub UNDEFINED_NAKED_FUNCTION_ABI,
+ Warn,
+ "undefined naked function ABI"
+}
+
declare_lint! {
/// The `unsupported_naked_functions` lint detects naked function
/// definitions that are unsupported but were previously accepted.
/// #![feature(naked_functions)]
///
/// #[naked]
- /// pub fn f() -> u32 {
+ /// pub extern "C" fn f() -> u32 {
/// 42
/// }
/// ```
/// The asm block must not contain any operands other than `const` and
/// `sym`. Additionally, naked function should specify a non-Rust ABI.
///
+ /// Naked functions cannot be inlined. All forms of the `inline` attribute
+ /// are prohibited.
+ ///
/// While other definitions of naked functions were previously accepted,
/// they are unsupported and might not work reliably. This is a
/// [future-incompatible] lint that will transition into hard error in
/// [issue #79813]: https://github.com/rust-lang/rust/issues/79813
/// [future-incompatible]: ../index.md#future-incompatible-lints
pub SEMICOLON_IN_EXPRESSIONS_FROM_MACROS,
- Allow,
+ Warn,
"trailing semicolon in macro body used as expression",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #79813 <https://github.com/rust-lang/rust/issues/79813>",
RUST_2021_PRELUDE_COLLISIONS,
RUST_2021_PREFIXES_INCOMPATIBLE_SYNTAX,
UNSUPPORTED_CALLING_CONVENTIONS,
+ BREAK_WITH_LABEL_AND_LOOP,
+ UNUSED_ATTRIBUTES,
]
}
declare_lint! {
/// The `rust_2021_incompatible_closure_captures` lint detects variables that aren't completely
- /// captured in Rust 2021 and affect the Drop order of at least one path starting at this variable.
- /// It can also detect when a variable implements a trait, but one of its field does not and
- /// the field is captured by a closure and used with the assumption that said field implements
+ /// captured in Rust 2021, such that the `Drop` order of their fields may differ between
+ /// Rust 2018 and 2021.
+ ///
+ /// It can also detect when a variable implements a trait like `Send`, but one of its fields does not,
+ /// and the field is captured by a closure and used with the assumption that said field implements
/// the same trait as the root variable.
///
/// ### Example of drop reorder
///
/// ```rust,compile_fail
- /// # #![deny(rust_2021_incompatible_closure_captures)]
+ /// #![deny(rust_2021_incompatible_closure_captures)]
/// # #![allow(unused)]
+ ///
/// struct FancyInteger(i32);
///
/// impl Drop for FancyInteger {
/// ### Explanation
///
/// In the above example, only `fptr.0` is captured in Rust 2021.
- /// The field is of type *mut i32 which doesn't implement Send, making the code invalid as the
- /// field cannot be sent between thread safely.
+ /// The field is of type `*mut i32`, which doesn't implement `Send`,
+ /// making the code invalid as the field cannot be sent between threads safely.
pub RUST_2021_INCOMPATIBLE_CLOSURE_CAPTURES,
Allow,
"detects closures affected by Rust 2021 changes",
///
/// ```rust,compile_fail
/// #![deny(rust_2021_incompatible_or_patterns)]
+ ///
/// macro_rules! match_any {
/// ( $expr:expr , $( $( $pat:pat )|+ => $expr_arm:expr ),+ ) => {
/// match $expr {
///
/// ### Explanation
///
- /// In Rust 2021, the pat matcher will match new patterns, which include the | character.
+ /// In Rust 2021, the `pat` matcher will match additional patterns, which include the `|` character.
pub RUST_2021_INCOMPATIBLE_OR_PATTERNS,
Allow,
"detects usage of old versions of or-patterns",
@future_incompatible = FutureIncompatibleInfo {
- reference: "issue #84869 <https://github.com/rust-lang/rust/issues/84869>",
+ reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2021/or-patterns-macro-rules.html>",
reason: FutureIncompatibilityReason::EditionError(Edition::Edition2021),
};
}
/// In Rust 2021, one of the important introductions is the [prelude changes], which add
/// `TryFrom`, `TryInto`, and `FromIterator` into the standard library's prelude. Since this
/// results in an ambiguity as to which method/function to call when an existing `try_into`
- /// method is called via dot-call syntax or a `try_from`/`from_iter` associated function
- /// is called directly on a type.
+ /// method is called via dot-call syntax or a `try_from`/`from_iter` associated function
+ /// is called directly on a type.
///
/// [prelude changes]: https://blog.rust-lang.org/inside-rust/2021/03/04/planning-rust-2021.html#prelude-changes
pub RUST_2021_PRELUDE_COLLISIONS,
"detects the usage of trait methods which are ambiguous with traits added to the \
prelude in future editions",
@future_incompatible = FutureIncompatibleInfo {
- reference: "issue #85684 <https://github.com/rust-lang/rust/issues/85684>",
+ reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>",
reason: FutureIncompatibilityReason::EditionError(Edition::Edition2021),
};
}
Allow,
"identifiers that will be parsed as a prefix in Rust 2021",
@future_incompatible = FutureIncompatibleInfo {
- reference: "issue #84978 <https://github.com/rust-lang/rust/issues/84978>",
+ reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2021/reserving-syntax.html>",
reason: FutureIncompatibilityReason::EditionError(Edition::Edition2021),
};
crate_level_only
}
declare_lint! {
- /// The `unsupported_calling_conventions` lint is output whenever there is an use of the
+ /// The `unsupported_calling_conventions` lint is output whenever there is a use of the
/// `stdcall`, `fastcall`, `thiscall`, `vectorcall` calling conventions (or their unwind
/// variants) on targets that cannot meaningfully be supported for the requested target.
///
reference: "issue #87678 <https://github.com/rust-lang/rust/issues/87678>",
};
}
+
+declare_lint! {
+ /// The `break_with_label_and_loop` lint detects labeled `break` expressions with
+ /// an unlabeled loop as their value expression.
+ ///
+ /// ### Example
+ ///
+ /// ```rust
+ /// 'label: loop {
+ /// break 'label loop { break 42; };
+ /// };
+ /// ```
+ ///
+ /// {{produces}}
+ ///
+ /// ### Explanation
+ ///
+ /// In Rust, loops can have a label, and `break` expressions can refer to that label to
+ /// break out of specific loops (and not necessarily the innermost one). `break` expressions
+ /// can also carry a value expression, which can be another loop. A labeled `break` with an
+ /// unlabeled loop as its value expression is easy to confuse with an unlabeled break with
+ /// a labeled loop and is thus discouraged (but allowed for compatibility); use parentheses
+ /// around the loop expression to silence this warning. Unlabeled `break` expressions with
+ /// labeled loops yield a hard error, which can also be silenced by wrapping the expression
+ /// in parentheses.
+ pub BREAK_WITH_LABEL_AND_LOOP,
+ Warn,
+ "`break` expression with label and unlabeled loop as value expression"
+}