Skip to content

Remove unstable macro_reexport #49982

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 1, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 1 addition & 28 deletions src/librustc_resolve/build_reduced_graph.rs
Original file line number Diff line number Diff line change
@@ -71,7 +71,6 @@ impl<'a> ToNameBinding<'a> for (Def, ty::Visibility, Span, Mark) {
struct LegacyMacroImports {
import_all: Option<Span>,
imports: Vec<(Name, Span)>,
reexports: Vec<(Name, Span)>,
}

impl<'a> Resolver<'a> {
@@ -621,7 +620,7 @@ impl<'a> Resolver<'a> {
let legacy_imports = self.legacy_macro_imports(&item.attrs);
let mut used = legacy_imports != LegacyMacroImports::default();

// `#[macro_use]` and `#[macro_reexport]` are only allowed at the crate root.
// `#[macro_use]` is only allowed at the crate root.
if self.current_module.parent.is_some() && used {
span_err!(self.session, item.span, E0468,
"an `extern crate` loading macros must be at the crate root");
@@ -669,17 +668,6 @@ impl<'a> Resolver<'a> {
}
}
}
for (name, span) in legacy_imports.reexports {
self.cstore.export_macros_untracked(module.def_id().unwrap().krate);
let ident = Ident::with_empty_ctxt(name);
let result = self.resolve_ident_in_module(module, ident, MacroNS, false, false, span);
if let Ok(binding) = result {
let (def, vis) = (binding.def(), binding.vis);
self.macro_exports.push(Export { ident, def, vis, span, is_import: true });
} else {
span_err!(self.session, span, E0470, "re-exported macro not found");
}
}
used
}

@@ -721,21 +709,6 @@ impl<'a> Resolver<'a> {
},
None => imports.import_all = Some(attr.span),
}
} else if attr.check_name("macro_reexport") {
let bad_macro_reexport = |this: &mut Self, span| {
span_err!(this.session, span, E0467, "bad macro re-export");
};
if let Some(names) = attr.meta_item_list() {
for attr in names {
if let Some(word) = attr.word() {
imports.reexports.push((word.ident.name, attr.span()));
} else {
bad_macro_reexport(self, attr.span());
}
}
} else {
bad_macro_reexport(self, attr.span());
}
}
}
imports
73 changes: 2 additions & 71 deletions src/librustc_resolve/diagnostics.rs
Original file line number Diff line number Diff line change
@@ -1395,35 +1395,6 @@ If you would like to import all exported macros, write `macro_use` with no
arguments.
"##,

E0467: r##"
Macro re-export declarations were empty or malformed.
Erroneous code examples:
```compile_fail,E0467
#[macro_reexport] // error: no macros listed for export
extern crate core as macros_for_good;
#[macro_reexport(fun_macro = "foo")] // error: not a macro identifier
extern crate core as other_macros_for_good;
```
This is a syntax error at the level of attribute declarations.
Currently, `macro_reexport` requires at least one macro name to be listed.
Unlike `macro_use`, listing no names does not re-export all macros from the
given crate.
Decide which macros you would like to export and list them properly.
These are proper re-export declarations:
```ignore (cannot-doctest-multicrate-project)
#[macro_reexport(some_macro, another_macro)]
extern crate macros_for_good;
```
"##,

