Skip to content

Commit 88e2ee1

Browse files
authored
Rollup merge of rust-lang#79877 - bstrie:depinfut, r=oli-obk
Allow `since="TBD"` for rustc_deprecated Closes rust-lang#78381. This PR only affects `#[rustc_deprecated]`, not `#[deprecated]`, so there is no effect on any stable language feature. Likewise this PR only implements `since="TBD"`, it does not actually tag any library functions with it, so there is no effect on any stable API. Overview of changes: * `rustc_middle/stability.rs`: * change `deprecation_in_effect` function to return `false` when `since="TBD"` * tidy up the compiler output when a deprecated item has `since="TBD"` * `rustc_passes/stability.rs`: * allow `since="TBD"` to pass the sanity check for stable_version < deprecated_version * refactor the "invalid stability version" and "invalid deprecation version" error into separate errors * rustdoc: make `since="TBD"` message on a deprecated item's page match the command-line deprecation output * tests: * test rustdoc output * test that the `deprecated_in_future` lint fires when `since="TBD"` * test the new "invalid deprecation version" error message
2 parents 3d8241d + 1e1ca28 commit 88e2ee1

File tree

8 files changed

+111
-69
lines changed

8 files changed

+111
-69
lines changed

compiler/rustc_middle/src/middle/stability.rs

