resolve: Use standard stability diagnostics for macros

This commit is contained in:
Vadim Petrochenkov 2019-06-22 00:18:09 +03:00
parent 3542995ff9
commit d9ee97e896
4 changed files with 43 additions and 40 deletions

View file

@ -477,6 +477,36 @@ pub fn provide(providers: &mut Providers<'_>) {
};
}
pub fn report_unstable(
sess: &Session, feature: Symbol, reason: Option<Symbol>, issue: u32, span: Span
) {
let msg = match reason {
Some(r) => format!("use of unstable library feature '{}': {}", feature, r),
None => format!("use of unstable library feature '{}'", &feature)
};
let msp: MultiSpan = span.into();
let cm = &sess.parse_sess.source_map();
let span_key = msp.primary_span().and_then(|sp: Span|
if !sp.is_dummy() {
let file = cm.lookup_char_pos(sp.lo()).file;
if file.name.is_macros() {
None
} else {
Some(span)
}
} else {
None
}
);
let error_id = (DiagnosticMessageId::StabilityId(issue), span_key, msg.clone());
let fresh = sess.one_time_diagnostics.borrow_mut().insert(error_id);
if fresh {
emit_feature_err(&sess.parse_sess, feature, span, GateIssue::Library(Some(issue)), &msg);
}
}
/// Checks 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 {
@ -715,34 +745,8 @@ impl<'tcx> TyCtxt<'tcx> {
pub fn check_stability(self, def_id: DefId, id: Option<HirId>, span: Span) {
match self.eval_stability(def_id, id, span) {
EvalResult::Allow => {}
EvalResult::Deny { feature, reason, issue } => {
let msg = match reason {
Some(r) => format!("use of unstable library feature '{}': {}", feature, r),
None => format!("use of unstable library feature '{}'", &feature)
};
let msp: MultiSpan = span.into();
let cm = &self.sess.parse_sess.source_map();
let span_key = msp.primary_span().and_then(|sp: Span|
if !sp.is_dummy() {
let file = cm.lookup_char_pos(sp.lo()).file;
if file.name.is_macros() {
None
} else {
Some(span)
}
} else {
None
}
);
let error_id = (DiagnosticMessageId::StabilityId(issue), span_key, msg.clone());
let fresh = self.sess.one_time_diagnostics.borrow_mut().insert(error_id);
if fresh {
emit_feature_err(&self.sess.parse_sess, feature, span,
GateIssue::Library(Some(issue)), &msg);
}
}
EvalResult::Deny { feature, reason, issue } =>
report_unstable(self.sess, feature, reason, issue, span),
EvalResult::Unmarked => {
// The API could be uncallable for other reasons, for example when a private module
// was referenced.

View file

@ -9,6 +9,7 @@ use crate::resolve_imports::ImportResolver;
use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX};
use rustc::hir::def::{self, DefKind, NonMacroAttrKind};
use rustc::hir::map::{self, DefCollector};
use rustc::middle::stability;
use rustc::{ty, lint, span_bug};
use syntax::ast::{self, Ident};
use syntax::attr::{self, StabilityLevel};
@ -18,7 +19,7 @@ use syntax::ext::base::{MacroKind, SyntaxExtension};
use syntax::ext::expand::{AstFragment, Invocation, InvocationKind};
use syntax::ext::hygiene::Mark;
use syntax::ext::tt::macro_rules;
use syntax::feature_gate::{feature_err, emit_feature_err, is_builtin_attr_name};
use syntax::feature_gate::{feature_err, is_builtin_attr_name};
use syntax::feature_gate::{AttributeGate, GateIssue, Stability, BUILTIN_ATTRIBUTES};
use syntax::symbol::{Symbol, kw, sym};
use syntax::visit::Visitor;
@ -237,13 +238,11 @@ impl<'a> base::Resolver for Resolver<'a> {
invoc.expansion_data.mark.set_expn_info(ext.expn_info(span, &format));
if let Some(stability) = ext.stability {
if let StabilityLevel::Unstable { issue, .. } = stability.level {
let features = self.session.features_untracked();
if !span.allows_unstable(stability.feature) &&
features.declared_lib_features.iter().all(|(feat, _)| *feat != stability.feature) {
let msg = format!("macro {}! is unstable", path);
emit_feature_err(&self.session.parse_sess, stability.feature, span,
GateIssue::Library(Some(issue)), &msg);
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);
}
}
}

View file

@ -7,6 +7,6 @@
macro_rules! local_unstable { () => () }
fn main() {
local_unstable!(); //~ ERROR: macro local_unstable! is unstable
unstable_macro!(); //~ ERROR: macro unstable_macro! is unstable
local_unstable!(); //~ ERROR use of unstable library feature 'local_unstable'
unstable_macro!(); //~ ERROR use of unstable library feature 'unstable_macros'
}

View file

@ -1,4 +1,4 @@
error[E0658]: macro local_unstable! is unstable
error[E0658]: use of unstable library feature 'local_unstable'
--> $DIR/macro-stability.rs:10:5
|
LL | local_unstable!();
@ -6,7 +6,7 @@ LL | local_unstable!();
|
= help: add #![feature(local_unstable)] to the crate attributes to enable
error[E0658]: macro unstable_macro! is unstable
error[E0658]: use of unstable library feature 'unstable_macros'
--> $DIR/macro-stability.rs:11:5
|
LL | unstable_macro!();