Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle future deprecation annotations #49179

Merged
merged 5 commits into from
Apr 5, 2018
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.as_ref())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't use as_ref to get the &str; that tends to be a footgun. Passing &since should cause deref coercion to pass the &str to deprecation_in_effect.

} 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 @@ -2108,9 +2108,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 @@ -2160,7 +2166,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;