diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 29c8ac046b815..328b2db2b5828 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -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 { + // 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 = parse_version(since); + let rustc: Vec = 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); } diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 678e1762a5519..194e301af3dd4 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -2108,9 +2108,15 @@ fn short_stability(item: &clean::Item, cx: &Context, show_reason: bool) -> Vec{}", text)) }; @@ -2160,7 +2166,15 @@ fn short_stability(item: &clean::Item, cx: &Context, show_reason: bool) -> Vec{}", text)) } diff --git a/src/test/compile-fail/deprecation-lint.rs b/src/test/compile-fail/deprecation-lint.rs index a058234a64921..93eb6b6b11544 100644 --- a/src/test/compile-fail/deprecation-lint.rs +++ b/src/test/compile-fail/deprecation-lint.rs @@ -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 { ::trait_deprecated_text(&foo); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated_text': text ::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 diff --git a/src/test/rustdoc/deprecated-future.rs b/src/test/rustdoc/deprecated-future.rs new file mode 100644 index 0000000000000..6feb98dad09c6 --- /dev/null +++ b/src/test/rustdoc/deprecated-future.rs @@ -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 or the MIT license +// , 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;