E0468: r##"
A non-root module attempts to import macros from another crate.
@@ -1496,48 +1467,6 @@ extern crate some_crate; //ok!
```
"##,

E0470: r##"
A macro listed for re-export was not found.
Erroneous code example:
```compile_fail,E0470
#[macro_reexport(drink, be_merry)]
extern crate alloc;
fn main() {
// ...
}
```
Either the listed macro is not contained in the imported crate, or it is not
exported from the given crate.
This could be caused by a typo. Did you misspell the macro's name?
Double-check the names of the macros listed for re-export, and that the crate
in question exports them.
A working version:
```ignore (cannot-doctest-multicrate-project)
// In some_crate crate:
#[macro_export]
macro_rules! eat {
...
}
#[macro_export]
macro_rules! drink {
...
}
// In your_crate:
#[macro_reexport(eat, drink)]
extern crate some_crate;
```
"##,

E0530: r##"
A binding shadowed something it shouldn't.
@@ -1715,6 +1644,8 @@ register_diagnostics! {
// E0421, merged into 531
E0531, // unresolved pattern path kind `name`
// E0427, merged into 530
// E0467, removed
// E0470, removed
E0573,
E0574,
E0575,
15 changes: 1 addition & 14 deletions src/librustdoc/visit_ast.rs
Original file line number Diff line number Diff line change
@@ -49,7 +49,6 @@ pub struct RustdocVisitor<'a, 'tcx: 'a, 'rcx: 'a> {
inlining: bool,
/// Is the current module and all of its parents public?
inside_public_path: bool,
reexported_macros: FxHashSet<DefId>,
exact_paths: Option<FxHashMap<DefId, Vec<String>>>,
}

@@ -66,7 +65,6 @@ impl<'a, 'tcx, 'rcx> RustdocVisitor<'a, 'tcx, 'rcx> {
view_item_stack: stack,
inlining: false,
inside_public_path: true,
reexported_macros: FxHashSet(),
exact_paths: Some(FxHashMap()),
cstore,
}
@@ -221,7 +219,7 @@ impl<'a, 'tcx, 'rcx> RustdocVisitor<'a, 'tcx, 'rcx> {
if let Some(exports) = self.cx.tcx.module_exports(def_id) {
for export in exports.iter().filter(|e| e.vis == Visibility::Public) {
if let Def::Macro(def_id, ..) = export.def {
if def_id.krate == LOCAL_CRATE || self.reexported_macros.contains(&def_id) {
if def_id.krate == LOCAL_CRATE {
continue // These are `krate.exported_macros`, handled in `self.visit()`.
}

@@ -298,17 +296,6 @@ impl<'a, 'tcx, 'rcx> RustdocVisitor<'a, 'tcx, 'rcx> {
let is_no_inline = use_attrs.lists("doc").has_word("no_inline") ||
use_attrs.lists("doc").has_word("hidden");

// Memoize the non-inlined `pub use`'d macros so we don't push an extra
// declaration in `visit_mod_contents()`
if !def_did.is_local() {
if let Def::Macro(did, _) = def {
if please_inline { return true }
debug!("memoizing non-inlined macro export: {:?}", def);
self.reexported_macros.insert(did);
return false;
}
}

// For cross-crate impl inlining we need to know whether items are
// reachable in documentation - a previously nonreachable item can be
// made reachable by cross-crate inlining which we're checking here.
17 changes: 9 additions & 8 deletions src/libstd/lib.rs
Original file line number Diff line number Diff line change
@@ -273,7 +273,6 @@
#![feature(libc)]
#![feature(link_args)]
#![feature(linkage)]
#![feature(macro_reexport)]
#![feature(macro_vis_matcher)]
#![feature(needs_panic_runtime)]
#![feature(never_type)]
@@ -313,6 +312,7 @@
#![feature(unboxed_closures)]
#![feature(untagged_unions)]
#![feature(unwind_attributes)]
#![feature(use_extern_macros)]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@petrochenkov: How likely are the changes in this file to cause crates to break, e.g. because of an unknown compiler bug? Phrased differently, do you think a crater run would make sense?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd say unlikely.
If all local users of libstd like compiler and test suite build succesfully, then everything should be okay.

#![feature(vec_push_all)]
#![feature(doc_cfg)]
#![feature(doc_masked)]
@@ -347,15 +347,14 @@ use prelude::v1::*;
#[cfg(test)] extern crate test;
#[cfg(test)] extern crate rand;

// We want to re-export a few macros from core but libcore has already been
// imported by the compiler (via our #[no_std] attribute) In this case we just
// add a new crate name so we can attach the re-exports to it.
#[macro_reexport(assert_eq, assert_ne, debug_assert, debug_assert_eq,
debug_assert_ne, unreachable, unimplemented, write, writeln, try)]
extern crate core as __core;
// Re-export a few macros from core
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::{assert_eq, assert_ne, debug_assert, debug_assert_eq, debug_assert_ne};
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::{unreachable, unimplemented, write, writeln, try};

#[allow(unused_imports)] // macros from `alloc` are not used on all platforms
#[macro_use]
#[macro_reexport(vec, format)]
extern crate alloc as alloc_crate;
extern crate alloc_system;
#[doc(masked)]
@@ -450,6 +449,8 @@ pub use alloc_crate::borrow;
#[stable(feature = "rust1", since = "1.0.0")]
pub use alloc_crate::fmt;
#[stable(feature = "rust1", since = "1.0.0")]
pub use alloc_crate::format;
#[stable(feature = "rust1", since = "1.0.0")]
pub use alloc_crate::slice;
#[stable(feature = "rust1", since = "1.0.0")]
pub use alloc_crate::str;
83 changes: 40 additions & 43 deletions src/libsyntax/feature_gate.rs
Original file line number Diff line number Diff line change
@@ -90,24 +90,24 @@ macro_rules! declare_features {
}
};

($((removed, $feature: ident, $ver: expr, $issue: expr, None),)+) => {
($((removed, $feature: ident, $ver: expr, $issue: expr, None, $reason: expr),)+) => {
/// Represents unstable features which have since been removed (it was once Active)
const REMOVED_FEATURES: &'static [(&'static str, &'static str, Option<u32>)] = &[
$((stringify!($feature), $ver, $issue)),+
const REMOVED_FEATURES: &[(&str, &str, Option<u32>, Option<&str>)] = &[
$((stringify!($feature), $ver, $issue, $reason)),+
];
};

($((stable_removed, $feature: ident, $ver: expr, $issue: expr, None),)+) => {
/// Represents stable features which have since been removed (it was once Accepted)
const STABLE_REMOVED_FEATURES: &'static [(&'static str, &'static str, Option<u32>)] = &[
$((stringify!($feature), $ver, $issue)),+
const STABLE_REMOVED_FEATURES: &[(&str, &str, Option<u32>, Option<&str>)] = &[
$((stringify!($feature), $ver, $issue, None)),+
];
};

($((accepted, $feature: ident, $ver: expr, $issue: expr, None),)+) => {
/// Those language feature has since been Accepted (it was once Active)
const ACCEPTED_FEATURES: &'static [(&'static str, &'static str, Option<u32>)] = &[
$((stringify!($feature), $ver, $issue)),+
const ACCEPTED_FEATURES: &[(&str, &str, Option<u32>, Option<&str>)] = &[
$((stringify!($feature), $ver, $issue, None)),+
];
}
}
@@ -162,9 +162,6 @@ declare_features! (
// OIBIT specific features
(active, optin_builtin_traits, "1.0.0", Some(13231), None),

// macro re-export needs more discussion and stabilization
(active, macro_reexport, "1.0.0", Some(29638), None),

// Allows use of #[staged_api]
// rustc internal
(active, staged_api, "1.0.0", None, None),
@@ -463,27 +460,29 @@ declare_features! (
);

declare_features! (
(removed, import_shadowing, "1.0.0", None, None),
(removed, managed_boxes, "1.0.0", None, None),
(removed, import_shadowing, "1.0.0", None, None, None),
(removed, managed_boxes, "1.0.0", None, None, None),
// Allows use of unary negate on unsigned integers, e.g. -e for e: u8
(removed, negate_unsigned, "1.0.0", Some(29645), None),
(removed, reflect, "1.0.0", Some(27749), None),
(removed, negate_unsigned, "1.0.0", Some(29645), None, None),
(removed, reflect, "1.0.0", Some(27749), None, None),
// A way to temporarily opt out of opt in copy. This will *never* be accepted.
(removed, opt_out_copy, "1.0.0", None, None),
(removed, quad_precision_float, "1.0.0", None, None),
(removed, struct_inherit, "1.0.0", None, None),
(removed, test_removed_feature, "1.0.0", None, None),
(removed, visible_private_types, "1.0.0", None, None),
(removed, unsafe_no_drop_flag, "1.0.0", None, None),
(removed, opt_out_copy, "1.0.0", None, None, None),
(removed, quad_precision_float, "1.0.0", None, None, None),
(removed, struct_inherit, "1.0.0", None, None, None),
(removed, test_removed_feature, "1.0.0", None, None, None),
(removed, visible_private_types, "1.0.0", None, None, None),
(removed, unsafe_no_drop_flag, "1.0.0", None, None, None),
// Allows using items which are missing stability attributes
// rustc internal
(removed, unmarked_api, "1.0.0", None, None),
(removed, pushpop_unsafe, "1.2.0", None, None),
(removed, allocator, "1.0.0", None, None),
// Allows the `#[simd]` attribute -- removed in favor of `#[repr(simd)]`
(removed, simd, "1.0.0", Some(27731), None),
// Merged into `slice_patterns`
(removed, advanced_slice_patterns, "1.0.0", Some(23121), None),
(removed, unmarked_api, "1.0.0", None, None, None),
(removed, pushpop_unsafe, "1.2.0", None, None, None),
(removed, allocator, "1.0.0", None, None, None),
(removed, simd, "1.0.0", Some(27731), None,
Some("removed in favor of `#[repr(simd)]`")),
(removed, advanced_slice_patterns, "1.0.0", Some(23121), None,
Some("merged into `#![feature(slice_patterns)]`")),
(removed, macro_reexport, "1.0.0", Some(29638), None,
Some("subsumed by `#![feature(use_extern_macros)]` and `pub use`")),
);

