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

Rollup of 4 pull requests #62461

Closed
wants to merge 17 commits into from
Closed
Changes from 1 commit
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
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
5 changes: 5 additions & 0 deletions src/librustc/lint/builtin.rs
Original file line number Diff line number Diff line change
@@ -5,10 +5,12 @@
//! lints are all available in `rustc_lint::builtin`.
use crate::lint::{LintPass, LateLintPass, LintArray};
use crate::middle::stability;
use crate::session::Session;
use errors::{Applicability, DiagnosticBuilder};
use syntax::ast;
use syntax::source_map::Span;
use syntax::symbol::Symbol;

declare_lint! {
pub EXCEEDING_BITSHIFTS,
@@ -461,6 +463,7 @@ pub enum BuiltinLintDiagnostics {
UnusedImports(String, Vec<(Span, String)>),
NestedImplTrait { outer_impl_trait_span: Span, inner_impl_trait_span: Span },
RedundantImport(Vec<(Span, bool)>, ast::Ident),
DeprecatedMacro(Option<Symbol>, Span),
}

pub(crate) fn add_elided_lifetime_in_path_suggestion(
@@ -586,6 +589,8 @@ impl BuiltinLintDiagnostics {
);
}
}
BuiltinLintDiagnostics::DeprecatedMacro(suggestion, span) =>
stability::deprecation_suggestion(db, suggestion, span),
}
}
}
148 changes: 85 additions & 63 deletions src/librustc/middle/stability.rs
Original file line number Diff line number Diff line change
@@ -4,19 +4,21 @@
pub use self::StabilityLevel::*;

use crate::lint::{self, Lint, in_derive_expansion};
use crate::lint::builtin::BuiltinLintDiagnostics;
use crate::hir::{self, Item, Generics, StructField, Variant, HirId};
use crate::hir::def::{Res, DefKind};
use crate::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId, LOCAL_CRATE};
use crate::hir::intravisit::{self, Visitor, NestedVisitorMap};
use crate::ty::query::Providers;
use crate::middle::privacy::AccessLevels;
use crate::session::{DiagnosticMessageId, Session};
use errors::DiagnosticBuilder;
use syntax::symbol::{Symbol, sym};
use syntax_pos::{Span, MultiSpan};
use syntax::ast::Attribute;
use syntax::ast::{Attribute, CRATE_NODE_ID};
use syntax::errors::Applicability;
use syntax::feature_gate::{GateIssue, emit_feature_err};
use syntax::attr::{self, Stability, Deprecation};
use syntax::attr::{self, Stability, Deprecation, RustcDeprecation};
use crate::ty::{self, TyCtxt};
use crate::util::nodemap::{FxHashSet, FxHashMap};

@@ -531,6 +533,79 @@ pub fn deprecation_in_effect(since: &str) -> bool {
}
}

pub fn deprecation_suggestion(
diag: &mut DiagnosticBuilder<'_>, suggestion: Option<Symbol>, span: Span
) {
if let Some(suggestion) = suggestion {
diag.span_suggestion(
span,
"replace the use of the deprecated item",
suggestion.to_string(),
Applicability::MachineApplicable,
);
}
}

fn deprecation_message_common(message: String, reason: Option<Symbol>) -> String {
match reason {
Some(reason) => format!("{}: {}", message, reason),
None => message,
}
}

pub fn deprecation_message(depr: &Deprecation, path: &str) -> (String, &'static Lint) {
let message = format!("use of deprecated item '{}'", path);
(deprecation_message_common(message, depr.note), lint::builtin::DEPRECATED)
}

pub fn rustc_deprecation_message(depr: &RustcDeprecation, path: &str) -> (String, &'static Lint) {
let (message, lint) = if deprecation_in_effect(&depr.since.as_str()) {
(format!("use of deprecated item '{}'", path), lint::builtin::DEPRECATED)
} else {
(format!("use of item '{}' that will be deprecated in future version {}", path, depr.since),
lint::builtin::DEPRECATED_IN_FUTURE)
};
(deprecation_message_common(message, Some(depr.reason)), lint)
}

