From ffbf62c437ae9fe490051ae764b469791f831833 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 24 Apr 2024 16:30:05 +0000 Subject: [PATCH] Emit a future incompat lint when overwriting the function body --- compiler/rustc_lint_defs/src/builtin.rs | 29 +++++++++++++++++++++ compiler/rustc_mir_build/messages.ftl | 3 +++ compiler/rustc_mir_build/src/build/mod.rs | 10 +++++++ compiler/rustc_mir_build/src/errors.rs | 7 +++++ tests/ui/feature-gates/version_check.rs | 2 ++ tests/ui/feature-gates/version_check.stderr | 17 ++++++++++++ 6 files changed, 68 insertions(+) create mode 100644 tests/ui/feature-gates/version_check.stderr diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index e74cc388cab4c..7e67e1d70170b 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -43,6 +43,7 @@ declare_lint_pass! { ELIDED_LIFETIMES_IN_ASSOCIATED_CONSTANT, ELIDED_LIFETIMES_IN_PATHS, EXPORTED_PRIVATE_DEPENDENCIES, + FEATURE_DETECTION, FFI_UNWIND_CALLS, FORBIDDEN_LINT_GROUPS, FUNCTION_ITEM_REFERENCES, @@ -176,6 +177,34 @@ declare_lint! { }; } +declare_lint! { + /// The `feature_detection` lint detects flawed ways to determine + /// whether nightly features can be enabled. + /// + /// ### Example + /// + /// The `version_check` crate's `supports_feature` function. + /// + /// ### Recommended fix + /// + /// Remove dependencies that rely on `version_check`. + /// + /// ### Explanation + /// + /// Detecting if the current compiler is a nightly compiler, without checking if + /// the feature + /// will actually work for the user. This means that updates to the feature + /// will arbitrarily break nightly users that did not opt-in to using nightly + /// features. + pub FEATURE_DETECTION, + Warn, + "applying forbid to lint-groups", + @future_incompatible = FutureIncompatibleInfo { + reason: FutureIncompatibilityReason::Custom("nightly feature detection is disabled"), + reference: "", + }; +} + declare_lint! { /// The `ill_formed_attribute_input` lint detects ill-formed attribute /// inputs that were previously accepted and used in practice. diff --git a/compiler/rustc_mir_build/messages.ftl b/compiler/rustc_mir_build/messages.ftl index 34440c60cf378..fab6df7ff8a55 100644 --- a/compiler/rustc_mir_build/messages.ftl +++ b/compiler/rustc_mir_build/messages.ftl @@ -109,6 +109,9 @@ mir_build_extern_static_requires_unsafe_unsafe_op_in_unsafe_fn_allowed = .note = extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior .label = use of extern static +mir_build_feature_detection = Rust language and library feature detection via `version_check::feature_enabled` does not actually check whether the feature works correctly + .note = the fucntion has been disabled and will always return `None` on a nightly compiler. + mir_build_indirect_structural_match = to use a constant of type `{$non_sm_ty}` in a pattern, `{$non_sm_ty}` must be annotated with `#[derive(PartialEq)]` diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index a90f459b1a93c..1423634b5631a 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -1,5 +1,6 @@ use crate::build::expr::as_place::PlaceBuilder; use crate::build::scope::DropKind; +use crate::errors::FeatureDetection; use hir::def_id::LOCAL_CRATE; use itertools::Itertools; use rustc_apfloat::ieee::{Double, Half, Quad, Single}; @@ -21,6 +22,7 @@ use rustc_middle::mir::*; use rustc_middle::query::TyCtxtAt; use rustc_middle::thir::{self, ExprId, LintLevel, LocalVarId, Param, ParamId, PatKind, Thir}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; +use rustc_session::lint; use rustc_span::symbol::sym; use rustc_span::Symbol; use rustc_span::{Span, DUMMY_SP}; @@ -535,6 +537,14 @@ fn construct_fn<'tcx>( ), ); builder.cfg.terminate(block, source_info, TerminatorKind::Return); + + tcx.emit_node_span_lint( + lint::builtin::FEATURE_DETECTION, + fn_id, + span, + FeatureDetection { span }, + ); + return builder.finish(); } diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index f67113afd6d9d..0777e9fc9bd8b 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -950,3 +950,10 @@ pub enum RustcBoxAttrReason { #[note(mir_build_missing_box)] MissingBox, } + +#[derive(LintDiagnostic)] +#[diag(mir_build_feature_detection)] +pub struct FeatureDetection { + #[note] + pub span: Span, +} diff --git a/tests/ui/feature-gates/version_check.rs b/tests/ui/feature-gates/version_check.rs index db72a05d94ac7..0344431d9c3a6 100644 --- a/tests/ui/feature-gates/version_check.rs +++ b/tests/ui/feature-gates/version_check.rs @@ -1,6 +1,8 @@ //@ run-pass fn supports_feature(_: &str) -> Option { + //~^ WARN:`version_check::feature_enabled` does not actually check + //~| WARN: nightly feature detection is disabled Some(true) } diff --git a/tests/ui/feature-gates/version_check.stderr b/tests/ui/feature-gates/version_check.stderr new file mode 100644 index 0000000000000..6c3f9b335e884 --- /dev/null +++ b/tests/ui/feature-gates/version_check.stderr @@ -0,0 +1,17 @@ +warning: Rust language and library feature detection via `version_check::feature_enabled` does not actually check whether the feature works correctly + --> $DIR/version_check.rs:3:1 + | +LL | fn supports_feature(_: &str) -> Option { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: nightly feature detection is disabled + = note: for more information, see TODO +note: the fucntion has been disabled and will always return `None` on a nightly compiler. + --> $DIR/version_check.rs:3:1 + | +LL | fn supports_feature(_: &str) -> Option { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: `#[warn(feature_detection)]` on by default + +warning: 1 warning emitted +