diff options
| author | bors <bors@rust-lang.org> | 2023-10-26 06:59:19 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-10-26 06:59:19 +0000 |
| commit | 3e05710beebe0ecfcd849aea3ce8efd5000d381c (patch) | |
| tree | 2525428b2bd672ac424eb7ff9e6cc6091beb3c79 | |
| parent | d9148904e0c7ff2c41e5bc355909bb67ba94c23f (diff) | |
| parent | 76d7af0df1e35df45f6e37a20528f4da6264de72 (diff) | |
| download | rust-3e05710beebe0ecfcd849aea3ce8efd5000d381c.tar.gz rust-3e05710beebe0ecfcd849aea3ce8efd5000d381c.zip | |
Auto merge of #117148 - dtolnay:sinceversion, r=cjgillot
Store #[stable] attribute's `since` value in structured form Followup to https://github.com/rust-lang/rust/pull/116773#pullrequestreview-1680913901. Prior to this PR, if you wrote an improper `since` version in a `stable` attribute, such as `#[stable(feature = "foo", since = "wat.0")]`, rustc would emit a diagnostic saying **_'since' must be a Rust version number, such as "1.31.0"_** and then throw out the whole `stable` attribute as if it weren't there. This strategy had 2 problems, both fixed in this PR: 1. If there was also a `#[deprecated]` attribute on the same item, rustc would want to enforce that the stabilization version is older than the deprecation version. This involved reparsing the `stable` attribute's `since` version, with a diagnostic **_invalid stability version found_** if it failed to parse. Of course this diagnostic was unreachable because an invalid `since` version would have already caused the `stable` attribute to be thrown out. This PR deletes that unreachable diagnostic. 2. By throwing out the `stable` attribute when `since` is invalid, you'd end up with a second diagnostic saying **_function has missing stability attribute_** even though your function is not missing a stability attribute. This PR preserves the `stable` attribute even when `since` cannot be parsed, avoiding the misleading second diagnostic. Followups I plan to try next: - Do the same for the `since` value of `#[deprecated]`. - See whether it makes sense to also preserve `stable` and/or `unstable` attributes when they contain an invalid `feature`. What redundant/misleading diagnostics can this eliminate? What problems arise from not having a usable feature name for some API, in the situation that we're already failing compilation, so not concerned about anything that happens in downstream code?
| -rw-r--r-- | clippy_utils/src/qualify_min_const_fn.rs | 30 |
1 files changed, 18 insertions, 12 deletions
diff --git a/clippy_utils/src/qualify_min_const_fn.rs b/clippy_utils/src/qualify_min_const_fn.rs index f6096ea546d..1e465ac91b7 100644 --- a/clippy_utils/src/qualify_min_const_fn.rs +++ b/clippy_utils/src/qualify_min_const_fn.rs @@ -5,6 +5,7 @@ use crate::msrvs::Msrv; use hir::LangItem; +use rustc_attr::{Since, CURRENT_RUSTC_VERSION}; use rustc_const_eval::transform::check_consts::ConstCx; use rustc_hir as hir; use rustc_hir::def_id::DefId; @@ -370,19 +371,24 @@ fn is_const_fn(tcx: TyCtxt<'_>, def_id: DefId, msrv: &Msrv) -> bool { // function could be removed if `rustc` provided a MSRV-aware version of `is_const_fn`. // as a part of an unimplemented MSRV check https://github.com/rust-lang/rust/issues/65262. - // HACK(nilstrieb): CURRENT_RUSTC_VERSION can return versions like 1.66.0-dev. `rustc-semver` - // doesn't accept the `-dev` version number so we have to strip it off. - let short_version = since - .as_str() - .split('-') - .next() - .expect("rustc_attr::StabilityLevel::Stable::since` is empty"); + let const_stab_rust_version = match since { + Since::Version(version) => RustcVersion::new( + u32::from(version.major), + u32::from(version.minor), + u32::from(version.patch), + ), + Since::Current => { + // HACK(nilstrieb): CURRENT_RUSTC_VERSION can return versions like 1.66.0-dev. + // `rustc-semver` doesn't accept the `-dev` version number so we have to strip it off. + let short_version = CURRENT_RUSTC_VERSION.split('-').next().unwrap(); + RustcVersion::parse(short_version).unwrap_or_else(|err| { + panic!("`rustc_attr::StabilityLevel::Stable::since` is ill-formatted: `{CURRENT_RUSTC_VERSION}`, {err:?}") + }) + }, + Since::Err => return false, + }; - let since = rustc_span::Symbol::intern(short_version); - - msrv.meets(RustcVersion::parse(since.as_str()).unwrap_or_else(|err| { - panic!("`rustc_attr::StabilityLevel::Stable::since` is ill-formatted: `{since}`, {err:?}") - })) + msrv.meets(const_stab_rust_version) } else { // Unstable const fn with the feature enabled. msrv.current().is_none() |
