Skip to content

Commit 5f50da5

Browse files
authored
Rollup merge of rust-lang#49179 - varkor:future-deprecation, r=QuietMisdreavus,GuillaumeGomez
Handle future deprecation annotations This adds special handling to the `since` parameter of the `deprecated` attribute: in particular, if the `since` version exceeds the version of the compiler, the deprecation notice will not be printed; but a note is added to the documentation stating that the item will be deprecated in a later version. (I've used `since` for this, rather than adding a new attribute, because it's more seamless and, I feel, intuitive. Plus it involves less code churn.) ![image](https://user-images.githubusercontent.com/3943692/37611317-ef5cdf16-2b99-11e8-8251-e35e8f7b0137.png) ![image](https://user-images.githubusercontent.com/3943692/37611323-f748c2d0-2b99-11e8-966b-11408c73d416.png) This is a prerequisite for doing things renaming methods in the standard library (e.g. rust-lang#30459). Resolves rust-lang#30785.
2 parents b12af86 + b2ed9dd commit 5f50da5

File tree

4 files changed

+78
-6
lines changed

4 files changed

+78
-6
lines changed

src/librustc/middle/stability.rs

+36-2
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,30 @@ pub fn check_unstable_api_usage<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
470470
tcx.hir.krate().visit_all_item_likes(&mut checker.as_deep_visitor());
471471
}
472472

473+
/// Check whether an item marked with `deprecated(since="X")` is currently
474+
/// deprecated (i.e. whether X is not greater than the current rustc version).
475+
pub fn deprecation_in_effect(since: &str) -> bool {
476+
fn parse_version(ver: &str) -> Vec<u32> {
477+
// We ignore non-integer components of the version (e.g. "nightly").
478+
ver.split(|c| c == '.' || c == '-').flat_map(|s| s.parse()).collect()
479+
}
480+
481+
if let Some(rustc) = option_env!("CFG_RELEASE") {
482+
let since: Vec<u32> = parse_version(since);
483+
let rustc: Vec<u32> = parse_version(rustc);
484+
// We simply treat invalid `since` attributes as relating to a previous
485+
// Rust version, thus always displaying the warning.
486+
if since.len() != 3 {
487+
return true;
488+
}
489+
since <= rustc
490+
} else {
491+
// By default, a deprecation warning applies to
492+
// the current version of the compiler.
493+
true
494+
}
495+
}
496+
473497
struct Checker<'a, 'tcx: 'a> {
474498
tcx: TyCtxt<'a, 'tcx, 'tcx>,
475499
}
@@ -559,9 +583,19 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
559583
// Deprecated attributes apply in-crate and cross-crate.
560584
if let Some(id) = id {
561585
if let Some(depr_entry) = self.lookup_deprecation_entry(def_id) {
586+
// If the deprecation is scheduled for a future Rust
587+
// version, then we should display no warning message.
588+
let deprecated_in_future_version = if let Some(sym) = depr_entry.attr.since {
589+
let since = sym.as_str();
590+
!deprecation_in_effect(&since)
591+
} else {
592+
false
593+
};
594+
562595
let parent_def_id = self.hir.local_def_id(self.hir.get_parent(id));
563-
let skip = self.lookup_deprecation_entry(parent_def_id)
564-
.map_or(false, |parent_depr| parent_depr.same_origin(&depr_entry));
596+
let skip = deprecated_in_future_version ||
597+
self.lookup_deprecation_entry(parent_def_id)
598+
.map_or(false, |parent_depr| parent_depr.same_origin(&depr_entry));
565599
if !skip {
566600
lint_deprecated(def_id, id, depr_entry.attr.note);
567601
}

src/librustdoc/html/render.rs

+18-4
Original file line numberDiff line numberDiff line change
@@ -2113,9 +2113,15 @@ fn short_stability(item: &clean::Item, cx: &Context, show_reason: bool) -> Vec<S
21132113
} else {
21142114
String::new()
21152115
};
2116-
let text = format!("Deprecated{}{}",
2117-
since,
2118-
MarkdownHtml(&deprecated_reason));
2116+
let text = if stability::deprecation_in_effect(&stab.deprecated_since) {
2117+
format!("Deprecated{}{}",
2118+
since,
2119+
MarkdownHtml(&deprecated_reason))
2120+
} else {
2121+
format!("Deprecating in {}{}",
2122+
Escape(&stab.deprecated_since),
2123+
MarkdownHtml(&deprecated_reason))
2124+
};
21192125
stability.push(format!("<div class='stab deprecated'>{}</div>", text))
21202126
};
21212127

@@ -2165,7 +2171,15 @@ fn short_stability(item: &clean::Item, cx: &Context, show_reason: bool) -> Vec<S
21652171
String::new()
21662172
};
21672173

2168-
let text = format!("Deprecated{}{}", since, MarkdownHtml(&note));
2174+
let text = if stability::deprecation_in_effect(&depr.since) {
2175+
format!("Deprecated{}{}",
2176+
since,
2177+
MarkdownHtml(&note))
2178+
} else {
2179+
format!("Deprecating in {}{}",
2180+
Escape(&depr.since),
2181+
MarkdownHtml(&note))
2182+
};
21692183
stability.push(format!("<div class='stab deprecated'>{}</div>", text))
21702184
}
21712185

src/test/compile-fail/deprecation-lint.rs

+8
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,11 @@ mod this_crate {
180180
#[deprecated(since = "1.0.0", note = "text")]
181181
pub fn deprecated_text() {}
182182

183+
#[deprecated(since = "99.99.99", note = "text")]
184+
pub fn deprecated_future() {}
185+
#[deprecated(since = "99.99.99", note = "text")]
186+
pub fn deprecated_future_text() {}
187+
183188
pub struct MethodTester;
184189

185190
impl MethodTester {
@@ -266,6 +271,9 @@ mod this_crate {
266271
<Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated_text': text
267272
<Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated_text': text
268273

274+
deprecated_future(); // Fine; no error.
275+
deprecated_future_text(); // Fine; no error.
276+
269277
let _ = DeprecatedStruct {
270278
//~^ ERROR use of deprecated item 'this_crate::DeprecatedStruct': text
271279
i: 0 //~ ERROR use of deprecated item 'this_crate::DeprecatedStruct::i': text

src/test/rustdoc/deprecated-future.rs

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![feature(deprecated)]
12+
13+
// @has deprecated_future/struct.S.html '//*[@class="stab deprecated"]' \
14+
// 'Deprecating in 99.99.99: effectively never'
15+
#[deprecated(since = "99.99.99", note = "effectively never")]
16+
pub struct S;

0 commit comments

Comments
 (0)