/// Checks whether an item marked with `deprecated(since="X")` is currently
/// deprecated (i.e., whether X is not greater than the current rustc version).
pub fn deprecation_in_effect(is_since_rustc_version: bool, since: Option<&str>) -> bool {
- let since = if let Some(since) = since {
- if is_since_rustc_version {
- since
- } else {
- // We assume that the deprecation is in effect if it's not a
- // rustc version.
- return true;
- }
- } else {
- // If since attribute is not set, then we're definitely in effect.
- return true;
- };
fn parse_version(ver: &str) -> Vec<u32> {
// We ignore non-integer components of the version (e.g., "nightly").
ver.split(|c| c == '.' || c == '-').flat_map(|s| s.parse()).collect()
}
- if let Some(rustc) = option_env!("CFG_RELEASE") {
- let since: Vec<u32> = parse_version(&since);
- let rustc: Vec<u32> = parse_version(rustc);
- // We simply treat invalid `since` attributes as relating to a previous
- // Rust version, thus always displaying the warning.
- if since.len() != 3 {
- return true;
- }
- since <= rustc
- } else {
- // By default, a deprecation warning applies to
- // the current version of the compiler.
- true
+ if !is_since_rustc_version {
+ // The `since` field doesn't have semantic purpose in the stable `deprecated`
+ // attribute, only in `rustc_deprecated`.
+ return true;
}
+
+ if let Some(since) = since {
+ if since == "TBD" {
+ return false;
+ }
+
+ if let Some(rustc) = option_env!("CFG_RELEASE") {
+ let since: Vec<u32> = parse_version(&since);
+ let rustc: Vec<u32> = parse_version(rustc);
+ // We simply treat invalid `since` attributes as relating to a previous
+ // Rust version, thus always displaying the warning.
+ if since.len() != 3 {
+ return true;
+ }
+ return since <= rustc;
+ }
+ };
+
+ // Assume deprecation is in effect if "since" field is missing
+ // or if we can't determine the current Rust version.
+ true
}
pub fn deprecation_suggestion(
}
pub fn deprecation_message(depr: &Deprecation, kind: &str, path: &str) -> (String, &'static Lint) {
- let (message, lint) = if deprecation_in_effect(
- depr.is_since_rustc_version,
- depr.since.map(Symbol::as_str).as_deref(),
- ) {
+ let since = depr.since.map(Symbol::as_str);
+ let (message, lint) = if deprecation_in_effect(depr.is_since_rustc_version, since.as_deref()) {
(format!("use of deprecated {} `{}`", kind, path), DEPRECATED)
} else {
(
- format!(
- "use of {} `{}` that will be deprecated in future version {}",
- kind,
- path,
- depr.since.unwrap()
- ),
+ if since.as_deref() == Some("TBD") {
+ format!(
+ "use of {} `{}` that will be deprecated in a future Rust version",
+ kind, path
+ )
+ } else {
+ format!(
+ "use of {} `{}` that will be deprecated in future version {}",
+ kind,
+ path,
+ since.unwrap()
+ )
+ },
DEPRECATED_IN_FUTURE,
)
};
for (dep_v, stab_v) in
dep_since.as_str().split('.').zip(stab_since.as_str().split('.'))
{
- if let (Ok(dep_v), Ok(stab_v)) = (dep_v.parse::<u64>(), stab_v.parse()) {
- match dep_v.cmp(&stab_v) {
- Ordering::Less => {
- self.tcx.sess.span_err(
- item_sp,
- "An API can't be stabilized \
- after it is deprecated",
- );
+ match stab_v.parse::<u64>() {
+ Err(_) => {
+ self.tcx.sess.span_err(item_sp, "Invalid stability version found");
+ break;
+ }
+ Ok(stab_vp) => match dep_v.parse::<u64>() {
+ Ok(dep_vp) => match dep_vp.cmp(&stab_vp) {
+ Ordering::Less => {
+ self.tcx.sess.span_err(
+ item_sp,
+ "An API can't be stabilized after it is deprecated",
+ );
+ break;
+ }
+ Ordering::Equal => continue,
+ Ordering::Greater => break,
+ },
+ Err(_) => {
+ if dep_v != "TBD" {
+ self.tcx
+ .sess
+ .span_err(item_sp, "Invalid deprecation version found");
+ }
break;
}
- Ordering::Equal => continue,
- Ordering::Greater => break,
- }
- } else {
- // Act like it isn't less because the question is now nonsensical,
- // and this makes us not do anything else interesting.
- self.tcx.sess.span_err(
- item_sp,
- "Invalid stability or deprecation \
- version found",
- );
- break;
+ },
}
}
}
let mut message = if let Some(since) = since {
let since = &since.as_str();
if !stability::deprecation_in_effect(is_since_rustc_version, Some(since)) {
- format!("Deprecating in {}", Escape(since))
+ if *since == "TBD" {
+ format!("Deprecating in a future Rust version")
+ } else {
+ format!("Deprecating in {}", Escape(since))
+ }
} else {
format!("Deprecated since {}", Escape(since))
}
// @has rustc_deprecated_future/index.html '//*[@class="stab deprecated"]' \
// 'Deprecation planned'
-// @has rustc_deprecated_future/struct.S.html '//*[@class="stab deprecated"]' \
+// @has rustc_deprecated_future/struct.S1.html '//*[@class="stab deprecated"]' \
// 'Deprecating in 99.99.99: effectively never'
#[rustc_deprecated(since = "99.99.99", reason = "effectively never")]
#[stable(feature = "rustc_deprecated-future-test", since = "1.0.0")]
-pub struct S;
+pub struct S1;
+
+// @has rustc_deprecated_future/index.html '//*[@class="stab deprecated"]' \
+// 'Deprecation planned'
+// @has rustc_deprecated_future/struct.S2.html '//*[@class="stab deprecated"]' \
+// 'Deprecating in a future Rust version: literally never'
+#[rustc_deprecated(since = "TBD", reason = "literally never")]
+#[stable(feature = "rustc_deprecated-future-test", since = "1.0.0")]
+pub struct S2;
#[rustc_deprecated(since = "99.99.99", reason = "effectively never")]
#[stable(feature = "rustc_deprecation-in-future-test", since = "1.0.0")]
-pub struct S;
+pub struct S1;
+
+#[rustc_deprecated(since = "TBD", reason = "literally never")]
+#[stable(feature = "rustc_deprecation-in-future-test", since = "1.0.0")]
+pub struct S2;
fn main() {
- let _ = S; //~ ERROR use of unit struct `S` that will be deprecated in future version 99.99.99: effectively never
+ let _ = S1; //~ ERROR use of unit struct `S1` that will be deprecated in future version 99.99.99: effectively never
+ let _ = S2; //~ ERROR use of unit struct `S2` that will be deprecated in a future Rust version: literally never
}
-error: use of unit struct `S` that will be deprecated in future version 99.99.99: effectively never
- --> $DIR/rustc_deprecation-in-future.rs:14:13
+error: use of unit struct `S1` that will be deprecated in future version 99.99.99: effectively never
+ --> $DIR/rustc_deprecation-in-future.rs:18:13
|
-LL | let _ = S;
- | ^
+LL | let _ = S1;
+ | ^^
|
note: the lint level is defined here
--> $DIR/rustc_deprecation-in-future.rs:3:9
LL | #![deny(deprecated_in_future)]
| ^^^^^^^^^^^^^^^^^^^^
-error: aborting due to previous error
+error: use of unit struct `S2` that will be deprecated in a future Rust version: literally never
+ --> $DIR/rustc_deprecation-in-future.rs:19:13
+ |
+LL | let _ = S2;
+ | ^^
+
+error: aborting due to 2 previous errors
#[rustc_const_unstable(feature = "c", issue = "none")]
#[rustc_const_unstable(feature = "d", issue = "none")] //~ ERROR multiple stability levels
pub const fn multiple4() { }
-//~^ ERROR Invalid stability or deprecation version found
+//~^ ERROR Invalid stability version found
+
+#[stable(feature = "a", since = "1.0.0")]
+#[rustc_deprecated(since = "invalid", reason = "text")]
+fn invalid_deprecation_version() {} //~ ERROR Invalid deprecation version found
#[rustc_deprecated(since = "a", reason = "text")]
fn deprecated_without_unstable_or_stable() { }
LL | #[rustc_const_unstable(feature = "d", issue = "none")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: Invalid stability or deprecation version found
+error: Invalid stability version found
--> $DIR/stability-attribute-sanity.rs:65:1
|
LL | pub const fn multiple4() { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+error: Invalid deprecation version found
+ --> $DIR/stability-attribute-sanity.rs:70:1
+ |
+LL | fn invalid_deprecation_version() {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
error[E0549]: rustc_deprecated attribute must be paired with either stable or unstable attribute
- --> $DIR/stability-attribute-sanity.rs:68:1
+ --> $DIR/stability-attribute-sanity.rs:72:1
|
LL | #[rustc_deprecated(since = "a", reason = "text")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: aborting due to 18 previous errors
+error: aborting due to 19 previous errors
Some errors have detailed explanations: E0539, E0541, E0546, E0550.
For more information about an error, try `rustc --explain E0539`.