diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index 00775647ac61a..c52dbd892bf4a 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -126,7 +126,7 @@ fn lints_that_dont_need_to_run(tcx: TyCtxt<'_>, (): ()) -> UnordSet { .filter(|lint| { // Lints that show up in future-compat reports must always be run. let has_future_breakage = - lint.future_incompatible.is_some_and(|fut| fut.reason.has_future_breakage()); + lint.future_incompatible.is_some_and(|fut| fut.report_in_deps); !has_future_breakage && !lint.eval_always }) .filter(|lint| { diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 7c7ba85d4848c..1b14157c5f0e6 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -178,8 +178,9 @@ declare_lint! { Warn, "applying forbid to lint-groups", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps, + reason: FutureIncompatibilityReason::FutureReleaseError, reference: "issue #81670 ", + report_in_deps: true, }; } @@ -214,7 +215,7 @@ declare_lint! { Deny, "ill-formed attribute inputs that were previously accepted and used in practice", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps, + reason: FutureIncompatibilityReason::FutureReleaseError, reference: "issue #57571 ", }; crate_level_only @@ -251,8 +252,9 @@ declare_lint! { Deny, "conflicts between `#[repr(..)]` hints that were previously accepted and used in practice", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps, + reason: FutureIncompatibilityReason::FutureReleaseError, reference: "issue #68585 ", + report_in_deps: true, }; } @@ -1240,8 +1242,9 @@ declare_lint! { Deny, "detect public re-exports of private extern crates", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps, + reason: FutureIncompatibilityReason::FutureReleaseError, reference: "issue #127909 ", + report_in_deps: true, }; } @@ -1270,8 +1273,9 @@ declare_lint! { Deny, "type parameter default erroneously allowed in invalid location", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps, + reason: FutureIncompatibilityReason::FutureReleaseError, reference: "issue #36887 ", + report_in_deps: true, }; } @@ -1409,7 +1413,7 @@ declare_lint! { Deny, "patterns in functions without body were erroneously allowed", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps, + reason: FutureIncompatibilityReason::FutureReleaseError, reference: "issue #35203 ", }; } @@ -1453,8 +1457,9 @@ declare_lint! { Deny, "detects missing fragment specifiers in unused `macro_rules!` patterns", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps, + reason: FutureIncompatibilityReason::FutureReleaseError, reference: "issue #40107 ", + report_in_deps: true, }; } @@ -1495,7 +1500,7 @@ declare_lint! { Warn, "detects generic lifetime arguments in path segments with late bound lifetime parameters", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps, + reason: FutureIncompatibilityReason::FutureReleaseError, reference: "issue #42868 ", }; } @@ -2122,8 +2127,9 @@ declare_lint! { Deny, "detects proc macro derives using inaccessible names from parent modules", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps, + reason: FutureIncompatibilityReason::FutureReleaseError, reference: "issue #83583 ", + report_in_deps: true, }; } @@ -2225,7 +2231,7 @@ declare_lint! { "macro-expanded `macro_export` macros from the current crate \ cannot be referred to by absolute paths", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps, + reason: FutureIncompatibilityReason::FutureReleaseError, reference: "issue #52234 ", }; crate_level_only @@ -2346,7 +2352,7 @@ declare_lint! { Deny, "ambiguous associated items", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps, + reason: FutureIncompatibilityReason::FutureReleaseError, reference: "issue #57644 ", }; } @@ -2362,8 +2368,9 @@ declare_lint! { Deny, "a feature gate that doesn't break dependent crates", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps, + reason: FutureIncompatibilityReason::FutureReleaseError, reference: "issue #64266 ", + report_in_deps: true, }; } @@ -2674,7 +2681,7 @@ declare_lint! { Warn, "detects a generic constant is used in a type without a emitting a warning", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps, + reason: FutureIncompatibilityReason::FutureReleaseError, reference: "issue #76200 ", }; } @@ -2733,7 +2740,7 @@ declare_lint! { Warn, "uninhabited static", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps, + reason: FutureIncompatibilityReason::FutureReleaseError, reference: "issue #74840 ", }; } @@ -2866,7 +2873,7 @@ declare_lint! { Warn, "detect unsupported use of `Self` from outer item", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps, + reason: FutureIncompatibilityReason::FutureReleaseError, reference: "issue #124186 ", }; } @@ -2912,8 +2919,9 @@ declare_lint! { Warn, "trailing semicolon in macro body used as expression", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps, + reason: FutureIncompatibilityReason::FutureReleaseError, reference: "issue #79813 ", + report_in_deps: true, }; } @@ -2959,7 +2967,7 @@ declare_lint! { Warn, "detects derive helper attributes that are used before they are introduced", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps, + reason: FutureIncompatibilityReason::FutureReleaseError, reference: "issue #79202 ", }; } @@ -3126,7 +3134,7 @@ declare_lint! { Warn, "transparent type contains an external ZST that is marked #[non_exhaustive] or contains private fields", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps, + reason: FutureIncompatibilityReason::FutureReleaseError, reference: "issue #78586 ", }; } @@ -3177,7 +3185,7 @@ declare_lint! { Warn, "unstable syntax can change at any point in the future, causing a hard error!", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps, + reason: FutureIncompatibilityReason::FutureReleaseError, reference: "issue #65860 ", }; } @@ -3685,8 +3693,9 @@ declare_lint! { Warn, "use of unsupported calling convention for function pointer", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps, + reason: FutureIncompatibilityReason::FutureReleaseError, reference: "issue #130260 ", + report_in_deps: true, }; } @@ -4368,7 +4377,7 @@ declare_lint! { Warn, "detects certain glob imports that require reporting an ambiguity error", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps, + reason: FutureIncompatibilityReason::FutureReleaseError, reference: "issue #114095 ", }; } @@ -4523,7 +4532,7 @@ declare_lint! { Deny, "elided lifetimes cannot be used in associated constants in impls", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps, + reason: FutureIncompatibilityReason::FutureReleaseError, reference: "issue #115010 ", }; } @@ -4570,7 +4579,7 @@ declare_lint! { Warn, "detects certain macro bindings that should not be re-exported", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps, + reason: FutureIncompatibilityReason::FutureReleaseError, reference: "issue #120192 ", }; } @@ -4635,7 +4644,7 @@ declare_lint! { Warn, "impl contains type parameters that are not covered", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps, + reason: FutureIncompatibilityReason::FutureReleaseError, reference: "issue #124559 ", }; } @@ -4799,7 +4808,7 @@ declare_lint! { Warn, "detects out of scope calls to `macro_rules` in key-value attributes", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps, + reason: FutureIncompatibilityReason::FutureReleaseError, reference: "issue #124535 ", }; } @@ -5040,8 +5049,9 @@ declare_lint! { Warn, "detects code relying on rustc's non-spec-compliant wasm C ABI", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps, + reason: FutureIncompatibilityReason::FutureReleaseError, reference: "issue #138762 ", + report_in_deps: true, }; } @@ -5081,7 +5091,8 @@ declare_lint! { Warn, "detects code that could be affected by ABI issues on aarch64 softfloat targets", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps, + reason: FutureIncompatibilityReason::FutureReleaseError, reference: "issue #134375 ", + report_in_deps: true, }; } diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 6cbdc245d2125..e19bf59e5432d 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -361,6 +361,18 @@ pub struct FutureIncompatibleInfo { /// Set to false for lints that already include a more detailed /// explanation. pub explain_reason: bool, + /// If set to `true`, this will make future incompatibility warnings show up in cargo's + /// reports. + /// + /// When a future incompatibility warning is first inroduced, set this to `false` + /// (or, rather, don't override the default). This allows crate developers an opportunity + /// to fix the warning before blasting all dependents with a warning they can't fix + /// (dependents have to wait for a new release of the affected crate to be published). + /// + /// After a lint has been in this state for a while, consider setting this to true, so it + /// warns for everyone. It is a good signal that it is ready if you can determine that all + /// or most affected crates on crates.io have been updated. + pub report_in_deps: bool, } /// The reason for future incompatibility @@ -380,46 +392,24 @@ pub struct FutureIncompatibleInfo { pub enum FutureIncompatibilityReason { /// This will be an error in a future release for all editions /// - /// This will *not* show up in cargo's future breakage report. - /// The warning will hence only be seen in local crates, not in dependencies. - /// /// Choose this variant when you are first introducing a "future /// incompatible" warning that is intended to eventually be fixed in the - /// future. This allows crate developers an opportunity to fix the warning - /// before blasting all dependents with a warning they can't fix - /// (dependents have to wait for a new release of the affected crate to be - /// published). - /// - /// After a lint has been in this state for a while, consider graduating - /// it to [`FutureIncompatibilityReason::FutureReleaseErrorReportInDeps`]. - FutureReleaseErrorDontReportInDeps, - /// This will be an error in a future release, and - /// Cargo should create a report even for dependencies + /// future. /// - /// This is the *only* reason that will make future incompatibility warnings show up in cargo's - /// reports. All other future incompatibility warnings are not visible when they occur in a - /// dependency. - /// - /// Choose this variant after the lint has been sitting in the - /// [`FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps`] - /// state for a while, and you feel like it is ready to graduate to - /// warning everyone. It is a good signal that it is ready if you can - /// determine that all or most affected crates on crates.io have been - /// updated. + /// After a lint has been in this state for a while and you feel like it is ready to graduate + /// to warning everyone, consider setting [`FutureIncompatibleInfo::report_in_deps`] to true. + /// (see it's documentation for more guidance) /// /// After some period of time, lints with this variant can be turned into /// hard errors (and the lint removed). Preferably when there is some /// confidence that the number of impacted projects is very small (few /// should have a broken dependency in their dependency tree). - /// - /// [`EditionAndFutureReleaseError`]: FutureIncompatibilityReason::EditionAndFutureReleaseError - FutureReleaseErrorReportInDeps, + FutureReleaseError, /// Code that changes meaning in some way in a /// future release. /// /// Choose this variant when the semantics of existing code is changing, - /// (as opposed to - /// [`FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps`], + /// (as opposed to [`FutureIncompatibilityReason::FutureReleaseError`], /// which is for when code is going to be rejected in the future). FutureReleaseSemanticsChange, /// Previously accepted code that will become an @@ -454,13 +444,12 @@ pub enum FutureIncompatibilityReason { /// This will be an error in the provided edition *and* in a future /// release. /// - /// This variant a combination of [`FutureReleaseErrorDontReportInDeps`] - /// and [`EditionError`]. This is useful in rare cases when we - /// want to have "preview" of a breaking change in an edition, but do a - /// breaking change later on all editions anyway. + /// This variant a combination of [`FutureReleaseError`] and [`EditionError`]. + /// This is useful in rare cases when we want to have "preview" of a breaking + /// change in an edition, but do a breaking change later on all editions anyway. /// /// [`EditionError`]: FutureIncompatibilityReason::EditionError - /// [`FutureReleaseErrorDontReportInDeps`]: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps + /// [`FutureReleaseError`]: FutureIncompatibilityReason::FutureReleaseError EditionAndFutureReleaseError(Edition), /// This will change meaning in the provided edition *and* in a future /// release. @@ -478,7 +467,7 @@ pub enum FutureIncompatibilityReason { /// Choose this variant if the built-in text of the diagnostic of the /// other variants doesn't match your situation. This is behaviorally /// equivalent to - /// [`FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps`]. + /// [`FutureIncompatibilityReason::FutureReleaseError`]. Custom(&'static str), } @@ -490,34 +479,20 @@ impl FutureIncompatibilityReason { | Self::EditionAndFutureReleaseError(e) | Self::EditionAndFutureReleaseSemanticsChange(e) => Some(e), - FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps - | FutureIncompatibilityReason::FutureReleaseErrorReportInDeps + FutureIncompatibilityReason::FutureReleaseError | FutureIncompatibilityReason::FutureReleaseSemanticsChange | FutureIncompatibilityReason::Custom(_) => None, } } - - pub fn has_future_breakage(self) -> bool { - match self { - FutureIncompatibilityReason::FutureReleaseErrorReportInDeps => true, - - FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps - | FutureIncompatibilityReason::FutureReleaseSemanticsChange - | FutureIncompatibilityReason::EditionError(_) - | FutureIncompatibilityReason::EditionSemanticsChange(_) - | FutureIncompatibilityReason::EditionAndFutureReleaseError(_) - | FutureIncompatibilityReason::EditionAndFutureReleaseSemanticsChange(_) - | FutureIncompatibilityReason::Custom(_) => false, - } - } } impl FutureIncompatibleInfo { pub const fn default_fields_for_macro() -> Self { FutureIncompatibleInfo { reference: "", - reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps, + reason: FutureIncompatibilityReason::FutureReleaseError, explain_reason: true, + report_in_deps: false, } } } diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index d5a408fdfa6a3..341a735f88fe0 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -299,7 +299,7 @@ pub fn lint_level( let has_future_breakage = future_incompatible.map_or( // Default allow lints trigger too often for testing. sess.opts.unstable_opts.future_incompat_test && lint.default_level != Level::Allow, - |incompat| incompat.reason.has_future_breakage(), + |incompat| incompat.report_in_deps, ); // Convert lint level to error level. @@ -370,8 +370,7 @@ pub fn lint_level( if let Some(future_incompatible) = future_incompatible { let explanation = match future_incompatible.reason { - FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps - | FutureIncompatibilityReason::FutureReleaseErrorReportInDeps => { + FutureIncompatibilityReason::FutureReleaseError => { "this was previously accepted by the compiler but is being phased out; \ it will become a hard error in a future release!" .to_owned()