Rollup merge of #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. #30459). Resolves #30785.
This commit is contained in:
commit
b7b2ae2b6f
@ -470,6 +470,30 @@ pub fn check_unstable_api_usage<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
|
||||
tcx.hir.krate().visit_all_item_likes(&mut checker.as_deep_visitor());
|
||||
}
|
||||
|
||||
/// Check 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(since: &str) -> bool {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
struct Checker<'a, 'tcx: 'a> {
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
}
|
||||
@ -559,9 +583,19 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
// Deprecated attributes apply in-crate and cross-crate.
|
||||
if let Some(id) = id {
|
||||
if let Some(depr_entry) = self.lookup_deprecation_entry(def_id) {
|
||||
// If the deprecation is scheduled for a future Rust
|
||||
// version, then we should display no warning message.
|
||||
let deprecated_in_future_version = if let Some(sym) = depr_entry.attr.since {
|
||||
let since = sym.as_str();
|
||||
!deprecation_in_effect(&since)
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
let parent_def_id = self.hir.local_def_id(self.hir.get_parent(id));
|
||||
let skip = self.lookup_deprecation_entry(parent_def_id)
|
||||
.map_or(false, |parent_depr| parent_depr.same_origin(&depr_entry));
|
||||
let skip = deprecated_in_future_version ||
|
||||
self.lookup_deprecation_entry(parent_def_id)
|
||||
.map_or(false, |parent_depr| parent_depr.same_origin(&depr_entry));
|
||||
if !skip {
|
||||
lint_deprecated(def_id, id, depr_entry.attr.note);
|
||||
}
|
||||
|
@ -2113,9 +2113,15 @@ fn short_stability(item: &clean::Item, cx: &Context, show_reason: bool) -> Vec<S
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
let text = format!("Deprecated{}{}",
|
||||
since,
|
||||
MarkdownHtml(&deprecated_reason));
|
||||
let text = if stability::deprecation_in_effect(&stab.deprecated_since) {
|
||||
format!("Deprecated{}{}",
|
||||
since,
|
||||
MarkdownHtml(&deprecated_reason))
|
||||
} else {
|
||||
format!("Deprecating in {}{}",
|
||||
Escape(&stab.deprecated_since),
|
||||
MarkdownHtml(&deprecated_reason))
|
||||
};
|
||||
stability.push(format!("<div class='stab deprecated'>{}</div>", text))
|
||||
};
|
||||
|
||||
@ -2165,7 +2171,15 @@ fn short_stability(item: &clean::Item, cx: &Context, show_reason: bool) -> Vec<S
|
||||
String::new()
|
||||
};
|
||||
|
||||
let text = format!("Deprecated{}{}", since, MarkdownHtml(¬e));
|
||||
let text = if stability::deprecation_in_effect(&depr.since) {
|
||||
format!("Deprecated{}{}",
|
||||
since,
|
||||
MarkdownHtml(¬e))
|
||||
} else {
|
||||
format!("Deprecating in {}{}",
|
||||
Escape(&depr.since),
|
||||
MarkdownHtml(¬e))
|
||||
};
|
||||
stability.push(format!("<div class='stab deprecated'>{}</div>", text))
|
||||
}
|
||||
|
||||
|
@ -180,6 +180,11 @@ mod this_crate {
|
||||
#[deprecated(since = "1.0.0", note = "text")]
|
||||
pub fn deprecated_text() {}
|
||||
|
||||
#[deprecated(since = "99.99.99", note = "text")]
|
||||
pub fn deprecated_future() {}
|
||||
#[deprecated(since = "99.99.99", note = "text")]
|
||||
pub fn deprecated_future_text() {}
|
||||
|
||||
pub struct MethodTester;
|
||||
|
||||
impl MethodTester {
|
||||
@ -266,6 +271,9 @@ mod this_crate {
|
||||
<Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated_text': text
|
||||
<Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated_text': text
|
||||
|
||||
deprecated_future(); // Fine; no error.
|
||||
deprecated_future_text(); // Fine; no error.
|
||||
|
||||
let _ = DeprecatedStruct {
|
||||
//~^ ERROR use of deprecated item 'this_crate::DeprecatedStruct': text
|
||||
i: 0 //~ ERROR use of deprecated item 'this_crate::DeprecatedStruct::i': text
|
||||
|
16
src/test/rustdoc/deprecated-future.rs
Normal file
16
src/test/rustdoc/deprecated-future.rs
Normal file
@ -0,0 +1,16 @@
|
||||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(deprecated)]
|
||||
|
||||
// @has deprecated_future/struct.S.html '//*[@class="stab deprecated"]' \
|
||||
// 'Deprecating in 99.99.99: effectively never'
|
||||
#[deprecated(since = "99.99.99", note = "effectively never")]
|
||||
pub struct S;
|
Loading…
x
Reference in New Issue
Block a user