+40-35
Original file line numberDiff line numberDiff line change
@@ -132,37 +132,37 @@ pub fn report_unstable(
132132
/// Checks whether an item marked with `deprecated(since="X")` is currently
133133
/// deprecated (i.e., whether X is not greater than the current rustc version).
134134
pub fn deprecation_in_effect(is_since_rustc_version: bool, since: Option<&str>) -> bool {
135-
let since = if let Some(since) = since {
136-
if is_since_rustc_version {
137-
since
138-
} else {
139-
// We assume that the deprecation is in effect if it's not a
140-
// rustc version.
141-
return true;
142-
}
143-
} else {
144-
// If since attribute is not set, then we're definitely in effect.
145-
return true;
146-
};
147135
fn parse_version(ver: &str) -> Vec<u32> {
148136
// We ignore non-integer components of the version (e.g., "nightly").
149137
ver.split(|c| c == '.' || c == '-').flat_map(|s| s.parse()).collect()
150138
}
151139

152-
if let Some(rustc) = option_env!("CFG_RELEASE") {
153-
let since: Vec<u32> = parse_version(&since);
154-
let rustc: Vec<u32> = parse_version(rustc);
155-
// We simply treat invalid `since` attributes as relating to a previous
156-
// Rust version, thus always displaying the warning.
157-
if since.len() != 3 {
158-
return true;
159-
}
160-
since <= rustc
161-
} else {
162-
// By default, a deprecation warning applies to
163-
// the current version of the compiler.
164-
true
140+
if !is_since_rustc_version {
141+
// The `since` field doesn't have semantic purpose in the stable `deprecated`
142+
// attribute, only in `rustc_deprecated`.
143+
return true;
165144
}
145+
146+
if let Some(since) = since {
147+
if since == "TBD" {
148+
return false;
149+
}
150+
151+
if let Some(rustc) = option_env!("CFG_RELEASE") {
152+
let since: Vec<u32> = parse_version(&since);
153+
let rustc: Vec<u32> = parse_version(rustc);
154+
// We simply treat invalid `since` attributes as relating to a previous
155+
// Rust version, thus always displaying the warning.
156+
if since.len() != 3 {
157+
return true;
158+
}
159+
return since <= rustc;
160+
}
161+
};
162+
163+
// Assume deprecation is in effect if "since" field is missing
164+
// or if we can't determine the current Rust version.
165+
true
166166
}
167167

168168
pub fn deprecation_suggestion(
@@ -182,19 +182,24 @@ pub fn deprecation_suggestion(
182182
}
183183

184184
pub fn deprecation_message(depr: &Deprecation, kind: &str, path: &str) -> (String, &'static Lint) {
185-
let (message, lint) = if deprecation_in_effect(
186-
depr.is_since_rustc_version,
187-
depr.since.map(Symbol::as_str).as_deref(),
188-
) {
185+
let since = depr.since.map(Symbol::as_str);
186+
let (message, lint) = if deprecation_in_effect(depr.is_since_rustc_version, since.as_deref()) {
189187
(format!("use of deprecated {} `{}`", kind, path), DEPRECATED)
190188
} else {
191189
(
192-
format!(
193-
"use of {} `{}` that will be deprecated in future version {}",
194-
kind,
195-
path,
196-
depr.since.unwrap()
197-
),
190+
if since.as_deref() == Some("TBD") {
191+
format!(
192+
"use of {} `{}` that will be deprecated in a future Rust version",
193+
kind, path
194+
)
195+
} else {
196+
format!(
197+
"use of {} `{}` that will be deprecated in future version {}",
198+
kind,
199+
path,
200+
since.unwrap()
201+
)
202+
},
198203
DEPRECATED_IN_FUTURE,
199204
)
200205
};

compiler/rustc_passes/src/stability.rs

+24-20
Original file line numberDiff line numberDiff line change
@@ -182,28 +182,32 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
182182
for (dep_v, stab_v) in
183183
dep_since.as_str().split('.').zip(stab_since.as_str().split('.'))
184184
{
185-
if let (Ok(dep_v), Ok(stab_v)) = (dep_v.parse::<u64>(), stab_v.parse()) {
186-
match dep_v.cmp(&stab_v) {
187-
Ordering::Less => {
188-
self.tcx.sess.span_err(
189-
item_sp,
190-
"An API can't be stabilized \
191-
after it is deprecated",
192-
);
185+
match stab_v.parse::<u64>() {
186+
Err(_) => {
187+
self.tcx.sess.span_err(item_sp, "Invalid stability version found");
188+
break;
189+
}
190+
Ok(stab_vp) => match dep_v.parse::<u64>() {
191+
Ok(dep_vp) => match dep_vp.cmp(&stab_vp) {
192+
Ordering::Less => {
193+
self.tcx.sess.span_err(
194+
item_sp,
195+
"An API can't be stabilized after it is deprecated",
196+
);
197+
break;
198+
}
199+
Ordering::Equal => continue,
200+
Ordering::Greater => break,
201+
},
202+
Err(_) => {
203+
if dep_v != "TBD" {
204+
self.tcx
205+
.sess
206+
.span_err(item_sp, "Invalid deprecation version found");
207+
}
193208
break;
194209
}
195-
Ordering::Equal => continue,
196-
Ordering::Greater => break,
197-
}
198-
} else {
199-
// Act like it isn't less because the question is now nonsensical,
200-
// and this makes us not do anything else interesting.
201-
self.tcx.sess.span_err(
202-
item_sp,
203-
"Invalid stability or deprecation \
204-
version found",
205-
);
206-
break;
210+
},
207211
}
208212
}
209213
}

src/librustdoc/html/render/mod.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -2279,7 +2279,11 @@ fn short_item_info(item: &clean::Item, cx: &Context, parent: Option<&clean::Item
22792279
let mut message = if let Some(since) = since {
22802280
let since = &since.as_str();
22812281
if !stability::deprecation_in_effect(is_since_rustc_version, Some(since)) {
2282-
format!("Deprecating in {}", Escape(since))
2282+
if *since == "TBD" {
2283+
format!("Deprecating in a future Rust version")
2284+
} else {
2285+
format!("Deprecating in {}", Escape(since))
2286+
}
22832287
} else {
22842288
format!("Deprecated since {}", Escape(since))
22852289
}

src/test/rustdoc/rustc_deprecated-future.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,16 @@
44

55
// @has rustc_deprecated_future/index.html '//*[@class="stab deprecated"]' \
66
// 'Deprecation planned'
7-
// @has rustc_deprecated_future/struct.S.html '//*[@class="stab deprecated"]' \
7+
// @has rustc_deprecated_future/struct.S1.html '//*[@class="stab deprecated"]' \
88
// 'Deprecating in 99.99.99: effectively never'
99
#[rustc_deprecated(since = "99.99.99", reason = "effectively never")]
1010
#[stable(feature = "rustc_deprecated-future-test", since = "1.0.0")]
11-
pub struct S;
11+
pub struct S1;
12+
13+
// @has rustc_deprecated_future/index.html '//*[@class="stab deprecated"]' \
14+
// 'Deprecation planned'
15+
// @has rustc_deprecated_future/struct.S2.html '//*[@class="stab deprecated"]' \
16+
// 'Deprecating in a future Rust version: literally never'
17+
#[rustc_deprecated(since = "TBD", reason = "literally never")]
18+
#[stable(feature = "rustc_deprecated-future-test", since = "1.0.0")]
19+
pub struct S2;

src/test/ui/deprecation/rustc_deprecation-in-future.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,13 @@
88

99
#[rustc_deprecated(since = "99.99.99", reason = "effectively never")]
1010
#[stable(feature = "rustc_deprecation-in-future-test", since = "1.0.0")]
11-
pub struct S;
11+
pub struct S1;
12+
13+
#[rustc_deprecated(since = "TBD", reason = "literally never")]
14+
#[stable(feature = "rustc_deprecation-in-future-test", since = "1.0.0")]
15+
pub struct S2;
1216

1317
fn main() {
14-
let _ = S; //~ ERROR use of unit struct `S` that will be deprecated in future version 99.99.99: effectively never
18+
let _ = S1; //~ ERROR use of unit struct `S1` that will be deprecated in future version 99.99.99: effectively never
19+
let _ = S2; //~ ERROR use of unit struct `S2` that will be deprecated in a future Rust version: literally never
1520
}
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,20 @@
1-
error: use of unit struct `S` that will be deprecated in future version 99.99.99: effectively never
2-
--> $DIR/rustc_deprecation-in-future.rs:14:13
1+
error: use of unit struct `S1` that will be deprecated in future version 99.99.99: effectively never
2+
--> $DIR/rustc_deprecation-in-future.rs:18:13
33
|
4-
LL | let _ = S;
5-
| ^
4+
LL | let _ = S1;
5+
| ^^
66
|
77
note: the lint level is defined here
88
--> $DIR/rustc_deprecation-in-future.rs:3:9
99
|
1010
LL | #![deny(deprecated_in_future)]
1111
| ^^^^^^^^^^^^^^^^^^^^
1212

13-
error: aborting due to previous error
13+
error: use of unit struct `S2` that will be deprecated in a future Rust version: literally never
14+
--> $DIR/rustc_deprecation-in-future.rs:19:13
15+
|
16+
LL | let _ = S2;
17+
| ^^
18+
19+
error: aborting due to 2 previous errors
1420

src/test/ui/stability-attribute/stability-attribute-sanity.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,11 @@ fn multiple3() { }
6363
#[rustc_const_unstable(feature = "c", issue = "none")]
6464
#[rustc_const_unstable(feature = "d", issue = "none")] //~ ERROR multiple stability levels
6565
pub const fn multiple4() { }
66-
//~^ ERROR Invalid stability or deprecation version found
66+
//~^ ERROR Invalid stability version found
67+
68+
#[stable(feature = "a", since = "1.0.0")]
69+
#[rustc_deprecated(since = "invalid", reason = "text")]
70+
fn invalid_deprecation_version() {} //~ ERROR Invalid deprecation version found
6771

6872
#[rustc_deprecated(since = "a", reason = "text")]
6973
fn deprecated_without_unstable_or_stable() { }

src/test/ui/stability-attribute/stability-attribute-sanity.stderr

+9-3
Original file line numberDiff line numberDiff line change
@@ -96,19 +96,25 @@ error[E0544]: multiple stability levels
9696
LL | #[rustc_const_unstable(feature = "d", issue = "none")]
9797
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
9898

99-
error: Invalid stability or deprecation version found
99+
error: Invalid stability version found
100100
--> $DIR/stability-attribute-sanity.rs:65:1
101101
|
102102
LL | pub const fn multiple4() { }
103103
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
104104

105+
error: Invalid deprecation version found
106+
--> $DIR/stability-attribute-sanity.rs:70:1
107+
|
108+
LL | fn invalid_deprecation_version() {}
109+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
110+
105111
error[E0549]: rustc_deprecated attribute must be paired with either stable or unstable attribute
106-
--> $DIR/stability-attribute-sanity.rs:68:1
112+
--> $DIR/stability-attribute-sanity.rs:72:1
107113
|
108114
LL | #[rustc_deprecated(since = "a", reason = "text")]
109115
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
110116

111-
error: aborting due to 18 previous errors
117+
error: aborting due to 19 previous errors
112118

113119
Some errors have detailed explanations: E0539, E0541, E0546, E0550.
114120
For more information about an error, try `rustc --explain E0539`.

0 commit comments

Comments
 (0)