Skip to content

Commit

Permalink
Rollup merge of rust-lang#49179 - varkor:future-deprecation, r=QuietM…
Browse files Browse the repository at this point in the history
…isdreavus,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.
  • Loading branch information
kennytm committed Apr 4, 2018
2 parents 5758c2d + b2ed9dd commit b7b2ae2
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 6 deletions.
38 changes: 36 additions & 2 deletions src/librustc/middle/stability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>,
}
Expand Down Expand Up @@ -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);
}
Expand Down
22 changes: 18 additions & 4 deletions src/librustdoc/html/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
};

Expand Down Expand Up @@ -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(&note));
let text = if stability::deprecation_in_effect(&depr.since) {
format!("Deprecated{}{}",
since,
MarkdownHtml(&note))
} else {
format!("Deprecating in {}{}",
Escape(&depr.since),
MarkdownHtml(&note))
};
stability.push(format!("<div class='stab deprecated'>{}</div>", text))
}

Expand Down
8 changes: 8 additions & 0 deletions src/test/compile-fail/deprecation-lint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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
Expand Down
16 changes: 16 additions & 0 deletions src/test/rustdoc/deprecated-future.rs
Original file line number Diff line number Diff line change
@@ -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;

0 comments on commit b7b2ae2

Please sign in to comment.