declare_features! (
@@ -673,7 +672,6 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG
("forbid", Normal, Ungated),
("deny", Normal, Ungated),

("macro_reexport", Normal, Ungated),
("macro_use", Normal, Ungated),
("macro_export", Normal, Ungated),
("plugin_registrar", Normal, Ungated),
@@ -1202,7 +1200,7 @@ fn find_lang_feature_issue(feature: &str) -> Option<u32> {
let found = ACCEPTED_FEATURES.iter().chain(REMOVED_FEATURES).chain(STABLE_REMOVED_FEATURES)
.find(|t| t.0 == feature);
match found {
Some(&(_, _, issue)) => issue,
Some(&(_, _, issue, _)) => issue,
None => panic!("Feature `{}` is not declared anywhere", feature),
}
}
@@ -1516,11 +1514,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
gate_feature_post!(&self, underscore_imports, i.span,
"renaming extern crates with `_` is unstable");
}
if let Some(attr) = attr::find_by_name(&i.attrs[..], "macro_reexport") {
gate_feature_post!(&self, macro_reexport, attr.span,
"macros re-exports are experimental \
and possibly buggy");
}
}

ast::ItemKind::ForeignMod(ref foreign_module) => {
@@ -1821,8 +1814,12 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {

pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
crate_edition: Edition) -> Features {
fn feature_removed(span_handler: &Handler, span: Span) {
span_err!(span_handler, span, E0557, "feature has been removed");
fn feature_removed(span_handler: &Handler, span: Span, reason: Option<&str>) {
let mut err = struct_span_err!(span_handler, span, E0557, "feature has been removed");
if let Some(reason) = reason {
err.span_note(span, reason);
}
err.emit();
}

let mut features = Features::new();
@@ -1855,19 +1852,19 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
set(&mut features, mi.span);
feature_checker.collect(&features, mi.span);
}
else if let Some(&(_, _, _)) = REMOVED_FEATURES.iter()
.find(|& &(n, _, _)| name == n)
else if let Some(&(.., reason)) = REMOVED_FEATURES.iter()
.find(|& &(n, ..)| name == n)
.or_else(|| STABLE_REMOVED_FEATURES.iter()
.find(|& &(n, _, _)| name == n)) {
feature_removed(span_handler, mi.span);
.find(|& &(n, ..)| name == n)) {
feature_removed(span_handler, mi.span, reason);
}
else if let Some(&(_, _, _)) = ACCEPTED_FEATURES.iter()
.find(|& &(n, _, _)| name == n) {
else if let Some(&(..)) = ACCEPTED_FEATURES.iter()
.find(|& &(n, ..)| name == n) {
features.declared_stable_lang_features.push((name, mi.span));
} else if let Some(&edition) = ALL_EDITIONS.iter()
.find(|e| name == e.feature_name()) {
if edition <= crate_edition {
feature_removed(span_handler, mi.span);
feature_removed(span_handler, mi.span, None);
} else {
for &(.., f_edition, set) in ACTIVE_FEATURES.iter() {
if let Some(f_edition) = f_edition {
21 changes: 0 additions & 21 deletions src/test/compile-fail-fulldeps/gated-macro-reexports.rs

This file was deleted.

19 changes: 0 additions & 19 deletions src/test/compile-fail/auxiliary/macro_non_reexport_2.rs

This file was deleted.

15 changes: 0 additions & 15 deletions src/test/compile-fail/auxiliary/macro_reexport_1.rs

This file was deleted.

20 changes: 0 additions & 20 deletions src/test/compile-fail/macro-no-implicit-reexport.rs

This file was deleted.

16 changes: 0 additions & 16 deletions src/test/compile-fail/macro-reexport-malformed-1.rs

This file was deleted.

16 changes: 0 additions & 16 deletions src/test/compile-fail/macro-reexport-malformed-2.rs

This file was deleted.

16 changes: 0 additions & 16 deletions src/test/compile-fail/macro-reexport-malformed-3.rs

This file was deleted.

22 changes: 0 additions & 22 deletions src/test/compile-fail/macro-reexport-not-locally-visible.rs

This file was deleted.

16 changes: 0 additions & 16 deletions src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-reexport.rs

This file was deleted.

21 changes: 0 additions & 21 deletions src/test/run-pass-fulldeps/proc-macro/use-reexport.rs

This file was deleted.

15 changes: 0 additions & 15 deletions src/test/run-pass/auxiliary/macro_reexport_1.rs

This file was deleted.

16 changes: 0 additions & 16 deletions src/test/run-pass/auxiliary/macro_reexport_2.rs

This file was deleted.

16 changes: 0 additions & 16 deletions src/test/run-pass/auxiliary/macro_reexport_2_no_use.rs

This file was deleted.

19 changes: 0 additions & 19 deletions src/test/run-pass/macro-reexport-no-intermediate-use.rs

This file was deleted.

19 changes: 0 additions & 19 deletions src/test/run-pass/macro-reexport.rs

This file was deleted.

2 changes: 1 addition & 1 deletion src/test/rustdoc/cross-crate-links.rs
Original file line number Diff line number Diff line change
@@ -66,6 +66,6 @@ pub use all_item_types::FOO_STATIC;
#[doc(no_inline)]
pub use all_item_types::FOO_CONSTANT;

// @has 'foo/index.html' '//a[@href="../all_item_types/macro.foo_macro.html"]' 'foo_macro'
// @has 'foo/index.html' '//a[@href="../foo/macro.foo_macro.html"]' 'foo_macro'
#[doc(no_inline)]
pub use all_item_types::foo_macro;
11 changes: 4 additions & 7 deletions src/test/rustdoc/pub-use-extern-macros.rs
Original file line number Diff line number Diff line change
@@ -10,22 +10,19 @@

// aux-build:pub-use-extern-macros.rs

#![feature(use_extern_macros, macro_reexport)]
#![feature(use_extern_macros)]

// @has pub_use_extern_macros/macro.foo.html
// @!has pub_use_extern_macros/index.html 'pub use macros::foo;'
#[macro_reexport(foo)] extern crate macros;
extern crate macros;

// @has pub_use_extern_macros/index.html 'pub use macros::bar;'
// @!has pub_use_extern_macros/macro.bar.html
// @has pub_use_extern_macros/macro.bar.html
pub use macros::bar;

// @has pub_use_extern_macros/macro.baz.html
// @!has pub_use_extern_macros/index.html 'pub use macros::baz;'
#[doc(inline)]
pub use macros::baz;

// @!has pub_use_extern_macros/macro.quux.html
// @has pub_use_extern_macros/macro.quux.html
// @!has pub_use_extern_macros/index.html 'pub use macros::quux;'
#[doc(hidden)]
pub use macros::quux;
20 changes: 0 additions & 20 deletions src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs
Original file line number Diff line number Diff line change
@@ -50,7 +50,6 @@
#![allow (x5300)] //~ WARN unknown lint: `x5300`
#![forbid (x5200)] //~ WARN unknown lint: `x5200`
#![deny (x5100)] //~ WARN unknown lint: `x5100`
#![macro_reexport = "5000"] //~ WARN unused attribute
#![macro_use] // (allowed if no argument; see issue-43160-gating-of-macro_use.rs)
#![macro_export = "4800"] //~ WARN unused attribute
#![plugin_registrar = "4700"] //~ WARN unused attribute
@@ -186,25 +185,6 @@ mod deny {
//~^ WARN unknown lint: `x5100`
}

#[macro_reexport = "5000"]
//~^ WARN unused attribute
mod macro_reexport {
mod inner { #![macro_reexport="5000"] }
//~^ WARN unused attribute

#[macro_reexport = "5000"] fn f() { }
//~^ WARN unused attribute

#[macro_reexport = "5000"] struct S;
//~^ WARN unused attribute

#[macro_reexport = "5000"] type T = S;
//~^ WARN unused attribute

#[macro_reexport = "5000"] impl S { }
//~^ WARN unused attribute
}

#[macro_use]
mod macro_use {
mod inner { #![macro_use] }
452 changes: 205 additions & 247 deletions src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -10,12 +10,9 @@

// aux-build:two_macros.rs

#![feature(macro_reexport)]
#![feature(macro_reexport)] //~ ERROR feature has been removed

#[macro_use(macro_two)]
#[macro_reexport(no_way)] //~ ERROR re-exported macro not found
#[macro_reexport(macro_one)] //~ ERROR attribute `macro_reexport` is currently unknown
extern crate two_macros;

pub fn main() {
macro_two!();
}
fn main() {}
24 changes: 24 additions & 0 deletions src/test/ui/macro-reexport-removed.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
error[E0557]: feature has been removed
--> $DIR/macro-reexport-removed.rs:13:12
|
LL | #![feature(macro_reexport)] //~ ERROR feature has been removed
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably have some note about why the feature was removed and what should be used instead.

| ^^^^^^^^^^^^^^
|
note: subsumed by `#![feature(use_extern_macros)]` and `pub use`
--> $DIR/macro-reexport-removed.rs:13:12
|
LL | #![feature(macro_reexport)] //~ ERROR feature has been removed
| ^^^^^^^^^^^^^^

error[E0658]: The attribute `macro_reexport` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
--> $DIR/macro-reexport-removed.rs:15:1
|
LL | #[macro_reexport(macro_one)] //~ ERROR attribute `macro_reexport` is currently unknown
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: add #![feature(custom_attribute)] to the crate attributes to enable

error: aborting due to 2 previous errors

Some errors occurred: E0557, E0658.
For more information about an error, try `rustc --explain E0557`.