From 069c52fa111e592f65605c54f5e9b77be0676595 Mon Sep 17 00:00:00 2001 From: Petr Hosek Date: Mon, 1 Jul 2019 17:28:10 -0700 Subject: [PATCH 01/14] Check if the archive has already been added to avoid duplicates This avoids adding archives multiple times, which results in duplicate objects in the resulting rlib, leading to symbol collision and link failures. This could happen when crate contains multiple link attributes that all reference the same archive. --- src/librustc_codegen_llvm/back/archive.rs | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/librustc_codegen_llvm/back/archive.rs b/src/librustc_codegen_llvm/back/archive.rs index e0e26e9af2537..90c0cf748d1e0 100644 --- a/src/librustc_codegen_llvm/back/archive.rs +++ b/src/librustc_codegen_llvm/back/archive.rs @@ -36,11 +36,20 @@ enum Addition { name_in_archive: String, }, Archive { + path: PathBuf, archive: ArchiveRO, skip: Box bool>, }, } +impl Addition { + fn path(&self) -> &Path { + match self { + Addition::File { path, .. } | Addition::Archive { path, .. } => path, + } + } +} + fn is_relevant_child(c: &Child<'_>) -> bool { match c.name() { Some(name) => !name.contains("SYMDEF"), @@ -188,12 +197,16 @@ impl<'a> LlvmArchiveBuilder<'a> { -> io::Result<()> where F: FnMut(&str) -> bool + 'static { - let archive = match ArchiveRO::open(archive) { + let archive_ro = match ArchiveRO::open(archive) { Ok(ar) => ar, Err(e) => return Err(io::Error::new(io::ErrorKind::Other, e)), }; + if self.additions.iter().any(|ar| ar.path() == archive) { + return Ok(()) + } self.additions.push(Addition::Archive { - archive, + path: archive.to_path_buf(), + archive: archive_ro, skip: Box::new(skip), }); Ok(()) @@ -243,7 +256,7 @@ impl<'a> LlvmArchiveBuilder<'a> { strings.push(path); strings.push(name); } - Addition::Archive { archive, skip } => { + Addition::Archive { archive, skip, .. } => { for child in archive.iter() { let child = child.map_err(string_to_io_error)?; if !is_relevant_child(&child) { From 6de8e39e2612305cef4e2d8ef3eca296294d01b5 Mon Sep 17 00:00:00 2001 From: "Zack M. Davis" Date: Sat, 15 Jun 2019 20:22:07 -0700 Subject: [PATCH 02/14] in which the `non_ascii_idents` lint appears (RFC 2457) RFC 2457 declares: "A `non_ascii_idents` lint is added to the compiler. This lint is allow by default." --- src/librustc_lint/lib.rs | 3 ++ src/librustc_lint/non_ascii_idents.rs | 22 +++++++++++++ .../lint-non-ascii-idents.rs | 11 +++++++ .../lint-non-ascii-idents.stderr | 32 +++++++++++++++++++ 4 files changed, 68 insertions(+) create mode 100644 src/librustc_lint/non_ascii_idents.rs create mode 100644 src/test/ui/lint/rfc-2457-non-ascii-idents/lint-non-ascii-idents.rs create mode 100644 src/test/ui/lint/rfc-2457-non-ascii-idents/lint-non-ascii-idents.stderr diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 2519981fa21b2..13a9963fa901a 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -30,6 +30,7 @@ mod nonstandard_style; pub mod builtin; mod types; mod unused; +mod non_ascii_idents; use rustc::lint; use rustc::lint::{EarlyContext, LateContext, LateLintPass, EarlyLintPass, LintPass, LintArray}; @@ -61,6 +62,7 @@ use nonstandard_style::*; use builtin::*; use types::*; use unused::*; +use non_ascii_idents::*; use rustc::lint::internal::*; /// Useful for other parts of the compiler. @@ -97,6 +99,7 @@ macro_rules! early_lint_passes { NonCamelCaseTypes: NonCamelCaseTypes, DeprecatedAttr: DeprecatedAttr::new(), WhileTrue: WhileTrue, + NonAsciiIdents: NonAsciiIdents, ]); ) } diff --git a/src/librustc_lint/non_ascii_idents.rs b/src/librustc_lint/non_ascii_idents.rs new file mode 100644 index 0000000000000..aa39211efc71e --- /dev/null +++ b/src/librustc_lint/non_ascii_idents.rs @@ -0,0 +1,22 @@ +use crate::lint::{EarlyContext, EarlyLintPass, LintArray, LintContext, LintPass}; +use syntax::ast; + +declare_lint! { + pub NON_ASCII_IDENTS, + Allow, + "detects non-ASCII identifiers" +} + +declare_lint_pass!(NonAsciiIdents => [NON_ASCII_IDENTS]); + +impl EarlyLintPass for NonAsciiIdents { + fn check_ident(&mut self, cx: &EarlyContext<'_>, ident: ast::Ident) { + if !ident.name.as_str().is_ascii() { + cx.struct_span_lint( + NON_ASCII_IDENTS, + ident.span, + "identifier contains non-ASCII characters", + ).emit(); + } + } +} diff --git a/src/test/ui/lint/rfc-2457-non-ascii-idents/lint-non-ascii-idents.rs b/src/test/ui/lint/rfc-2457-non-ascii-idents/lint-non-ascii-idents.rs new file mode 100644 index 0000000000000..057329a0a650c --- /dev/null +++ b/src/test/ui/lint/rfc-2457-non-ascii-idents/lint-non-ascii-idents.rs @@ -0,0 +1,11 @@ +#![feature(non_ascii_idents)] +#![deny(non_ascii_idents)] + +const חלודה: usize = 2; //~ ERROR identifier contains non-ASCII characters + +fn coöperation() {} //~ ERROR identifier contains non-ASCII characters + +fn main() { + let naïveté = 2; //~ ERROR identifier contains non-ASCII characters + println!("{}", naïveté); //~ ERROR identifier contains non-ASCII characters +} diff --git a/src/test/ui/lint/rfc-2457-non-ascii-idents/lint-non-ascii-idents.stderr b/src/test/ui/lint/rfc-2457-non-ascii-idents/lint-non-ascii-idents.stderr new file mode 100644 index 0000000000000..56925846e956b --- /dev/null +++ b/src/test/ui/lint/rfc-2457-non-ascii-idents/lint-non-ascii-idents.stderr @@ -0,0 +1,32 @@ +error: identifier contains non-ASCII characters + --> $DIR/lint-non-ascii-idents.rs:4:7 + | +LL | const חלודה: usize = 2; + | ^^^^^ + | +note: lint level defined here + --> $DIR/lint-non-ascii-idents.rs:2:9 + | +LL | #![deny(non_ascii_idents)] + | ^^^^^^^^^^^^^^^^ + +error: identifier contains non-ASCII characters + --> $DIR/lint-non-ascii-idents.rs:6:4 + | +LL | fn coöperation() {} + | ^^^^^^^^^^^ + +error: identifier contains non-ASCII characters + --> $DIR/lint-non-ascii-idents.rs:9:9 + | +LL | let naïveté = 2; + | ^^^^^^^ + +error: identifier contains non-ASCII characters + --> $DIR/lint-non-ascii-idents.rs:10:20 + | +LL | println!("{}", naïveté); + | ^^^^^^^ + +error: aborting due to 4 previous errors + From bed54cf85457d76f479fcd406f07b39c5e8abb12 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Fri, 28 Jun 2019 10:31:27 -0500 Subject: [PATCH 03/14] rustdoc: set cfg(doctest) when collecting doctests --- src/doc/rustdoc/src/unstable-features.md | 30 +++++++++++++++++++ src/librustdoc/config.rs | 3 ++ src/libsyntax/feature_gate.rs | 4 +++ src/libsyntax_pos/symbol.rs | 2 ++ src/test/rustdoc-ui/cfg-test.rs | 10 +++++++ src/test/rustdoc-ui/cfg-test.stdout | 7 +++-- src/test/rustdoc/cfg-doctest.rs | 8 +++++ .../feature-gate/feature-gate-cfg_doctest.rs | 4 +++ .../feature-gate-cfg_doctest.stderr | 12 ++++++++ 9 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 src/test/rustdoc/cfg-doctest.rs create mode 100644 src/test/ui/feature-gate/feature-gate-cfg_doctest.rs create mode 100644 src/test/ui/feature-gate/feature-gate-cfg_doctest.stderr diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 3938df1a68267..1d9510c9aacab 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -212,6 +212,36 @@ pub struct BigX; Then, when looking for it through the `rustdoc` search, if you enter "x" or "big", search will show the `BigX` struct first. +### Include items only when collecting doctests + +Rustdoc's [documentation tests] can do some things that regular unit tests can't, so it can +sometimes be useful to extend your doctests with samples that wouldn't otherwise need to be in +documentation. To this end, Rustdoc allows you to have certain items only appear when it's +collecting doctests, so you can utilize doctest functionality without forcing the test to appear in +docs, or to find an arbitrary private item to include it on. + +If you add `#![feature(cfg_doctest)]` to your crate, Rustdoc will set `cfg(doctest)` when collecting +doctests. Note that they will still link against only the public items of your crate; if you need to +test private items, unit tests are still the way to go. + +In this example, we're adding doctests that we know won't compile, to verify that our struct can +only take in valid data: + +```rust +#![feature(cfg_doctest)] + +/// We have a struct here. Remember it doesn't accept negative numbers! +pub struct MyStruct(usize); + +/// ```compile_fail +/// let x = my_crate::MyStruct(-5); +/// ``` +#[cfg(doctest)] +pub struct MyStructOnlyTakesUsize; +``` + +[documentation tests]: documentation-tests.html + ## Unstable command-line arguments These features are enabled by passing a command-line flag to Rustdoc, but the flags in question are diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 67ca7f407d801..9fae246155e06 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -351,6 +351,9 @@ impl Options { .unwrap_or_else(|| PathBuf::from("doc")); let mut cfgs = matches.opt_strs("cfg"); cfgs.push("rustdoc".to_string()); + if should_test { + cfgs.push("doctest".to_string()); + } let extension_css = matches.opt_str("e").map(|s| PathBuf::from(&s)); diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 2b242a71ad4cc..c1a794a0d006a 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -577,6 +577,9 @@ declare_features! ( // Allows `async || body` closures. (active, async_closure, "1.37.0", Some(62290), None), + // Allows the use of `#[cfg(doctest)]`, set when rustdoc is collecting doctests + (active, cfg_doctest, "1.37.0", Some(62210), None), + // ------------------------------------------------------------------------- // feature-group-end: actual feature gates // ------------------------------------------------------------------------- @@ -1592,6 +1595,7 @@ const GATED_CFGS: &[(Symbol, Symbol, fn(&Features) -> bool)] = &[ (sym::target_thread_local, sym::cfg_target_thread_local, cfg_fn!(cfg_target_thread_local)), (sym::target_has_atomic, sym::cfg_target_has_atomic, cfg_fn!(cfg_target_has_atomic)), (sym::rustdoc, sym::doc_cfg, cfg_fn!(doc_cfg)), + (sym::doctest, sym::cfg_doctest, cfg_fn!(cfg_doctest)), ]; #[derive(Debug)] diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index 410f4b36b67f2..bfcb185785266 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -170,6 +170,7 @@ symbols! { cfg, cfg_attr, cfg_attr_multi, + cfg_doctest, cfg_target_feature, cfg_target_has_atomic, cfg_target_thread_local, @@ -235,6 +236,7 @@ symbols! { doc_keyword, doc_masked, doc_spotlight, + doctest, document_private_items, dotdoteq_in_patterns, dotdot_in_tuple_patterns, diff --git a/src/test/rustdoc-ui/cfg-test.rs b/src/test/rustdoc-ui/cfg-test.rs index 4dcf512d286ff..5360354d77a85 100644 --- a/src/test/rustdoc-ui/cfg-test.rs +++ b/src/test/rustdoc-ui/cfg-test.rs @@ -5,6 +5,8 @@ // Crates like core have doctests gated on `cfg(not(test))` so we need to make // sure `cfg(test)` is not active when running `rustdoc --test`. +#![feature(cfg_doctest)] + /// this doctest will be ignored: /// /// ``` @@ -20,3 +22,11 @@ pub struct Foo; /// ``` #[cfg(not(test))] pub struct Foo; + +/// this doctest will be tested, but will not appear in documentation: +/// +/// ``` +/// assert!(true) +/// ``` +#[cfg(doctest)] +pub struct Bar; diff --git a/src/test/rustdoc-ui/cfg-test.stdout b/src/test/rustdoc-ui/cfg-test.stdout index 67873870e89b2..de7e6097fb788 100644 --- a/src/test/rustdoc-ui/cfg-test.stdout +++ b/src/test/rustdoc-ui/cfg-test.stdout @@ -1,6 +1,7 @@ -running 1 test -test $DIR/cfg-test.rs - Foo (line 18) ... ok +running 2 tests +test $DIR/cfg-test.rs - Foo (line 20) ... ok +test $DIR/cfg-test.rs - Bar (line 28) ... ok -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out diff --git a/src/test/rustdoc/cfg-doctest.rs b/src/test/rustdoc/cfg-doctest.rs new file mode 100644 index 0000000000000..fca6d1029f981 --- /dev/null +++ b/src/test/rustdoc/cfg-doctest.rs @@ -0,0 +1,8 @@ +#![feature(cfg_doctest)] + +// @!has cfg_doctest/struct.SomeStruct.html +// @!has cfg_doctest/index.html '//a/@href' 'struct.SomeStruct.html' + +/// Sneaky, this isn't actually part of docs. +#[cfg(doctest)] +pub struct SomeStruct; diff --git a/src/test/ui/feature-gate/feature-gate-cfg_doctest.rs b/src/test/ui/feature-gate/feature-gate-cfg_doctest.rs new file mode 100644 index 0000000000000..308f68bd52a79 --- /dev/null +++ b/src/test/ui/feature-gate/feature-gate-cfg_doctest.rs @@ -0,0 +1,4 @@ +#[cfg(doctest)] //~ ERROR +pub struct SomeStruct; + +fn main() {} diff --git a/src/test/ui/feature-gate/feature-gate-cfg_doctest.stderr b/src/test/ui/feature-gate/feature-gate-cfg_doctest.stderr new file mode 100644 index 0000000000000..aa1d18a6f759d --- /dev/null +++ b/src/test/ui/feature-gate/feature-gate-cfg_doctest.stderr @@ -0,0 +1,12 @@ +error[E0658]: `cfg(doctest)` is experimental and subject to change + --> $DIR/feature-gate-cfg_doctest.rs:1:7 + | +LL | #[cfg(doctest)] + | ^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/62210 + = help: add #![feature(cfg_doctest)] to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. From cff6ce667fd8c5002f789a55f75ba70b67be42f7 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Tue, 2 Jul 2019 13:30:54 -0500 Subject: [PATCH 04/14] force single-threaded text execution --- src/test/rustdoc-ui/cfg-test.rs | 2 +- src/test/rustdoc-ui/cfg-test.stdout | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/rustdoc-ui/cfg-test.rs b/src/test/rustdoc-ui/cfg-test.rs index 5360354d77a85..e88ddfb9e2ad2 100644 --- a/src/test/rustdoc-ui/cfg-test.rs +++ b/src/test/rustdoc-ui/cfg-test.rs @@ -1,5 +1,5 @@ // build-pass (FIXME(62277): could be check-pass?) -// compile-flags:--test +// compile-flags:--test --test-args --test-threads=1 // normalize-stdout-test: "src/test/rustdoc-ui" -> "$$DIR" // Crates like core have doctests gated on `cfg(not(test))` so we need to make diff --git a/src/test/rustdoc-ui/cfg-test.stdout b/src/test/rustdoc-ui/cfg-test.stdout index de7e6097fb788..86141aed5c3f2 100644 --- a/src/test/rustdoc-ui/cfg-test.stdout +++ b/src/test/rustdoc-ui/cfg-test.stdout @@ -1,7 +1,7 @@ running 2 tests -test $DIR/cfg-test.rs - Foo (line 20) ... ok test $DIR/cfg-test.rs - Bar (line 28) ... ok +test $DIR/cfg-test.rs - Foo (line 20) ... ok test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out From 03ac05338c4ae4d01a8d3b2b05eb8e6d53384460 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Thu, 20 Jun 2019 11:52:31 +0300 Subject: [PATCH 05/14] syntax: Remove `NodeId` from `SyntaxExtension` --- src/librustc_plugin/registry.rs | 5 +---- src/librustc_resolve/lib.rs | 7 ++----- src/librustc_resolve/macros.rs | 23 ++++++++++------------- src/libsyntax/ext/base.rs | 8 ++++---- src/libsyntax/ext/expand.rs | 5 ++--- src/libsyntax/ext/tt/macro_rules.rs | 2 +- 6 files changed, 20 insertions(+), 30 deletions(-) diff --git a/src/librustc_plugin/registry.rs b/src/librustc_plugin/registry.rs index ec2855f826a46..bb3c950edae3b 100644 --- a/src/librustc_plugin/registry.rs +++ b/src/librustc_plugin/registry.rs @@ -84,10 +84,7 @@ impl<'a> Registry<'a> { /// Register a syntax extension of any kind. /// /// This is the most general hook into `libsyntax`'s expansion behavior. - pub fn register_syntax_extension(&mut self, name: ast::Name, mut extension: SyntaxExtension) { - if extension.def_info.is_none() { - extension.def_info = Some((ast::CRATE_NODE_ID, self.krate_span)); - } + pub fn register_syntax_extension(&mut self, name: ast::Name, extension: SyntaxExtension) { self.syntax_exts.push((name, extension)); } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 13b9855dbd71a..d2a9627201bc8 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1666,10 +1666,7 @@ pub struct Resolver<'a> { non_macro_attrs: [Lrc; 2], macro_defs: FxHashMap, local_macro_def_scopes: FxHashMap>, - - /// 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, + unused_macros: NodeMap, /// Maps the `Mark` of an expansion to its containing module or block. invocations: FxHashMap>, @@ -2009,7 +2006,7 @@ impl<'a> Resolver<'a> { name_already_seen: FxHashMap::default(), potentially_unused_imports: Vec::new(), struct_constructors: Default::default(), - unused_macros: FxHashSet::default(), + unused_macros: Default::default(), current_type_ascription: Vec::new(), injected_crate: None, } diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 0955c425f2f7d..e9c7a3add62a1 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -9,8 +9,7 @@ use crate::resolve_imports::ImportResolver; use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX}; use rustc::hir::def::{self, DefKind, NonMacroAttrKind}; use rustc::hir::map::{self, DefCollector}; -use rustc::{ty, lint}; -use rustc::{bug, span_bug}; +use rustc::{ty, lint, span_bug}; use syntax::ast::{self, Ident}; use syntax::attr; use syntax::errors::DiagnosticBuilder; @@ -259,14 +258,10 @@ impl<'a> base::Resolver for Resolver<'a> { } fn check_unused_macros(&self) { - for did in self.unused_macros.iter() { - if let Some((id, span)) = self.macro_map[did].def_info { - let lint = lint::builtin::UNUSED_MACROS; - 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"); - } + for (&node_id, &span) in self.unused_macros.iter() { + self.session.buffer_lint( + lint::builtin::UNUSED_MACROS, node_id, span, "unused macro definition" + ); } } } @@ -323,7 +318,9 @@ impl<'a> Resolver<'a> { match res { 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 { let msg = "can't use a procedural macro from the same crate that defines it"; self.session.span_err(path.span, msg); @@ -1157,13 +1154,13 @@ impl<'a> Resolver<'a> { (res, vis, item.span, expansion, IsMacroExport)); } else { self.check_reserved_macro_name(ident, res); - self.unused_macros.insert(def_id); + self.unused_macros.insert(item.id, item.span); } } else { let module = self.current_module; let vis = self.resolve_visibility(&item.vis); 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)); } diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 318a5a3a82a2e..57dabf98d2cc6 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -606,8 +606,8 @@ pub enum SyntaxExtensionKind { pub struct SyntaxExtension { /// A syntax extension kind. pub kind: SyntaxExtensionKind, - /// Some info about the macro's definition point. - pub def_info: Option<(ast::NodeId, Span)>, + /// Span of the macro definition. + pub span: Span, /// Hygienic properties of spans produced by this macro by default. pub default_transparency: Transparency, /// Whitelist of unstable features that are treated as stable inside this macro. @@ -657,7 +657,7 @@ impl SyntaxExtension { /// Constructs a syntax extension with default properties. pub fn default(kind: SyntaxExtensionKind, edition: Edition) -> SyntaxExtension { SyntaxExtension { - def_info: None, + span: DUMMY_SP, default_transparency: kind.default_transparency(), allow_internal_unstable: None, allow_internal_unsafe: false, @@ -681,7 +681,7 @@ impl SyntaxExtension { ExpnInfo { call_site, 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, allow_internal_unstable: self.allow_internal_unstable.clone(), allow_internal_unsafe: self.allow_internal_unsafe, diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 6fbd2ab7c43f2..da965eda61e47 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -673,8 +673,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { 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)) + if !crate_span.contains(ext.span) && !span.allows_unstable(feature) && this.cx.ecfg.features.map_or(true, |feats| { // macro features will count as lib features @@ -699,7 +698,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { self.cx, span, mac.node.stream(), - ext.def_info.map(|(_, s)| s), + Some(ext.span), )) } } diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index cf3c748cd8206..341d68c9c3201 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -442,7 +442,7 @@ pub fn compile( SyntaxExtension { kind: SyntaxExtensionKind::LegacyBang(expander), - def_info: Some((def.id, def.span)), + span: def.span, default_transparency, allow_internal_unstable, allow_internal_unsafe, From 3b6370b4ab645d65e0729b3a419946a6f2f4d1cd Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Thu, 20 Jun 2019 22:00:47 +0300 Subject: [PATCH 06/14] resolve/expand: Move macro stability checking to an earlier point --- src/librustc_resolve/macros.rs | 17 +++++++++--- src/libsyntax/ext/base.rs | 2 -- src/libsyntax/ext/expand.rs | 49 +++++++--------------------------- 3 files changed, 23 insertions(+), 45 deletions(-) diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index e9c7a3add62a1..dcdf0be41c225 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -229,16 +229,27 @@ impl<'a> base::Resolver for Resolver<'a> { Err(determinacy) => return Err(determinacy), }; + let span = invoc.span(); let format = match kind { MacroKind::Derive => format!("derive({})", fast_print_path(path)), _ => fast_print_path(path), }; - 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)); if let Res::Def(_, def_id) = res { if after_derive { - self.session.span_err(invoc.span(), - "macro attributes must be placed before `#[derive]`"); + self.session.span_err(span, "macro attributes must be placed before `#[derive]`"); + } + if let Some((feature, issue)) = ext.unstable_feature { + // Do not stability-check macros in the same crate. + let features = self.session.features_untracked(); + if !def_id.is_local() && + !span.allows_unstable(feature) && + features.declared_lib_features.iter().all(|(feat, _)| *feat != feature) { + let msg = format!("macro {}! is unstable", path); + emit_feature_err(&self.session.parse_sess, feature, span, + GateIssue::Library(Some(issue)), &msg); + } } self.macro_defs.insert(invoc.expansion_data.mark, def_id); let normal_module_def_id = diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 57dabf98d2cc6..bde989a464b41 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -738,7 +738,6 @@ pub struct ExpansionData { pub depth: usize, pub module: Rc, pub directory_ownership: DirectoryOwnership, - pub crate_span: Option, } /// One of these is made during expansion and incrementally updated as we go; @@ -768,7 +767,6 @@ impl<'a> ExtCtxt<'a> { depth: 0, module: Rc::new(ModuleData { mod_path: Vec::new(), directory: PathBuf::new() }), directory_ownership: DirectoryOwnership::Owned { relative: None }, - crate_span: None, }, expansions: FxHashMap::default(), } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index da965eda61e47..6be5988d03bb6 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -243,7 +243,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> { module.directory.pop(); self.cx.root_path = module.directory.clone(); self.cx.current_expansion.module = Rc::new(module); - self.cx.current_expansion.crate_span = Some(krate.span); let orig_mod_span = krate.module.inner; @@ -668,39 +667,17 @@ impl<'a, 'b> MacroExpander<'a, 'b> { }; 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 - if !crate_span.contains(ext.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 { + 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) => { - if let Err(dummy_span) = validate(self) { - dummy_span - } else { - kind.make_from(expander.expand( - self.cx, - span, - mac.node.stream(), - Some(ext.span), - )) - } + let tok_result = expander.expand(self.cx, span, mac.node.stream(), Some(ext.span)); + kind.make_from(tok_result) } SyntaxExtensionKind::Attr(..) | @@ -717,14 +694,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> { self.cx.trace_macros_diag(); 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() { From 290475e837d7c485c524d059cda90e63435e63c3 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Fri, 21 Jun 2019 01:55:40 +0300 Subject: [PATCH 07/14] Collect library features from non-exported macros --- src/librustc/hir/lowering.rs | 5 +++++ src/librustc/hir/map/collector.rs | 1 + src/librustc/hir/mod.rs | 2 ++ src/librustc/middle/lib_features.rs | 6 +++++- src/test/run-pass/macros/macro-stability.rs | 2 +- 5 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 271fac544a4d2..2a9fd58f84b3b 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -90,6 +90,7 @@ pub struct LoweringContext<'a> { impl_items: BTreeMap, bodies: BTreeMap, exported_macros: Vec, + non_exported_macro_attrs: Vec, trait_impls: BTreeMap>, @@ -252,6 +253,7 @@ pub fn lower_crate( trait_impls: BTreeMap::new(), modules: BTreeMap::new(), exported_macros: Vec::new(), + non_exported_macro_attrs: Vec::new(), catch_scopes: Vec::new(), loop_scopes: Vec::new(), is_in_loop_condition: false, @@ -662,6 +664,7 @@ impl<'a> LoweringContext<'a> { attrs, span: c.span, exported_macros: hir::HirVec::from(self.exported_macros), + non_exported_macro_attrs: hir::HirVec::from(self.non_exported_macro_attrs), items: self.items, trait_items: self.trait_items, impl_items: self.impl_items, @@ -4022,6 +4025,8 @@ impl<'a> LoweringContext<'a> { body, legacy: def.legacy, }); + } else { + self.non_exported_macro_attrs.extend(attrs.into_iter()); } return None; } diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs index 8a59f6b69bcd6..12ea772c1fb31 100644 --- a/src/librustc/hir/map/collector.rs +++ b/src/librustc/hir/map/collector.rs @@ -119,6 +119,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> { span, // These fields are handled separately: exported_macros: _, + non_exported_macro_attrs: _, items: _, trait_items: _, impl_items: _, diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 7b760a872387e..e7b37d40b4b2f 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -727,6 +727,8 @@ pub struct Crate { pub attrs: HirVec, pub span: Span, pub exported_macros: HirVec, + // Attributes from non-exported macros, kept only for collecting the library feature list. + pub non_exported_macro_attrs: HirVec, // N.B., we use a BTreeMap here so that `visit_all_items` iterates // over the ids in increasing order. In principle it should not diff --git a/src/librustc/middle/lib_features.rs b/src/librustc/middle/lib_features.rs index 694b0a9862960..0d6d016e50701 100644 --- a/src/librustc/middle/lib_features.rs +++ b/src/librustc/middle/lib_features.rs @@ -144,6 +144,10 @@ impl Visitor<'tcx> for LibFeatureCollector<'tcx> { pub fn collect(tcx: TyCtxt<'_>) -> LibFeatures { 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 } diff --git a/src/test/run-pass/macros/macro-stability.rs b/src/test/run-pass/macros/macro-stability.rs index b471aa655e9c6..817bddf69562b 100644 --- a/src/test/run-pass/macros/macro-stability.rs +++ b/src/test/run-pass/macros/macro-stability.rs @@ -1,7 +1,7 @@ // run-pass // aux-build:unstable-macros.rs -#![feature(unstable_macros)] +#![feature(unstable_macros, local_unstable)] #[macro_use] extern crate unstable_macros; From 73dec4a804c0dd63405f01f38664e6026a56df31 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Fri, 21 Jun 2019 01:59:30 +0300 Subject: [PATCH 08/14] resolve: Check stability for local macros as well --- src/librustc_resolve/macros.rs | 21 ++++++++++----------- src/test/ui/macros/macro-stability.rs | 2 +- src/test/ui/macros/macro-stability.stderr | 10 +++++++++- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index dcdf0be41c225..724b30800fa0f 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -236,21 +236,20 @@ impl<'a> base::Resolver for Resolver<'a> { }; invoc.expansion_data.mark.set_expn_info(ext.expn_info(span, &format)); + if let Some((feature, issue)) = ext.unstable_feature { + let features = self.session.features_untracked(); + if !span.allows_unstable(feature) && + features.declared_lib_features.iter().all(|(feat, _)| *feat != feature) { + let msg = format!("macro {}! is unstable", path); + emit_feature_err(&self.session.parse_sess, feature, span, + GateIssue::Library(Some(issue)), &msg); + } + } + if let Res::Def(_, def_id) = res { if after_derive { self.session.span_err(span, "macro attributes must be placed before `#[derive]`"); } - if let Some((feature, issue)) = ext.unstable_feature { - // Do not stability-check macros in the same crate. - let features = self.session.features_untracked(); - if !def_id.is_local() && - !span.allows_unstable(feature) && - features.declared_lib_features.iter().all(|(feat, _)| *feat != feature) { - let msg = format!("macro {}! is unstable", path); - emit_feature_err(&self.session.parse_sess, feature, span, - GateIssue::Library(Some(issue)), &msg); - } - } self.macro_defs.insert(invoc.expansion_data.mark, def_id); let normal_module_def_id = self.macro_def_scope(invoc.expansion_data.mark).normal_ancestor_id; diff --git a/src/test/ui/macros/macro-stability.rs b/src/test/ui/macros/macro-stability.rs index 7d1ee6a43b6ad..e6a81c96696a9 100644 --- a/src/test/ui/macros/macro-stability.rs +++ b/src/test/ui/macros/macro-stability.rs @@ -7,6 +7,6 @@ macro_rules! local_unstable { () => () } fn main() { - local_unstable!(); + local_unstable!(); //~ ERROR: macro local_unstable! is unstable unstable_macro!(); //~ ERROR: macro unstable_macro! is unstable } diff --git a/src/test/ui/macros/macro-stability.stderr b/src/test/ui/macros/macro-stability.stderr index a0e0c351a4834..d609c3bc765f3 100644 --- a/src/test/ui/macros/macro-stability.stderr +++ b/src/test/ui/macros/macro-stability.stderr @@ -1,3 +1,11 @@ +error[E0658]: macro local_unstable! is unstable + --> $DIR/macro-stability.rs:10:5 + | +LL | local_unstable!(); + | ^^^^^^^^^^^^^^^^^^ + | + = help: add #![feature(local_unstable)] to the crate attributes to enable + error[E0658]: macro unstable_macro! is unstable --> $DIR/macro-stability.rs:11:5 | @@ -6,6 +14,6 @@ LL | unstable_macro!(); | = help: add #![feature(unstable_macros)] 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`. From 3542995ff9d04684ccd0a856e97d1c981fbf74c4 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Fri, 21 Jun 2019 11:50:30 +0300 Subject: [PATCH 09/14] syntax: Keep full `Stability` in `SyntaxExtension` --- src/librustc_resolve/macros.rs | 18 ++++++++++-------- src/libsyntax/attr/builtin.rs | 3 ++- src/libsyntax/ext/base.rs | 8 ++++---- src/libsyntax/ext/tt/macro_rules.rs | 15 ++------------- 4 files changed, 18 insertions(+), 26 deletions(-) diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 724b30800fa0f..46704bc791c41 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -11,7 +11,7 @@ use rustc::hir::def::{self, DefKind, NonMacroAttrKind}; use rustc::hir::map::{self, DefCollector}; use rustc::{ty, lint, span_bug}; use syntax::ast::{self, Ident}; -use syntax::attr; +use syntax::attr::{self, StabilityLevel}; use syntax::errors::DiagnosticBuilder; use syntax::ext::base::{self, Determinacy}; use syntax::ext::base::{MacroKind, SyntaxExtension}; @@ -236,13 +236,15 @@ impl<'a> base::Resolver for Resolver<'a> { }; invoc.expansion_data.mark.set_expn_info(ext.expn_info(span, &format)); - if let Some((feature, issue)) = ext.unstable_feature { - let features = self.session.features_untracked(); - if !span.allows_unstable(feature) && - features.declared_lib_features.iter().all(|(feat, _)| *feat != feature) { - let msg = format!("macro {}! is unstable", path); - emit_feature_err(&self.session.parse_sess, feature, span, - GateIssue::Library(Some(issue)), &msg); + if let Some(stability) = ext.stability { + if let StabilityLevel::Unstable { issue, .. } = stability.level { + let features = self.session.features_untracked(); + if !span.allows_unstable(stability.feature) && + features.declared_lib_features.iter().all(|(feat, _)| *feat != stability.feature) { + let msg = format!("macro {}! is unstable", path); + emit_feature_err(&self.session.parse_sess, stability.feature, span, + GateIssue::Library(Some(issue)), &msg); + } } } diff --git a/src/libsyntax/attr/builtin.rs b/src/libsyntax/attr/builtin.rs index 752ab5d474dff..9b411981ed34a 100644 --- a/src/libsyntax/attr/builtin.rs +++ b/src/libsyntax/attr/builtin.rs @@ -171,7 +171,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], item_sp: Span) -> Option { find_stability_generic(sess, attrs.iter(), item_sp) diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index bde989a464b41..d5d1c7662b2b8 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -1,5 +1,5 @@ use crate::ast::{self, Attribute, Name, PatKind}; -use crate::attr::HasAttrs; +use crate::attr::{HasAttrs, Stability}; use crate::source_map::{SourceMap, Spanned, respan}; use crate::edition::Edition; use crate::ext::expand::{self, AstFragment, Invocation}; @@ -616,8 +616,8 @@ pub struct SyntaxExtension { pub allow_internal_unsafe: bool, /// Enables the macro helper hack (`ident!(...)` -> `$crate::ident!(...)`) for this macro. pub local_inner_macros: bool, - /// The macro's feature name and tracking issue number if it is unstable. - pub unstable_feature: Option<(Symbol, u32)>, + /// The macro's stability and deprecation info. + pub stability: Option, /// Names of helper attributes registered by this macro. pub helper_attrs: Vec, /// Edition of the crate in which this macro is defined. @@ -662,7 +662,7 @@ impl SyntaxExtension { allow_internal_unstable: None, allow_internal_unsafe: false, local_inner_macros: false, - unstable_feature: None, + stability: None, helper_attrs: Vec::new(), edition, kind, diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 341d68c9c3201..5b5588a02f268 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -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; if let Some(macro_export) = attr::find_by_name(&def.attrs, sym::macro_export) { if let Some(l) = macro_export.meta_item_list() { @@ -431,23 +429,14 @@ 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 { kind: SyntaxExtensionKind::LegacyBang(expander), span: def.span, default_transparency, allow_internal_unstable, - allow_internal_unsafe, + allow_internal_unsafe: attr::contains_name(&def.attrs, sym::allow_internal_unsafe), local_inner_macros, - unstable_feature, + stability: attr::find_stability(&sess, &def.attrs, def.span), helper_attrs: Vec::new(), edition, } From d9ee97e896125b38dba199c763e5e35c5107a735 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 22 Jun 2019 00:18:09 +0300 Subject: [PATCH 10/14] resolve: Use standard stability diagnostics for macros --- src/librustc/middle/stability.rs | 60 ++++++++++++----------- src/librustc_resolve/macros.rs | 15 +++--- src/test/ui/macros/macro-stability.rs | 4 +- src/test/ui/macros/macro-stability.stderr | 4 +- 4 files changed, 43 insertions(+), 40 deletions(-) diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 7757336cf9c36..fed9dfd38e59f 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -477,6 +477,36 @@ pub fn provide(providers: &mut Providers<'_>) { }; } +pub fn report_unstable( + sess: &Session, feature: Symbol, reason: Option, issue: u32, span: Span +) { + let msg = match reason { + Some(r) => format!("use of unstable library feature '{}': {}", feature, r), + None => format!("use of unstable library feature '{}'", &feature) + }; + + let msp: MultiSpan = span.into(); + let cm = &sess.parse_sess.source_map(); + let span_key = msp.primary_span().and_then(|sp: Span| + if !sp.is_dummy() { + let file = cm.lookup_char_pos(sp.lo()).file; + if file.name.is_macros() { + None + } else { + Some(span) + } + } else { + None + } + ); + + let error_id = (DiagnosticMessageId::StabilityId(issue), span_key, msg.clone()); + let fresh = sess.one_time_diagnostics.borrow_mut().insert(error_id); + if fresh { + emit_feature_err(&sess.parse_sess, feature, span, GateIssue::Library(Some(issue)), &msg); + } +} + /// Checks whether an item marked with `deprecated(since="X")` is currently /// deprecated (i.e., whether X is not greater than the current rustc version). pub fn deprecation_in_effect(since: &str) -> bool { @@ -715,34 +745,8 @@ impl<'tcx> TyCtxt<'tcx> { pub fn check_stability(self, def_id: DefId, id: Option, span: Span) { match self.eval_stability(def_id, id, span) { EvalResult::Allow => {} - EvalResult::Deny { feature, reason, issue } => { - let msg = match reason { - Some(r) => format!("use of unstable library feature '{}': {}", feature, r), - None => format!("use of unstable library feature '{}'", &feature) - }; - - let msp: MultiSpan = span.into(); - let cm = &self.sess.parse_sess.source_map(); - let span_key = msp.primary_span().and_then(|sp: Span| - if !sp.is_dummy() { - let file = cm.lookup_char_pos(sp.lo()).file; - if file.name.is_macros() { - None - } else { - Some(span) - } - } else { - None - } - ); - - let error_id = (DiagnosticMessageId::StabilityId(issue), span_key, msg.clone()); - let fresh = self.sess.one_time_diagnostics.borrow_mut().insert(error_id); - if fresh { - emit_feature_err(&self.sess.parse_sess, feature, span, - GateIssue::Library(Some(issue)), &msg); - } - } + EvalResult::Deny { feature, reason, issue } => + report_unstable(self.sess, feature, reason, issue, span), EvalResult::Unmarked => { // The API could be uncallable for other reasons, for example when a private module // was referenced. diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 46704bc791c41..8cd3f6d94139f 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -9,6 +9,7 @@ use crate::resolve_imports::ImportResolver; use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX}; use rustc::hir::def::{self, DefKind, NonMacroAttrKind}; use rustc::hir::map::{self, DefCollector}; +use rustc::middle::stability; use rustc::{ty, lint, span_bug}; use syntax::ast::{self, Ident}; use syntax::attr::{self, StabilityLevel}; @@ -18,7 +19,7 @@ use syntax::ext::base::{MacroKind, SyntaxExtension}; use syntax::ext::expand::{AstFragment, Invocation, InvocationKind}; use syntax::ext::hygiene::Mark; use syntax::ext::tt::macro_rules; -use syntax::feature_gate::{feature_err, emit_feature_err, is_builtin_attr_name}; +use syntax::feature_gate::{feature_err, is_builtin_attr_name}; use syntax::feature_gate::{AttributeGate, GateIssue, Stability, BUILTIN_ATTRIBUTES}; use syntax::symbol::{Symbol, kw, sym}; use syntax::visit::Visitor; @@ -237,13 +238,11 @@ impl<'a> base::Resolver for Resolver<'a> { invoc.expansion_data.mark.set_expn_info(ext.expn_info(span, &format)); if let Some(stability) = ext.stability { - if let StabilityLevel::Unstable { issue, .. } = stability.level { - let features = self.session.features_untracked(); - if !span.allows_unstable(stability.feature) && - features.declared_lib_features.iter().all(|(feat, _)| *feat != stability.feature) { - let msg = format!("macro {}! is unstable", path); - emit_feature_err(&self.session.parse_sess, stability.feature, span, - GateIssue::Library(Some(issue)), &msg); + if let StabilityLevel::Unstable { reason, issue } = stability.level { + let (feature, features) = (stability.feature, self.session.features_untracked()); + if !span.allows_unstable(feature) && + features.declared_lib_features.iter().all(|(feat, _)| *feat != feature) { + stability::report_unstable(self.session, feature, reason, issue, span); } } } diff --git a/src/test/ui/macros/macro-stability.rs b/src/test/ui/macros/macro-stability.rs index e6a81c96696a9..c904ec30f0b72 100644 --- a/src/test/ui/macros/macro-stability.rs +++ b/src/test/ui/macros/macro-stability.rs @@ -7,6 +7,6 @@ macro_rules! local_unstable { () => () } fn main() { - local_unstable!(); //~ ERROR: macro local_unstable! is unstable - unstable_macro!(); //~ ERROR: macro unstable_macro! is unstable + local_unstable!(); //~ ERROR use of unstable library feature 'local_unstable' + unstable_macro!(); //~ ERROR use of unstable library feature 'unstable_macros' } diff --git a/src/test/ui/macros/macro-stability.stderr b/src/test/ui/macros/macro-stability.stderr index d609c3bc765f3..8cf72d183342d 100644 --- a/src/test/ui/macros/macro-stability.stderr +++ b/src/test/ui/macros/macro-stability.stderr @@ -1,4 +1,4 @@ -error[E0658]: macro local_unstable! is unstable +error[E0658]: use of unstable library feature 'local_unstable' --> $DIR/macro-stability.rs:10:5 | LL | local_unstable!(); @@ -6,7 +6,7 @@ LL | local_unstable!(); | = help: add #![feature(local_unstable)] to the crate attributes to enable -error[E0658]: macro unstable_macro! is unstable +error[E0658]: use of unstable library feature 'unstable_macros' --> $DIR/macro-stability.rs:11:5 | LL | unstable_macro!(); From 0817fc6c6cd880c51318d476de9ecb43327e12b1 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 22 Jun 2019 02:44:45 +0300 Subject: [PATCH 11/14] Support deprecation checking for macros --- src/librustc/lint/builtin.rs | 5 + src/librustc/middle/stability.rs | 148 ++++++++++-------- src/librustc_resolve/macros.rs | 37 +++-- src/libsyntax/ext/base.rs | 7 +- src/libsyntax/ext/tt/macro_rules.rs | 1 + .../ui/macros/auxiliary/deprecated-macros.rs | 3 + .../ui/macros/auxiliary/unstable-macros.rs | 10 ++ src/test/ui/macros/macro-deprecation.rs | 13 ++ src/test/ui/macros/macro-deprecation.stderr | 14 ++ src/test/ui/macros/macro-stability.rs | 16 ++ src/test/ui/macros/macro-stability.stderr | 28 +++- 11 files changed, 203 insertions(+), 79 deletions(-) create mode 100644 src/test/ui/macros/auxiliary/deprecated-macros.rs create mode 100644 src/test/ui/macros/macro-deprecation.rs create mode 100644 src/test/ui/macros/macro-deprecation.stderr diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 45e598531b969..dd879ec6aff34 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -5,10 +5,12 @@ //! lints are all available in `rustc_lint::builtin`. use crate::lint::{LintPass, LateLintPass, LintArray}; +use crate::middle::stability; use crate::session::Session; use errors::{Applicability, DiagnosticBuilder}; use syntax::ast; use syntax::source_map::Span; +use syntax::symbol::Symbol; declare_lint! { pub EXCEEDING_BITSHIFTS, @@ -461,6 +463,7 @@ pub enum BuiltinLintDiagnostics { UnusedImports(String, Vec<(Span, String)>), NestedImplTrait { outer_impl_trait_span: Span, inner_impl_trait_span: Span }, RedundantImport(Vec<(Span, bool)>, ast::Ident), + DeprecatedMacro(Option, Span), } pub(crate) fn add_elided_lifetime_in_path_suggestion( @@ -586,6 +589,8 @@ impl BuiltinLintDiagnostics { ); } } + BuiltinLintDiagnostics::DeprecatedMacro(suggestion, span) => + stability::deprecation_suggestion(db, suggestion, span), } } } diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index fed9dfd38e59f..5ab762ab225f9 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -4,6 +4,7 @@ pub use self::StabilityLevel::*; use crate::lint::{self, Lint, in_derive_expansion}; +use crate::lint::builtin::BuiltinLintDiagnostics; use crate::hir::{self, Item, Generics, StructField, Variant, HirId}; use crate::hir::def::{Res, DefKind}; use crate::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId, LOCAL_CRATE}; @@ -11,12 +12,13 @@ use crate::hir::intravisit::{self, Visitor, NestedVisitorMap}; use crate::ty::query::Providers; use crate::middle::privacy::AccessLevels; use crate::session::{DiagnosticMessageId, Session}; +use errors::DiagnosticBuilder; use syntax::symbol::{Symbol, sym}; use syntax_pos::{Span, MultiSpan}; -use syntax::ast::Attribute; +use syntax::ast::{Attribute, CRATE_NODE_ID}; use syntax::errors::Applicability; use syntax::feature_gate::{GateIssue, emit_feature_err}; -use syntax::attr::{self, Stability, Deprecation}; +use syntax::attr::{self, Stability, Deprecation, RustcDeprecation}; use crate::ty::{self, TyCtxt}; use crate::util::nodemap::{FxHashSet, FxHashMap}; @@ -531,6 +533,79 @@ pub fn deprecation_in_effect(since: &str) -> bool { } } +pub fn deprecation_suggestion( + diag: &mut DiagnosticBuilder<'_>, suggestion: Option, 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) -> 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, + 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, + lint: &'static Lint, + span: Span, + def_id: DefId, + hir_id: HirId, +) { + if in_derive_expansion(span) { + return; + } + + let mut diag = tcx.struct_span_lint_hir(lint, hir_id, span, message); + if let hir::Node::Expr(_) = tcx.hir().get(hir_id) { + deprecation_suggestion(&mut diag, suggestion, span); + } + diag.emit(); + if hir_id == hir::DUMMY_HIR_ID { + span_bug!(span, "emitted a {} lint with dummy HIR id: {:?}", lint.name, def_id); + } +} + struct Checker<'tcx> { tcx: TyCtxt<'tcx>, } @@ -593,38 +668,6 @@ impl<'tcx> TyCtxt<'tcx> { /// deprecated. If the item is indeed deprecated, we will emit a deprecation lint attached to /// `id`. pub fn eval_stability(self, def_id: DefId, id: Option, span: Span) -> EvalResult { - let lint_deprecated = |def_id: DefId, - id: HirId, - note: Option, - suggestion: Option, - message: &str, - lint: &'static Lint| { - if in_derive_expansion(span) { - return; - } - let msg = if let Some(note) = note { - format!("{}: {}", message, note) - } else { - format!("{}", message) - }; - - let mut diag = self.struct_span_lint_hir(lint, id, span, &msg); - if let Some(suggestion) = suggestion { - if let hir::Node::Expr(_) = self.hir().get(id) { - diag.span_suggestion( - span, - "replace the use of the deprecated item", - suggestion.to_string(), - Applicability::MachineApplicable, - ); - } - } - diag.emit(); - if id == hir::DUMMY_HIR_ID { - span_bug!(span, "emitted a {} lint with dummy HIR id: {:?}", lint.name, def_id); - } - }; - // Deprecated attributes apply in-crate and cross-crate. if let Some(id) = id { if let Some(depr_entry) = self.lookup_deprecation_entry(def_id) { @@ -634,14 +677,9 @@ impl<'tcx> TyCtxt<'tcx> { .map_or(false, |parent_depr| parent_depr.same_origin(&depr_entry)); if !skip { - let path = self.def_path_str(def_id); - let message = format!("use of deprecated item '{}'", path); - lint_deprecated(def_id, - id, - depr_entry.attr.note, - None, - &message, - lint::builtin::DEPRECATED); + let (message, lint) = + deprecation_message(&depr_entry.attr, &self.def_path_str(def_id)); + late_report_deprecation(self, &message, None, lint, span, def_id, id); } }; } @@ -661,27 +699,11 @@ impl<'tcx> TyCtxt<'tcx> { if let Some(id) = id { if let Some(stability) = stability { if let Some(depr) = &stability.rustc_depr { - let path = self.def_path_str(def_id); - if deprecation_in_effect(&depr.since.as_str()) { - let message = format!("use of deprecated item '{}'", path); - lint_deprecated(def_id, - id, - Some(depr.reason), - depr.suggestion, - &message, - lint::builtin::DEPRECATED); - } else { - let message = format!("use of item '{}' \ - that will be deprecated in future version {}", - path, - depr.since); - lint_deprecated(def_id, - id, - Some(depr.reason), - depr.suggestion, - &message, - lint::builtin::DEPRECATED_IN_FUTURE); - } + let (message, lint) = + rustc_deprecation_message(depr, &self.def_path_str(def_id)); + late_report_deprecation( + self, &message, depr.suggestion, lint, span, def_id, id + ); } } } diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 8cd3f6d94139f..c65208b8ed207 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -231,21 +231,14 @@ impl<'a> base::Resolver for Resolver<'a> { }; let span = invoc.span(); + let path = fast_print_path(path); let format = match kind { - MacroKind::Derive => format!("derive({})", fast_print_path(path)), - _ => fast_print_path(path), + MacroKind::Derive => format!("derive({})", path), + _ => path.clone(), }; invoc.expansion_data.mark.set_expn_info(ext.expn_info(span, &format)); - if let Some(stability) = ext.stability { - if let StabilityLevel::Unstable { reason, issue } = stability.level { - let (feature, features) = (stability.feature, self.session.features_untracked()); - if !span.allows_unstable(feature) && - features.declared_lib_features.iter().all(|(feat, _)| *feat != feature) { - stability::report_unstable(self.session, feature, reason, issue, span); - } - } - } + self.check_stability_and_deprecation(&ext, &path, span); if let Res::Def(_, def_id) = res { if after_derive { @@ -1017,6 +1010,28 @@ impl<'a> Resolver<'a> { } } + fn check_stability_and_deprecation(&self, ext: &SyntaxExtension, path: &str, span: Span) { + if let Some(stability) = &ext.stability { + if let StabilityLevel::Unstable { reason, issue } = stability.level { + let (feature, features) = (stability.feature, self.session.features_untracked()); + if !span.allows_unstable(feature) && + features.declared_lib_features.iter().all(|(feat, _)| *feat != feature) { + stability::report_unstable(self.session, feature, reason, issue, span); + } + } + if let Some(depr) = &stability.rustc_depr { + let (message, lint) = stability::rustc_deprecation_message(depr, path); + stability::early_report_deprecation( + self.session, &message, depr.suggestion, lint, span + ); + } + } + if let Some(depr) = &ext.deprecation { + let (message, lint) = stability::deprecation_message(depr, path); + stability::early_report_deprecation(self.session, &message, None, lint, span); + } + } + fn prohibit_imported_non_macro_attrs(&self, binding: Option<&'a NameBinding<'a>>, res: Option, span: Span) { if let Some(Res::NonMacroAttr(kind)) = res { diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index d5d1c7662b2b8..15c0b6ca5aa81 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -1,5 +1,5 @@ use crate::ast::{self, Attribute, Name, PatKind}; -use crate::attr::{HasAttrs, Stability}; +use crate::attr::{HasAttrs, Stability, Deprecation}; use crate::source_map::{SourceMap, Spanned, respan}; use crate::edition::Edition; use crate::ext::expand::{self, AstFragment, Invocation}; @@ -616,8 +616,10 @@ pub struct SyntaxExtension { pub allow_internal_unsafe: bool, /// Enables the macro helper hack (`ident!(...)` -> `$crate::ident!(...)`) for this macro. pub local_inner_macros: bool, - /// The macro's stability and deprecation info. + /// The macro's stability info. pub stability: Option, + /// The macro's deprecation info. + pub deprecation: Option, /// Names of helper attributes registered by this macro. pub helper_attrs: Vec, /// Edition of the crate in which this macro is defined. @@ -663,6 +665,7 @@ impl SyntaxExtension { allow_internal_unsafe: false, local_inner_macros: false, stability: None, + deprecation: None, helper_attrs: Vec::new(), edition, kind, diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 5b5588a02f268..665c794422d49 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -437,6 +437,7 @@ pub fn compile( allow_internal_unsafe: attr::contains_name(&def.attrs, sym::allow_internal_unsafe), local_inner_macros, stability: attr::find_stability(&sess, &def.attrs, def.span), + deprecation: attr::find_deprecation(&sess, &def.attrs, def.span), helper_attrs: Vec::new(), edition, } diff --git a/src/test/ui/macros/auxiliary/deprecated-macros.rs b/src/test/ui/macros/auxiliary/deprecated-macros.rs new file mode 100644 index 0000000000000..657a7252a36de --- /dev/null +++ b/src/test/ui/macros/auxiliary/deprecated-macros.rs @@ -0,0 +1,3 @@ +#[deprecated(since = "1.0.0", note = "deprecation note")] +#[macro_export] +macro_rules! deprecated_macro{ () => () } diff --git a/src/test/ui/macros/auxiliary/unstable-macros.rs b/src/test/ui/macros/auxiliary/unstable-macros.rs index b8d580702c9bc..e928dc705d71f 100644 --- a/src/test/ui/macros/auxiliary/unstable-macros.rs +++ b/src/test/ui/macros/auxiliary/unstable-macros.rs @@ -1,6 +1,16 @@ +#![feature(decl_macro)] #![feature(staged_api)] #![stable(feature = "unit_test", since = "1.0.0")] #[unstable(feature = "unstable_macros", issue = "0")] #[macro_export] macro_rules! unstable_macro{ () => () } + +#[stable(feature = "deprecated_macros", since = "1.0.0")] +#[rustc_deprecated(since = "1.0.0", reason = "deprecation reason")] +#[macro_export] +macro_rules! deprecated_macro{ () => () } + +// FIXME: Cannot use a `pub` macro 2.0 in a staged API crate due to reachability issues. +// #[unstable(feature = "unstable_macros", issue = "0")] +// pub macro unstable_macro_modern() {} diff --git a/src/test/ui/macros/macro-deprecation.rs b/src/test/ui/macros/macro-deprecation.rs new file mode 100644 index 0000000000000..ae3827604faf0 --- /dev/null +++ b/src/test/ui/macros/macro-deprecation.rs @@ -0,0 +1,13 @@ +// compile-pass +// aux-build:deprecated-macros.rs + +#[macro_use] extern crate deprecated_macros; + +#[deprecated(since = "1.0.0", note = "local deprecation note")] +#[macro_export] +macro_rules! local_deprecated{ () => () } + +fn main() { + local_deprecated!(); //~ WARN use of deprecated item 'local_deprecated': local deprecation note + deprecated_macro!(); //~ WARN use of deprecated item 'deprecated_macro': deprecation note +} diff --git a/src/test/ui/macros/macro-deprecation.stderr b/src/test/ui/macros/macro-deprecation.stderr new file mode 100644 index 0000000000000..e5f4df5223752 --- /dev/null +++ b/src/test/ui/macros/macro-deprecation.stderr @@ -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!(); + | ^^^^^^^^^^^^^^^^^^^^ + diff --git a/src/test/ui/macros/macro-stability.rs b/src/test/ui/macros/macro-stability.rs index c904ec30f0b72..ab927e419b4c3 100644 --- a/src/test/ui/macros/macro-stability.rs +++ b/src/test/ui/macros/macro-stability.rs @@ -1,12 +1,28 @@ // aux-build:unstable-macros.rs +#![feature(decl_macro)] #![feature(staged_api)] #[macro_use] extern crate unstable_macros; #[unstable(feature = "local_unstable", issue = "0")] macro_rules! local_unstable { () => () } +#[unstable(feature = "local_unstable", issue = "0")] +macro local_unstable_modern() {} + +#[stable(feature = "deprecated_macros", since = "1.0.0")] +#[rustc_deprecated(since = "1.0.0", reason = "local deprecation reason")] +#[macro_export] +macro_rules! local_deprecated{ () => () } + fn main() { local_unstable!(); //~ ERROR use of unstable library feature 'local_unstable' + local_unstable_modern!(); //~ ERROR use of unstable library feature 'local_unstable' unstable_macro!(); //~ ERROR use of unstable library feature 'unstable_macros' + // unstable_macro_modern!(); // ERROR use of unstable library feature 'unstable_macros' + + deprecated_macro!(); + //~^ WARN use of deprecated item 'deprecated_macro': deprecation reason + local_deprecated!(); + //~^ WARN use of deprecated item 'local_deprecated': local deprecation reason } diff --git a/src/test/ui/macros/macro-stability.stderr b/src/test/ui/macros/macro-stability.stderr index 8cf72d183342d..88edadc3811bc 100644 --- a/src/test/ui/macros/macro-stability.stderr +++ b/src/test/ui/macros/macro-stability.stderr @@ -1,19 +1,41 @@ error[E0658]: use of unstable library feature 'local_unstable' - --> $DIR/macro-stability.rs:10:5 + --> $DIR/macro-stability.rs:19:5 | LL | local_unstable!(); | ^^^^^^^^^^^^^^^^^^ | = help: add #![feature(local_unstable)] to the crate attributes to enable +error[E0658]: use of unstable library feature 'local_unstable' + --> $DIR/macro-stability.rs:20:5 + | +LL | local_unstable_modern!(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add #![feature(local_unstable)] to the crate attributes to enable + error[E0658]: use of unstable library feature 'unstable_macros' - --> $DIR/macro-stability.rs:11:5 + --> $DIR/macro-stability.rs:21:5 | LL | unstable_macro!(); | ^^^^^^^^^^^^^^^^^^ | = help: add #![feature(unstable_macros)] to the crate attributes to enable -error: aborting due to 2 previous errors +warning: use of deprecated item 'deprecated_macro': deprecation reason + --> $DIR/macro-stability.rs:24:5 + | +LL | deprecated_macro!(); + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: #[warn(deprecated)] on by default + +warning: use of deprecated item 'local_deprecated': local deprecation reason + --> $DIR/macro-stability.rs:26:5 + | +LL | local_deprecated!(); + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0658`. From 1ee0ce82cba66305f03725fb73ad381349a9b8e4 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 22 Jun 2019 16:18:05 +0300 Subject: [PATCH 12/14] syntax: Migrate built-in macros to the regular stability checking --- src/librustc_resolve/lib.rs | 8 ++ src/librustc_resolve/macros.rs | 5 +- src/libserialize/json.rs | 2 + src/libsyntax/attr/builtin.rs | 13 +++ src/libsyntax/ext/expand.rs | 36 ++------- src/libsyntax/ext/source_util.rs | 12 +-- src/libsyntax/feature_gate.rs | 22 +---- src/libsyntax_ext/asm.rs | 9 --- src/libsyntax_ext/concat_idents.rs | 11 +-- src/libsyntax_ext/deriving/decodable.rs | 2 - src/libsyntax_ext/deriving/encodable.rs | 2 - src/libsyntax_ext/deriving/mod.rs | 34 ++++---- src/libsyntax_ext/format.rs | 47 ++++------- src/libsyntax_ext/global_asm.rs | 12 --- src/libsyntax_ext/lib.rs | 80 +++++++++++++++---- src/libsyntax_ext/log_syntax.rs | 12 +-- src/libsyntax_ext/test_case.rs | 9 --- src/libsyntax_ext/trace_macros.rs | 11 +-- src/test/ui-fulldeps/deprecated-derive.stderr | 4 +- .../ui/feature-gates/feature-gate-asm.stderr | 2 +- .../ui/feature-gates/feature-gate-asm2.stderr | 2 +- .../feature-gate-concat_idents.stderr | 4 +- .../feature-gate-concat_idents2.stderr | 2 +- .../feature-gate-concat_idents3.stderr | 4 +- .../feature-gate-format_args_nl.stderr | 2 +- .../feature-gate-global_asm.stderr | 2 +- .../feature-gate-log_syntax.stderr | 2 +- .../feature-gate-log_syntax2.stderr | 2 +- .../feature-gate-trace_macros.stderr | 2 +- src/test/ui/rust-unstable-column-gated.rs | 2 +- src/test/ui/rust-unstable-column-gated.stderr | 5 +- src/test/ui/trace_macros-gate.stderr | 8 +- 32 files changed, 161 insertions(+), 209 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index d2a9627201bc8..66410482cc6d7 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1684,6 +1684,9 @@ pub struct Resolver<'a> { current_type_ascription: Vec, injected_crate: Option>, + + /// Features enabled for this crate. + active_features: FxHashSet, } /// Nothing really interesting here; it just provides memory for the rest of the crate. @@ -1922,6 +1925,7 @@ impl<'a> Resolver<'a> { let mut macro_defs = FxHashMap::default(); macro_defs.insert(Mark::root(), root_def_id); + let features = session.features_untracked(); let non_macro_attr = |mark_used| Lrc::new(SyntaxExtension::default( SyntaxExtensionKind::NonMacroAttr { mark_used }, session.edition() )); @@ -2009,6 +2013,10 @@ impl<'a> Resolver<'a> { unused_macros: Default::default(), current_type_ascription: Vec::new(), injected_crate: None, + active_features: + features.declared_lib_features.iter().map(|(feat, ..)| *feat) + .chain(features.declared_lang_features.iter().map(|(feat, ..)| *feat)) + .collect(), } } diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index c65208b8ed207..6d669aafc81a4 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -1013,9 +1013,8 @@ impl<'a> Resolver<'a> { fn check_stability_and_deprecation(&self, ext: &SyntaxExtension, path: &str, span: Span) { if let Some(stability) = &ext.stability { if let StabilityLevel::Unstable { reason, issue } = stability.level { - let (feature, features) = (stability.feature, self.session.features_untracked()); - if !span.allows_unstable(feature) && - features.declared_lib_features.iter().all(|(feat, _)| *feat != feature) { + let feature = stability.feature; + if !self.active_features.contains(&feature) && !span.allows_unstable(feature) { stability::report_unstable(self.session, feature, reason, issue, span); } } diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index 726306d60ce1e..77947a4be7ff8 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -103,6 +103,7 @@ //! //! ```rust //! # #![feature(rustc_private)] +//! # #![allow(deprecated)] //! extern crate serialize; //! use serialize::json::{self, ToJson, Json}; //! @@ -143,6 +144,7 @@ //! //! ```rust //! # #![feature(rustc_private)] +//! # #![allow(deprecated)] //! extern crate serialize; //! use std::collections::BTreeMap; //! use serialize::json::{self, Json, ToJson}; diff --git a/src/libsyntax/attr/builtin.rs b/src/libsyntax/attr/builtin.rs index 9b411981ed34a..b41f1047fcba3 100644 --- a/src/libsyntax/attr/builtin.rs +++ b/src/libsyntax/attr/builtin.rs @@ -135,6 +135,19 @@ pub enum StabilityLevel { Stable { since: Symbol }, } +impl Stability { + pub fn unstable(feature: Symbol, reason: Option, 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 { pub fn is_unstable(&self) -> bool { if let StabilityLevel::Unstable {..} = *self { diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 6be5988d03bb6..74ef5cbe9177e 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -487,7 +487,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { fn expand_invoc(&mut self, invoc: Invocation, ext: &SyntaxExtension) -> Option { 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 { emit_feature_err(&self.cx.parse_sess, sym::macros_in_extern, invoc.span(), GateIssue::Language, @@ -919,7 +919,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { }) .map(|i| attrs.remove(i)); 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 { emit_feature_err(&self.cx.parse_sess, sym::custom_inner_attributes, attr.span, GateIssue::Language, @@ -1432,19 +1432,6 @@ pub struct ExpansionConfig<'feat> { 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> { pub fn default(crate_name: String) -> ExpansionConfig<'static> { ExpansionConfig { @@ -1458,20 +1445,13 @@ impl<'feat> ExpansionConfig<'feat> { } } - feature_tests! { - fn enable_asm = asm, - 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 macros_in_extern(&self) -> bool { + self.features.map_or(false, |features| features.macros_in_extern) } - - fn enable_custom_inner_attributes(&self) -> bool { + fn proc_macro_hygiene(&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) } } diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs index 4e2aab46542d2..c2ba8b983f5a8 100644 --- a/src/libsyntax/ext/source_util.rs +++ b/src/libsyntax/ext/source_util.rs @@ -4,7 +4,7 @@ use crate::ext::build::AstBuilder; use crate::parse::{self, token, DirectoryOwnership}; use crate::print::pprust; use crate::ptr::P; -use crate::symbol::{Symbol, sym}; +use crate::symbol::Symbol; use crate::tokenstream; 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)) } -/* __rust_unstable_column!(): expands to the current column number */ -pub fn expand_column_gated(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree]) - -> Box { - 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 */ /// The source_file (`loc.file`) contains a bunch more information we could spit /// out if we wanted. diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 2b242a71ad4cc..f4f0d041e64d8 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -1568,7 +1568,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ (sym::type_length_limit, CrateLevel, template!(NameValueStr: "N"), Ungated), (sym::test_runner, CrateLevel, template!(List: "path"), Gated(Stability::Unstable, sym::custom_test_frameworks, - EXPLAIN_CUSTOM_TEST_FRAMEWORKS, + "custom test frameworks are an unstable feature", cfg_fn!(custom_test_frameworks))), ]; @@ -1819,26 +1819,6 @@ const EXPLAIN_BOX_SYNTAX: &str = pub const EXPLAIN_STMT_ATTR_SYNTAX: &str = "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 = "allow_internal_unstable side-steps feature gating and stability checks"; pub const EXPLAIN_ALLOW_INTERNAL_UNSAFE: &str = diff --git a/src/libsyntax_ext/asm.rs b/src/libsyntax_ext/asm.rs index b015815ac9c1e..c1c2732605c46 100644 --- a/src/libsyntax_ext/asm.rs +++ b/src/libsyntax_ext/asm.rs @@ -8,7 +8,6 @@ use errors::DiagnosticBuilder; use syntax::ast; use syntax::ext::base::{self, *}; -use syntax::feature_gate; use syntax::parse; use syntax::parse::token::{self, Token}; use syntax::ptr::P; @@ -46,14 +45,6 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree]) -> Box { - 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) { Ok(Some(inline_asm)) => inline_asm, Ok(None) => return DummyResult::expr(sp), diff --git a/src/libsyntax_ext/concat_idents.rs b/src/libsyntax_ext/concat_idents.rs index 8f061abc77b8d..df9191416038d 100644 --- a/src/libsyntax_ext/concat_idents.rs +++ b/src/libsyntax_ext/concat_idents.rs @@ -2,25 +2,16 @@ use rustc_data_structures::thin_vec::ThinVec; use syntax::ast; use syntax::ext::base::{self, *}; -use syntax::feature_gate; use syntax::parse::token::{self, Token}; use syntax::ptr::P; use syntax_pos::Span; -use syntax_pos::symbol::{Symbol, sym}; +use syntax_pos::symbol::Symbol; use syntax::tokenstream::TokenTree; pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt<'_>, sp: Span, tts: &[TokenTree]) -> Box { - 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() { cx.span_err(sp, "concat_idents! takes 1 or more arguments."); return DummyResult::any(sp); diff --git a/src/libsyntax_ext/deriving/decodable.rs b/src/libsyntax_ext/deriving/decodable.rs index d773f3ff7bcc5..8009f42b8cf95 100644 --- a/src/libsyntax_ext/deriving/decodable.rs +++ b/src/libsyntax_ext/deriving/decodable.rs @@ -3,7 +3,6 @@ use crate::deriving::{self, pathvec_std}; use crate::deriving::generic::*; use crate::deriving::generic::ty::*; -use crate::deriving::warn_if_deprecated; use syntax::ast; use syntax::ast::{Expr, MetaItem, Mutability}; @@ -26,7 +25,6 @@ pub fn expand_deriving_decodable(cx: &mut ExtCtxt<'_>, mitem: &MetaItem, item: &Annotatable, push: &mut dyn FnMut(Annotatable)) { - warn_if_deprecated(cx, span, "Decodable"); expand_deriving_decodable_imp(cx, span, mitem, item, push, "serialize") } diff --git a/src/libsyntax_ext/deriving/encodable.rs b/src/libsyntax_ext/deriving/encodable.rs index faaedba3e77dd..cd89a42cf8270 100644 --- a/src/libsyntax_ext/deriving/encodable.rs +++ b/src/libsyntax_ext/deriving/encodable.rs @@ -85,7 +85,6 @@ use crate::deriving::{self, pathvec_std}; use crate::deriving::generic::*; use crate::deriving::generic::ty::*; -use crate::deriving::warn_if_deprecated; use syntax::ast::{Expr, ExprKind, MetaItem, Mutability}; use syntax::ext::base::{Annotatable, ExtCtxt}; @@ -107,7 +106,6 @@ pub fn expand_deriving_encodable(cx: &mut ExtCtxt<'_>, mitem: &MetaItem, item: &Annotatable, push: &mut dyn FnMut(Annotatable)) { - warn_if_deprecated(cx, span, "Encodable"); expand_deriving_encodable_imp(cx, span, mitem, item, push, "serialize") } diff --git a/src/libsyntax_ext/deriving/mod.rs b/src/libsyntax_ext/deriving/mod.rs index aa9913d436cfa..f7889b9cac08c 100644 --- a/src/libsyntax_ext/deriving/mod.rs +++ b/src/libsyntax_ext/deriving/mod.rs @@ -2,6 +2,7 @@ use rustc_data_structures::sync::Lrc; use syntax::ast::{self, MetaItem}; +use syntax::attr::Deprecation; use syntax::edition::Edition; use syntax::ext::base::{Annotatable, ExtCtxt, Resolver, MultiItemModifier}; use syntax::ext::base::{SyntaxExtension, SyntaxExtensionKind}; @@ -60,7 +61,7 @@ impl MultiItemModifier for BuiltinDerive { } macro_rules! derive_traits { - ($( $name:expr => $func:path, )+) => { + ($( [$deprecation:expr] $name:expr => $func:path, )+) => { pub fn is_builtin_trait(name: ast::Name) -> bool { match &*name.as_str() { $( $name )|+ => true, @@ -81,6 +82,10 @@ macro_rules! derive_traits { resolver.add_builtin( ast::Ident::with_empty_ctxt(Symbol::intern($name)), 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(), ..SyntaxExtension::default( SyntaxExtensionKind::LegacyDerive(Box::new(BuiltinDerive($func))), @@ -94,44 +99,43 @@ macro_rules! derive_traits { } derive_traits! { + [None] "Clone" => clone::expand_deriving_clone, + [None] "Hash" => hash::expand_deriving_hash, + [None] "RustcEncodable" => encodable::expand_deriving_rustc_encodable, + [None] "RustcDecodable" => decodable::expand_deriving_rustc_decodable, + [None] "PartialEq" => partial_eq::expand_deriving_partial_eq, + [None] "Eq" => eq::expand_deriving_eq, + [None] "PartialOrd" => partial_ord::expand_deriving_partial_ord, + [None] "Ord" => ord::expand_deriving_ord, + [None] "Debug" => debug::expand_deriving_debug, + [None] "Default" => default::expand_deriving_default, + [None] "Copy" => bounds::expand_deriving_copy, // deprecated + [Some("derive(Encodable) is deprecated in favor of derive(RustcEncodable)")] "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 /// the item. This is achieved by starting with a base and then concatenating the names of all /// other type parameters. diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs index a5f96559ca8a2..c3dbd48cc6e4e 100644 --- a/src/libsyntax_ext/format.rs +++ b/src/libsyntax_ext/format.rs @@ -9,7 +9,6 @@ use errors::Applicability; use syntax::ast; use syntax::ext::base::{self, *}; use syntax::ext::build::AstBuilder; -use syntax::feature_gate; use syntax::parse::token; use syntax::ptr::P; 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<'_>, - mut sp: Span, - tts: &[tokenstream::TokenTree]) - -> Box { +fn expand_format_args_impl<'cx>( + ecx: &'cx mut ExtCtxt<'_>, + mut sp: Span, + tts: &[tokenstream::TokenTree], + nl: bool, +) -> Box { 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, false)) + MacEager::expr(expand_preparsed_format_args(ecx, sp, efmt, args, names, nl)) } Err(mut err) => { err.emit(); @@ -702,34 +703,20 @@ pub fn expand_format_args<'cx>(ecx: &'cx mut ExtCtxt<'_>, } } +pub fn expand_format_args<'cx>( + ecx: &'cx mut ExtCtxt<'_>, + sp: Span, + tts: &[tokenstream::TokenTree], +) -> Box { + expand_format_args_impl(ecx, sp, tts, false) +} + pub fn expand_format_args_nl<'cx>( ecx: &'cx mut ExtCtxt<'_>, - mut sp: Span, + sp: Span, tts: &[tokenstream::TokenTree], ) -> Box { - //if !ecx.ecfg.enable_allow_internal_unstable() { - - // For some reason, the only one that actually works for `println` is the first check - if !sp.allows_unstable(sym::format_args_nl) // the span is marked `#[allow_insternal_unsable]` - && !ecx.ecfg.enable_allow_internal_unstable() // NOTE: when is this enabled? - && !ecx.ecfg.enable_format_args_nl() // enabled using `#[feature(format_args_nl]` - { - feature_gate::emit_feature_err(&ecx.parse_sess, - 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) - } - } + expand_format_args_impl(ecx, sp, tts, true) } /// Take the various parts of `format_args!(efmt, args..., name=names...)` diff --git a/src/libsyntax_ext/global_asm.rs b/src/libsyntax_ext/global_asm.rs index 5220143a3cc46..112192fac5d26 100644 --- a/src/libsyntax_ext/global_asm.rs +++ b/src/libsyntax_ext/global_asm.rs @@ -13,27 +13,15 @@ use errors::DiagnosticBuilder; use syntax::ast; use syntax::source_map::respan; use syntax::ext::base::{self, *}; -use syntax::feature_gate; use syntax::parse::token; use syntax::ptr::P; -use syntax::symbol::{Symbol, sym}; use syntax_pos::Span; use syntax::tokenstream; use smallvec::smallvec; -pub const MACRO: Symbol = sym::global_asm; - pub fn expand_global_asm<'cx>(cx: &'cx mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree]) -> Box { - 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) { Ok(Some(global_asm)) => { MacEager::items(smallvec![P(ast::Item { diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs index 77b69ddd303b4..1ca5cc47fa25b 100644 --- a/src/libsyntax_ext/lib.rs +++ b/src/libsyntax_ext/lib.rs @@ -41,12 +41,29 @@ pub mod proc_macro_impl; use rustc_data_structures::sync::Lrc; use syntax::ast; - +use syntax::attr::Stability; use syntax::ext::base::MacroExpanderFn; use syntax::ext::base::{NamedSyntaxExtension, SyntaxExtension, SyntaxExtensionKind}; use syntax::edition::Edition; 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, user_exts: Vec, edition: Edition) { @@ -62,18 +79,22 @@ pub fn register_builtins(resolver: &mut dyn syntax::ext::base::Resolver, )); )* } } - macro_rules! register_attr { - ($( $name:ident: $f:expr, )*) => { $( - register(Symbol::intern(stringify!($name)), SyntaxExtension::default( - SyntaxExtensionKind::LegacyAttr(Box::new($f)), edition - )); + macro_rules! register_unstable { + ($( [$feature:expr, $reason:expr, $issue:expr] $name:ident: $f:expr, )*) => { $( + register(Symbol::intern(stringify!($name)), SyntaxExtension { + 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::*; register! { line: expand_line, - __rust_unstable_column: expand_column_gated, column: expand_column, file: expand_file, stringify: expand_stringify, @@ -81,26 +102,46 @@ pub fn register_builtins(resolver: &mut dyn syntax::ext::base::Resolver, include_str: expand_include_str, include_bytes: expand_include_bytes, module_path: expand_mod, - - asm: asm::expand_asm, - global_asm: global_asm::expand_global_asm, cfg: cfg::expand_cfg, concat: concat::expand_syntax_ext, - concat_idents: concat_idents::expand_syntax_ext, env: env::expand_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, assert: assert::expand_assert, } - register_attr! { - test_case: test_case::expand, - test: test::expand_test, - bench: test::expand_bench, + register_unstable! { + [sym::__rust_unstable_column, EXPLAIN_UNSTABLE_COLUMN, 0] + __rust_unstable_column: expand_column, + [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. let allow_internal_unstable = Some([sym::fmt_internals][..].into()); register(Symbol::intern("format_args"), SyntaxExtension { @@ -110,6 +151,11 @@ pub fn register_builtins(resolver: &mut dyn syntax::ext::base::Resolver, ) }); 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, ..SyntaxExtension::default( SyntaxExtensionKind::LegacyBang(Box::new(format::expand_format_args_nl)), edition diff --git a/src/libsyntax_ext/log_syntax.rs b/src/libsyntax_ext/log_syntax.rs index 1be3990837cfe..cbdfd08b4977f 100644 --- a/src/libsyntax_ext/log_syntax.rs +++ b/src/libsyntax_ext/log_syntax.rs @@ -1,22 +1,12 @@ use syntax::ext::base; -use syntax::feature_gate; use syntax::print; use syntax::tokenstream; -use syntax::symbol::sym; 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, tts: &[tokenstream::TokenTree]) -> Box { - 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)); // any so that `log_syntax` can be invoked as an expression and item. diff --git a/src/libsyntax_ext/test_case.rs b/src/libsyntax_ext/test_case.rs index 6e3bc05b65e4e..186673c142f14 100644 --- a/src/libsyntax_ext/test_case.rs +++ b/src/libsyntax_ext/test_case.rs @@ -17,7 +17,6 @@ use syntax::source_map::respan; use syntax::symbol::sym; use syntax_pos::Span; use syntax::source_map::{ExpnInfo, MacroAttribute}; -use syntax::feature_gate; pub fn expand( ecx: &mut ExtCtxt<'_>, @@ -25,14 +24,6 @@ pub fn expand( _meta_item: &ast::MetaItem, anno_item: Annotatable ) -> Vec { - 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![]; } let sp = { diff --git a/src/libsyntax_ext/trace_macros.rs b/src/libsyntax_ext/trace_macros.rs index 512513e9b414c..0dce8a36f4c7b 100644 --- a/src/libsyntax_ext/trace_macros.rs +++ b/src/libsyntax_ext/trace_macros.rs @@ -1,6 +1,5 @@ use syntax::ext::base::{self, ExtCtxt}; -use syntax::feature_gate; -use syntax::symbol::{kw, sym}; +use syntax::symbol::kw; use syntax_pos::Span; use syntax::tokenstream::TokenTree; @@ -8,14 +7,6 @@ pub fn expand_trace_macros(cx: &mut ExtCtxt<'_>, sp: Span, tt: &[TokenTree]) -> Box { - 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 { [TokenTree::Token(token)] if token.is_keyword(kw::True) => { cx.set_trace_macros(true); diff --git a/src/test/ui-fulldeps/deprecated-derive.stderr b/src/test/ui-fulldeps/deprecated-derive.stderr index 27762910e6a4d..9afb3a35cb402 100644 --- a/src/test/ui-fulldeps/deprecated-derive.stderr +++ b/src/test/ui-fulldeps/deprecated-derive.stderr @@ -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 | LL | #[derive(Encodable)] | ^^^^^^^^^ + | + = note: #[warn(deprecated)] on by default diff --git a/src/test/ui/feature-gates/feature-gate-asm.stderr b/src/test/ui/feature-gates/feature-gate-asm.stderr index ccaf34f0169fd..30a7582a92bd4 100644 --- a/src/test/ui/feature-gates/feature-gate-asm.stderr +++ b/src/test/ui/feature-gates/feature-gate-asm.stderr @@ -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 | LL | asm!(""); diff --git a/src/test/ui/feature-gates/feature-gate-asm2.stderr b/src/test/ui/feature-gates/feature-gate-asm2.stderr index cafe2be9d0bb0..8f4c6806a9701 100644 --- a/src/test/ui/feature-gates/feature-gate-asm2.stderr +++ b/src/test/ui/feature-gates/feature-gate-asm2.stderr @@ -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 | LL | println!("{:?}", asm!("")); diff --git a/src/test/ui/feature-gates/feature-gate-concat_idents.stderr b/src/test/ui/feature-gates/feature-gate-concat_idents.stderr index be8c727e2beec..2a1e5f54592f8 100644 --- a/src/test/ui/feature-gates/feature-gate-concat_idents.stderr +++ b/src/test/ui/feature-gates/feature-gate-concat_idents.stderr @@ -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 | 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 = 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 | LL | let b = concat_idents!(X, Y_2); diff --git a/src/test/ui/feature-gates/feature-gate-concat_idents2.stderr b/src/test/ui/feature-gates/feature-gate-concat_idents2.stderr index 864ee63b201d6..0dc6c13734ef1 100644 --- a/src/test/ui/feature-gates/feature-gate-concat_idents2.stderr +++ b/src/test/ui/feature-gates/feature-gate-concat_idents2.stderr @@ -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 | LL | concat_idents!(a, b); diff --git a/src/test/ui/feature-gates/feature-gate-concat_idents3.stderr b/src/test/ui/feature-gates/feature-gate-concat_idents3.stderr index cb8725ab566a2..543570f0afc3f 100644 --- a/src/test/ui/feature-gates/feature-gate-concat_idents3.stderr +++ b/src/test/ui/feature-gates/feature-gate-concat_idents3.stderr @@ -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 | 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 = 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 | LL | assert_eq!(20, concat_idents!(X, Y_2)); diff --git a/src/test/ui/feature-gates/feature-gate-format_args_nl.stderr b/src/test/ui/feature-gates/feature-gate-format_args_nl.stderr index 58d2c790ffe87..5cf48d8749c8f 100644 --- a/src/test/ui/feature-gates/feature-gate-format_args_nl.stderr +++ b/src/test/ui/feature-gates/feature-gate-format_args_nl.stderr @@ -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 | LL | format_args_nl!(""); diff --git a/src/test/ui/feature-gates/feature-gate-global_asm.stderr b/src/test/ui/feature-gates/feature-gate-global_asm.stderr index 7d8abac399068..c65f8d87a6a23 100644 --- a/src/test/ui/feature-gates/feature-gate-global_asm.stderr +++ b/src/test/ui/feature-gates/feature-gate-global_asm.stderr @@ -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 | LL | global_asm!(""); diff --git a/src/test/ui/feature-gates/feature-gate-log_syntax.stderr b/src/test/ui/feature-gates/feature-gate-log_syntax.stderr index 67bd48d3bedf2..f6a07616c5308 100644 --- a/src/test/ui/feature-gates/feature-gate-log_syntax.stderr +++ b/src/test/ui/feature-gates/feature-gate-log_syntax.stderr @@ -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 | LL | log_syntax!() diff --git a/src/test/ui/feature-gates/feature-gate-log_syntax2.stderr b/src/test/ui/feature-gates/feature-gate-log_syntax2.stderr index ff0fa343c84d1..cfc2beb80879c 100644 --- a/src/test/ui/feature-gates/feature-gate-log_syntax2.stderr +++ b/src/test/ui/feature-gates/feature-gate-log_syntax2.stderr @@ -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 | LL | println!("{:?}", log_syntax!()); diff --git a/src/test/ui/feature-gates/feature-gate-trace_macros.stderr b/src/test/ui/feature-gates/feature-gate-trace_macros.stderr index bcce31d873b0a..e08b173ae84ad 100644 --- a/src/test/ui/feature-gates/feature-gate-trace_macros.stderr +++ b/src/test/ui/feature-gates/feature-gate-trace_macros.stderr @@ -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 | LL | trace_macros!(true); diff --git a/src/test/ui/rust-unstable-column-gated.rs b/src/test/ui/rust-unstable-column-gated.rs index ed5e6f2489cd9..053806ead2d12 100644 --- a/src/test/ui/rust-unstable-column-gated.rs +++ b/src/test/ui/rust-unstable-column-gated.rs @@ -1,4 +1,4 @@ fn main() { println!("{}", __rust_unstable_column!()); - //~^ERROR the __rust_unstable_column macro is unstable + //~^ ERROR use of unstable library feature '__rust_unstable_column' } diff --git a/src/test/ui/rust-unstable-column-gated.stderr b/src/test/ui/rust-unstable-column-gated.stderr index b9f1df2bcc992..70b3654b5af7e 100644 --- a/src/test/ui/rust-unstable-column-gated.stderr +++ b/src/test/ui/rust-unstable-column-gated.stderr @@ -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 | LL | println!("{}", __rust_unstable_column!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add #![feature(__rust_unstable_column)] to the crate attributes to enable error: aborting due to previous error +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/trace_macros-gate.stderr b/src/test/ui/trace_macros-gate.stderr index e0ffcfe295fdf..18745e9ab5a6c 100644 --- a/src/test/ui/trace_macros-gate.stderr +++ b/src/test/ui/trace_macros-gate.stderr @@ -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 | LL | trace_macros!(); @@ -13,7 +13,7 @@ error: trace_macros! accepts only `true` or `false` 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 | 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 = 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 | 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 = 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 | LL | ($x: ident) => { trace_macros!($x) } From b6d522a101982b4c6919391a378e799bd74a4da6 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 23 Jun 2019 14:59:42 +0300 Subject: [PATCH 13/14] syntax: Pre-intern names of all built-in macros They always end up interned anyway --- src/libsyntax/ext/derive.rs | 6 ++--- src/libsyntax/parse/lexer/mod.rs | 2 +- src/libsyntax_ext/deriving/mod.rs | 34 +++++++++++++------------- src/libsyntax_ext/lib.rs | 6 ++--- src/libsyntax_ext/proc_macro_server.rs | 4 +-- src/libsyntax_pos/symbol.rs | 20 ++++++++++++++- 6 files changed, 45 insertions(+), 27 deletions(-) diff --git a/src/libsyntax/ext/derive.rs b/src/libsyntax/ext/derive.rs index 3b4243ed24f7c..2a56f3dd7566b 100644 --- a/src/libsyntax/ext/derive.rs +++ b/src/libsyntax/ext/derive.rs @@ -63,11 +63,11 @@ pub fn add_derived_markers(cx: &mut ExtCtxt<'_>, span: Span, traits: &[ast::P let span = span.with_ctxt(cx.backtrace()); item.visit_attrs(|attrs| { - if names.contains(&Symbol::intern("Eq")) && names.contains(&Symbol::intern("PartialEq")) { - let meta = cx.meta_word(span, Symbol::intern("structural_match")); + if names.contains(&sym::Eq) && names.contains(&sym::PartialEq) { + let meta = cx.meta_word(span, sym::structural_match); 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); attrs.push(cx.attribute(span, meta)); } diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 1abbf0ff1eeb7..d0c4e8d6a5634 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -613,7 +613,7 @@ impl<'a> StringReader<'a> { if num_digits == 0 { 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 diff --git a/src/libsyntax_ext/deriving/mod.rs b/src/libsyntax_ext/deriving/mod.rs index f7889b9cac08c..e491e93256d1c 100644 --- a/src/libsyntax_ext/deriving/mod.rs +++ b/src/libsyntax_ext/deriving/mod.rs @@ -61,10 +61,10 @@ impl MultiItemModifier for BuiltinDerive { } macro_rules! derive_traits { - ($( [$deprecation:expr] $name:expr => $func:path, )+) => { + ($( [$deprecation:expr] $name:ident => $func:path, )+) => { pub fn is_builtin_trait(name: ast::Name) -> bool { - match &*name.as_str() { - $( $name )|+ => true, + match name { + $( sym::$name )|+ => true, _ => false, } } @@ -80,7 +80,7 @@ macro_rules! derive_traits { $( resolver.add_builtin( - ast::Ident::with_empty_ctxt(Symbol::intern($name)), + ast::Ident::with_empty_ctxt(sym::$name), Lrc::new(SyntaxExtension { deprecation: $deprecation.map(|msg| Deprecation { since: Some(Symbol::intern("1.0.0")), @@ -100,40 +100,40 @@ macro_rules! derive_traits { derive_traits! { [None] - "Clone" => clone::expand_deriving_clone, + Clone => clone::expand_deriving_clone, [None] - "Hash" => hash::expand_deriving_hash, + Hash => hash::expand_deriving_hash, [None] - "RustcEncodable" => encodable::expand_deriving_rustc_encodable, + RustcEncodable => encodable::expand_deriving_rustc_encodable, [None] - "RustcDecodable" => decodable::expand_deriving_rustc_decodable, + RustcDecodable => decodable::expand_deriving_rustc_decodable, [None] - "PartialEq" => partial_eq::expand_deriving_partial_eq, + PartialEq => partial_eq::expand_deriving_partial_eq, [None] - "Eq" => eq::expand_deriving_eq, + Eq => eq::expand_deriving_eq, [None] - "PartialOrd" => partial_ord::expand_deriving_partial_ord, + PartialOrd => partial_ord::expand_deriving_partial_ord, [None] - "Ord" => ord::expand_deriving_ord, + Ord => ord::expand_deriving_ord, [None] - "Debug" => debug::expand_deriving_debug, + Debug => debug::expand_deriving_debug, [None] - "Default" => default::expand_deriving_default, + Default => default::expand_deriving_default, [None] - "Copy" => bounds::expand_deriving_copy, + Copy => bounds::expand_deriving_copy, // deprecated [Some("derive(Encodable) is deprecated in favor of derive(RustcEncodable)")] - "Encodable" => encodable::expand_deriving_encodable, + Encodable => encodable::expand_deriving_encodable, [Some("derive(Decodable) is deprecated in favor of derive(RustcDecodable)")] - "Decodable" => decodable::expand_deriving_decodable, + Decodable => decodable::expand_deriving_decodable, } /// Construct a name for the inner type parameter that can't collide with any type parameters of diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs index 1ca5cc47fa25b..62530f4fe7b33 100644 --- a/src/libsyntax_ext/lib.rs +++ b/src/libsyntax_ext/lib.rs @@ -74,14 +74,14 @@ pub fn register_builtins(resolver: &mut dyn syntax::ext::base::Resolver, }; macro_rules! register { ($( $name:ident: $f:expr, )*) => { $( - register(Symbol::intern(stringify!($name)), SyntaxExtension::default( + register(sym::$name, SyntaxExtension::default( SyntaxExtensionKind::LegacyBang(Box::new($f as MacroExpanderFn)), edition )); )* } } macro_rules! register_unstable { ($( [$feature:expr, $reason:expr, $issue:expr] $name:ident: $f:expr, )*) => { $( - register(Symbol::intern(stringify!($name)), SyntaxExtension { + register(sym::$name, SyntaxExtension { stability: Some(Stability::unstable( $feature, Some(Symbol::intern($reason)), $issue )), @@ -144,7 +144,7 @@ pub fn register_builtins(resolver: &mut dyn syntax::ext::base::Resolver, // format_args uses `unstable` things internally. 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(), ..SyntaxExtension::default( SyntaxExtensionKind::LegacyBang(Box::new(format::expand_format_args)), edition diff --git a/src/libsyntax_ext/proc_macro_server.rs b/src/libsyntax_ext/proc_macro_server.rs index c9d99e5831ac4..e502735452735 100644 --- a/src/libsyntax_ext/proc_macro_server.rs +++ b/src/libsyntax_ext/proc_macro_server.rs @@ -548,10 +548,10 @@ impl server::Literal for Rustc<'_> { self.lit(token::Float, Symbol::intern(n), None) } 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 { - 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 { let mut escaped = String::new(); diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index 410f4b36b67f2..8bb622a68552f 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -141,6 +141,7 @@ symbols! { ArgumentV1, arm_target_feature, asm, + assert, associated_consts, associated_type_bounds, associated_type_defaults, @@ -184,8 +185,10 @@ symbols! { cmp, cmpxchg16b_target_feature, cold, + column, compile_error, compiler_builtins, + concat, concat_idents, conservative_impl_trait, console, @@ -203,6 +206,7 @@ symbols! { contents, context, convert, + Copy, copy_closures, core, core_intrinsics, @@ -217,8 +221,10 @@ symbols! { custom_inner_attributes, custom_test_frameworks, c_variadic, + Debug, declare_lint_pass, decl_macro, + Decodable, Default, default_lib_allocator, default_type_parameter_fallback, @@ -253,9 +259,12 @@ symbols! { eh_personality, eh_unwind_resume, enable, + Encodable, + env, eq, err, Err, + Eq, Equal, except, exclusive_range_pattern, @@ -284,6 +293,7 @@ symbols! { fmt_internals, fn_must_use, forbid, + format_args, format_args_nl, from, From, @@ -335,6 +345,8 @@ symbols! { index_mut, in_band_lifetimes, include, + include_bytes, + include_str, inclusive_range_syntax, infer_outlives_requirements, infer_static_outlives_requirements, @@ -363,6 +375,7 @@ symbols! { lhs, lib, lifetime, + line, link, linkage, link_args, @@ -402,6 +415,7 @@ symbols! { mips_target_feature, mmx_target_feature, module, + module_path, more_struct_aliases, movbe_target_feature, must_use, @@ -447,6 +461,7 @@ symbols! { optin_builtin_traits, option, Option, + option_env, opt_out_copy, or, Ord, @@ -462,6 +477,7 @@ symbols! { parent_trait, partial_cmp, param_attrs, + PartialEq, PartialOrd, passes, pat, @@ -532,6 +548,8 @@ symbols! { rust_2018_preview, rust_begin_unwind, rustc, + RustcDecodable, + RustcEncodable, rustc_allocator, rustc_allocator_nounwind, rustc_allow_const_fn_ptr, @@ -591,7 +609,6 @@ symbols! { _Self, self_in_typedefs, self_struct_ctor, - Send, should_panic, simd, simd_ffi, @@ -613,6 +630,7 @@ symbols! { static_recursion, std, str, + stringify, stmt, stmt_expr_attributes, stop_after_dataflow, From 941653b528deb96d5ed13935143db14c45d99d6e Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 6 Jul 2019 01:58:52 +0300 Subject: [PATCH 14/14] Address review comments + Fix rebase --- src/librustc_resolve/macros.rs | 2 +- src/libserialize/json.rs | 16 +++++++--------- .../feature-gate-custom_test_frameworks.rs | 3 +++ .../feature-gate-custom_test_frameworks.stderr | 11 ++++++++++- src/test/ui/macros/macro-deprecation.rs | 2 +- 5 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 6d669aafc81a4..f26c3b8ae6afc 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -19,7 +19,7 @@ use syntax::ext::base::{MacroKind, SyntaxExtension}; use syntax::ext::expand::{AstFragment, Invocation, InvocationKind}; use syntax::ext::hygiene::Mark; use syntax::ext::tt::macro_rules; -use syntax::feature_gate::{feature_err, is_builtin_attr_name}; +use syntax::feature_gate::{feature_err, emit_feature_err, is_builtin_attr_name}; use syntax::feature_gate::{AttributeGate, GateIssue, Stability, BUILTIN_ATTRIBUTES}; use syntax::symbol::{Symbol, kw, sym}; use syntax::visit::Visitor; diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index 77947a4be7ff8..d0007074a823c 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -103,9 +103,8 @@ //! //! ```rust //! # #![feature(rustc_private)] -//! # #![allow(deprecated)] -//! extern crate serialize; -//! use serialize::json::{self, ToJson, Json}; +//! extern crate serialize as rustc_serialize; +//! use rustc_serialize::json::{self, ToJson, Json}; //! //! // A custom data structure //! struct ComplexNum { @@ -121,7 +120,7 @@ //! } //! //! // Only generate `RustcEncodable` trait implementation -//! #[derive(Encodable)] +//! #[derive(RustcEncodable)] //! pub struct ComplexNumRecord { //! uid: u8, //! dsc: String, @@ -144,13 +143,12 @@ //! //! ```rust //! # #![feature(rustc_private)] -//! # #![allow(deprecated)] -//! extern crate serialize; +//! extern crate serialize as rustc_serialize; //! use std::collections::BTreeMap; -//! use serialize::json::{self, Json, ToJson}; +//! use rustc_serialize::json::{self, Json, ToJson}; //! -//! // Only generate `Decodable` trait implementation -//! #[derive(Decodable)] +//! // Only generate `RustcDecodable` trait implementation +//! #[derive(RustcDecodable)] //! pub struct TestStruct { //! data_int: u8, //! data_str: String, diff --git a/src/test/ui/feature-gates/feature-gate-custom_test_frameworks.rs b/src/test/ui/feature-gates/feature-gate-custom_test_frameworks.rs index 0a20049793928..83bb153ba08a1 100644 --- a/src/test/ui/feature-gates/feature-gate-custom_test_frameworks.rs +++ b/src/test/ui/feature-gates/feature-gate-custom_test_frameworks.rs @@ -1,3 +1,6 @@ #![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() {} diff --git a/src/test/ui/feature-gates/feature-gate-custom_test_frameworks.stderr b/src/test/ui/feature-gates/feature-gate-custom_test_frameworks.stderr index e288af54cb270..31ff7aebe3a01 100644 --- a/src/test/ui/feature-gates/feature-gate-custom_test_frameworks.stderr +++ b/src/test/ui/feature-gates/feature-gate-custom_test_frameworks.stderr @@ -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 --> $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 = 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`. diff --git a/src/test/ui/macros/macro-deprecation.rs b/src/test/ui/macros/macro-deprecation.rs index ae3827604faf0..9636b48c2daa3 100644 --- a/src/test/ui/macros/macro-deprecation.rs +++ b/src/test/ui/macros/macro-deprecation.rs @@ -1,4 +1,4 @@ -// compile-pass +// check-pass // aux-build:deprecated-macros.rs #[macro_use] extern crate deprecated_macros;