Rollup merge of #62042 - petrochenkov:macstab, r=matthewjasper
Support stability and deprecation checking for all macros RELNOTES: Deprecation attributes on macros now have effect. Fixes https://github.com/rust-lang/rust/issues/34079 Fixes https://github.com/rust-lang/rust/issues/49912 Unblocks https://github.com/rust-lang/rust/pull/62086 Unblocks https://github.com/rust-lang/rust/pull/61000
This commit is contained in:
commit
3250b8ee59
|
@ -90,6 +90,7 @@ pub struct LoweringContext<'a> {
|
||||||
impl_items: BTreeMap<hir::ImplItemId, hir::ImplItem>,
|
impl_items: BTreeMap<hir::ImplItemId, hir::ImplItem>,
|
||||||
bodies: BTreeMap<hir::BodyId, hir::Body>,
|
bodies: BTreeMap<hir::BodyId, hir::Body>,
|
||||||
exported_macros: Vec<hir::MacroDef>,
|
exported_macros: Vec<hir::MacroDef>,
|
||||||
|
non_exported_macro_attrs: Vec<ast::Attribute>,
|
||||||
|
|
||||||
trait_impls: BTreeMap<DefId, Vec<hir::HirId>>,
|
trait_impls: BTreeMap<DefId, Vec<hir::HirId>>,
|
||||||
|
|
||||||
|
@ -252,6 +253,7 @@ pub fn lower_crate(
|
||||||
trait_impls: BTreeMap::new(),
|
trait_impls: BTreeMap::new(),
|
||||||
modules: BTreeMap::new(),
|
modules: BTreeMap::new(),
|
||||||
exported_macros: Vec::new(),
|
exported_macros: Vec::new(),
|
||||||
|
non_exported_macro_attrs: Vec::new(),
|
||||||
catch_scopes: Vec::new(),
|
catch_scopes: Vec::new(),
|
||||||
loop_scopes: Vec::new(),
|
loop_scopes: Vec::new(),
|
||||||
is_in_loop_condition: false,
|
is_in_loop_condition: false,
|
||||||
|
@ -662,6 +664,7 @@ impl<'a> LoweringContext<'a> {
|
||||||
attrs,
|
attrs,
|
||||||
span: c.span,
|
span: c.span,
|
||||||
exported_macros: hir::HirVec::from(self.exported_macros),
|
exported_macros: hir::HirVec::from(self.exported_macros),
|
||||||
|
non_exported_macro_attrs: hir::HirVec::from(self.non_exported_macro_attrs),
|
||||||
items: self.items,
|
items: self.items,
|
||||||
trait_items: self.trait_items,
|
trait_items: self.trait_items,
|
||||||
impl_items: self.impl_items,
|
impl_items: self.impl_items,
|
||||||
|
@ -4022,6 +4025,8 @@ impl<'a> LoweringContext<'a> {
|
||||||
body,
|
body,
|
||||||
legacy: def.legacy,
|
legacy: def.legacy,
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
self.non_exported_macro_attrs.extend(attrs.into_iter());
|
||||||
}
|
}
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,6 +119,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
|
||||||
span,
|
span,
|
||||||
// These fields are handled separately:
|
// These fields are handled separately:
|
||||||
exported_macros: _,
|
exported_macros: _,
|
||||||
|
non_exported_macro_attrs: _,
|
||||||
items: _,
|
items: _,
|
||||||
trait_items: _,
|
trait_items: _,
|
||||||
impl_items: _,
|
impl_items: _,
|
||||||
|
|
|
@ -727,6 +727,8 @@ pub struct Crate {
|
||||||
pub attrs: HirVec<Attribute>,
|
pub attrs: HirVec<Attribute>,
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub exported_macros: HirVec<MacroDef>,
|
pub exported_macros: HirVec<MacroDef>,
|
||||||
|
// Attributes from non-exported macros, kept only for collecting the library feature list.
|
||||||
|
pub non_exported_macro_attrs: HirVec<Attribute>,
|
||||||
|
|
||||||
// N.B., we use a BTreeMap here so that `visit_all_items` iterates
|
// N.B., we use a BTreeMap here so that `visit_all_items` iterates
|
||||||
// over the ids in increasing order. In principle it should not
|
// over the ids in increasing order. In principle it should not
|
||||||
|
|
|
@ -5,10 +5,12 @@
|
||||||
//! lints are all available in `rustc_lint::builtin`.
|
//! lints are all available in `rustc_lint::builtin`.
|
||||||
|
|
||||||
use crate::lint::{LintPass, LateLintPass, LintArray};
|
use crate::lint::{LintPass, LateLintPass, LintArray};
|
||||||
|
use crate::middle::stability;
|
||||||
use crate::session::Session;
|
use crate::session::Session;
|
||||||
use errors::{Applicability, DiagnosticBuilder};
|
use errors::{Applicability, DiagnosticBuilder};
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::source_map::Span;
|
use syntax::source_map::Span;
|
||||||
|
use syntax::symbol::Symbol;
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
pub EXCEEDING_BITSHIFTS,
|
pub EXCEEDING_BITSHIFTS,
|
||||||
|
@ -461,6 +463,7 @@ pub enum BuiltinLintDiagnostics {
|
||||||
UnusedImports(String, Vec<(Span, String)>),
|
UnusedImports(String, Vec<(Span, String)>),
|
||||||
NestedImplTrait { outer_impl_trait_span: Span, inner_impl_trait_span: Span },
|
NestedImplTrait { outer_impl_trait_span: Span, inner_impl_trait_span: Span },
|
||||||
RedundantImport(Vec<(Span, bool)>, ast::Ident),
|
RedundantImport(Vec<(Span, bool)>, ast::Ident),
|
||||||
|
DeprecatedMacro(Option<Symbol>, Span),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn add_elided_lifetime_in_path_suggestion(
|
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),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -144,6 +144,10 @@ impl Visitor<'tcx> for LibFeatureCollector<'tcx> {
|
||||||
|
|
||||||
pub fn collect(tcx: TyCtxt<'_>) -> LibFeatures {
|
pub fn collect(tcx: TyCtxt<'_>) -> LibFeatures {
|
||||||
let mut collector = LibFeatureCollector::new(tcx);
|
let mut collector = LibFeatureCollector::new(tcx);
|
||||||
intravisit::walk_crate(&mut collector, tcx.hir().krate());
|
let krate = tcx.hir().krate();
|
||||||
|
for attr in &krate.non_exported_macro_attrs {
|
||||||
|
collector.visit_attribute(attr);
|
||||||
|
}
|
||||||
|
intravisit::walk_crate(&mut collector, krate);
|
||||||
collector.lib_features
|
collector.lib_features
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
pub use self::StabilityLevel::*;
|
pub use self::StabilityLevel::*;
|
||||||
|
|
||||||
use crate::lint::{self, Lint, in_derive_expansion};
|
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::{self, Item, Generics, StructField, Variant, HirId};
|
||||||
use crate::hir::def::{Res, DefKind};
|
use crate::hir::def::{Res, DefKind};
|
||||||
use crate::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId, LOCAL_CRATE};
|
use crate::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId, LOCAL_CRATE};
|
||||||
|
@ -11,12 +12,13 @@ use crate::hir::intravisit::{self, Visitor, NestedVisitorMap};
|
||||||
use crate::ty::query::Providers;
|
use crate::ty::query::Providers;
|
||||||
use crate::middle::privacy::AccessLevels;
|
use crate::middle::privacy::AccessLevels;
|
||||||
use crate::session::{DiagnosticMessageId, Session};
|
use crate::session::{DiagnosticMessageId, Session};
|
||||||
|
use errors::DiagnosticBuilder;
|
||||||
use syntax::symbol::{Symbol, sym};
|
use syntax::symbol::{Symbol, sym};
|
||||||
use syntax_pos::{Span, MultiSpan};
|
use syntax_pos::{Span, MultiSpan};
|
||||||
use syntax::ast::Attribute;
|
use syntax::ast::{Attribute, CRATE_NODE_ID};
|
||||||
use syntax::errors::Applicability;
|
use syntax::errors::Applicability;
|
||||||
use syntax::feature_gate::{GateIssue, emit_feature_err};
|
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::ty::{self, TyCtxt};
|
||||||
use crate::util::nodemap::{FxHashSet, FxHashMap};
|
use crate::util::nodemap::{FxHashSet, FxHashMap};
|
||||||
|
|
||||||
|
@ -477,6 +479,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
|
/// Checks whether an item marked with `deprecated(since="X")` is currently
|
||||||
/// deprecated (i.e., whether X is not greater than the current rustc version).
|
/// deprecated (i.e., whether X is not greater than the current rustc version).
|
||||||
pub fn deprecation_in_effect(since: &str) -> bool {
|
pub fn deprecation_in_effect(since: &str) -> bool {
|
||||||
|
@ -501,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> {
|
struct Checker<'tcx> {
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
}
|
}
|
||||||
|
@ -563,38 +668,6 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
/// deprecated. If the item is indeed deprecated, we will emit a deprecation lint attached to
|
/// deprecated. If the item is indeed deprecated, we will emit a deprecation lint attached to
|
||||||
/// `id`.
|
/// `id`.
|
||||||
pub fn eval_stability(self, def_id: DefId, id: Option<HirId>, span: Span) -> EvalResult {
|
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.
|
// Deprecated attributes apply in-crate and cross-crate.
|
||||||
if let Some(id) = id {
|
if let Some(id) = id {
|
||||||
if let Some(depr_entry) = self.lookup_deprecation_entry(def_id) {
|
if let Some(depr_entry) = self.lookup_deprecation_entry(def_id) {
|
||||||
|
@ -604,14 +677,9 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
.map_or(false, |parent_depr| parent_depr.same_origin(&depr_entry));
|
.map_or(false, |parent_depr| parent_depr.same_origin(&depr_entry));
|
||||||
|
|
||||||
if !skip {
|
if !skip {
|
||||||
let path = self.def_path_str(def_id);
|
let (message, lint) =
|
||||||
let message = format!("use of deprecated item '{}'", path);
|
deprecation_message(&depr_entry.attr, &self.def_path_str(def_id));
|
||||||
lint_deprecated(def_id,
|
late_report_deprecation(self, &message, None, lint, span, def_id, id);
|
||||||
id,
|
|
||||||
depr_entry.attr.note,
|
|
||||||
None,
|
|
||||||
&message,
|
|
||||||
lint::builtin::DEPRECATED);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -631,27 +699,11 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
if let Some(id) = id {
|
if let Some(id) = id {
|
||||||
if let Some(stability) = stability {
|
if let Some(stability) = stability {
|
||||||
if let Some(depr) = &stability.rustc_depr {
|
if let Some(depr) = &stability.rustc_depr {
|
||||||
let path = self.def_path_str(def_id);
|
let (message, lint) =
|
||||||
if deprecation_in_effect(&depr.since.as_str()) {
|
rustc_deprecation_message(depr, &self.def_path_str(def_id));
|
||||||
let message = format!("use of deprecated item '{}'", path);
|
late_report_deprecation(
|
||||||
lint_deprecated(def_id,
|
self, &message, depr.suggestion, lint, span, def_id, 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -715,34 +767,8 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
pub fn check_stability(self, def_id: DefId, id: Option<HirId>, span: Span) {
|
pub fn check_stability(self, def_id: DefId, id: Option<HirId>, span: Span) {
|
||||||
match self.eval_stability(def_id, id, span) {
|
match self.eval_stability(def_id, id, span) {
|
||||||
EvalResult::Allow => {}
|
EvalResult::Allow => {}
|
||||||
EvalResult::Deny { feature, reason, issue } => {
|
EvalResult::Deny { feature, reason, issue } =>
|
||||||
let msg = match reason {
|
report_unstable(self.sess, feature, reason, issue, span),
|
||||||
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::Unmarked => {
|
EvalResult::Unmarked => {
|
||||||
// The API could be uncallable for other reasons, for example when a private module
|
// The API could be uncallable for other reasons, for example when a private module
|
||||||
// was referenced.
|
// was referenced.
|
||||||
|
|
|
@ -84,10 +84,7 @@ impl<'a> Registry<'a> {
|
||||||
/// Register a syntax extension of any kind.
|
/// Register a syntax extension of any kind.
|
||||||
///
|
///
|
||||||
/// This is the most general hook into `libsyntax`'s expansion behavior.
|
/// This is the most general hook into `libsyntax`'s expansion behavior.
|
||||||
pub fn register_syntax_extension(&mut self, name: ast::Name, mut extension: SyntaxExtension) {
|
pub fn register_syntax_extension(&mut self, name: ast::Name, extension: SyntaxExtension) {
|
||||||
if extension.def_info.is_none() {
|
|
||||||
extension.def_info = Some((ast::CRATE_NODE_ID, self.krate_span));
|
|
||||||
}
|
|
||||||
self.syntax_exts.push((name, extension));
|
self.syntax_exts.push((name, extension));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1666,10 +1666,7 @@ pub struct Resolver<'a> {
|
||||||
non_macro_attrs: [Lrc<SyntaxExtension>; 2],
|
non_macro_attrs: [Lrc<SyntaxExtension>; 2],
|
||||||
macro_defs: FxHashMap<Mark, DefId>,
|
macro_defs: FxHashMap<Mark, DefId>,
|
||||||
local_macro_def_scopes: FxHashMap<NodeId, Module<'a>>,
|
local_macro_def_scopes: FxHashMap<NodeId, Module<'a>>,
|
||||||
|
unused_macros: NodeMap<Span>,
|
||||||
/// List of crate local macros that we need to warn about as being unused.
|
|
||||||
/// Right now this only includes macro_rules! macros, and macros 2.0.
|
|
||||||
unused_macros: FxHashSet<DefId>,
|
|
||||||
|
|
||||||
/// Maps the `Mark` of an expansion to its containing module or block.
|
/// Maps the `Mark` of an expansion to its containing module or block.
|
||||||
invocations: FxHashMap<Mark, &'a InvocationData<'a>>,
|
invocations: FxHashMap<Mark, &'a InvocationData<'a>>,
|
||||||
|
@ -1687,6 +1684,9 @@ pub struct Resolver<'a> {
|
||||||
current_type_ascription: Vec<Span>,
|
current_type_ascription: Vec<Span>,
|
||||||
|
|
||||||
injected_crate: Option<Module<'a>>,
|
injected_crate: Option<Module<'a>>,
|
||||||
|
|
||||||
|
/// Features enabled for this crate.
|
||||||
|
active_features: FxHashSet<Symbol>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Nothing really interesting here; it just provides memory for the rest of the crate.
|
/// Nothing really interesting here; it just provides memory for the rest of the crate.
|
||||||
|
@ -1925,6 +1925,7 @@ impl<'a> Resolver<'a> {
|
||||||
let mut macro_defs = FxHashMap::default();
|
let mut macro_defs = FxHashMap::default();
|
||||||
macro_defs.insert(Mark::root(), root_def_id);
|
macro_defs.insert(Mark::root(), root_def_id);
|
||||||
|
|
||||||
|
let features = session.features_untracked();
|
||||||
let non_macro_attr = |mark_used| Lrc::new(SyntaxExtension::default(
|
let non_macro_attr = |mark_used| Lrc::new(SyntaxExtension::default(
|
||||||
SyntaxExtensionKind::NonMacroAttr { mark_used }, session.edition()
|
SyntaxExtensionKind::NonMacroAttr { mark_used }, session.edition()
|
||||||
));
|
));
|
||||||
|
@ -2009,9 +2010,13 @@ impl<'a> Resolver<'a> {
|
||||||
name_already_seen: FxHashMap::default(),
|
name_already_seen: FxHashMap::default(),
|
||||||
potentially_unused_imports: Vec::new(),
|
potentially_unused_imports: Vec::new(),
|
||||||
struct_constructors: Default::default(),
|
struct_constructors: Default::default(),
|
||||||
unused_macros: FxHashSet::default(),
|
unused_macros: Default::default(),
|
||||||
current_type_ascription: Vec::new(),
|
current_type_ascription: Vec::new(),
|
||||||
injected_crate: None,
|
injected_crate: None,
|
||||||
|
active_features:
|
||||||
|
features.declared_lib_features.iter().map(|(feat, ..)| *feat)
|
||||||
|
.chain(features.declared_lang_features.iter().map(|(feat, ..)| *feat))
|
||||||
|
.collect(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,10 +9,10 @@ use crate::resolve_imports::ImportResolver;
|
||||||
use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX};
|
use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX};
|
||||||
use rustc::hir::def::{self, DefKind, NonMacroAttrKind};
|
use rustc::hir::def::{self, DefKind, NonMacroAttrKind};
|
||||||
use rustc::hir::map::{self, DefCollector};
|
use rustc::hir::map::{self, DefCollector};
|
||||||
use rustc::{ty, lint};
|
use rustc::middle::stability;
|
||||||
use rustc::{bug, span_bug};
|
use rustc::{ty, lint, span_bug};
|
||||||
use syntax::ast::{self, Ident};
|
use syntax::ast::{self, Ident};
|
||||||
use syntax::attr;
|
use syntax::attr::{self, StabilityLevel};
|
||||||
use syntax::errors::DiagnosticBuilder;
|
use syntax::errors::DiagnosticBuilder;
|
||||||
use syntax::ext::base::{self, Determinacy};
|
use syntax::ext::base::{self, Determinacy};
|
||||||
use syntax::ext::base::{MacroKind, SyntaxExtension};
|
use syntax::ext::base::{MacroKind, SyntaxExtension};
|
||||||
|
@ -230,16 +230,19 @@ impl<'a> base::Resolver for Resolver<'a> {
|
||||||
Err(determinacy) => return Err(determinacy),
|
Err(determinacy) => return Err(determinacy),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let span = invoc.span();
|
||||||
|
let path = fast_print_path(path);
|
||||||
let format = match kind {
|
let format = match kind {
|
||||||
MacroKind::Derive => format!("derive({})", fast_print_path(path)),
|
MacroKind::Derive => format!("derive({})", path),
|
||||||
_ => fast_print_path(path),
|
_ => path.clone(),
|
||||||
};
|
};
|
||||||
invoc.expansion_data.mark.set_expn_info(ext.expn_info(invoc.span(), &format));
|
invoc.expansion_data.mark.set_expn_info(ext.expn_info(span, &format));
|
||||||
|
|
||||||
|
self.check_stability_and_deprecation(&ext, &path, span);
|
||||||
|
|
||||||
if let Res::Def(_, def_id) = res {
|
if let Res::Def(_, def_id) = res {
|
||||||
if after_derive {
|
if after_derive {
|
||||||
self.session.span_err(invoc.span(),
|
self.session.span_err(span, "macro attributes must be placed before `#[derive]`");
|
||||||
"macro attributes must be placed before `#[derive]`");
|
|
||||||
}
|
}
|
||||||
self.macro_defs.insert(invoc.expansion_data.mark, def_id);
|
self.macro_defs.insert(invoc.expansion_data.mark, def_id);
|
||||||
let normal_module_def_id =
|
let normal_module_def_id =
|
||||||
|
@ -259,14 +262,10 @@ impl<'a> base::Resolver for Resolver<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_unused_macros(&self) {
|
fn check_unused_macros(&self) {
|
||||||
for did in self.unused_macros.iter() {
|
for (&node_id, &span) in self.unused_macros.iter() {
|
||||||
if let Some((id, span)) = self.macro_map[did].def_info {
|
self.session.buffer_lint(
|
||||||
let lint = lint::builtin::UNUSED_MACROS;
|
lint::builtin::UNUSED_MACROS, node_id, span, "unused macro definition"
|
||||||
let msg = "unused macro definition";
|
);
|
||||||
self.session.buffer_lint(lint, id, span, msg);
|
|
||||||
} else {
|
|
||||||
bug!("attempted to create unused macro error, but span not available");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -323,7 +322,9 @@ impl<'a> Resolver<'a> {
|
||||||
|
|
||||||
match res {
|
match res {
|
||||||
Res::Def(DefKind::Macro(macro_kind), def_id) => {
|
Res::Def(DefKind::Macro(macro_kind), def_id) => {
|
||||||
self.unused_macros.remove(&def_id);
|
if let Some(node_id) = self.definitions.as_local_node_id(def_id) {
|
||||||
|
self.unused_macros.remove(&node_id);
|
||||||
|
}
|
||||||
if macro_kind == MacroKind::ProcMacroStub {
|
if macro_kind == MacroKind::ProcMacroStub {
|
||||||
let msg = "can't use a procedural macro from the same crate that defines it";
|
let msg = "can't use a procedural macro from the same crate that defines it";
|
||||||
self.session.span_err(path.span, msg);
|
self.session.span_err(path.span, msg);
|
||||||
|
@ -1009,6 +1010,27 @@ 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 = stability.feature;
|
||||||
|
if !self.active_features.contains(&feature) && !span.allows_unstable(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>>,
|
fn prohibit_imported_non_macro_attrs(&self, binding: Option<&'a NameBinding<'a>>,
|
||||||
res: Option<Res>, span: Span) {
|
res: Option<Res>, span: Span) {
|
||||||
if let Some(Res::NonMacroAttr(kind)) = res {
|
if let Some(Res::NonMacroAttr(kind)) = res {
|
||||||
|
@ -1157,13 +1179,13 @@ impl<'a> Resolver<'a> {
|
||||||
(res, vis, item.span, expansion, IsMacroExport));
|
(res, vis, item.span, expansion, IsMacroExport));
|
||||||
} else {
|
} else {
|
||||||
self.check_reserved_macro_name(ident, res);
|
self.check_reserved_macro_name(ident, res);
|
||||||
self.unused_macros.insert(def_id);
|
self.unused_macros.insert(item.id, item.span);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let module = self.current_module;
|
let module = self.current_module;
|
||||||
let vis = self.resolve_visibility(&item.vis);
|
let vis = self.resolve_visibility(&item.vis);
|
||||||
if vis != ty::Visibility::Public {
|
if vis != ty::Visibility::Public {
|
||||||
self.unused_macros.insert(def_id);
|
self.unused_macros.insert(item.id, item.span);
|
||||||
}
|
}
|
||||||
self.define(module, ident, MacroNS, (res, vis, item.span, expansion));
|
self.define(module, ident, MacroNS, (res, vis, item.span, expansion));
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,8 +103,8 @@
|
||||||
//!
|
//!
|
||||||
//! ```rust
|
//! ```rust
|
||||||
//! # #![feature(rustc_private)]
|
//! # #![feature(rustc_private)]
|
||||||
//! extern crate serialize;
|
//! extern crate serialize as rustc_serialize;
|
||||||
//! use serialize::json::{self, ToJson, Json};
|
//! use rustc_serialize::json::{self, ToJson, Json};
|
||||||
//!
|
//!
|
||||||
//! // A custom data structure
|
//! // A custom data structure
|
||||||
//! struct ComplexNum {
|
//! struct ComplexNum {
|
||||||
|
@ -120,7 +120,7 @@
|
||||||
//! }
|
//! }
|
||||||
//!
|
//!
|
||||||
//! // Only generate `RustcEncodable` trait implementation
|
//! // Only generate `RustcEncodable` trait implementation
|
||||||
//! #[derive(Encodable)]
|
//! #[derive(RustcEncodable)]
|
||||||
//! pub struct ComplexNumRecord {
|
//! pub struct ComplexNumRecord {
|
||||||
//! uid: u8,
|
//! uid: u8,
|
||||||
//! dsc: String,
|
//! dsc: String,
|
||||||
|
@ -143,12 +143,12 @@
|
||||||
//!
|
//!
|
||||||
//! ```rust
|
//! ```rust
|
||||||
//! # #![feature(rustc_private)]
|
//! # #![feature(rustc_private)]
|
||||||
//! extern crate serialize;
|
//! extern crate serialize as rustc_serialize;
|
||||||
//! use std::collections::BTreeMap;
|
//! use std::collections::BTreeMap;
|
||||||
//! use serialize::json::{self, Json, ToJson};
|
//! use rustc_serialize::json::{self, Json, ToJson};
|
||||||
//!
|
//!
|
||||||
//! // Only generate `Decodable` trait implementation
|
//! // Only generate `RustcDecodable` trait implementation
|
||||||
//! #[derive(Decodable)]
|
//! #[derive(RustcDecodable)]
|
||||||
//! pub struct TestStruct {
|
//! pub struct TestStruct {
|
||||||
//! data_int: u8,
|
//! data_int: u8,
|
||||||
//! data_str: String,
|
//! data_str: String,
|
||||||
|
|
|
@ -135,6 +135,19 @@ pub enum StabilityLevel {
|
||||||
Stable { since: Symbol },
|
Stable { since: Symbol },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Stability {
|
||||||
|
pub fn unstable(feature: Symbol, reason: Option<Symbol>, issue: u32) -> Stability {
|
||||||
|
Stability {
|
||||||
|
level: StabilityLevel::Unstable { reason, issue },
|
||||||
|
feature,
|
||||||
|
rustc_depr: None,
|
||||||
|
const_stability: None,
|
||||||
|
promotable: false,
|
||||||
|
allow_const_fn_ptr: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl StabilityLevel {
|
impl StabilityLevel {
|
||||||
pub fn is_unstable(&self) -> bool {
|
pub fn is_unstable(&self) -> bool {
|
||||||
if let StabilityLevel::Unstable {..} = *self {
|
if let StabilityLevel::Unstable {..} = *self {
|
||||||
|
@ -171,7 +184,8 @@ pub fn contains_feature_attr(attrs: &[Attribute], feature_name: Symbol) -> bool
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Finds the first stability attribute. `None` if none exists.
|
/// Collects stability info from all stability attributes in `attrs`.
|
||||||
|
/// Returns `None` if no stability attributes are found.
|
||||||
pub fn find_stability(sess: &ParseSess, attrs: &[Attribute],
|
pub fn find_stability(sess: &ParseSess, attrs: &[Attribute],
|
||||||
item_sp: Span) -> Option<Stability> {
|
item_sp: Span) -> Option<Stability> {
|
||||||
find_stability_generic(sess, attrs.iter(), item_sp)
|
find_stability_generic(sess, attrs.iter(), item_sp)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::ast::{self, Attribute, Name, PatKind};
|
use crate::ast::{self, Attribute, Name, PatKind};
|
||||||
use crate::attr::HasAttrs;
|
use crate::attr::{HasAttrs, Stability, Deprecation};
|
||||||
use crate::source_map::{SourceMap, Spanned, respan};
|
use crate::source_map::{SourceMap, Spanned, respan};
|
||||||
use crate::edition::Edition;
|
use crate::edition::Edition;
|
||||||
use crate::ext::expand::{self, AstFragment, Invocation};
|
use crate::ext::expand::{self, AstFragment, Invocation};
|
||||||
|
@ -606,8 +606,8 @@ pub enum SyntaxExtensionKind {
|
||||||
pub struct SyntaxExtension {
|
pub struct SyntaxExtension {
|
||||||
/// A syntax extension kind.
|
/// A syntax extension kind.
|
||||||
pub kind: SyntaxExtensionKind,
|
pub kind: SyntaxExtensionKind,
|
||||||
/// Some info about the macro's definition point.
|
/// Span of the macro definition.
|
||||||
pub def_info: Option<(ast::NodeId, Span)>,
|
pub span: Span,
|
||||||
/// Hygienic properties of spans produced by this macro by default.
|
/// Hygienic properties of spans produced by this macro by default.
|
||||||
pub default_transparency: Transparency,
|
pub default_transparency: Transparency,
|
||||||
/// Whitelist of unstable features that are treated as stable inside this macro.
|
/// Whitelist of unstable features that are treated as stable inside this macro.
|
||||||
|
@ -616,8 +616,10 @@ pub struct SyntaxExtension {
|
||||||
pub allow_internal_unsafe: bool,
|
pub allow_internal_unsafe: bool,
|
||||||
/// Enables the macro helper hack (`ident!(...)` -> `$crate::ident!(...)`) for this macro.
|
/// Enables the macro helper hack (`ident!(...)` -> `$crate::ident!(...)`) for this macro.
|
||||||
pub local_inner_macros: bool,
|
pub local_inner_macros: bool,
|
||||||
/// The macro's feature name and tracking issue number if it is unstable.
|
/// The macro's stability info.
|
||||||
pub unstable_feature: Option<(Symbol, u32)>,
|
pub stability: Option<Stability>,
|
||||||
|
/// The macro's deprecation info.
|
||||||
|
pub deprecation: Option<Deprecation>,
|
||||||
/// Names of helper attributes registered by this macro.
|
/// Names of helper attributes registered by this macro.
|
||||||
pub helper_attrs: Vec<Symbol>,
|
pub helper_attrs: Vec<Symbol>,
|
||||||
/// Edition of the crate in which this macro is defined.
|
/// Edition of the crate in which this macro is defined.
|
||||||
|
@ -657,12 +659,13 @@ impl SyntaxExtension {
|
||||||
/// Constructs a syntax extension with default properties.
|
/// Constructs a syntax extension with default properties.
|
||||||
pub fn default(kind: SyntaxExtensionKind, edition: Edition) -> SyntaxExtension {
|
pub fn default(kind: SyntaxExtensionKind, edition: Edition) -> SyntaxExtension {
|
||||||
SyntaxExtension {
|
SyntaxExtension {
|
||||||
def_info: None,
|
span: DUMMY_SP,
|
||||||
default_transparency: kind.default_transparency(),
|
default_transparency: kind.default_transparency(),
|
||||||
allow_internal_unstable: None,
|
allow_internal_unstable: None,
|
||||||
allow_internal_unsafe: false,
|
allow_internal_unsafe: false,
|
||||||
local_inner_macros: false,
|
local_inner_macros: false,
|
||||||
unstable_feature: None,
|
stability: None,
|
||||||
|
deprecation: None,
|
||||||
helper_attrs: Vec::new(),
|
helper_attrs: Vec::new(),
|
||||||
edition,
|
edition,
|
||||||
kind,
|
kind,
|
||||||
|
@ -681,7 +684,7 @@ impl SyntaxExtension {
|
||||||
ExpnInfo {
|
ExpnInfo {
|
||||||
call_site,
|
call_site,
|
||||||
format: self.expn_format(Symbol::intern(format)),
|
format: self.expn_format(Symbol::intern(format)),
|
||||||
def_site: self.def_info.map(|(_, span)| span),
|
def_site: Some(self.span),
|
||||||
default_transparency: self.default_transparency,
|
default_transparency: self.default_transparency,
|
||||||
allow_internal_unstable: self.allow_internal_unstable.clone(),
|
allow_internal_unstable: self.allow_internal_unstable.clone(),
|
||||||
allow_internal_unsafe: self.allow_internal_unsafe,
|
allow_internal_unsafe: self.allow_internal_unsafe,
|
||||||
|
@ -738,7 +741,6 @@ pub struct ExpansionData {
|
||||||
pub depth: usize,
|
pub depth: usize,
|
||||||
pub module: Rc<ModuleData>,
|
pub module: Rc<ModuleData>,
|
||||||
pub directory_ownership: DirectoryOwnership,
|
pub directory_ownership: DirectoryOwnership,
|
||||||
pub crate_span: Option<Span>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// One of these is made during expansion and incrementally updated as we go;
|
/// One of these is made during expansion and incrementally updated as we go;
|
||||||
|
@ -768,7 +770,6 @@ impl<'a> ExtCtxt<'a> {
|
||||||
depth: 0,
|
depth: 0,
|
||||||
module: Rc::new(ModuleData { mod_path: Vec::new(), directory: PathBuf::new() }),
|
module: Rc::new(ModuleData { mod_path: Vec::new(), directory: PathBuf::new() }),
|
||||||
directory_ownership: DirectoryOwnership::Owned { relative: None },
|
directory_ownership: DirectoryOwnership::Owned { relative: None },
|
||||||
crate_span: None,
|
|
||||||
},
|
},
|
||||||
expansions: FxHashMap::default(),
|
expansions: FxHashMap::default(),
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,11 +63,11 @@ pub fn add_derived_markers<T>(cx: &mut ExtCtxt<'_>, span: Span, traits: &[ast::P
|
||||||
|
|
||||||
let span = span.with_ctxt(cx.backtrace());
|
let span = span.with_ctxt(cx.backtrace());
|
||||||
item.visit_attrs(|attrs| {
|
item.visit_attrs(|attrs| {
|
||||||
if names.contains(&Symbol::intern("Eq")) && names.contains(&Symbol::intern("PartialEq")) {
|
if names.contains(&sym::Eq) && names.contains(&sym::PartialEq) {
|
||||||
let meta = cx.meta_word(span, Symbol::intern("structural_match"));
|
let meta = cx.meta_word(span, sym::structural_match);
|
||||||
attrs.push(cx.attribute(span, meta));
|
attrs.push(cx.attribute(span, meta));
|
||||||
}
|
}
|
||||||
if names.contains(&Symbol::intern("Copy")) {
|
if names.contains(&sym::Copy) {
|
||||||
let meta = cx.meta_word(span, sym::rustc_copy_clone_marker);
|
let meta = cx.meta_word(span, sym::rustc_copy_clone_marker);
|
||||||
attrs.push(cx.attribute(span, meta));
|
attrs.push(cx.attribute(span, meta));
|
||||||
}
|
}
|
||||||
|
|
|
@ -243,7 +243,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||||
module.directory.pop();
|
module.directory.pop();
|
||||||
self.cx.root_path = module.directory.clone();
|
self.cx.root_path = module.directory.clone();
|
||||||
self.cx.current_expansion.module = Rc::new(module);
|
self.cx.current_expansion.module = Rc::new(module);
|
||||||
self.cx.current_expansion.crate_span = Some(krate.span);
|
|
||||||
|
|
||||||
let orig_mod_span = krate.module.inner;
|
let orig_mod_span = krate.module.inner;
|
||||||
|
|
||||||
|
@ -488,7 +487,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||||
|
|
||||||
fn expand_invoc(&mut self, invoc: Invocation, ext: &SyntaxExtension) -> Option<AstFragment> {
|
fn expand_invoc(&mut self, invoc: Invocation, ext: &SyntaxExtension) -> Option<AstFragment> {
|
||||||
if invoc.fragment_kind == AstFragmentKind::ForeignItems &&
|
if invoc.fragment_kind == AstFragmentKind::ForeignItems &&
|
||||||
!self.cx.ecfg.macros_in_extern_enabled() {
|
!self.cx.ecfg.macros_in_extern() {
|
||||||
if let SyntaxExtensionKind::NonMacroAttr { .. } = ext.kind {} else {
|
if let SyntaxExtensionKind::NonMacroAttr { .. } = ext.kind {} else {
|
||||||
emit_feature_err(&self.cx.parse_sess, sym::macros_in_extern,
|
emit_feature_err(&self.cx.parse_sess, sym::macros_in_extern,
|
||||||
invoc.span(), GateIssue::Language,
|
invoc.span(), GateIssue::Language,
|
||||||
|
@ -668,40 +667,17 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||||
};
|
};
|
||||||
let path = &mac.node.path;
|
let path = &mac.node.path;
|
||||||
|
|
||||||
let validate = |this: &mut Self| {
|
|
||||||
// feature-gate the macro invocation
|
|
||||||
if let Some((feature, issue)) = ext.unstable_feature {
|
|
||||||
let crate_span = this.cx.current_expansion.crate_span.unwrap();
|
|
||||||
// don't stability-check macros in the same crate
|
|
||||||
// (the only time this is null is for syntax extensions registered as macros)
|
|
||||||
if ext.def_info.map_or(false, |(_, def_span)| !crate_span.contains(def_span))
|
|
||||||
&& !span.allows_unstable(feature)
|
|
||||||
&& this.cx.ecfg.features.map_or(true, |feats| {
|
|
||||||
// macro features will count as lib features
|
|
||||||
!feats.declared_lib_features.iter().any(|&(feat, _)| feat == feature)
|
|
||||||
}) {
|
|
||||||
let explain = format!("macro {}! is unstable", path);
|
|
||||||
emit_feature_err(this.cx.parse_sess, feature, span,
|
|
||||||
GateIssue::Library(Some(issue)), &explain);
|
|
||||||
this.cx.trace_macros_diag();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
};
|
|
||||||
|
|
||||||
let opt_expanded = match &ext.kind {
|
let opt_expanded = match &ext.kind {
|
||||||
|
SyntaxExtensionKind::Bang(expander) => {
|
||||||
|
self.gate_proc_macro_expansion_kind(span, kind);
|
||||||
|
let tok_result = expander.expand(self.cx, span, mac.node.stream());
|
||||||
|
let result = self.parse_ast_fragment(tok_result, kind, path, span);
|
||||||
|
self.gate_proc_macro_expansion(span, &result);
|
||||||
|
result
|
||||||
|
}
|
||||||
SyntaxExtensionKind::LegacyBang(expander) => {
|
SyntaxExtensionKind::LegacyBang(expander) => {
|
||||||
if let Err(dummy_span) = validate(self) {
|
let tok_result = expander.expand(self.cx, span, mac.node.stream(), Some(ext.span));
|
||||||
dummy_span
|
kind.make_from(tok_result)
|
||||||
} else {
|
|
||||||
kind.make_from(expander.expand(
|
|
||||||
self.cx,
|
|
||||||
span,
|
|
||||||
mac.node.stream(),
|
|
||||||
ext.def_info.map(|(_, s)| s),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SyntaxExtensionKind::Attr(..) |
|
SyntaxExtensionKind::Attr(..) |
|
||||||
|
@ -718,14 +694,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||||
self.cx.trace_macros_diag();
|
self.cx.trace_macros_diag();
|
||||||
kind.dummy(span)
|
kind.dummy(span)
|
||||||
}
|
}
|
||||||
|
|
||||||
SyntaxExtensionKind::Bang(expander) => {
|
|
||||||
self.gate_proc_macro_expansion_kind(span, kind);
|
|
||||||
let tok_result = expander.expand(self.cx, span, mac.node.stream());
|
|
||||||
let result = self.parse_ast_fragment(tok_result, kind, path, span);
|
|
||||||
self.gate_proc_macro_expansion(span, &result);
|
|
||||||
result
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if opt_expanded.is_some() {
|
if opt_expanded.is_some() {
|
||||||
|
@ -951,7 +919,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
|
||||||
})
|
})
|
||||||
.map(|i| attrs.remove(i));
|
.map(|i| attrs.remove(i));
|
||||||
if let Some(attr) = &attr {
|
if let Some(attr) = &attr {
|
||||||
if !self.cx.ecfg.enable_custom_inner_attributes() &&
|
if !self.cx.ecfg.custom_inner_attributes() &&
|
||||||
attr.style == ast::AttrStyle::Inner && attr.path != sym::test {
|
attr.style == ast::AttrStyle::Inner && attr.path != sym::test {
|
||||||
emit_feature_err(&self.cx.parse_sess, sym::custom_inner_attributes,
|
emit_feature_err(&self.cx.parse_sess, sym::custom_inner_attributes,
|
||||||
attr.span, GateIssue::Language,
|
attr.span, GateIssue::Language,
|
||||||
|
@ -1464,19 +1432,6 @@ pub struct ExpansionConfig<'feat> {
|
||||||
pub keep_macs: bool,
|
pub keep_macs: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! feature_tests {
|
|
||||||
($( fn $getter:ident = $field:ident, )*) => {
|
|
||||||
$(
|
|
||||||
pub fn $getter(&self) -> bool {
|
|
||||||
match self.features {
|
|
||||||
Some(&Features { $field: true, .. }) => true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)*
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'feat> ExpansionConfig<'feat> {
|
impl<'feat> ExpansionConfig<'feat> {
|
||||||
pub fn default(crate_name: String) -> ExpansionConfig<'static> {
|
pub fn default(crate_name: String) -> ExpansionConfig<'static> {
|
||||||
ExpansionConfig {
|
ExpansionConfig {
|
||||||
|
@ -1490,20 +1445,13 @@ impl<'feat> ExpansionConfig<'feat> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
feature_tests! {
|
fn macros_in_extern(&self) -> bool {
|
||||||
fn enable_asm = asm,
|
self.features.map_or(false, |features| features.macros_in_extern)
|
||||||
fn enable_custom_test_frameworks = custom_test_frameworks,
|
|
||||||
fn enable_global_asm = global_asm,
|
|
||||||
fn enable_log_syntax = log_syntax,
|
|
||||||
fn enable_concat_idents = concat_idents,
|
|
||||||
fn enable_trace_macros = trace_macros,
|
|
||||||
fn enable_allow_internal_unstable = allow_internal_unstable,
|
|
||||||
fn enable_format_args_nl = format_args_nl,
|
|
||||||
fn macros_in_extern_enabled = macros_in_extern,
|
|
||||||
fn proc_macro_hygiene = proc_macro_hygiene,
|
|
||||||
}
|
}
|
||||||
|
fn proc_macro_hygiene(&self) -> bool {
|
||||||
fn enable_custom_inner_attributes(&self) -> bool {
|
self.features.map_or(false, |features| features.proc_macro_hygiene)
|
||||||
|
}
|
||||||
|
fn custom_inner_attributes(&self) -> bool {
|
||||||
self.features.map_or(false, |features| features.custom_inner_attributes)
|
self.features.map_or(false, |features| features.custom_inner_attributes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ use crate::ext::build::AstBuilder;
|
||||||
use crate::parse::{self, token, DirectoryOwnership};
|
use crate::parse::{self, token, DirectoryOwnership};
|
||||||
use crate::print::pprust;
|
use crate::print::pprust;
|
||||||
use crate::ptr::P;
|
use crate::ptr::P;
|
||||||
use crate::symbol::{Symbol, sym};
|
use crate::symbol::Symbol;
|
||||||
use crate::tokenstream;
|
use crate::tokenstream;
|
||||||
|
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
@ -41,16 +41,6 @@ pub fn expand_column(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTr
|
||||||
base::MacEager::expr(cx.expr_u32(topmost, loc.col.to_usize() as u32 + 1))
|
base::MacEager::expr(cx.expr_u32(topmost, loc.col.to_usize() as u32 + 1))
|
||||||
}
|
}
|
||||||
|
|
||||||
/* __rust_unstable_column!(): expands to the current column number */
|
|
||||||
pub fn expand_column_gated(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree])
|
|
||||||
-> Box<dyn base::MacResult+'static> {
|
|
||||||
if sp.allows_unstable(sym::__rust_unstable_column) {
|
|
||||||
expand_column(cx, sp, tts)
|
|
||||||
} else {
|
|
||||||
cx.span_fatal(sp, "the __rust_unstable_column macro is unstable");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// file!(): expands to the current filename */
|
/// file!(): expands to the current filename */
|
||||||
/// The source_file (`loc.file`) contains a bunch more information we could spit
|
/// The source_file (`loc.file`) contains a bunch more information we could spit
|
||||||
/// out if we wanted.
|
/// out if we wanted.
|
||||||
|
|
|
@ -422,8 +422,6 @@ pub fn compile(
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
let allow_internal_unsafe = attr::contains_name(&def.attrs, sym::allow_internal_unsafe);
|
|
||||||
|
|
||||||
let mut local_inner_macros = false;
|
let mut local_inner_macros = false;
|
||||||
if let Some(macro_export) = attr::find_by_name(&def.attrs, sym::macro_export) {
|
if let Some(macro_export) = attr::find_by_name(&def.attrs, sym::macro_export) {
|
||||||
if let Some(l) = macro_export.meta_item_list() {
|
if let Some(l) = macro_export.meta_item_list() {
|
||||||
|
@ -431,23 +429,15 @@ pub fn compile(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let unstable_feature =
|
|
||||||
attr::find_stability(&sess, &def.attrs, def.span).and_then(|stability| {
|
|
||||||
if let attr::StabilityLevel::Unstable { issue, .. } = stability.level {
|
|
||||||
Some((stability.feature, issue))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
SyntaxExtension {
|
SyntaxExtension {
|
||||||
kind: SyntaxExtensionKind::LegacyBang(expander),
|
kind: SyntaxExtensionKind::LegacyBang(expander),
|
||||||
def_info: Some((def.id, def.span)),
|
span: def.span,
|
||||||
default_transparency,
|
default_transparency,
|
||||||
allow_internal_unstable,
|
allow_internal_unstable,
|
||||||
allow_internal_unsafe,
|
allow_internal_unsafe: attr::contains_name(&def.attrs, sym::allow_internal_unsafe),
|
||||||
local_inner_macros,
|
local_inner_macros,
|
||||||
unstable_feature,
|
stability: attr::find_stability(&sess, &def.attrs, def.span),
|
||||||
|
deprecation: attr::find_deprecation(&sess, &def.attrs, def.span),
|
||||||
helper_attrs: Vec::new(),
|
helper_attrs: Vec::new(),
|
||||||
edition,
|
edition,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1568,7 +1568,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
|
||||||
(sym::type_length_limit, CrateLevel, template!(NameValueStr: "N"), Ungated),
|
(sym::type_length_limit, CrateLevel, template!(NameValueStr: "N"), Ungated),
|
||||||
(sym::test_runner, CrateLevel, template!(List: "path"), Gated(Stability::Unstable,
|
(sym::test_runner, CrateLevel, template!(List: "path"), Gated(Stability::Unstable,
|
||||||
sym::custom_test_frameworks,
|
sym::custom_test_frameworks,
|
||||||
EXPLAIN_CUSTOM_TEST_FRAMEWORKS,
|
"custom test frameworks are an unstable feature",
|
||||||
cfg_fn!(custom_test_frameworks))),
|
cfg_fn!(custom_test_frameworks))),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -1819,26 +1819,6 @@ const EXPLAIN_BOX_SYNTAX: &str =
|
||||||
pub const EXPLAIN_STMT_ATTR_SYNTAX: &str =
|
pub const EXPLAIN_STMT_ATTR_SYNTAX: &str =
|
||||||
"attributes on expressions are experimental";
|
"attributes on expressions are experimental";
|
||||||
|
|
||||||
pub const EXPLAIN_ASM: &str =
|
|
||||||
"inline assembly is not stable enough for use and is subject to change";
|
|
||||||
|
|
||||||
pub const EXPLAIN_GLOBAL_ASM: &str =
|
|
||||||
"`global_asm!` is not stable enough for use and is subject to change";
|
|
||||||
|
|
||||||
pub const EXPLAIN_CUSTOM_TEST_FRAMEWORKS: &str =
|
|
||||||
"custom test frameworks are an unstable feature";
|
|
||||||
|
|
||||||
pub const EXPLAIN_LOG_SYNTAX: &str =
|
|
||||||
"`log_syntax!` is not stable enough for use and is subject to change";
|
|
||||||
|
|
||||||
pub const EXPLAIN_CONCAT_IDENTS: &str =
|
|
||||||
"`concat_idents` is not stable enough for use and is subject to change";
|
|
||||||
|
|
||||||
pub const EXPLAIN_FORMAT_ARGS_NL: &str =
|
|
||||||
"`format_args_nl` is only for internal language use and is subject to change";
|
|
||||||
|
|
||||||
pub const EXPLAIN_TRACE_MACROS: &str =
|
|
||||||
"`trace_macros` is not stable enough for use and is subject to change";
|
|
||||||
pub const EXPLAIN_ALLOW_INTERNAL_UNSTABLE: &str =
|
pub const EXPLAIN_ALLOW_INTERNAL_UNSTABLE: &str =
|
||||||
"allow_internal_unstable side-steps feature gating and stability checks";
|
"allow_internal_unstable side-steps feature gating and stability checks";
|
||||||
pub const EXPLAIN_ALLOW_INTERNAL_UNSAFE: &str =
|
pub const EXPLAIN_ALLOW_INTERNAL_UNSAFE: &str =
|
||||||
|
|
|
@ -613,7 +613,7 @@ impl<'a> StringReader<'a> {
|
||||||
if num_digits == 0 {
|
if num_digits == 0 {
|
||||||
self.err_span_(start_bpos, self.pos, "no valid digits found for number");
|
self.err_span_(start_bpos, self.pos, "no valid digits found for number");
|
||||||
|
|
||||||
return (token::Integer, Symbol::intern("0"));
|
return (token::Integer, sym::integer(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
// might be a float, but don't be greedy if this is actually an
|
// might be a float, but don't be greedy if this is actually an
|
||||||
|
|
|
@ -8,7 +8,6 @@ use errors::DiagnosticBuilder;
|
||||||
|
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::ext::base::{self, *};
|
use syntax::ext::base::{self, *};
|
||||||
use syntax::feature_gate;
|
|
||||||
use syntax::parse;
|
use syntax::parse;
|
||||||
use syntax::parse::token::{self, Token};
|
use syntax::parse::token::{self, Token};
|
||||||
use syntax::ptr::P;
|
use syntax::ptr::P;
|
||||||
|
@ -46,14 +45,6 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt<'_>,
|
||||||
sp: Span,
|
sp: Span,
|
||||||
tts: &[tokenstream::TokenTree])
|
tts: &[tokenstream::TokenTree])
|
||||||
-> Box<dyn base::MacResult + 'cx> {
|
-> Box<dyn base::MacResult + 'cx> {
|
||||||
if !cx.ecfg.enable_asm() {
|
|
||||||
feature_gate::emit_feature_err(&cx.parse_sess,
|
|
||||||
sym::asm,
|
|
||||||
sp,
|
|
||||||
feature_gate::GateIssue::Language,
|
|
||||||
feature_gate::EXPLAIN_ASM);
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut inline_asm = match parse_inline_asm(cx, sp, tts) {
|
let mut inline_asm = match parse_inline_asm(cx, sp, tts) {
|
||||||
Ok(Some(inline_asm)) => inline_asm,
|
Ok(Some(inline_asm)) => inline_asm,
|
||||||
Ok(None) => return DummyResult::expr(sp),
|
Ok(None) => return DummyResult::expr(sp),
|
||||||
|
|
|
@ -2,25 +2,16 @@ use rustc_data_structures::thin_vec::ThinVec;
|
||||||
|
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::ext::base::{self, *};
|
use syntax::ext::base::{self, *};
|
||||||
use syntax::feature_gate;
|
|
||||||
use syntax::parse::token::{self, Token};
|
use syntax::parse::token::{self, Token};
|
||||||
use syntax::ptr::P;
|
use syntax::ptr::P;
|
||||||
use syntax_pos::Span;
|
use syntax_pos::Span;
|
||||||
use syntax_pos::symbol::{Symbol, sym};
|
use syntax_pos::symbol::Symbol;
|
||||||
use syntax::tokenstream::TokenTree;
|
use syntax::tokenstream::TokenTree;
|
||||||
|
|
||||||
pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt<'_>,
|
pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt<'_>,
|
||||||
sp: Span,
|
sp: Span,
|
||||||
tts: &[TokenTree])
|
tts: &[TokenTree])
|
||||||
-> Box<dyn base::MacResult + 'cx> {
|
-> Box<dyn base::MacResult + 'cx> {
|
||||||
if !cx.ecfg.enable_concat_idents() {
|
|
||||||
feature_gate::emit_feature_err(&cx.parse_sess,
|
|
||||||
sym::concat_idents,
|
|
||||||
sp,
|
|
||||||
feature_gate::GateIssue::Language,
|
|
||||||
feature_gate::EXPLAIN_CONCAT_IDENTS);
|
|
||||||
}
|
|
||||||
|
|
||||||
if tts.is_empty() {
|
if tts.is_empty() {
|
||||||
cx.span_err(sp, "concat_idents! takes 1 or more arguments.");
|
cx.span_err(sp, "concat_idents! takes 1 or more arguments.");
|
||||||
return DummyResult::any(sp);
|
return DummyResult::any(sp);
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
use crate::deriving::{self, pathvec_std};
|
use crate::deriving::{self, pathvec_std};
|
||||||
use crate::deriving::generic::*;
|
use crate::deriving::generic::*;
|
||||||
use crate::deriving::generic::ty::*;
|
use crate::deriving::generic::ty::*;
|
||||||
use crate::deriving::warn_if_deprecated;
|
|
||||||
|
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::ast::{Expr, MetaItem, Mutability};
|
use syntax::ast::{Expr, MetaItem, Mutability};
|
||||||
|
@ -26,7 +25,6 @@ pub fn expand_deriving_decodable(cx: &mut ExtCtxt<'_>,
|
||||||
mitem: &MetaItem,
|
mitem: &MetaItem,
|
||||||
item: &Annotatable,
|
item: &Annotatable,
|
||||||
push: &mut dyn FnMut(Annotatable)) {
|
push: &mut dyn FnMut(Annotatable)) {
|
||||||
warn_if_deprecated(cx, span, "Decodable");
|
|
||||||
expand_deriving_decodable_imp(cx, span, mitem, item, push, "serialize")
|
expand_deriving_decodable_imp(cx, span, mitem, item, push, "serialize")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,7 +85,6 @@
|
||||||
use crate::deriving::{self, pathvec_std};
|
use crate::deriving::{self, pathvec_std};
|
||||||
use crate::deriving::generic::*;
|
use crate::deriving::generic::*;
|
||||||
use crate::deriving::generic::ty::*;
|
use crate::deriving::generic::ty::*;
|
||||||
use crate::deriving::warn_if_deprecated;
|
|
||||||
|
|
||||||
use syntax::ast::{Expr, ExprKind, MetaItem, Mutability};
|
use syntax::ast::{Expr, ExprKind, MetaItem, Mutability};
|
||||||
use syntax::ext::base::{Annotatable, ExtCtxt};
|
use syntax::ext::base::{Annotatable, ExtCtxt};
|
||||||
|
@ -107,7 +106,6 @@ pub fn expand_deriving_encodable(cx: &mut ExtCtxt<'_>,
|
||||||
mitem: &MetaItem,
|
mitem: &MetaItem,
|
||||||
item: &Annotatable,
|
item: &Annotatable,
|
||||||
push: &mut dyn FnMut(Annotatable)) {
|
push: &mut dyn FnMut(Annotatable)) {
|
||||||
warn_if_deprecated(cx, span, "Encodable");
|
|
||||||
expand_deriving_encodable_imp(cx, span, mitem, item, push, "serialize")
|
expand_deriving_encodable_imp(cx, span, mitem, item, push, "serialize")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
use rustc_data_structures::sync::Lrc;
|
use rustc_data_structures::sync::Lrc;
|
||||||
use syntax::ast::{self, MetaItem};
|
use syntax::ast::{self, MetaItem};
|
||||||
|
use syntax::attr::Deprecation;
|
||||||
use syntax::edition::Edition;
|
use syntax::edition::Edition;
|
||||||
use syntax::ext::base::{Annotatable, ExtCtxt, Resolver, MultiItemModifier};
|
use syntax::ext::base::{Annotatable, ExtCtxt, Resolver, MultiItemModifier};
|
||||||
use syntax::ext::base::{SyntaxExtension, SyntaxExtensionKind};
|
use syntax::ext::base::{SyntaxExtension, SyntaxExtensionKind};
|
||||||
|
@ -60,10 +61,10 @@ impl MultiItemModifier for BuiltinDerive {
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! derive_traits {
|
macro_rules! derive_traits {
|
||||||
($( $name:expr => $func:path, )+) => {
|
($( [$deprecation:expr] $name:ident => $func:path, )+) => {
|
||||||
pub fn is_builtin_trait(name: ast::Name) -> bool {
|
pub fn is_builtin_trait(name: ast::Name) -> bool {
|
||||||
match &*name.as_str() {
|
match name {
|
||||||
$( $name )|+ => true,
|
$( sym::$name )|+ => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,8 +80,12 @@ macro_rules! derive_traits {
|
||||||
|
|
||||||
$(
|
$(
|
||||||
resolver.add_builtin(
|
resolver.add_builtin(
|
||||||
ast::Ident::with_empty_ctxt(Symbol::intern($name)),
|
ast::Ident::with_empty_ctxt(sym::$name),
|
||||||
Lrc::new(SyntaxExtension {
|
Lrc::new(SyntaxExtension {
|
||||||
|
deprecation: $deprecation.map(|msg| Deprecation {
|
||||||
|
since: Some(Symbol::intern("1.0.0")),
|
||||||
|
note: Some(Symbol::intern(msg)),
|
||||||
|
}),
|
||||||
allow_internal_unstable: allow_internal_unstable.clone(),
|
allow_internal_unstable: allow_internal_unstable.clone(),
|
||||||
..SyntaxExtension::default(
|
..SyntaxExtension::default(
|
||||||
SyntaxExtensionKind::LegacyDerive(Box::new(BuiltinDerive($func))),
|
SyntaxExtensionKind::LegacyDerive(Box::new(BuiltinDerive($func))),
|
||||||
|
@ -94,42 +99,41 @@ macro_rules! derive_traits {
|
||||||
}
|
}
|
||||||
|
|
||||||
derive_traits! {
|
derive_traits! {
|
||||||
"Clone" => clone::expand_deriving_clone,
|
[None]
|
||||||
|
Clone => clone::expand_deriving_clone,
|
||||||
|
|
||||||
"Hash" => hash::expand_deriving_hash,
|
[None]
|
||||||
|
Hash => hash::expand_deriving_hash,
|
||||||
|
|
||||||
"RustcEncodable" => encodable::expand_deriving_rustc_encodable,
|
[None]
|
||||||
|
RustcEncodable => encodable::expand_deriving_rustc_encodable,
|
||||||
|
|
||||||
"RustcDecodable" => decodable::expand_deriving_rustc_decodable,
|
[None]
|
||||||
|
RustcDecodable => decodable::expand_deriving_rustc_decodable,
|
||||||
|
|
||||||
"PartialEq" => partial_eq::expand_deriving_partial_eq,
|
[None]
|
||||||
"Eq" => eq::expand_deriving_eq,
|
PartialEq => partial_eq::expand_deriving_partial_eq,
|
||||||
"PartialOrd" => partial_ord::expand_deriving_partial_ord,
|
[None]
|
||||||
"Ord" => ord::expand_deriving_ord,
|
Eq => eq::expand_deriving_eq,
|
||||||
|
[None]
|
||||||
|
PartialOrd => partial_ord::expand_deriving_partial_ord,
|
||||||
|
[None]
|
||||||
|
Ord => ord::expand_deriving_ord,
|
||||||
|
|
||||||
"Debug" => debug::expand_deriving_debug,
|
[None]
|
||||||
|
Debug => debug::expand_deriving_debug,
|
||||||
|
|
||||||
"Default" => default::expand_deriving_default,
|
[None]
|
||||||
|
Default => default::expand_deriving_default,
|
||||||
|
|
||||||
"Copy" => bounds::expand_deriving_copy,
|
[None]
|
||||||
|
Copy => bounds::expand_deriving_copy,
|
||||||
|
|
||||||
// deprecated
|
// deprecated
|
||||||
"Encodable" => encodable::expand_deriving_encodable,
|
[Some("derive(Encodable) is deprecated in favor of derive(RustcEncodable)")]
|
||||||
"Decodable" => decodable::expand_deriving_decodable,
|
Encodable => encodable::expand_deriving_encodable,
|
||||||
}
|
[Some("derive(Decodable) is deprecated in favor of derive(RustcDecodable)")]
|
||||||
|
Decodable => decodable::expand_deriving_decodable,
|
||||||
#[inline] // because `name` is a compile-time constant
|
|
||||||
fn warn_if_deprecated(ecx: &mut ExtCtxt<'_>, sp: Span, name: &str) {
|
|
||||||
if let Some(replacement) = match name {
|
|
||||||
"Encodable" => Some("RustcEncodable"),
|
|
||||||
"Decodable" => Some("RustcDecodable"),
|
|
||||||
_ => None,
|
|
||||||
} {
|
|
||||||
ecx.span_warn(sp,
|
|
||||||
&format!("derive({}) is deprecated in favor of derive({})",
|
|
||||||
name,
|
|
||||||
replacement));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct a name for the inner type parameter that can't collide with any type parameters of
|
/// Construct a name for the inner type parameter that can't collide with any type parameters of
|
||||||
|
|
|
@ -9,7 +9,6 @@ use errors::Applicability;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::ext::base::{self, *};
|
use syntax::ext::base::{self, *};
|
||||||
use syntax::ext::build::AstBuilder;
|
use syntax::ext::build::AstBuilder;
|
||||||
use syntax::feature_gate;
|
|
||||||
use syntax::parse::token;
|
use syntax::parse::token;
|
||||||
use syntax::ptr::P;
|
use syntax::ptr::P;
|
||||||
use syntax::symbol::{Symbol, sym};
|
use syntax::symbol::{Symbol, sym};
|
||||||
|
@ -686,14 +685,16 @@ impl<'a, 'b> Context<'a, 'b> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn expand_format_args<'cx>(ecx: &'cx mut ExtCtxt<'_>,
|
fn expand_format_args_impl<'cx>(
|
||||||
mut sp: Span,
|
ecx: &'cx mut ExtCtxt<'_>,
|
||||||
tts: &[tokenstream::TokenTree])
|
mut sp: Span,
|
||||||
-> Box<dyn base::MacResult + 'cx> {
|
tts: &[tokenstream::TokenTree],
|
||||||
|
nl: bool,
|
||||||
|
) -> Box<dyn base::MacResult + 'cx> {
|
||||||
sp = sp.apply_mark(ecx.current_expansion.mark);
|
sp = sp.apply_mark(ecx.current_expansion.mark);
|
||||||
match parse_args(ecx, sp, tts) {
|
match parse_args(ecx, sp, tts) {
|
||||||
Ok((efmt, args, names)) => {
|
Ok((efmt, args, names)) => {
|
||||||
MacEager::expr(expand_preparsed_format_args(ecx, sp, efmt, args, names, false))
|
MacEager::expr(expand_preparsed_format_args(ecx, sp, efmt, args, names, nl))
|
||||||
}
|
}
|
||||||
Err(mut err) => {
|
Err(mut err) => {
|
||||||
err.emit();
|
err.emit();
|
||||||
|
@ -702,34 +703,20 @@ pub fn expand_format_args<'cx>(ecx: &'cx mut ExtCtxt<'_>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn expand_format_args_nl<'cx>(
|
pub fn expand_format_args<'cx>(
|
||||||
ecx: &'cx mut ExtCtxt<'_>,
|
ecx: &'cx mut ExtCtxt<'_>,
|
||||||
mut sp: Span,
|
sp: Span,
|
||||||
tts: &[tokenstream::TokenTree],
|
tts: &[tokenstream::TokenTree],
|
||||||
) -> Box<dyn base::MacResult + 'cx> {
|
) -> Box<dyn base::MacResult + 'cx> {
|
||||||
//if !ecx.ecfg.enable_allow_internal_unstable() {
|
expand_format_args_impl(ecx, sp, tts, false)
|
||||||
|
}
|
||||||
|
|
||||||
// For some reason, the only one that actually works for `println` is the first check
|
pub fn expand_format_args_nl<'cx>(
|
||||||
if !sp.allows_unstable(sym::format_args_nl) // the span is marked `#[allow_insternal_unsable]`
|
ecx: &'cx mut ExtCtxt<'_>,
|
||||||
&& !ecx.ecfg.enable_allow_internal_unstable() // NOTE: when is this enabled?
|
sp: Span,
|
||||||
&& !ecx.ecfg.enable_format_args_nl() // enabled using `#[feature(format_args_nl]`
|
tts: &[tokenstream::TokenTree],
|
||||||
{
|
) -> Box<dyn base::MacResult + 'cx> {
|
||||||
feature_gate::emit_feature_err(&ecx.parse_sess,
|
expand_format_args_impl(ecx, sp, tts, true)
|
||||||
sym::format_args_nl,
|
|
||||||
sp,
|
|
||||||
feature_gate::GateIssue::Language,
|
|
||||||
feature_gate::EXPLAIN_FORMAT_ARGS_NL);
|
|
||||||
}
|
|
||||||
sp = sp.apply_mark(ecx.current_expansion.mark);
|
|
||||||
match parse_args(ecx, sp, tts) {
|
|
||||||
Ok((efmt, args, names)) => {
|
|
||||||
MacEager::expr(expand_preparsed_format_args(ecx, sp, efmt, args, names, true))
|
|
||||||
}
|
|
||||||
Err(mut err) => {
|
|
||||||
err.emit();
|
|
||||||
DummyResult::expr(sp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Take the various parts of `format_args!(efmt, args..., name=names...)`
|
/// Take the various parts of `format_args!(efmt, args..., name=names...)`
|
||||||
|
|
|
@ -13,27 +13,15 @@ use errors::DiagnosticBuilder;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::source_map::respan;
|
use syntax::source_map::respan;
|
||||||
use syntax::ext::base::{self, *};
|
use syntax::ext::base::{self, *};
|
||||||
use syntax::feature_gate;
|
|
||||||
use syntax::parse::token;
|
use syntax::parse::token;
|
||||||
use syntax::ptr::P;
|
use syntax::ptr::P;
|
||||||
use syntax::symbol::{Symbol, sym};
|
|
||||||
use syntax_pos::Span;
|
use syntax_pos::Span;
|
||||||
use syntax::tokenstream;
|
use syntax::tokenstream;
|
||||||
use smallvec::smallvec;
|
use smallvec::smallvec;
|
||||||
|
|
||||||
pub const MACRO: Symbol = sym::global_asm;
|
|
||||||
|
|
||||||
pub fn expand_global_asm<'cx>(cx: &'cx mut ExtCtxt<'_>,
|
pub fn expand_global_asm<'cx>(cx: &'cx mut ExtCtxt<'_>,
|
||||||
sp: Span,
|
sp: Span,
|
||||||
tts: &[tokenstream::TokenTree]) -> Box<dyn base::MacResult + 'cx> {
|
tts: &[tokenstream::TokenTree]) -> Box<dyn base::MacResult + 'cx> {
|
||||||
if !cx.ecfg.enable_global_asm() {
|
|
||||||
feature_gate::emit_feature_err(&cx.parse_sess,
|
|
||||||
MACRO,
|
|
||||||
sp,
|
|
||||||
feature_gate::GateIssue::Language,
|
|
||||||
feature_gate::EXPLAIN_GLOBAL_ASM);
|
|
||||||
}
|
|
||||||
|
|
||||||
match parse_global_asm(cx, sp, tts) {
|
match parse_global_asm(cx, sp, tts) {
|
||||||
Ok(Some(global_asm)) => {
|
Ok(Some(global_asm)) => {
|
||||||
MacEager::items(smallvec![P(ast::Item {
|
MacEager::items(smallvec![P(ast::Item {
|
||||||
|
|
|
@ -41,12 +41,29 @@ pub mod proc_macro_impl;
|
||||||
|
|
||||||
use rustc_data_structures::sync::Lrc;
|
use rustc_data_structures::sync::Lrc;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
|
use syntax::attr::Stability;
|
||||||
use syntax::ext::base::MacroExpanderFn;
|
use syntax::ext::base::MacroExpanderFn;
|
||||||
use syntax::ext::base::{NamedSyntaxExtension, SyntaxExtension, SyntaxExtensionKind};
|
use syntax::ext::base::{NamedSyntaxExtension, SyntaxExtension, SyntaxExtensionKind};
|
||||||
use syntax::edition::Edition;
|
use syntax::edition::Edition;
|
||||||
use syntax::symbol::{sym, Symbol};
|
use syntax::symbol::{sym, Symbol};
|
||||||
|
|
||||||
|
const EXPLAIN_ASM: &str =
|
||||||
|
"inline assembly is not stable enough for use and is subject to change";
|
||||||
|
const EXPLAIN_GLOBAL_ASM: &str =
|
||||||
|
"`global_asm!` is not stable enough for use and is subject to change";
|
||||||
|
const EXPLAIN_CUSTOM_TEST_FRAMEWORKS: &str =
|
||||||
|
"custom test frameworks are an unstable feature";
|
||||||
|
const EXPLAIN_LOG_SYNTAX: &str =
|
||||||
|
"`log_syntax!` is not stable enough for use and is subject to change";
|
||||||
|
const EXPLAIN_CONCAT_IDENTS: &str =
|
||||||
|
"`concat_idents` is not stable enough for use and is subject to change";
|
||||||
|
const EXPLAIN_FORMAT_ARGS_NL: &str =
|
||||||
|
"`format_args_nl` is only for internal language use and is subject to change";
|
||||||
|
const EXPLAIN_TRACE_MACROS: &str =
|
||||||
|
"`trace_macros` is not stable enough for use and is subject to change";
|
||||||
|
const EXPLAIN_UNSTABLE_COLUMN: &str =
|
||||||
|
"internal implementation detail of the `column` macro";
|
||||||
|
|
||||||
pub fn register_builtins(resolver: &mut dyn syntax::ext::base::Resolver,
|
pub fn register_builtins(resolver: &mut dyn syntax::ext::base::Resolver,
|
||||||
user_exts: Vec<NamedSyntaxExtension>,
|
user_exts: Vec<NamedSyntaxExtension>,
|
||||||
edition: Edition) {
|
edition: Edition) {
|
||||||
|
@ -57,23 +74,27 @@ pub fn register_builtins(resolver: &mut dyn syntax::ext::base::Resolver,
|
||||||
};
|
};
|
||||||
macro_rules! register {
|
macro_rules! register {
|
||||||
($( $name:ident: $f:expr, )*) => { $(
|
($( $name:ident: $f:expr, )*) => { $(
|
||||||
register(Symbol::intern(stringify!($name)), SyntaxExtension::default(
|
register(sym::$name, SyntaxExtension::default(
|
||||||
SyntaxExtensionKind::LegacyBang(Box::new($f as MacroExpanderFn)), edition
|
SyntaxExtensionKind::LegacyBang(Box::new($f as MacroExpanderFn)), edition
|
||||||
));
|
));
|
||||||
)* }
|
)* }
|
||||||
}
|
}
|
||||||
macro_rules! register_attr {
|
macro_rules! register_unstable {
|
||||||
($( $name:ident: $f:expr, )*) => { $(
|
($( [$feature:expr, $reason:expr, $issue:expr] $name:ident: $f:expr, )*) => { $(
|
||||||
register(Symbol::intern(stringify!($name)), SyntaxExtension::default(
|
register(sym::$name, SyntaxExtension {
|
||||||
SyntaxExtensionKind::LegacyAttr(Box::new($f)), edition
|
stability: Some(Stability::unstable(
|
||||||
));
|
$feature, Some(Symbol::intern($reason)), $issue
|
||||||
|
)),
|
||||||
|
..SyntaxExtension::default(
|
||||||
|
SyntaxExtensionKind::LegacyBang(Box::new($f as MacroExpanderFn)), edition
|
||||||
|
)
|
||||||
|
});
|
||||||
)* }
|
)* }
|
||||||
}
|
}
|
||||||
|
|
||||||
use syntax::ext::source_util::*;
|
use syntax::ext::source_util::*;
|
||||||
register! {
|
register! {
|
||||||
line: expand_line,
|
line: expand_line,
|
||||||
__rust_unstable_column: expand_column_gated,
|
|
||||||
column: expand_column,
|
column: expand_column,
|
||||||
file: expand_file,
|
file: expand_file,
|
||||||
stringify: expand_stringify,
|
stringify: expand_stringify,
|
||||||
|
@ -81,35 +102,60 @@ pub fn register_builtins(resolver: &mut dyn syntax::ext::base::Resolver,
|
||||||
include_str: expand_include_str,
|
include_str: expand_include_str,
|
||||||
include_bytes: expand_include_bytes,
|
include_bytes: expand_include_bytes,
|
||||||
module_path: expand_mod,
|
module_path: expand_mod,
|
||||||
|
|
||||||
asm: asm::expand_asm,
|
|
||||||
global_asm: global_asm::expand_global_asm,
|
|
||||||
cfg: cfg::expand_cfg,
|
cfg: cfg::expand_cfg,
|
||||||
concat: concat::expand_syntax_ext,
|
concat: concat::expand_syntax_ext,
|
||||||
concat_idents: concat_idents::expand_syntax_ext,
|
|
||||||
env: env::expand_env,
|
env: env::expand_env,
|
||||||
option_env: env::expand_option_env,
|
option_env: env::expand_option_env,
|
||||||
log_syntax: log_syntax::expand_syntax_ext,
|
|
||||||
trace_macros: trace_macros::expand_trace_macros,
|
|
||||||
compile_error: compile_error::expand_compile_error,
|
compile_error: compile_error::expand_compile_error,
|
||||||
assert: assert::expand_assert,
|
assert: assert::expand_assert,
|
||||||
}
|
}
|
||||||
|
|
||||||
register_attr! {
|
register_unstable! {
|
||||||
test_case: test_case::expand,
|
[sym::__rust_unstable_column, EXPLAIN_UNSTABLE_COLUMN, 0]
|
||||||
test: test::expand_test,
|
__rust_unstable_column: expand_column,
|
||||||
bench: test::expand_bench,
|
[sym::asm, EXPLAIN_ASM, 29722]
|
||||||
|
asm: asm::expand_asm,
|
||||||
|
[sym::global_asm, EXPLAIN_GLOBAL_ASM, 35119]
|
||||||
|
global_asm: global_asm::expand_global_asm,
|
||||||
|
[sym::concat_idents, EXPLAIN_CONCAT_IDENTS, 29599]
|
||||||
|
concat_idents: concat_idents::expand_syntax_ext,
|
||||||
|
[sym::log_syntax, EXPLAIN_LOG_SYNTAX, 29598]
|
||||||
|
log_syntax: log_syntax::expand_syntax_ext,
|
||||||
|
[sym::trace_macros, EXPLAIN_TRACE_MACROS, 29598]
|
||||||
|
trace_macros: trace_macros::expand_trace_macros,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
register(sym::test_case, SyntaxExtension {
|
||||||
|
stability: Some(Stability::unstable(
|
||||||
|
sym::custom_test_frameworks,
|
||||||
|
Some(Symbol::intern(EXPLAIN_CUSTOM_TEST_FRAMEWORKS)),
|
||||||
|
50297,
|
||||||
|
)),
|
||||||
|
..SyntaxExtension::default(
|
||||||
|
SyntaxExtensionKind::LegacyAttr(Box::new(test_case::expand)), edition
|
||||||
|
)
|
||||||
|
});
|
||||||
|
register(sym::test, SyntaxExtension::default(
|
||||||
|
SyntaxExtensionKind::LegacyAttr(Box::new(test::expand_test)), edition
|
||||||
|
));
|
||||||
|
register(sym::bench, SyntaxExtension::default(
|
||||||
|
SyntaxExtensionKind::LegacyAttr(Box::new(test::expand_bench)), edition
|
||||||
|
));
|
||||||
|
|
||||||
// format_args uses `unstable` things internally.
|
// format_args uses `unstable` things internally.
|
||||||
let allow_internal_unstable = Some([sym::fmt_internals][..].into());
|
let allow_internal_unstable = Some([sym::fmt_internals][..].into());
|
||||||
register(Symbol::intern("format_args"), SyntaxExtension {
|
register(sym::format_args, SyntaxExtension {
|
||||||
allow_internal_unstable: allow_internal_unstable.clone(),
|
allow_internal_unstable: allow_internal_unstable.clone(),
|
||||||
..SyntaxExtension::default(
|
..SyntaxExtension::default(
|
||||||
SyntaxExtensionKind::LegacyBang(Box::new(format::expand_format_args)), edition
|
SyntaxExtensionKind::LegacyBang(Box::new(format::expand_format_args)), edition
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
register(sym::format_args_nl, SyntaxExtension {
|
register(sym::format_args_nl, SyntaxExtension {
|
||||||
|
stability: Some(Stability::unstable(
|
||||||
|
sym::format_args_nl,
|
||||||
|
Some(Symbol::intern(EXPLAIN_FORMAT_ARGS_NL)),
|
||||||
|
0,
|
||||||
|
)),
|
||||||
allow_internal_unstable,
|
allow_internal_unstable,
|
||||||
..SyntaxExtension::default(
|
..SyntaxExtension::default(
|
||||||
SyntaxExtensionKind::LegacyBang(Box::new(format::expand_format_args_nl)), edition
|
SyntaxExtensionKind::LegacyBang(Box::new(format::expand_format_args_nl)), edition
|
||||||
|
|
|
@ -1,22 +1,12 @@
|
||||||
use syntax::ext::base;
|
use syntax::ext::base;
|
||||||
use syntax::feature_gate;
|
|
||||||
use syntax::print;
|
use syntax::print;
|
||||||
use syntax::tokenstream;
|
use syntax::tokenstream;
|
||||||
use syntax::symbol::sym;
|
|
||||||
use syntax_pos;
|
use syntax_pos;
|
||||||
|
|
||||||
pub fn expand_syntax_ext<'cx>(cx: &'cx mut base::ExtCtxt<'_>,
|
pub fn expand_syntax_ext<'cx>(_cx: &'cx mut base::ExtCtxt<'_>,
|
||||||
sp: syntax_pos::Span,
|
sp: syntax_pos::Span,
|
||||||
tts: &[tokenstream::TokenTree])
|
tts: &[tokenstream::TokenTree])
|
||||||
-> Box<dyn base::MacResult + 'cx> {
|
-> Box<dyn base::MacResult + 'cx> {
|
||||||
if !cx.ecfg.enable_log_syntax() {
|
|
||||||
feature_gate::emit_feature_err(&cx.parse_sess,
|
|
||||||
sym::log_syntax,
|
|
||||||
sp,
|
|
||||||
feature_gate::GateIssue::Language,
|
|
||||||
feature_gate::EXPLAIN_LOG_SYNTAX);
|
|
||||||
}
|
|
||||||
|
|
||||||
println!("{}", print::pprust::tts_to_string(tts));
|
println!("{}", print::pprust::tts_to_string(tts));
|
||||||
|
|
||||||
// any so that `log_syntax` can be invoked as an expression and item.
|
// any so that `log_syntax` can be invoked as an expression and item.
|
||||||
|
|
|
@ -548,10 +548,10 @@ impl server::Literal for Rustc<'_> {
|
||||||
self.lit(token::Float, Symbol::intern(n), None)
|
self.lit(token::Float, Symbol::intern(n), None)
|
||||||
}
|
}
|
||||||
fn f32(&mut self, n: &str) -> Self::Literal {
|
fn f32(&mut self, n: &str) -> Self::Literal {
|
||||||
self.lit(token::Float, Symbol::intern(n), Some(Symbol::intern("f32")))
|
self.lit(token::Float, Symbol::intern(n), Some(sym::f32))
|
||||||
}
|
}
|
||||||
fn f64(&mut self, n: &str) -> Self::Literal {
|
fn f64(&mut self, n: &str) -> Self::Literal {
|
||||||
self.lit(token::Float, Symbol::intern(n), Some(Symbol::intern("f64")))
|
self.lit(token::Float, Symbol::intern(n), Some(sym::f64))
|
||||||
}
|
}
|
||||||
fn string(&mut self, string: &str) -> Self::Literal {
|
fn string(&mut self, string: &str) -> Self::Literal {
|
||||||
let mut escaped = String::new();
|
let mut escaped = String::new();
|
||||||
|
|
|
@ -17,7 +17,6 @@ use syntax::source_map::respan;
|
||||||
use syntax::symbol::sym;
|
use syntax::symbol::sym;
|
||||||
use syntax_pos::Span;
|
use syntax_pos::Span;
|
||||||
use syntax::source_map::{ExpnInfo, MacroAttribute};
|
use syntax::source_map::{ExpnInfo, MacroAttribute};
|
||||||
use syntax::feature_gate;
|
|
||||||
|
|
||||||
pub fn expand(
|
pub fn expand(
|
||||||
ecx: &mut ExtCtxt<'_>,
|
ecx: &mut ExtCtxt<'_>,
|
||||||
|
@ -25,14 +24,6 @@ pub fn expand(
|
||||||
_meta_item: &ast::MetaItem,
|
_meta_item: &ast::MetaItem,
|
||||||
anno_item: Annotatable
|
anno_item: Annotatable
|
||||||
) -> Vec<Annotatable> {
|
) -> Vec<Annotatable> {
|
||||||
if !ecx.ecfg.enable_custom_test_frameworks() {
|
|
||||||
feature_gate::emit_feature_err(&ecx.parse_sess,
|
|
||||||
sym::custom_test_frameworks,
|
|
||||||
attr_sp,
|
|
||||||
feature_gate::GateIssue::Language,
|
|
||||||
feature_gate::EXPLAIN_CUSTOM_TEST_FRAMEWORKS);
|
|
||||||
}
|
|
||||||
|
|
||||||
if !ecx.ecfg.should_test { return vec![]; }
|
if !ecx.ecfg.should_test { return vec![]; }
|
||||||
|
|
||||||
let sp = {
|
let sp = {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use syntax::ext::base::{self, ExtCtxt};
|
use syntax::ext::base::{self, ExtCtxt};
|
||||||
use syntax::feature_gate;
|
use syntax::symbol::kw;
|
||||||
use syntax::symbol::{kw, sym};
|
|
||||||
use syntax_pos::Span;
|
use syntax_pos::Span;
|
||||||
use syntax::tokenstream::TokenTree;
|
use syntax::tokenstream::TokenTree;
|
||||||
|
|
||||||
|
@ -8,14 +7,6 @@ pub fn expand_trace_macros(cx: &mut ExtCtxt<'_>,
|
||||||
sp: Span,
|
sp: Span,
|
||||||
tt: &[TokenTree])
|
tt: &[TokenTree])
|
||||||
-> Box<dyn base::MacResult + 'static> {
|
-> Box<dyn base::MacResult + 'static> {
|
||||||
if !cx.ecfg.enable_trace_macros() {
|
|
||||||
feature_gate::emit_feature_err(&cx.parse_sess,
|
|
||||||
sym::trace_macros,
|
|
||||||
sp,
|
|
||||||
feature_gate::GateIssue::Language,
|
|
||||||
feature_gate::EXPLAIN_TRACE_MACROS);
|
|
||||||
}
|
|
||||||
|
|
||||||
match tt {
|
match tt {
|
||||||
[TokenTree::Token(token)] if token.is_keyword(kw::True) => {
|
[TokenTree::Token(token)] if token.is_keyword(kw::True) => {
|
||||||
cx.set_trace_macros(true);
|
cx.set_trace_macros(true);
|
||||||
|
|
|
@ -141,6 +141,7 @@ symbols! {
|
||||||
ArgumentV1,
|
ArgumentV1,
|
||||||
arm_target_feature,
|
arm_target_feature,
|
||||||
asm,
|
asm,
|
||||||
|
assert,
|
||||||
associated_consts,
|
associated_consts,
|
||||||
associated_type_bounds,
|
associated_type_bounds,
|
||||||
associated_type_defaults,
|
associated_type_defaults,
|
||||||
|
@ -184,8 +185,10 @@ symbols! {
|
||||||
cmp,
|
cmp,
|
||||||
cmpxchg16b_target_feature,
|
cmpxchg16b_target_feature,
|
||||||
cold,
|
cold,
|
||||||
|
column,
|
||||||
compile_error,
|
compile_error,
|
||||||
compiler_builtins,
|
compiler_builtins,
|
||||||
|
concat,
|
||||||
concat_idents,
|
concat_idents,
|
||||||
conservative_impl_trait,
|
conservative_impl_trait,
|
||||||
console,
|
console,
|
||||||
|
@ -203,6 +206,7 @@ symbols! {
|
||||||
contents,
|
contents,
|
||||||
context,
|
context,
|
||||||
convert,
|
convert,
|
||||||
|
Copy,
|
||||||
copy_closures,
|
copy_closures,
|
||||||
core,
|
core,
|
||||||
core_intrinsics,
|
core_intrinsics,
|
||||||
|
@ -217,8 +221,10 @@ symbols! {
|
||||||
custom_inner_attributes,
|
custom_inner_attributes,
|
||||||
custom_test_frameworks,
|
custom_test_frameworks,
|
||||||
c_variadic,
|
c_variadic,
|
||||||
|
Debug,
|
||||||
declare_lint_pass,
|
declare_lint_pass,
|
||||||
decl_macro,
|
decl_macro,
|
||||||
|
Decodable,
|
||||||
Default,
|
Default,
|
||||||
default_lib_allocator,
|
default_lib_allocator,
|
||||||
default_type_parameter_fallback,
|
default_type_parameter_fallback,
|
||||||
|
@ -253,9 +259,12 @@ symbols! {
|
||||||
eh_personality,
|
eh_personality,
|
||||||
eh_unwind_resume,
|
eh_unwind_resume,
|
||||||
enable,
|
enable,
|
||||||
|
Encodable,
|
||||||
|
env,
|
||||||
eq,
|
eq,
|
||||||
err,
|
err,
|
||||||
Err,
|
Err,
|
||||||
|
Eq,
|
||||||
Equal,
|
Equal,
|
||||||
except,
|
except,
|
||||||
exclusive_range_pattern,
|
exclusive_range_pattern,
|
||||||
|
@ -284,6 +293,7 @@ symbols! {
|
||||||
fmt_internals,
|
fmt_internals,
|
||||||
fn_must_use,
|
fn_must_use,
|
||||||
forbid,
|
forbid,
|
||||||
|
format_args,
|
||||||
format_args_nl,
|
format_args_nl,
|
||||||
from,
|
from,
|
||||||
From,
|
From,
|
||||||
|
@ -335,6 +345,8 @@ symbols! {
|
||||||
index_mut,
|
index_mut,
|
||||||
in_band_lifetimes,
|
in_band_lifetimes,
|
||||||
include,
|
include,
|
||||||
|
include_bytes,
|
||||||
|
include_str,
|
||||||
inclusive_range_syntax,
|
inclusive_range_syntax,
|
||||||
infer_outlives_requirements,
|
infer_outlives_requirements,
|
||||||
infer_static_outlives_requirements,
|
infer_static_outlives_requirements,
|
||||||
|
@ -363,6 +375,7 @@ symbols! {
|
||||||
lhs,
|
lhs,
|
||||||
lib,
|
lib,
|
||||||
lifetime,
|
lifetime,
|
||||||
|
line,
|
||||||
link,
|
link,
|
||||||
linkage,
|
linkage,
|
||||||
link_args,
|
link_args,
|
||||||
|
@ -402,6 +415,7 @@ symbols! {
|
||||||
mips_target_feature,
|
mips_target_feature,
|
||||||
mmx_target_feature,
|
mmx_target_feature,
|
||||||
module,
|
module,
|
||||||
|
module_path,
|
||||||
more_struct_aliases,
|
more_struct_aliases,
|
||||||
movbe_target_feature,
|
movbe_target_feature,
|
||||||
must_use,
|
must_use,
|
||||||
|
@ -447,6 +461,7 @@ symbols! {
|
||||||
optin_builtin_traits,
|
optin_builtin_traits,
|
||||||
option,
|
option,
|
||||||
Option,
|
Option,
|
||||||
|
option_env,
|
||||||
opt_out_copy,
|
opt_out_copy,
|
||||||
or,
|
or,
|
||||||
Ord,
|
Ord,
|
||||||
|
@ -462,6 +477,7 @@ symbols! {
|
||||||
parent_trait,
|
parent_trait,
|
||||||
partial_cmp,
|
partial_cmp,
|
||||||
param_attrs,
|
param_attrs,
|
||||||
|
PartialEq,
|
||||||
PartialOrd,
|
PartialOrd,
|
||||||
passes,
|
passes,
|
||||||
pat,
|
pat,
|
||||||
|
@ -532,6 +548,8 @@ symbols! {
|
||||||
rust_2018_preview,
|
rust_2018_preview,
|
||||||
rust_begin_unwind,
|
rust_begin_unwind,
|
||||||
rustc,
|
rustc,
|
||||||
|
RustcDecodable,
|
||||||
|
RustcEncodable,
|
||||||
rustc_allocator,
|
rustc_allocator,
|
||||||
rustc_allocator_nounwind,
|
rustc_allocator_nounwind,
|
||||||
rustc_allow_const_fn_ptr,
|
rustc_allow_const_fn_ptr,
|
||||||
|
@ -591,7 +609,6 @@ symbols! {
|
||||||
_Self,
|
_Self,
|
||||||
self_in_typedefs,
|
self_in_typedefs,
|
||||||
self_struct_ctor,
|
self_struct_ctor,
|
||||||
Send,
|
|
||||||
should_panic,
|
should_panic,
|
||||||
simd,
|
simd,
|
||||||
simd_ffi,
|
simd_ffi,
|
||||||
|
@ -613,6 +630,7 @@ symbols! {
|
||||||
static_recursion,
|
static_recursion,
|
||||||
std,
|
std,
|
||||||
str,
|
str,
|
||||||
|
stringify,
|
||||||
stmt,
|
stmt,
|
||||||
stmt_expr_attributes,
|
stmt_expr_attributes,
|
||||||
stop_after_dataflow,
|
stop_after_dataflow,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// run-pass
|
// run-pass
|
||||||
// aux-build:unstable-macros.rs
|
// aux-build:unstable-macros.rs
|
||||||
|
|
||||||
#![feature(unstable_macros)]
|
#![feature(unstable_macros, local_unstable)]
|
||||||
|
|
||||||
#[macro_use] extern crate unstable_macros;
|
#[macro_use] extern crate unstable_macros;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
warning: derive(Encodable) is deprecated in favor of derive(RustcEncodable)
|
warning: use of deprecated item 'Encodable': derive(Encodable) is deprecated in favor of derive(RustcEncodable)
|
||||||
--> $DIR/deprecated-derive.rs:8:10
|
--> $DIR/deprecated-derive.rs:8:10
|
||||||
|
|
|
|
||||||
LL | #[derive(Encodable)]
|
LL | #[derive(Encodable)]
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: #[warn(deprecated)] on by default
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error[E0658]: inline assembly is not stable enough for use and is subject to change
|
error[E0658]: use of unstable library feature 'asm': inline assembly is not stable enough for use and is subject to change
|
||||||
--> $DIR/feature-gate-asm.rs:3:9
|
--> $DIR/feature-gate-asm.rs:3:9
|
||||||
|
|
|
|
||||||
LL | asm!("");
|
LL | asm!("");
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error[E0658]: inline assembly is not stable enough for use and is subject to change
|
error[E0658]: use of unstable library feature 'asm': inline assembly is not stable enough for use and is subject to change
|
||||||
--> $DIR/feature-gate-asm2.rs:5:26
|
--> $DIR/feature-gate-asm2.rs:5:26
|
||||||
|
|
|
|
||||||
LL | println!("{:?}", asm!(""));
|
LL | println!("{:?}", asm!(""));
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error[E0658]: `concat_idents` is not stable enough for use and is subject to change
|
error[E0658]: use of unstable library feature 'concat_idents': `concat_idents` is not stable enough for use and is subject to change
|
||||||
--> $DIR/feature-gate-concat_idents.rs:5:13
|
--> $DIR/feature-gate-concat_idents.rs:5:13
|
||||||
|
|
|
|
||||||
LL | let a = concat_idents!(X, Y_1);
|
LL | let a = concat_idents!(X, Y_1);
|
||||||
|
@ -7,7 +7,7 @@ LL | let a = concat_idents!(X, Y_1);
|
||||||
= note: for more information, see https://github.com/rust-lang/rust/issues/29599
|
= note: for more information, see https://github.com/rust-lang/rust/issues/29599
|
||||||
= help: add #![feature(concat_idents)] to the crate attributes to enable
|
= help: add #![feature(concat_idents)] to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: `concat_idents` is not stable enough for use and is subject to change
|
error[E0658]: use of unstable library feature 'concat_idents': `concat_idents` is not stable enough for use and is subject to change
|
||||||
--> $DIR/feature-gate-concat_idents.rs:6:13
|
--> $DIR/feature-gate-concat_idents.rs:6:13
|
||||||
|
|
|
|
||||||
LL | let b = concat_idents!(X, Y_2);
|
LL | let b = concat_idents!(X, Y_2);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error[E0658]: `concat_idents` is not stable enough for use and is subject to change
|
error[E0658]: use of unstable library feature 'concat_idents': `concat_idents` is not stable enough for use and is subject to change
|
||||||
--> $DIR/feature-gate-concat_idents2.rs:4:5
|
--> $DIR/feature-gate-concat_idents2.rs:4:5
|
||||||
|
|
|
|
||||||
LL | concat_idents!(a, b);
|
LL | concat_idents!(a, b);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error[E0658]: `concat_idents` is not stable enough for use and is subject to change
|
error[E0658]: use of unstable library feature 'concat_idents': `concat_idents` is not stable enough for use and is subject to change
|
||||||
--> $DIR/feature-gate-concat_idents3.rs:7:20
|
--> $DIR/feature-gate-concat_idents3.rs:7:20
|
||||||
|
|
|
|
||||||
LL | assert_eq!(10, concat_idents!(X, Y_1));
|
LL | assert_eq!(10, concat_idents!(X, Y_1));
|
||||||
|
@ -7,7 +7,7 @@ LL | assert_eq!(10, concat_idents!(X, Y_1));
|
||||||
= note: for more information, see https://github.com/rust-lang/rust/issues/29599
|
= note: for more information, see https://github.com/rust-lang/rust/issues/29599
|
||||||
= help: add #![feature(concat_idents)] to the crate attributes to enable
|
= help: add #![feature(concat_idents)] to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: `concat_idents` is not stable enough for use and is subject to change
|
error[E0658]: use of unstable library feature 'concat_idents': `concat_idents` is not stable enough for use and is subject to change
|
||||||
--> $DIR/feature-gate-concat_idents3.rs:8:20
|
--> $DIR/feature-gate-concat_idents3.rs:8:20
|
||||||
|
|
|
|
||||||
LL | assert_eq!(20, concat_idents!(X, Y_2));
|
LL | assert_eq!(20, concat_idents!(X, Y_2));
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
#![test_runner(main)] //~ ERROR custom test frameworks are an unstable feature
|
#![test_runner(main)] //~ ERROR custom test frameworks are an unstable feature
|
||||||
|
|
||||||
|
#[test_case] //~ ERROR custom test frameworks are an unstable feature
|
||||||
|
fn f() {}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,3 +1,12 @@
|
||||||
|
error[E0658]: use of unstable library feature 'custom_test_frameworks': custom test frameworks are an unstable feature
|
||||||
|
--> $DIR/feature-gate-custom_test_frameworks.rs:3:1
|
||||||
|
|
|
||||||
|
LL | #[test_case]
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: for more information, see https://github.com/rust-lang/rust/issues/50297
|
||||||
|
= help: add #![feature(custom_test_frameworks)] to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: custom test frameworks are an unstable feature
|
error[E0658]: custom test frameworks are an unstable feature
|
||||||
--> $DIR/feature-gate-custom_test_frameworks.rs:1:1
|
--> $DIR/feature-gate-custom_test_frameworks.rs:1:1
|
||||||
|
|
|
|
||||||
|
@ -7,6 +16,6 @@ LL | #![test_runner(main)]
|
||||||
= note: for more information, see https://github.com/rust-lang/rust/issues/50297
|
= note: for more information, see https://github.com/rust-lang/rust/issues/50297
|
||||||
= help: add #![feature(custom_test_frameworks)] to the crate attributes to enable
|
= help: add #![feature(custom_test_frameworks)] to the crate attributes to enable
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0658`.
|
For more information about this error, try `rustc --explain E0658`.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error[E0658]: `format_args_nl` is only for internal language use and is subject to change
|
error[E0658]: use of unstable library feature 'format_args_nl': `format_args_nl` is only for internal language use and is subject to change
|
||||||
--> $DIR/feature-gate-format_args_nl.rs:2:5
|
--> $DIR/feature-gate-format_args_nl.rs:2:5
|
||||||
|
|
|
|
||||||
LL | format_args_nl!("");
|
LL | format_args_nl!("");
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error[E0658]: `global_asm!` is not stable enough for use and is subject to change
|
error[E0658]: use of unstable library feature 'global_asm': `global_asm!` is not stable enough for use and is subject to change
|
||||||
--> $DIR/feature-gate-global_asm.rs:1:1
|
--> $DIR/feature-gate-global_asm.rs:1:1
|
||||||
|
|
|
|
||||||
LL | global_asm!("");
|
LL | global_asm!("");
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error[E0658]: `log_syntax!` is not stable enough for use and is subject to change
|
error[E0658]: use of unstable library feature 'log_syntax': `log_syntax!` is not stable enough for use and is subject to change
|
||||||
--> $DIR/feature-gate-log_syntax.rs:2:5
|
--> $DIR/feature-gate-log_syntax.rs:2:5
|
||||||
|
|
|
|
||||||
LL | log_syntax!()
|
LL | log_syntax!()
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error[E0658]: `log_syntax!` is not stable enough for use and is subject to change
|
error[E0658]: use of unstable library feature 'log_syntax': `log_syntax!` is not stable enough for use and is subject to change
|
||||||
--> $DIR/feature-gate-log_syntax2.rs:4:22
|
--> $DIR/feature-gate-log_syntax2.rs:4:22
|
||||||
|
|
|
|
||||||
LL | println!("{:?}", log_syntax!());
|
LL | println!("{:?}", log_syntax!());
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error[E0658]: `trace_macros` is not stable enough for use and is subject to change
|
error[E0658]: use of unstable library feature 'trace_macros': `trace_macros` is not stable enough for use and is subject to change
|
||||||
--> $DIR/feature-gate-trace_macros.rs:2:5
|
--> $DIR/feature-gate-trace_macros.rs:2:5
|
||||||
|
|
|
|
||||||
LL | trace_macros!(true);
|
LL | trace_macros!(true);
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
#[deprecated(since = "1.0.0", note = "deprecation note")]
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! deprecated_macro{ () => () }
|
|
@ -1,6 +1,16 @@
|
||||||
|
#![feature(decl_macro)]
|
||||||
#![feature(staged_api)]
|
#![feature(staged_api)]
|
||||||
#![stable(feature = "unit_test", since = "1.0.0")]
|
#![stable(feature = "unit_test", since = "1.0.0")]
|
||||||
|
|
||||||
#[unstable(feature = "unstable_macros", issue = "0")]
|
#[unstable(feature = "unstable_macros", issue = "0")]
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! unstable_macro{ () => () }
|
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() {}
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
// check-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
|
||||||
|
}
|
|
@ -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!();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
@ -1,12 +1,28 @@
|
||||||
// aux-build:unstable-macros.rs
|
// aux-build:unstable-macros.rs
|
||||||
|
|
||||||
|
#![feature(decl_macro)]
|
||||||
#![feature(staged_api)]
|
#![feature(staged_api)]
|
||||||
#[macro_use] extern crate unstable_macros;
|
#[macro_use] extern crate unstable_macros;
|
||||||
|
|
||||||
#[unstable(feature = "local_unstable", issue = "0")]
|
#[unstable(feature = "local_unstable", issue = "0")]
|
||||||
macro_rules! local_unstable { () => () }
|
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() {
|
fn main() {
|
||||||
local_unstable!();
|
local_unstable!(); //~ ERROR use of unstable library feature 'local_unstable'
|
||||||
unstable_macro!(); //~ ERROR: macro unstable_macro! is 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
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,41 @@
|
||||||
error[E0658]: macro unstable_macro! is unstable
|
error[E0658]: use of unstable library feature 'local_unstable'
|
||||||
--> $DIR/macro-stability.rs:11: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:21:5
|
||||||
|
|
|
|
||||||
LL | unstable_macro!();
|
LL | unstable_macro!();
|
||||||
| ^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= help: add #![feature(unstable_macros)] to the crate attributes to enable
|
= help: add #![feature(unstable_macros)] to the crate attributes to enable
|
||||||
|
|
||||||
error: aborting due to previous error
|
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`.
|
For more information about this error, try `rustc --explain E0658`.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("{}", __rust_unstable_column!());
|
println!("{}", __rust_unstable_column!());
|
||||||
//~^ERROR the __rust_unstable_column macro is unstable
|
//~^ ERROR use of unstable library feature '__rust_unstable_column'
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
error: the __rust_unstable_column macro is unstable
|
error[E0658]: use of unstable library feature '__rust_unstable_column': internal implementation detail of the `column` macro
|
||||||
--> $DIR/rust-unstable-column-gated.rs:2:20
|
--> $DIR/rust-unstable-column-gated.rs:2:20
|
||||||
|
|
|
|
||||||
LL | println!("{}", __rust_unstable_column!());
|
LL | println!("{}", __rust_unstable_column!());
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: add #![feature(__rust_unstable_column)] to the crate attributes to enable
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0658`.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error[E0658]: `trace_macros` is not stable enough for use and is subject to change
|
error[E0658]: use of unstable library feature 'trace_macros': `trace_macros` is not stable enough for use and is subject to change
|
||||||
--> $DIR/trace_macros-gate.rs:4:5
|
--> $DIR/trace_macros-gate.rs:4:5
|
||||||
|
|
|
|
||||||
LL | trace_macros!();
|
LL | trace_macros!();
|
||||||
|
@ -13,7 +13,7 @@ error: trace_macros! accepts only `true` or `false`
|
||||||
LL | trace_macros!();
|
LL | trace_macros!();
|
||||||
| ^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0658]: `trace_macros` is not stable enough for use and is subject to change
|
error[E0658]: use of unstable library feature 'trace_macros': `trace_macros` is not stable enough for use and is subject to change
|
||||||
--> $DIR/trace_macros-gate.rs:6:5
|
--> $DIR/trace_macros-gate.rs:6:5
|
||||||
|
|
|
|
||||||
LL | trace_macros!(true);
|
LL | trace_macros!(true);
|
||||||
|
@ -22,7 +22,7 @@ LL | trace_macros!(true);
|
||||||
= note: for more information, see https://github.com/rust-lang/rust/issues/29598
|
= note: for more information, see https://github.com/rust-lang/rust/issues/29598
|
||||||
= help: add #![feature(trace_macros)] to the crate attributes to enable
|
= help: add #![feature(trace_macros)] to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: `trace_macros` is not stable enough for use and is subject to change
|
error[E0658]: use of unstable library feature 'trace_macros': `trace_macros` is not stable enough for use and is subject to change
|
||||||
--> $DIR/trace_macros-gate.rs:7:5
|
--> $DIR/trace_macros-gate.rs:7:5
|
||||||
|
|
|
|
||||||
LL | trace_macros!(false);
|
LL | trace_macros!(false);
|
||||||
|
@ -31,7 +31,7 @@ LL | trace_macros!(false);
|
||||||
= note: for more information, see https://github.com/rust-lang/rust/issues/29598
|
= note: for more information, see https://github.com/rust-lang/rust/issues/29598
|
||||||
= help: add #![feature(trace_macros)] to the crate attributes to enable
|
= help: add #![feature(trace_macros)] to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: `trace_macros` is not stable enough for use and is subject to change
|
error[E0658]: use of unstable library feature 'trace_macros': `trace_macros` is not stable enough for use and is subject to change
|
||||||
--> $DIR/trace_macros-gate.rs:10:26
|
--> $DIR/trace_macros-gate.rs:10:26
|
||||||
|
|
|
|
||||||
LL | ($x: ident) => { trace_macros!($x) }
|
LL | ($x: ident) => { trace_macros!($x) }
|
||||||
|
|
Loading…
Reference in New Issue