pub fn early_report_deprecation(
sess: &Session,
message: &str,
suggestion: Option<Symbol>,
lint: &'static Lint,
span: Span,
) {
if in_derive_expansion(span) {
return;
}

let diag = BuiltinLintDiagnostics::DeprecatedMacro(suggestion, span);
sess.buffer_lint_with_diagnostic(lint, CRATE_NODE_ID, span, message, diag);
}

fn late_report_deprecation(
tcx: TyCtxt<'_>,
message: &str,
suggestion: Option<Symbol>,
lint: &'static Lint,
span: Span,
def_id: DefId,
hir_id: HirId,
) {
if in_derive_expansion(span) {
return;
}

let mut diag = tcx.struct_span_lint_hir(lint, hir_id, span, message);
if let hir::Node::Expr(_) = tcx.hir().get(hir_id) {
deprecation_suggestion(&mut diag, suggestion, span);
}
diag.emit();
if hir_id == hir::DUMMY_HIR_ID {
span_bug!(span, "emitted a {} lint with dummy HIR id: {:?}", lint.name, def_id);
}
}

struct Checker<'tcx> {
tcx: TyCtxt<'tcx>,
}
@@ -593,38 +668,6 @@ impl<'tcx> TyCtxt<'tcx> {
/// deprecated. If the item is indeed deprecated, we will emit a deprecation lint attached to
/// `id`.
pub fn eval_stability(self, def_id: DefId, id: Option<HirId>, span: Span) -> EvalResult {
let lint_deprecated = |def_id: DefId,
id: HirId,
note: Option<Symbol>,
suggestion: Option<Symbol>,
message: &str,
lint: &'static Lint| {
if in_derive_expansion(span) {
return;
}
let msg = if let Some(note) = note {
format!("{}: {}", message, note)
} else {
format!("{}", message)
};

let mut diag = self.struct_span_lint_hir(lint, id, span, &msg);
if let Some(suggestion) = suggestion {
if let hir::Node::Expr(_) = self.hir().get(id) {
diag.span_suggestion(
span,
"replace the use of the deprecated item",
suggestion.to_string(),
Applicability::MachineApplicable,
);
}
}
diag.emit();
if id == hir::DUMMY_HIR_ID {
span_bug!(span, "emitted a {} lint with dummy HIR id: {:?}", lint.name, def_id);
}
};

// Deprecated attributes apply in-crate and cross-crate.
if let Some(id) = id {
if let Some(depr_entry) = self.lookup_deprecation_entry(def_id) {
@@ -634,14 +677,9 @@ impl<'tcx> TyCtxt<'tcx> {
.map_or(false, |parent_depr| parent_depr.same_origin(&depr_entry));

if !skip {
let path = self.def_path_str(def_id);
let message = format!("use of deprecated item '{}'", path);
lint_deprecated(def_id,
id,
depr_entry.attr.note,
None,
&message,
lint::builtin::DEPRECATED);
let (message, lint) =
deprecation_message(&depr_entry.attr, &self.def_path_str(def_id));
late_report_deprecation(self, &message, None, lint, span, def_id, id);
}
};
}
@@ -661,27 +699,11 @@ impl<'tcx> TyCtxt<'tcx> {
if let Some(id) = id {
if let Some(stability) = stability {
if let Some(depr) = &stability.rustc_depr {
let path = self.def_path_str(def_id);
if deprecation_in_effect(&depr.since.as_str()) {
let message = format!("use of deprecated item '{}'", path);
lint_deprecated(def_id,
id,
Some(depr.reason),
depr.suggestion,
&message,
lint::builtin::DEPRECATED);
} else {
let message = format!("use of item '{}' \
that will be deprecated in future version {}",
path,
depr.since);
lint_deprecated(def_id,
id,
Some(depr.reason),
depr.suggestion,
&message,
lint::builtin::DEPRECATED_IN_FUTURE);
}
let (message, lint) =
rustc_deprecation_message(depr, &self.def_path_str(def_id));
late_report_deprecation(
self, &message, depr.suggestion, lint, span, def_id, id
);
}
}
}
37 changes: 26 additions & 11 deletions src/librustc_resolve/macros.rs
Original file line number Diff line number Diff line change
@@ -231,21 +231,14 @@ impl<'a> base::Resolver for Resolver<'a> {
};

let span = invoc.span();
let path = fast_print_path(path);
let format = match kind {
MacroKind::Derive => format!("derive({})", fast_print_path(path)),
_ => fast_print_path(path),
MacroKind::Derive => format!("derive({})", path),
_ => path.clone(),
};
invoc.expansion_data.mark.set_expn_info(ext.expn_info(span, &format));

if let Some(stability) = ext.stability {
if let StabilityLevel::Unstable { reason, issue } = stability.level {
let (feature, features) = (stability.feature, self.session.features_untracked());
if !span.allows_unstable(feature) &&
features.declared_lib_features.iter().all(|(feat, _)| *feat != feature) {
stability::report_unstable(self.session, feature, reason, issue, span);
}
}
}
self.check_stability_and_deprecation(&ext, &path, span);

if let Res::Def(_, def_id) = res {
if after_derive {
@@ -1017,6 +1010,28 @@ impl<'a> Resolver<'a> {
}
}

fn check_stability_and_deprecation(&self, ext: &SyntaxExtension, path: &str, span: Span) {
if let Some(stability) = &ext.stability {
if let StabilityLevel::Unstable { reason, issue } = stability.level {
let (feature, features) = (stability.feature, self.session.features_untracked());
if !span.allows_unstable(feature) &&
features.declared_lib_features.iter().all(|(feat, _)| *feat != feature) {
stability::report_unstable(self.session, feature, reason, issue, span);
}
}
if let Some(depr) = &stability.rustc_depr {
let (message, lint) = stability::rustc_deprecation_message(depr, path);
stability::early_report_deprecation(
self.session, &message, depr.suggestion, lint, span
);
}
}
if let Some(depr) = &ext.deprecation {
let (message, lint) = stability::deprecation_message(depr, path);
stability::early_report_deprecation(self.session, &message, None, lint, span);
}
}

fn prohibit_imported_non_macro_attrs(&self, binding: Option<&'a NameBinding<'a>>,
res: Option<Res>, span: Span) {
if let Some(Res::NonMacroAttr(kind)) = res {
7 changes: 5 additions & 2 deletions src/libsyntax/ext/base.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::ast::{self, Attribute, Name, PatKind};
use crate::attr::{HasAttrs, Stability};
use crate::attr::{HasAttrs, Stability, Deprecation};
use crate::source_map::{SourceMap, Spanned, respan};
use crate::edition::Edition;
use crate::ext::expand::{self, AstFragment, Invocation};
@@ -616,8 +616,10 @@ pub struct SyntaxExtension {
pub allow_internal_unsafe: bool,
/// Enables the macro helper hack (`ident!(...)` -> `$crate::ident!(...)`) for this macro.
pub local_inner_macros: bool,
/// The macro's stability and deprecation info.
/// The macro's stability info.
pub stability: Option<Stability>,
/// The macro's deprecation info.
pub deprecation: Option<Deprecation>,
/// Names of helper attributes registered by this macro.
pub helper_attrs: Vec<Symbol>,
/// Edition of the crate in which this macro is defined.
@@ -663,6 +665,7 @@ impl SyntaxExtension {
allow_internal_unsafe: false,
local_inner_macros: false,
stability: None,
deprecation: None,
helper_attrs: Vec::new(),
edition,
kind,
1 change: 1 addition & 0 deletions src/libsyntax/ext/tt/macro_rules.rs
Original file line number Diff line number Diff line change
@@ -437,6 +437,7 @@ pub fn compile(
allow_internal_unsafe: attr::contains_name(&def.attrs, sym::allow_internal_unsafe),
local_inner_macros,
stability: attr::find_stability(&sess, &def.attrs, def.span),
deprecation: attr::find_deprecation(&sess, &def.attrs, def.span),
helper_attrs: Vec::new(),
edition,
}
3 changes: 3 additions & 0 deletions src/test/ui/macros/auxiliary/deprecated-macros.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#[deprecated(since = "1.0.0", note = "deprecation note")]
#[macro_export]
macro_rules! deprecated_macro{ () => () }
10 changes: 10 additions & 0 deletions src/test/ui/macros/auxiliary/unstable-macros.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
#![feature(decl_macro)]
#![feature(staged_api)]
#![stable(feature = "unit_test", since = "1.0.0")]

#[unstable(feature = "unstable_macros", issue = "0")]
#[macro_export]
macro_rules! unstable_macro{ () => () }

#[stable(feature = "deprecated_macros", since = "1.0.0")]
#[rustc_deprecated(since = "1.0.0", reason = "deprecation reason")]
#[macro_export]
macro_rules! deprecated_macro{ () => () }

// FIXME: Cannot use a `pub` macro 2.0 in a staged API crate due to reachability issues.
// #[unstable(feature = "unstable_macros", issue = "0")]
// pub macro unstable_macro_modern() {}
13 changes: 13 additions & 0 deletions src/test/ui/macros/macro-deprecation.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// compile-pass
// aux-build:deprecated-macros.rs

#[macro_use] extern crate deprecated_macros;

#[deprecated(since = "1.0.0", note = "local deprecation note")]
#[macro_export]
macro_rules! local_deprecated{ () => () }

fn main() {
local_deprecated!(); //~ WARN use of deprecated item 'local_deprecated': local deprecation note
deprecated_macro!(); //~ WARN use of deprecated item 'deprecated_macro': deprecation note
}
14 changes: 14 additions & 0 deletions src/test/ui/macros/macro-deprecation.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
warning: use of deprecated item 'local_deprecated': local deprecation note
--> $DIR/macro-deprecation.rs:11:5
|
LL | local_deprecated!();
| ^^^^^^^^^^^^^^^^^^^^
|
= note: #[warn(deprecated)] on by default

warning: use of deprecated item 'deprecated_macro': deprecation note
--> $DIR/macro-deprecation.rs:12:5
|
LL | deprecated_macro!();
| ^^^^^^^^^^^^^^^^^^^^

16 changes: 16 additions & 0 deletions src/test/ui/macros/macro-stability.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,28 @@
// aux-build:unstable-macros.rs

#![feature(decl_macro)]
#![feature(staged_api)]
#[macro_use] extern crate unstable_macros;

#[unstable(feature = "local_unstable", issue = "0")]
macro_rules! local_unstable { () => () }

#[unstable(feature = "local_unstable", issue = "0")]
macro local_unstable_modern() {}

#[stable(feature = "deprecated_macros", since = "1.0.0")]
#[rustc_deprecated(since = "1.0.0", reason = "local deprecation reason")]
#[macro_export]
macro_rules! local_deprecated{ () => () }

fn main() {
local_unstable!(); //~ ERROR use of unstable library feature 'local_unstable'
local_unstable_modern!(); //~ ERROR use of unstable library feature 'local_unstable'
unstable_macro!(); //~ ERROR use of unstable library feature 'unstable_macros'
// unstable_macro_modern!(); // ERROR use of unstable library feature 'unstable_macros'

deprecated_macro!();
//~^ WARN use of deprecated item 'deprecated_macro': deprecation reason
local_deprecated!();
//~^ WARN use of deprecated item 'local_deprecated': local deprecation reason
}
28 changes: 25 additions & 3 deletions src/test/ui/macros/macro-stability.stderr
Original file line number Diff line number Diff line change
@@ -1,19 +1,41 @@
error[E0658]: use of unstable library feature 'local_unstable'
--> $DIR/macro-stability.rs:10:5
--> $DIR/macro-stability.rs:19:5
|
LL | local_unstable!();
| ^^^^^^^^^^^^^^^^^^
|
= help: add #![feature(local_unstable)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'local_unstable'
--> $DIR/macro-stability.rs:20:5
|
LL | local_unstable_modern!();
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: add #![feature(local_unstable)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'unstable_macros'
--> $DIR/macro-stability.rs:11:5
--> $DIR/macro-stability.rs:21:5
|
LL | unstable_macro!();
| ^^^^^^^^^^^^^^^^^^
|
= help: add #![feature(unstable_macros)] to the crate attributes to enable

error: aborting due to 2 previous errors
warning: use of deprecated item 'deprecated_macro': deprecation reason
--> $DIR/macro-stability.rs:24:5
|
LL | deprecated_macro!();
| ^^^^^^^^^^^^^^^^^^^^
|
= note: #[warn(deprecated)] on by default

warning: use of deprecated item 'local_deprecated': local deprecation reason
--> $DIR/macro-stability.rs:26:5
|
LL | local_deprecated!();
| ^^^^^^^^^^^^^^^^^^^^

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0658`.