diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index be51a6753fb62..d9663a507d961 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -391,6 +391,13 @@ pub fn rust_src(build: &Build) { } } + // If we're inside the vendor directory then we need to preserve + // everything as Cargo's vendoring support tracks all checksums and we + // want to be sure we don't accidentally leave out a file. + if spath.contains("vendor") { + return true + } + let excludes = [ "CVS", "RCS", "SCCS", ".git", ".gitignore", ".gitmodules", ".gitattributes", ".cvsignore", ".svn", ".arch-ids", "{arch}", diff --git a/src/doc/book/SUMMARY.md b/src/doc/book/SUMMARY.md index 18aa9f24580d5..babbafa078f4a 100644 --- a/src/doc/book/SUMMARY.md +++ b/src/doc/book/SUMMARY.md @@ -52,6 +52,7 @@ * [Borrow and AsRef](borrow-and-asref.md) * [Release Channels](release-channels.md) * [Using Rust without the standard library](using-rust-without-the-standard-library.md) + * [Procedural Macros (and custom derive)](procedural-macros.md) * [Nightly Rust](nightly-rust.md) * [Compiler Plugins](compiler-plugins.md) * [Inline Assembly](inline-assembly.md) diff --git a/src/doc/book/procedural-macros.md b/src/doc/book/procedural-macros.md new file mode 100644 index 0000000000000..37d3d20c06d96 --- /dev/null +++ b/src/doc/book/procedural-macros.md @@ -0,0 +1,213 @@ +% Procedural Macros (and custom Derive) + +As you've seen throughout the rest of the book, Rust provides a mechanism +called "derive" that lets you implement traits easily. For example, + +```rust +#[derive(Debug)] +struct Point { + x: i32, + y: i32, +} +``` + +is a lot simpler than + +```rust +struct Point { + x: i32, + y: i32, +} + +use std::fmt; + +impl fmt::Debug for Point { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "Point {{ x: {}, y: {} }}", self.x, self.y) + } +} +``` + +Rust includes several traits that you can derive, but it also lets you define +your own. We can accomplish this task through a feature of Rust called +"procedural macros." Eventually, procedural macros will allow for all sorts of +advanced metaprogramming in Rust, but today, they're only for custom derive. + +Let's build a very simple trait, and derive it with custom derive. + +## Hello World + +So the first thing we need to do is start a new crate for our project. + +```bash +$ cargo new --bin hello-world +``` + +All we want is to be able to call `hello_world()` on a derived type. Something +like this: + +```rust,ignore +#[derive(HelloWorld)] +struct Pancakes; + +fn main() { + Pancakes::hello_world(); +} +``` + +With some kind of nice output, like `Hello, World! My name is Pancakes.`. + +Let's go ahead and write up what we think our macro will look like from a user +perspective. In `src/main.rs` we write: + +```rust,ignore +#[macro_use] +extern crate hello_world_derive; + +trait HelloWorld { + fn hello_world(); +} + +#[derive(HelloWorld)] +struct FrenchToast; + +#[derive(HelloWorld)] +struct Waffles; + +fn main() { + FrenchToast::hello_world(); + Waffles::hello_world(); +} +``` + +Great. So now we just need to actually write the procedural macro. At the +moment, procedural macros need to be in their own crate. Eventually, this +restriction may be lifted, but for now, it's required. As such, there's a +convention; for a crate named `foo`, a custom derive procedural macro is called +`foo-derive`. Let's start a new crate called `hello-world-derive` inside our +`hello-world` project. + +```bash +$ cargo new hello-world-derive +``` + +To make sure that our `hello-world` crate is able to find this new crate we've +created, we'll add it to our toml: + +```toml +[dependencies] +hello-world-derive = { path = "hello-world-derive" } +``` + +As for our the source of our `hello-world-derive` crate, here's an example: + +```rust,ignore +extern crate proc_macro; +extern crate syn; +#[macro_use] +extern crate quote; + +use proc_macro::TokenStream; + +#[proc_macro_derive(HelloWorld)] +pub fn hello_world(input: TokenStream) -> TokenStream { + // Construct a string representation of the type definition + let s = input.to_string(); + + // Parse the string representation + let ast = syn::parse_macro_input(&s).unwrap(); + + // Build the impl + let gen = impl_hello_world(&ast); + + // Return the generated impl + gen.parse().unwrap() +} +``` + +So there is a lot going on here. We have introduced two new crates: [`syn`] and +[`quote`]. As you may have noticed, `input: TokenSteam` is immediately converted +to a `String`. This `String` is a string representation of the Rust code for which +we are deriving `HelloWorld` for. At the moment, the only thing you can do with a +`TokenStream` is convert it to a string. A richer API will exist in the future. + +So what we really need is to be able to _parse_ Rust code into something +usable. This is where `syn` comes to play. `syn` is a crate for parsing Rust +code. The other crate we've introduced is `quote`. It's essentially the dual of +`syn` as it will make generating Rust code really easy. We could write this +stuff on our own, but it's much simpler to use these libraries. Writing a full +parser for Rust code is no simple task. + +[`syn`]: https://crates.io/crates/syn +[`quote`]: https://crates.io/crates/quote + +The comments seem to give us a pretty good idea of our overall strategy. We +are going to take a `String` of the Rust code for the type we are deriving, parse +it using `syn`, construct the implementation of `hello_world` (using `quote`), +then pass it back to Rust compiler. + +One last note: you'll see some `unwrap()`s there. If you want to provide an +error for a procedural macro, then you should `panic!` with the error message. +In this case, we're keeping it as simple as possible. + +Great, so let's write `impl_hello_world(&ast)`. + +```rust,ignore +fn impl_hello_world(ast: &syn::MacroInput) -> quote::Tokens { + let name = &ast.ident; + quote! { + impl HelloWorld for #name { + fn hello_world() { + println!("Hello, World! My name is {}", stringify!(#name)); + } + } + } +} +``` + +So this is where quotes comes in. The `ast` argument is a struct that gives us +a representation of our type (which can be either a `struct` or an `enum`). +Check out the [docs](https://docs.rs/syn/0.10.5/syn/struct.MacroInput.html), +there is some useful information there. We are able to get the name of the +type using `ast.ident`. The `quote!` macro let's us write up the Rust code +that we wish to return and convert it into `Tokens`. `quote!` let's us use some +really cool templating mechanics; we simply write `#name` and `quote!` will +replace it with the variable named `name`. You can even do some repetition +similar to regular macros work. You should check out the +[docs](https://docs.rs/quote) for a good introduction. + +So I think that's it. Oh, well, we do need to add dependencies for `syn` and +`quote` in the `cargo.toml` for `hello-world-derive`. + +```toml +[dependencies] +syn = "0.10.5" +quote = "0.3.10" +``` + +That should be it. Let's try to compile `hello-world`. + +```bash +error: the `#[proc_macro_derive]` attribute is only usable with crates of the `proc-macro` crate type + --> hello-world-derive/src/lib.rs:8:3 + | +8 | #[proc_macro_derive(HelloWorld)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +``` + +Oh, so it appears that we need to declare that our `hello-world-derive` crate is +a `proc-macro` crate type. How do we do this? Like this: + +```toml +[lib] +proc-macro = true +``` + +Ok so now, let's compile `hello-world`. Executing `cargo run` now yields: + +```bash +Hello, World! My name is FrenchToast +Hello, World! My name is Waffles +``` + +We've done it! diff --git a/src/doc/reference.md b/src/doc/reference.md index bf286aaec4bb3..e7cfe4bb2eeb5 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -555,26 +555,24 @@ mod a { # fn main() {} ``` -# Syntax extensions +# Macros A number of minor features of Rust are not central enough to have their own syntax, and yet are not implementable as functions. Instead, they are given names, and invoked through a consistent syntax: `some_extension!(...)`. -Users of `rustc` can define new syntax extensions in two ways: - -* [Compiler plugins][plugin] can include arbitrary Rust code that - manipulates syntax trees at compile time. Note that the interface - for compiler plugins is considered highly unstable. +Users of `rustc` can define new macros in two ways: * [Macros](book/macros.html) define new syntax in a higher-level, declarative way. +* [Procedural Macros][procedural macros] can be used to implement custom derive. + +And one unstable way: [compiler plugins][plugin]. ## Macros `macro_rules` allows users to define syntax extension in a declarative way. We -call such extensions "macros by example" or simply "macros" — to be distinguished -from the "procedural macros" defined in [compiler plugins][plugin]. +call such extensions "macros by example" or simply "macros". Currently, macros can expand to expressions, statements, items, or patterns. @@ -652,6 +650,28 @@ Rust syntax is restricted in two ways: [RFC 550]: https://github.com/rust-lang/rfcs/blob/master/text/0550-macro-future-proofing.md +## Procedrual Macros + +"Procedrual macros" are the second way to implement a macro. For now, the only +thing they can be used for is to implement derive on your own types. See +[the book][procedural macros] for a tutorial. + +Procedural macros involve a few different parts of the language and its +standard libraries. First is the `proc_macro` crate, included with Rust, +that defines an interface for building a procedrual macro. The +`#[proc_macro_derive(Foo)]` attribute is used to mark the the deriving +function. This function must have the type signature: + +```rust,ignore +use proc_macro::TokenStream; + +#[proc_macro_derive(Hello)] +pub fn hello_world(input: TokenStream) -> TokenStream +``` + +Finally, procedural macros must be in their own crate, with the `proc-macro` +crate type. + # Crates and source files Although Rust, like any other language, can be implemented by an interpreter as @@ -2309,6 +2329,9 @@ impl PartialEq for Foo { } ``` +You can implement `derive` for your own type through [procedural +macros](#procedural-macros). + ### Compiler Features Certain aspects of Rust may be implemented in the compiler, but they're not @@ -4112,6 +4135,16 @@ be ignored in favor of only building the artifacts specified by command line. in dynamic libraries. This form of output is used to produce statically linked executables as well as `staticlib` outputs. +* `--crate-type=proc-macro`, `#[crate_type = "proc-macro"]` - The output + produced is not specified, but if a `-L` path is provided to it then the + compiler will recognize the output artifacts as a macro and it can be loaded + for a program. If a crate is compiled with the `proc-macro` crate type it + will forbid exporting any items in the crate other than those functions + tagged `#[proc_macro_derive]` and those functions must also be placed at the + crate root. Finally, the compiler will automatically set the + `cfg(proc_macro)` annotation whenever any crate type of a compilation is the + `proc-macro` crate type. + Note that these outputs are stackable in the sense that if multiple are specified, then the compiler will produce each form of output at once without having to recompile. However, this only applies for outputs specified by the @@ -4289,3 +4322,4 @@ that have since been removed): [ffi]: book/ffi.html [plugin]: book/compiler-plugins.html +[procedural macros]: book/procedural-macros.html diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs index 5ee9fecfb21b3..22b365fa64f0e 100644 --- a/src/libproc_macro/lib.rs +++ b/src/libproc_macro/lib.rs @@ -15,19 +15,16 @@ //! Currently the primary use of this crate is to provide the ability to define //! new custom derive modes through `#[proc_macro_derive]`. //! -//! Added recently as part of [RFC 1681] this crate is currently *unstable* and -//! requires the `#![feature(proc_macro_lib)]` directive to use. -//! -//! [RFC 1681]: https://github.com/rust-lang/rfcs/blob/master/text/1681-macros-1.1.md -//! //! Note that this crate is intentionally very bare-bones currently. The main //! type, `TokenStream`, only supports `fmt::Display` and `FromStr` //! implementations, indicating that it can only go to and come from a string. //! This functionality is intended to be expanded over time as more surface //! area for macro authors is stabilized. +//! +//! See [the book](../../book/procedural-macros.html) for more. #![crate_name = "proc_macro"] -#![unstable(feature = "proc_macro_lib", issue = "27812")] +#![stable(feature = "proc_macro_lib", since = "1.15.0")] #![crate_type = "rlib"] #![crate_type = "dylib"] #![cfg_attr(not(stage0), deny(warnings))] @@ -55,12 +52,14 @@ use syntax::ptr::P; /// /// The API of this type is intentionally bare-bones, but it'll be expanded over /// time! +#[stable(feature = "proc_macro_lib", since = "1.15.0")] pub struct TokenStream { inner: Vec>, } /// Error returned from `TokenStream::from_str`. #[derive(Debug)] +#[stable(feature = "proc_macro_lib", since = "1.15.0")] pub struct LexError { _inner: (), } @@ -131,6 +130,7 @@ pub mod __internal { } } +#[stable(feature = "proc_macro_lib", since = "1.15.0")] impl FromStr for TokenStream { type Err = LexError; @@ -154,6 +154,7 @@ impl FromStr for TokenStream { } } +#[stable(feature = "proc_macro_lib", since = "1.15.0")] impl fmt::Display for TokenStream { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { for item in self.inner.iter() { diff --git a/src/librustc/infer/error_reporting.rs b/src/librustc/infer/error_reporting.rs index 90d752ae6ee29..28edf3c587b19 100644 --- a/src/librustc/infer/error_reporting.rs +++ b/src/librustc/infer/error_reporting.rs @@ -114,6 +114,22 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } } + fn trait_item_scope_tag(item: &hir::TraitItem) -> &'static str { + match item.node { + hir::MethodTraitItem(..) => "method body", + hir::ConstTraitItem(..) | + hir::TypeTraitItem(..) => "associated item" + } + } + + fn impl_item_scope_tag(item: &hir::ImplItem) -> &'static str { + match item.node { + hir::ImplItemKind::Method(..) => "method body", + hir::ImplItemKind::Const(..) | + hir::ImplItemKind::Type(_) => "associated item" + } + } + fn explain_span<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, heading: &str, span: Span) -> (String, Option) { @@ -149,6 +165,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { }, Some(ast_map::NodeStmt(_)) => "statement", Some(ast_map::NodeItem(it)) => item_scope_tag(&it), + Some(ast_map::NodeTraitItem(it)) => trait_item_scope_tag(&it), + Some(ast_map::NodeImplItem(it)) => impl_item_scope_tag(&it), Some(_) | None => { err.span_note(span, &unknown_scope()); return; @@ -187,23 +205,31 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } }; - match self.map.find(fr.scope.node_id(&self.region_maps)) { - Some(ast_map::NodeBlock(ref blk)) => { - let (msg, opt_span) = explain_span(self, "block", blk.span); - (format!("{} {}", prefix, msg), opt_span) - } - Some(ast_map::NodeItem(it)) => { - let tag = item_scope_tag(&it); - let (msg, opt_span) = explain_span(self, tag, it.span); - (format!("{} {}", prefix, msg), opt_span) + let node = fr.scope.node_id(&self.region_maps); + let unknown; + let tag = match self.map.find(node) { + Some(ast_map::NodeBlock(_)) | + Some(ast_map::NodeExpr(_)) => "body", + Some(ast_map::NodeItem(it)) => item_scope_tag(&it), + Some(ast_map::NodeTraitItem(it)) => trait_item_scope_tag(&it), + Some(ast_map::NodeImplItem(it)) => impl_item_scope_tag(&it), + + // this really should not happen, but it does: + // FIXME(#27942) + Some(_) => { + unknown = format!("unexpected node ({}) for scope {:?}. \ + Please report a bug.", + self.map.node_to_string(node), fr.scope); + &unknown } - Some(_) | None => { - // this really should not happen, but it does: - // FIXME(#27942) - (format!("{} unknown free region bounded by scope {:?}", - prefix, fr.scope), None) + None => { + unknown = format!("unknown node for scope {:?}. \ + Please report a bug.", fr.scope); + &unknown } - } + }; + let (msg, opt_span) = explain_span(self, tag, self.map.span(node)); + (format!("{} {}", prefix, msg), opt_span) } ty::ReStatic => ("the static lifetime".to_owned(), None), diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index f2be97c832370..7ec0ef00780f2 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -298,8 +298,7 @@ pub trait CrateStore<'tcx> { // trait/impl-item info fn trait_of_item(&self, def_id: DefId) -> Option; - fn associated_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) - -> Option; + fn associated_item(&self, def: DefId) -> Option; // flags fn is_const_fn(&self, did: DefId) -> bool; @@ -462,7 +461,7 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore { // trait/impl-item info fn trait_of_item(&self, def_id: DefId) -> Option { bug!("trait_of_item") } - fn associated_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) + fn associated_item<'a>(&self, def: DefId) -> Option { bug!("associated_item") } // flags diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 3e32957aecfe0..a2c4b59db14f5 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -18,7 +18,7 @@ use hir::map as hir_map; use lint; use hir::def::Def; use hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId, DefIndex, LOCAL_CRATE}; -use ty::TyCtxt; +use ty::{self, TyCtxt}; use middle::privacy::AccessLevels; use syntax::symbol::Symbol; use syntax_pos::{Span, DUMMY_SP}; @@ -436,6 +436,36 @@ struct Checker<'a, 'tcx: 'a> { } impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { + // (See issue #38412) + fn skip_stability_check_due_to_privacy(self, def_id: DefId) -> bool { + let visibility = { + // Check if `def_id` is a trait method. + match self.sess.cstore.associated_item(def_id) { + Some(ty::AssociatedItem { container: ty::TraitContainer(trait_def_id), .. }) => { + // Trait methods do not declare visibility (even + // for visibility info in cstore). Use containing + // trait instead, so methods of pub traits are + // themselves considered pub. + self.sess.cstore.visibility(trait_def_id) + } + _ => { + // Otherwise, cstore info works directly. + self.sess.cstore.visibility(def_id) + } + } + }; + + match visibility { + // must check stability for pub items. + ty::Visibility::Public => false, + + // these are not visible outside crate; therefore + // stability markers are irrelevant, if even present. + ty::Visibility::Restricted(..) | + ty::Visibility::PrivateExternal => true, + } + } + pub fn check_stability(self, def_id: DefId, id: NodeId, span: Span) { if self.sess.codemap().span_allows_unstable(span) { debug!("stability: \ @@ -496,6 +526,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { self.stability.borrow_mut().used_features.insert(feature.clone(), level.clone()); } + // Issue 38412: private items lack stability markers. + if self.skip_stability_check_due_to_privacy(def_id) { + return + } + match stability { Some(&Stability { level: attr::Unstable {ref reason, issue}, ref feature, .. }) => { if !self.stability.borrow().active_features.contains(feature) { diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index df12c252907a5..dd1a6caa02fd4 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -2062,7 +2062,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn associated_item(self, def_id: DefId) -> AssociatedItem { self.associated_items.memoize(def_id, || { if !def_id.is_local() { - return self.sess.cstore.associated_item(self.global_tcx(), def_id) + return self.sess.cstore.associated_item(def_id) .expect("missing AssociatedItem in metadata"); } @@ -2540,7 +2540,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// ID of the impl that the method belongs to. Otherwise, return `None`. pub fn impl_of_method(self, def_id: DefId) -> Option { if def_id.krate != LOCAL_CRATE { - return self.sess.cstore.associated_item(self.global_tcx(), def_id) + return self.sess.cstore.associated_item(def_id) .and_then(|item| { match item.container { TraitContainer(_) => None, diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index ace00f031859d..7a1256926657c 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -714,8 +714,7 @@ pub fn phase_2_configure_and_expand(sess: &Session, is_proc_macro_crate, is_test_crate, num_crate_types, - sess.diagnostic(), - &sess.features.borrow()) + sess.diagnostic()) }); } diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 1a1bb1432eec1..79daab6bbc4fc 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -189,8 +189,7 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { self.get_crate_data(def_id.krate).get_trait_of_item(def_id.index) } - fn associated_item<'a>(&self, _tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) - -> Option + fn associated_item<'a>(&self, def: DefId) -> Option { self.dep_graph.read(DepNode::MetaData(def)); self.get_crate_data(def.krate).get_associated_item(def.index) diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 539c05b71bb1c..af325cefa6271 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -1021,6 +1021,7 @@ impl<'a, 'tcx> CrateMetadata { let filter = match filter.map(|def_id| self.reverse_translate_def_id(def_id)) { Some(Some(def_id)) => Some((def_id.krate.as_u32(), def_id.index)), Some(None) => return, + None if self.proc_macros.is_some() => return, None => None, }; diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs index 56f3cfc12c97f..25fa201a69468 100644 --- a/src/librustc_metadata/lib.rs +++ b/src/librustc_metadata/lib.rs @@ -21,7 +21,6 @@ #![feature(conservative_impl_trait)] #![feature(core_intrinsics)] #![feature(proc_macro_internals)] -#![feature(proc_macro_lib)] #![feature(quote)] #![feature(rustc_diagnostic_macros)] #![feature(rustc_private)] diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs index 41698574e0f1f..2a4b2b515cc68 100644 --- a/src/librustc_mir/transform/promote_consts.rs +++ b/src/librustc_mir/transform/promote_consts.rs @@ -66,6 +66,7 @@ impl TempState { /// A "root candidate" for promotion, which will become the /// returned value in a promoted MIR, unless it's a subset /// of a larger candidate. +#[derive(Debug)] pub enum Candidate { /// Borrow of a constant temporary. Ref(Location), @@ -190,15 +191,12 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { /// promoted MIR, recursing through temps. fn promote_temp(&mut self, temp: Local) -> Local { let old_keep_original = self.keep_original; - let (bb, stmt_idx) = match self.temps[temp] { - TempState::Defined { - location: Location { block, statement_index }, - uses - } if uses > 0 => { + let loc = match self.temps[temp] { + TempState::Defined { location, uses } if uses > 0 => { if uses > 1 { self.keep_original = true; } - (block, statement_index) + location } state => { span_bug!(self.promoted.span, "{:?} not promotable: {:?}", @@ -209,91 +207,80 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { self.temps[temp] = TempState::PromotedOut; } - let no_stmts = self.source[bb].statements.len(); + let no_stmts = self.source[loc.block].statements.len(); + let new_temp = self.promoted.local_decls.push( + LocalDecl::new_temp(self.source.local_decls[temp].ty)); + + debug!("promote({:?} @ {:?}/{:?}, {:?})", + temp, loc, no_stmts, self.keep_original); // First, take the Rvalue or Call out of the source MIR, // or duplicate it, depending on keep_original. - let (mut rvalue, mut call) = (None, None); - let source_info = if stmt_idx < no_stmts { - let statement = &mut self.source[bb].statements[stmt_idx]; - let rhs = match statement.kind { - StatementKind::Assign(_, ref mut rhs) => rhs, - _ => { - span_bug!(statement.source_info.span, "{:?} is not an assignment", - statement); - } + if loc.statement_index < no_stmts { + let (mut rvalue, source_info) = { + let statement = &mut self.source[loc.block].statements[loc.statement_index]; + let rhs = match statement.kind { + StatementKind::Assign(_, ref mut rhs) => rhs, + _ => { + span_bug!(statement.source_info.span, "{:?} is not an assignment", + statement); + } + }; + + (if self.keep_original { + rhs.clone() + } else { + let unit = Rvalue::Aggregate(AggregateKind::Tuple, vec![]); + mem::replace(rhs, unit) + }, statement.source_info) }; - if self.keep_original { - rvalue = Some(rhs.clone()); - } else { - let unit = Rvalue::Aggregate(AggregateKind::Tuple, vec![]); - rvalue = Some(mem::replace(rhs, unit)); - } - statement.source_info - } else if self.keep_original { - let terminator = self.source[bb].terminator().clone(); - call = Some(terminator.kind); - terminator.source_info + + self.visit_rvalue(&mut rvalue, loc); + self.assign(new_temp, rvalue, source_info.span); } else { - let terminator = self.source[bb].terminator_mut(); - let target = match terminator.kind { - TerminatorKind::Call { - destination: ref mut dest @ Some(_), - ref mut cleanup, .. - } => { - // No cleanup necessary. - cleanup.take(); - - // We'll put a new destination in later. - dest.take().unwrap().1 - } - ref kind => { - span_bug!(terminator.source_info.span, "{:?} not promotable", kind); + let mut terminator = if self.keep_original { + self.source[loc.block].terminator().clone() + } else { + let terminator = self.source[loc.block].terminator_mut(); + let target = match terminator.kind { + TerminatorKind::Call { destination: Some((_, target)), .. } => target, + ref kind => { + span_bug!(terminator.source_info.span, "{:?} not promotable", kind); + } + }; + Terminator { + source_info: terminator.source_info, + kind: mem::replace(&mut terminator.kind, TerminatorKind::Goto { + target: target + }) } }; - call = Some(mem::replace(&mut terminator.kind, TerminatorKind::Goto { - target: target - })); - terminator.source_info - }; - // Then, recurse for components in the Rvalue or Call. - if stmt_idx < no_stmts { - self.visit_rvalue(rvalue.as_mut().unwrap(), Location { - block: bb, - statement_index: stmt_idx - }); - } else { - self.visit_terminator_kind(bb, call.as_mut().unwrap(), Location { - block: bb, - statement_index: no_stmts - }); - } - - let new_temp = self.promoted.local_decls.push( - LocalDecl::new_temp(self.source.local_decls[temp].ty)); - - // Inject the Rvalue or Call into the promoted MIR. - if stmt_idx < no_stmts { - self.assign(new_temp, rvalue.unwrap(), source_info.span); - } else { let last = self.promoted.basic_blocks().last().unwrap(); let new_target = self.new_block(); - let mut call = call.unwrap(); - match call { - TerminatorKind::Call { ref mut destination, ..} => { - *destination = Some((Lvalue::Local(new_temp), new_target)); + + terminator.kind = match terminator.kind { + TerminatorKind::Call { mut func, mut args, .. } => { + self.visit_operand(&mut func, loc); + for arg in &mut args { + self.visit_operand(arg, loc); + } + TerminatorKind::Call { + func: func, + args: args, + cleanup: None, + destination: Some((Lvalue::Local(new_temp), new_target)) + } } - _ => bug!() - } - let terminator = self.promoted[last].terminator_mut(); - terminator.source_info.span = source_info.span; - terminator.kind = call; - } + ref kind => { + span_bug!(terminator.source_info.span, "{:?} not promotable", kind); + } + }; - // Restore the old duplication state. - self.keep_original = old_keep_original; + *self.promoted[last].terminator_mut() = terminator; + }; + self.keep_original = old_keep_original; new_temp } @@ -355,6 +342,7 @@ pub fn promote_candidates<'a, 'tcx>(mir: &mut Mir<'tcx>, mut temps: IndexVec, candidates: Vec) { // Visit candidates in reverse, in case they're nested. + debug!("promote_candidates({:?})", candidates); for candidate in candidates.into_iter().rev() { let (span, ty) = match candidate { Candidate::Ref(Location { block: bb, statement_index: stmt_idx }) => { diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 893478a933182..d144651fb7db6 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -993,9 +993,9 @@ impl<'tcx> MirPass<'tcx> for QualifyAndPromoteConstants { Entry::Vacant(entry) => { // Guard against `const` recursion. entry.insert(Qualif::RECURSIVE); + Mode::Const } } - Mode::Const } MirSource::Static(_, hir::MutImmutable) => Mode::Static, MirSource::Static(_, hir::MutMutable) => Mode::StaticMut, diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 613829bab8be3..59452d3040e8f 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -27,7 +27,7 @@ use syntax::ext::expand::Expansion; use syntax::ext::hygiene::Mark; use syntax::ext::tt::macro_rules; use syntax::feature_gate::{emit_feature_err, GateIssue}; -use syntax::fold::Folder; +use syntax::fold::{self, Folder}; use syntax::ptr::P; use syntax::util::lev_distance::find_best_match_for_name; use syntax::visit::Visitor; @@ -117,6 +117,10 @@ impl<'a> base::Resolver for Resolver<'a> { } path } + + fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac { + fold::noop_fold_mac(mac, self) + } } EliminateCrateVar(self).fold_item(item).expect_one("") diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 208c43d898ce0..5ea79ece37af4 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -20,6 +20,7 @@ use {resolve_error, ResolutionError}; use rustc::ty; use rustc::lint::builtin::PRIVATE_IN_PUBLIC; use rustc::hir::def::*; +use rustc::util::nodemap::FxHashSet; use syntax::ast::{Ident, NodeId, Name}; use syntax::ext::base::Determinacy::{self, Determined, Undetermined}; @@ -723,7 +724,12 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { let mut reexports = Vec::new(); if module as *const _ == self.graph_root as *const _ { - reexports = mem::replace(&mut self.macro_exports, Vec::new()); + let mut exported_macro_names = FxHashSet(); + for export in mem::replace(&mut self.macro_exports, Vec::new()).into_iter().rev() { + if exported_macro_names.insert(export.name) { + reexports.push(export); + } + } } for (&(name, ns), resolution) in module.resolutions.borrow().iter() { diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 19545e2e642b1..8abd3d252c8e4 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -923,7 +923,6 @@ impl<'feat> ExpansionConfig<'feat> { fn enable_allow_internal_unstable = allow_internal_unstable, fn enable_custom_derive = custom_derive, fn enable_pushpop_unsafe = pushpop_unsafe, - fn enable_proc_macro = proc_macro, } } diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 77c53542dcbec..10d76692b1e4c 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -279,9 +279,6 @@ declare_features! ( // instead of just the platforms on which it is the C ABI (active, abi_sysv64, "1.13.0", Some(36167)), - // Macros 1.1 - (active, proc_macro, "1.13.0", Some(35900)), - // Allows untagged unions `union U { ... }` (active, untagged_unions, "1.13.0", Some(32836)), @@ -364,6 +361,8 @@ declare_features! ( // Allows `..` in tuple (struct) patterns (accepted, dotdot_in_tuple_patterns, "1.14.0", Some(33627)), (accepted, item_like_imports, "1.14.0", Some(35120)), + // Macros 1.1 + (accepted, proc_macro, "1.15.0", Some(35900)), ); // (changing above list without updating src/doc/reference.md makes @cmr sad) @@ -637,11 +636,7 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG is an experimental feature", cfg_fn!(fundamental))), - ("proc_macro_derive", Normal, Gated(Stability::Unstable, - "proc_macro", - "the `#[proc_macro_derive]` attribute \ - is an experimental feature", - cfg_fn!(proc_macro))), + ("proc_macro_derive", Normal, Ungated), ("rustc_copy_clone_marker", Whitelisted, Gated(Stability::Unstable, "rustc_attrs", @@ -747,7 +742,6 @@ const GATED_CFGS: &'static [(&'static str, &'static str, fn(&Features) -> bool)] ("target_vendor", "cfg_target_vendor", cfg_fn!(cfg_target_vendor)), ("target_thread_local", "cfg_target_thread_local", cfg_fn!(cfg_target_thread_local)), ("target_has_atomic", "cfg_target_has_atomic", cfg_fn!(cfg_target_has_atomic)), - ("proc_macro", "proc_macro", cfg_fn!(proc_macro)), ]; #[derive(Debug, Eq, PartialEq)] diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index a1d4ad9d629c9..5bd03cc68ad90 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -4378,6 +4378,23 @@ impl<'a> Parser<'a> { return Ok(where_clause); } + // This is a temporary hack. + // + // We are considering adding generics to the `where` keyword as an alternative higher-rank + // parameter syntax (as in `where<'a>` or `where`. To avoid that being a breaking + // change, for now we refuse to parse `where < (ident | lifetime) (> | , | :)`. + if token::Lt == self.token { + let ident_or_lifetime = self.look_ahead(1, |t| t.is_ident() || t.is_lifetime()); + if ident_or_lifetime { + let gt_comma_or_colon = self.look_ahead(2, |t| { + *t == token::Gt || *t == token::Comma || *t == token::Colon + }); + if gt_comma_or_colon { + self.span_err(self.span, "syntax `where` is reserved for future use"); + } + } + } + let mut parsed_something = false; loop { let lo = self.span.lo; diff --git a/src/libsyntax_ext/deriving/custom.rs b/src/libsyntax_ext/deriving/custom.rs index 6f02a348f91dc..64ec460a52460 100644 --- a/src/libsyntax_ext/deriving/custom.rs +++ b/src/libsyntax_ext/deriving/custom.rs @@ -12,7 +12,7 @@ use std::panic; use errors::FatalError; use proc_macro::{TokenStream, __internal}; -use syntax::ast::{self, ItemKind, Attribute}; +use syntax::ast::{self, ItemKind, Attribute, Mac}; use syntax::attr::{mark_used, mark_known}; use syntax::codemap::Span; use syntax::ext::base::*; @@ -28,6 +28,8 @@ impl<'a> Visitor<'a> for MarkAttrs<'a> { mark_known(attr); } } + + fn visit_mac(&mut self, _mac: &Mac) {} } pub struct CustomDerive { diff --git a/src/libsyntax_ext/deriving/mod.rs b/src/libsyntax_ext/deriving/mod.rs index 535d7de19e341..ac4b07bbf2420 100644 --- a/src/libsyntax_ext/deriving/mod.rs +++ b/src/libsyntax_ext/deriving/mod.rs @@ -15,7 +15,7 @@ use syntax::attr::HasAttrs; use syntax::codemap; use syntax::ext::base::{Annotatable, ExtCtxt, SyntaxExtension}; use syntax::ext::build::AstBuilder; -use syntax::feature_gate::{self, emit_feature_err}; +use syntax::feature_gate; use syntax::ptr::P; use syntax::symbol::Symbol; use syntax_pos::Span; @@ -218,12 +218,6 @@ pub fn expand_derive(cx: &mut ExtCtxt, .filter(|&(_, ref name)| !is_builtin_trait(name.name().unwrap())) .next(); if let Some((i, titem)) = macros_11_derive { - if !cx.ecfg.features.unwrap().proc_macro { - let issue = feature_gate::GateIssue::Language; - let msg = "custom derive macros are experimentally supported"; - emit_feature_err(cx.parse_sess, "proc_macro", titem.span, issue, msg); - } - let tname = ast::Ident::with_empty_ctxt(titem.name().unwrap()); let path = ast::Path::from_ident(titem.span, tname); let ext = cx.resolver.resolve_macro(cx.current_expansion.mark, &path, false).unwrap(); diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs index 66d6c0570ace7..74464ca5313b7 100644 --- a/src/libsyntax_ext/lib.rs +++ b/src/libsyntax_ext/lib.rs @@ -19,7 +19,6 @@ html_root_url = "https://doc.rust-lang.org/nightly/")] #![cfg_attr(not(stage0), deny(warnings))] -#![feature(proc_macro_lib)] #![feature(proc_macro_internals)] #![feature(rustc_private)] #![feature(staged_api)] diff --git a/src/libsyntax_ext/proc_macro_registrar.rs b/src/libsyntax_ext/proc_macro_registrar.rs index 5323ace79d849..c93e2c054d240 100644 --- a/src/libsyntax_ext/proc_macro_registrar.rs +++ b/src/libsyntax_ext/proc_macro_registrar.rs @@ -17,7 +17,6 @@ use syntax::ext::base::ExtCtxt; use syntax::ext::build::AstBuilder; use syntax::ext::expand::ExpansionConfig; use syntax::parse::ParseSess; -use syntax::feature_gate::Features; use syntax::fold::Folder; use syntax::ptr::P; use syntax::symbol::Symbol; @@ -47,8 +46,7 @@ pub fn modify(sess: &ParseSess, is_proc_macro_crate: bool, is_test_crate: bool, num_crate_types: usize, - handler: &errors::Handler, - features: &Features) -> ast::Crate { + handler: &errors::Handler) -> ast::Crate { let ecfg = ExpansionConfig::default("proc_macro".to_string()); let mut cx = ExtCtxt::new(sess, ecfg, resolver); @@ -66,12 +64,6 @@ pub fn modify(sess: &ParseSess, if !is_proc_macro_crate { return krate - } else if !features.proc_macro { - let mut err = handler.struct_err("the `proc-macro` crate type is \ - experimental"); - err.help("add #![feature(proc_macro)] to the crate attributes to \ - enable"); - err.emit(); } if num_crate_types > 1 { diff --git a/src/test/compile-fail-fulldeps/auxiliary/pub_and_stability.rs b/src/test/compile-fail-fulldeps/auxiliary/pub_and_stability.rs new file mode 100644 index 0000000000000..9dc4cf1252ec3 --- /dev/null +++ b/src/test/compile-fail-fulldeps/auxiliary/pub_and_stability.rs @@ -0,0 +1,144 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// This crate attempts to enumerate the various scenarios for how a +// type can define fields and methods with various visiblities and +// stabilities. +// +// The basic stability pattern in this file has four cases: +// 1. no stability attribute at all +// 2. a stable attribute (feature "unit_test") +// 3. an unstable attribute that unit test declares (feature "unstable_declared") +// 4. an unstable attribute that unit test fails to declare (feature "unstable_undeclared") +// +// This file also covers four kinds of visibility: private, +// pub(module), pub(crate), and pub. +// +// However, since stability attributes can only be observed in +// cross-crate linkage scenarios, there is little reason to take the +// cross-product (4 stability cases * 4 visiblity cases), because the +// first three visibility cases cannot be accessed outside this crate, +// and therefore stability is only relevant when the visibility is pub +// to the whole universe. +// +// (The only reason to do so would be if one were worried about the +// compiler having some subtle bug where adding a stability attribute +// introduces a privacy violation. As a way to provide evidence that +// this is not occurring, I have put stability attributes on some +// non-pub fields, marked with SILLY below) + +#![feature(staged_api)] +#![feature(pub_restricted)] + +#![stable(feature = "unit_test", since = "0.0.0")] + +#[stable(feature = "unit_test", since = "0.0.0")] +pub use m::{Record, Trait, Tuple}; + +mod m { + #[derive(Default)] + #[stable(feature = "unit_test", since = "0.0.0")] + pub struct Record { + #[stable(feature = "unit_test", since = "0.0.0")] + pub a_stable_pub: i32, + #[unstable(feature = "unstable_declared", issue = "38412")] + pub a_unstable_declared_pub: i32, + #[unstable(feature = "unstable_undeclared", issue = "38412")] + pub a_unstable_undeclared_pub: i32, + #[unstable(feature = "unstable_undeclared", issue = "38412")] // SILLY + pub(crate) b_crate: i32, + #[unstable(feature = "unstable_declared", issue = "38412")] // SILLY + pub(m) c_mod: i32, + #[stable(feature = "unit_test", since = "0.0.0")] // SILLY + d_priv: i32 + } + + #[derive(Default)] + #[stable(feature = "unit_test", since = "1.0.0")] + pub struct Tuple( + #[stable(feature = "unit_test", since = "0.0.0")] + pub i32, + #[unstable(feature = "unstable_declared", issue = "38412")] + pub i32, + #[unstable(feature = "unstable_undeclared", issue = "38412")] + pub i32, + + pub(crate) i32, + pub(m) i32, + i32); + + impl Record { + #[stable(feature = "unit_test", since = "1.0.0")] + pub fn new() -> Self { Default::default() } + } + + impl Tuple { + #[stable(feature = "unit_test", since = "1.0.0")] + pub fn new() -> Self { Default::default() } + } + + + #[stable(feature = "unit_test", since = "0.0.0")] + pub trait Trait { + #[stable(feature = "unit_test", since = "0.0.0")] + type Type; + #[stable(feature = "unit_test", since = "0.0.0")] + fn stable_trait_method(&self) -> Self::Type; + #[unstable(feature = "unstable_undeclared", issue = "38412")] + fn unstable_undeclared_trait_method(&self) -> Self::Type; + #[unstable(feature = "unstable_declared", issue = "38412")] + fn unstable_declared_trait_method(&self) -> Self::Type; + } + + #[stable(feature = "unit_test", since = "0.0.0")] + impl Trait for Record { + type Type = i32; + fn stable_trait_method(&self) -> i32 { self.d_priv } + fn unstable_undeclared_trait_method(&self) -> i32 { self.d_priv } + fn unstable_declared_trait_method(&self) -> i32 { self.d_priv } + } + + #[stable(feature = "unit_test", since = "0.0.0")] + impl Trait for Tuple { + type Type = i32; + fn stable_trait_method(&self) -> i32 { self.3 } + fn unstable_undeclared_trait_method(&self) -> i32 { self.3 } + fn unstable_declared_trait_method(&self) -> i32 { self.3 } + } + + impl Record { + #[unstable(feature = "unstable_undeclared", issue = "38412")] + pub fn unstable_undeclared(&self) -> i32 { self.d_priv } + #[unstable(feature = "unstable_declared", issue = "38412")] + pub fn unstable_declared(&self) -> i32 { self.d_priv } + #[stable(feature = "unit_test", since = "0.0.0")] + pub fn stable(&self) -> i32 { self.d_priv } + + #[unstable(feature = "unstable_undeclared", issue = "38412")] // SILLY + pub(crate) fn pub_crate(&self) -> i32 { self.d_priv } + #[unstable(feature = "unstable_declared", issue = "38412")] // SILLY + pub(m) fn pub_mod(&self) -> i32 { self.d_priv } + #[stable(feature = "unit_test", since = "0.0.0")] // SILLY + fn private(&self) -> i32 { self.d_priv } + } + + impl Tuple { + #[unstable(feature = "unstable_undeclared", issue = "38412")] + pub fn unstable_undeclared(&self) -> i32 { self.0 } + #[unstable(feature = "unstable_declared", issue = "38412")] + pub fn unstable_declared(&self) -> i32 { self.0 } + #[stable(feature = "unit_test", since = "0.0.0")] + pub fn stable(&self) -> i32 { self.0 } + + pub(crate) fn pub_crate(&self) -> i32 { self.0 } + pub(m) fn pub_mod(&self) -> i32 { self.0 } + fn private(&self) -> i32 { self.0 } + } +} diff --git a/src/test/compile-fail-fulldeps/explore-issue-38412.rs b/src/test/compile-fail-fulldeps/explore-issue-38412.rs new file mode 100644 index 0000000000000..aab92575321e3 --- /dev/null +++ b/src/test/compile-fail-fulldeps/explore-issue-38412.rs @@ -0,0 +1,85 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:pub_and_stability.rs + +#![feature(staged_api)] +#![feature(unused_feature)] + +// A big point of this test is that we *declare* `unstable_declared`, +// but do *not* declare `unstable_undeclared`. This way we can check +// that the compiler is letting in uses of declared feature-gated +// stuff but still rejecting uses of undeclared feature-gated stuff. +#![feature(unstable_declared)] + +extern crate pub_and_stability; +use pub_and_stability::{Record, Trait, Tuple}; + +fn main() { + // Okay + let Record { .. } = Record::new(); + // Okay (for now; see RFC Issue #902) + let Tuple(..) = Tuple::new(); + + // Okay + let Record { a_stable_pub: _, a_unstable_declared_pub: _, .. } = Record::new(); + // Okay (for now; see RFC Issue #902) + let Tuple(_, _, ..) = Tuple::new(); // analogous to above + + let Record { a_stable_pub: _, a_unstable_declared_pub: _, a_unstable_undeclared_pub: _, .. } = + Record::new(); + //~^^ ERROR use of unstable library feature 'unstable_undeclared' + + let Tuple(_, _, _, ..) = Tuple::new(); // analogous to previous + //~^ ERROR use of unstable library feature 'unstable_undeclared' + + let r = Record::new(); + let t = Tuple::new(); + + r.a_stable_pub; + r.a_unstable_declared_pub; + r.a_unstable_undeclared_pub; //~ ERROR use of unstable library feature + r.b_crate; //~ ERROR is private + r.c_mod; //~ ERROR is private + r.d_priv; //~ ERROR is private + + t.0; + t.1; + t.2; //~ ERROR use of unstable library feature + t.3; //~ ERROR is private + t.4; //~ ERROR is private + t.5; //~ ERROR is private + + r.stable_trait_method(); + r.unstable_declared_trait_method(); + r.unstable_undeclared_trait_method(); //~ ERROR use of unstable library feature + + r.stable(); + r.unstable_declared(); + r.unstable_undeclared(); //~ ERROR use of unstable library feature + + r.pub_crate(); //~ ERROR `pub_crate` is private + r.pub_mod(); //~ ERROR `pub_mod` is private + r.private(); //~ ERROR `private` is private + + let t = Tuple::new(); + t.stable_trait_method(); + t.unstable_declared_trait_method(); + t.unstable_undeclared_trait_method(); //~ ERROR use of unstable library feature + + t.stable(); + t.unstable_declared(); + t.unstable_undeclared(); //~ ERROR use of unstable library feature + + t.pub_crate(); //~ ERROR `pub_crate` is private + t.pub_mod(); //~ ERROR `pub_mod` is private + t.private(); //~ ERROR `private` is private + +} diff --git a/src/test/compile-fail-fulldeps/proc-macro/attribute.rs b/src/test/compile-fail-fulldeps/proc-macro/attribute.rs index abf11637631f4..5d5e61270b61d 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/attribute.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/attribute.rs @@ -9,7 +9,6 @@ // except according to those terms. #![crate_type = "proc-macro"] -#![feature(proc_macro, proc_macro_lib)] extern crate proc_macro; diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-a-b.rs b/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-a-b.rs index 8a92ca74f376a..cd8750bc89c42 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-a-b.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-a-b.rs @@ -11,7 +11,6 @@ // force-host // no-prefer-dynamic -#![feature(proc_macro, proc_macro_lib)] #![crate_type = "proc-macro"] extern crate proc_macro; diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-a.rs b/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-a.rs index 8d26207273d42..53b2c23e5d7df 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-a.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-a.rs @@ -11,8 +11,6 @@ // force-host // no-prefer-dynamic -#![feature(proc_macro)] -#![feature(proc_macro_lib)] #![crate_type = "proc-macro"] extern crate proc_macro; diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-b.rs b/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-b.rs index 70b778b1030e7..5787546fb1e5a 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-b.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-b.rs @@ -11,8 +11,6 @@ // force-host // no-prefer-dynamic -#![feature(proc_macro)] -#![feature(proc_macro_lib)] #![crate_type = "proc-macro"] extern crate proc_macro; diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-bad.rs b/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-bad.rs index aae8b63e25354..841b39eaed07b 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-bad.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-bad.rs @@ -11,8 +11,6 @@ // no-prefer-dynamic // force-host -#![feature(proc_macro)] -#![feature(proc_macro_lib)] #![crate_type = "proc-macro"] extern crate proc_macro; diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-panic.rs b/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-panic.rs index f426fe5437671..3274f0324e1cb 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-panic.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-panic.rs @@ -11,8 +11,6 @@ // no-prefer-dynamic // force-host -#![feature(proc_macro)] -#![feature(proc_macro_lib)] #![crate_type = "proc-macro"] extern crate proc_macro; diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-unstable-2.rs b/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-unstable-2.rs index d8952e3478b6c..2d492d341ebba 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-unstable-2.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-unstable-2.rs @@ -11,8 +11,6 @@ // force-host // no-prefer-dynamic -#![feature(proc_macro)] -#![feature(proc_macro_lib)] #![crate_type = "proc-macro"] extern crate proc_macro; diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-unstable.rs b/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-unstable.rs index 1187b5102e23f..a7b5d1e3e54cf 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-unstable.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-unstable.rs @@ -11,8 +11,6 @@ // force-host // no-prefer-dynamic -#![feature(proc_macro)] -#![feature(proc_macro_lib)] #![crate_type = "proc-macro"] extern crate proc_macro; diff --git a/src/test/compile-fail-fulldeps/proc-macro/define-two.rs b/src/test/compile-fail-fulldeps/proc-macro/define-two.rs index bdb3c09c4d723..87b32096d7b01 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/define-two.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/define-two.rs @@ -11,7 +11,6 @@ // no-prefer-dynamic #![crate_type = "proc-macro"] -#![feature(proc_macro, proc_macro_lib)] extern crate proc_macro; diff --git a/src/test/compile-fail-fulldeps/proc-macro/derive-bad.rs b/src/test/compile-fail-fulldeps/proc-macro/derive-bad.rs index 4cc6b9f984c94..0e4ac9fe1eaf5 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/derive-bad.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/derive-bad.rs @@ -10,8 +10,6 @@ // aux-build:derive-bad.rs -#![feature(proc_macro)] - #[macro_use] extern crate derive_bad; diff --git a/src/test/compile-fail-fulldeps/proc-macro/derive-still-gated.rs b/src/test/compile-fail-fulldeps/proc-macro/derive-still-gated.rs index eb0bb00be9175..f36236c53562d 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/derive-still-gated.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/derive-still-gated.rs @@ -10,7 +10,6 @@ // aux-build:derive-a.rs -#![feature(proc_macro)] #![allow(warnings)] #[macro_use] diff --git a/src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable-2.rs b/src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable-2.rs index 4f4ed90f8fca2..e4fcbb117a505 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable-2.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable-2.rs @@ -10,7 +10,6 @@ // aux-build:derive-unstable-2.rs -#![feature(proc_macro)] #![allow(warnings)] #[macro_use] diff --git a/src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable.rs b/src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable.rs index 84ac776a765a2..836e336fc22f0 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable.rs @@ -10,7 +10,6 @@ // aux-build:derive-unstable.rs -#![feature(proc_macro)] #![allow(warnings)] #[macro_use] diff --git a/src/test/compile-fail-fulldeps/proc-macro/export-macro.rs b/src/test/compile-fail-fulldeps/proc-macro/export-macro.rs index 48b73e7333185..477039bd7a2fa 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/export-macro.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/export-macro.rs @@ -11,7 +11,6 @@ // error-pattern: cannot export macro_rules! macros from a `proc-macro` crate #![crate_type = "proc-macro"] -#![feature(proc_macro)] #[macro_export] macro_rules! foo { diff --git a/src/test/compile-fail-fulldeps/proc-macro/illegal-proc-macro-derive-use.rs b/src/test/compile-fail-fulldeps/proc-macro/illegal-proc-macro-derive-use.rs index 70c8db5ddd2ec..f37980c5e0f54 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/illegal-proc-macro-derive-use.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/illegal-proc-macro-derive-use.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(proc_macro, proc_macro_lib)] - extern crate proc_macro; #[proc_macro_derive(Foo)] diff --git a/src/test/compile-fail-fulldeps/proc-macro/import.rs b/src/test/compile-fail-fulldeps/proc-macro/import.rs index 8f907183cc39b..fae2439344fb0 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/import.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/import.rs @@ -10,7 +10,6 @@ // aux-build:derive-a.rs -#![feature(proc_macro)] #![allow(warnings)] #[macro_use] diff --git a/src/test/compile-fail-fulldeps/proc-macro/issue-37788.rs b/src/test/compile-fail-fulldeps/proc-macro/issue-37788.rs index 6d1030026dba2..691c280580122 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/issue-37788.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/issue-37788.rs @@ -10,8 +10,6 @@ // aux-build:derive-a-b.rs -#![feature(proc_macro)] - #[macro_use] extern crate derive_a_b; diff --git a/src/test/compile-fail-fulldeps/proc-macro/item-error.rs b/src/test/compile-fail-fulldeps/proc-macro/item-error.rs index 2a68accf91f71..4133e75e3a62d 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/item-error.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/item-error.rs @@ -10,7 +10,6 @@ // aux-build:derive-b.rs -#![feature(proc_macro)] #![allow(warnings)] #[macro_use] diff --git a/src/test/compile-fail-fulldeps/proc-macro/load-panic.rs b/src/test/compile-fail-fulldeps/proc-macro/load-panic.rs index 39c27e82fa5b3..f9906b650fb87 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/load-panic.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/load-panic.rs @@ -10,8 +10,6 @@ // aux-build:derive-panic.rs -#![feature(proc_macro)] - #[macro_use] extern crate derive_panic; diff --git a/src/test/compile-fail-fulldeps/proc-macro/proc-macro-attributes.rs b/src/test/compile-fail-fulldeps/proc-macro/proc-macro-attributes.rs index 651a277d4abd5..4ad1cf79d61c6 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/proc-macro-attributes.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/proc-macro-attributes.rs @@ -10,7 +10,6 @@ // aux-build:derive-b.rs -#![feature(proc_macro)] #![allow(warnings)] #[macro_use] diff --git a/src/test/compile-fail-fulldeps/proc-macro/pub-at-crate-root.rs b/src/test/compile-fail-fulldeps/proc-macro/pub-at-crate-root.rs index 2bf25892c44d2..238dde5160cd4 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/pub-at-crate-root.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/pub-at-crate-root.rs @@ -9,7 +9,6 @@ // except according to those terms. #![crate_type = "proc-macro"] -#![feature(proc_macro, proc_macro_lib)] extern crate proc_macro; diff --git a/src/test/compile-fail-fulldeps/proc-macro/shadow-builtin.rs b/src/test/compile-fail-fulldeps/proc-macro/shadow-builtin.rs index 1bcd4b15eb863..8c5affb7b5ab3 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/shadow-builtin.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/shadow-builtin.rs @@ -9,7 +9,6 @@ // except according to those terms. #![crate_type = "proc-macro"] -#![feature(proc_macro, proc_macro_lib)] extern crate proc_macro; diff --git a/src/test/compile-fail-fulldeps/proc-macro/shadow.rs b/src/test/compile-fail-fulldeps/proc-macro/shadow.rs index dc828fbf7d160..d76cf003ed14d 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/shadow.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/shadow.rs @@ -10,8 +10,6 @@ // aux-build:derive-a.rs -#![feature(proc_macro)] - #[macro_use] extern crate derive_a; #[macro_use] diff --git a/src/test/compile-fail-fulldeps/proc-macro/signature.rs b/src/test/compile-fail-fulldeps/proc-macro/signature.rs index b7df9489dff30..6d6b5a23e941f 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/signature.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/signature.rs @@ -9,7 +9,6 @@ // except according to those terms. #![crate_type = "proc-macro"] -#![feature(proc_macro, proc_macro_lib)] #![allow(warnings)] extern crate proc_macro; diff --git a/src/test/compile-fail/issue-27942.rs b/src/test/compile-fail/issue-27942.rs new file mode 100644 index 0000000000000..b8552794eb5ae --- /dev/null +++ b/src/test/compile-fail/issue-27942.rs @@ -0,0 +1,31 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +pub trait Resources<'a> {} + +pub trait Buffer<'a, R: Resources<'a>> { + fn select(&self) -> BufferViewHandle; + //~^ ERROR mismatched types + //~| lifetime mismatch + //~| NOTE expected type `Resources<'_>` + //~| NOTE found type `Resources<'a>` + //~| NOTE the lifetime 'a as defined on the method body at 14:4... + //~| NOTE ...does not necessarily outlive the anonymous lifetime #1 defined on the method body + //~| ERROR mismatched types + //~| lifetime mismatch + //~| NOTE expected type `Resources<'_>` + //~| NOTE found type `Resources<'a>` + //~| NOTE the anonymous lifetime #1 defined on the method body at 14:4... + //~| NOTE ...does not necessarily outlive the lifetime 'a as defined on the method body +} + +pub struct BufferViewHandle<'a, R: 'a+Resources<'a>>(&'a R); + +fn main() {} diff --git a/src/test/compile-fail/issue-37884.rs b/src/test/compile-fail/issue-37884.rs new file mode 100644 index 0000000000000..a73b1dbe34cff --- /dev/null +++ b/src/test/compile-fail/issue-37884.rs @@ -0,0 +1,27 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +struct RepeatMut<'a, T>(T, &'a ()); + +impl<'a, T: 'a> Iterator for RepeatMut<'a, T> { + type Item = &'a mut T; + fn next(&'a mut self) -> Option + //~^ ERROR method not compatible with trait + //~| lifetime mismatch + //~| NOTE expected type `fn(&mut RepeatMut<'a, T>) -> std::option::Option<&mut T>` + //~| NOTE found type `fn(&'a mut RepeatMut<'a, T>) -> std::option::Option<&mut T>` + { + //~^ NOTE the anonymous lifetime #1 defined on the body + //~| NOTE ...does not necessarily outlive the lifetime 'a as defined on the body + Some(&mut self.0) + } +} + +fn main() {} diff --git a/src/test/compile-fail/issue-38412.rs b/src/test/compile-fail/issue-38412.rs new file mode 100644 index 0000000000000..00305eb2bc04b --- /dev/null +++ b/src/test/compile-fail/issue-38412.rs @@ -0,0 +1,20 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + let Box(a) = loop { }; + //~^ ERROR field `0` of struct `std::boxed::Box` is private + + // (The below is a trick to allow compiler to infer a type for + // variable `a` without attempting to ascribe a type to the + // pattern or otherwise attempting to name the Box type, which + // would run afoul of issue #22207) + let _b: *mut i32 = *a; +} diff --git a/src/test/compile-fail-fulldeps/proc-macro/feature-gate-2.rs b/src/test/parse-fail/where_with_bound.rs similarity index 75% rename from src/test/compile-fail-fulldeps/proc-macro/feature-gate-2.rs rename to src/test/parse-fail/where_with_bound.rs index 9c4053266f471..cb57500df797e 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/feature-gate-2.rs +++ b/src/test/parse-fail/where_with_bound.rs @@ -8,6 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -extern crate proc_macro; //~ ERROR: use of unstable library feature +// compile-flags: -Z parse-only + +fn foo() where ::Item: ToString, T: Iterator { } + //~^ syntax `where` is reserved for future use fn main() {} diff --git a/src/test/run-make/issue-37839/a.rs b/src/test/run-make/issue-37839/a.rs index 3dff45388c75b..052317438c2f7 100644 --- a/src/test/run-make/issue-37839/a.rs +++ b/src/test/run-make/issue-37839/a.rs @@ -8,6 +8,5 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(proc_macro)] #![allow(unused)] #![crate_type = "proc-macro"] diff --git a/src/test/run-make/issue-37893/a.rs b/src/test/run-make/issue-37893/a.rs index 3dff45388c75b..052317438c2f7 100644 --- a/src/test/run-make/issue-37893/a.rs +++ b/src/test/run-make/issue-37893/a.rs @@ -8,6 +8,5 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(proc_macro)] #![allow(unused)] #![crate_type = "proc-macro"] diff --git a/src/test/run-make/issue-38237/Makefile b/src/test/run-make/issue-38237/Makefile new file mode 100644 index 0000000000000..0a681401b1afb --- /dev/null +++ b/src/test/run-make/issue-38237/Makefile @@ -0,0 +1,5 @@ +-include ../tools.mk + +all: + $(RUSTC) foo.rs; $(RUSTC) bar.rs + $(RUSTDOC) baz.rs -L $(TMPDIR) -o $(TMPDIR) diff --git a/src/test/compile-fail-fulldeps/proc-macro/feature-gate-5.rs b/src/test/run-make/issue-38237/bar.rs similarity index 86% rename from src/test/compile-fail-fulldeps/proc-macro/feature-gate-5.rs rename to src/test/run-make/issue-38237/bar.rs index 672579ce8f14b..794e08c2fe338 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/feature-gate-5.rs +++ b/src/test/run-make/issue-38237/bar.rs @@ -8,5 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[cfg(proc_macro)] //~ ERROR: experimental and subject to change -fn foo() {} +#![crate_type = "lib"] + +#[derive(Debug)] +pub struct S; diff --git a/src/test/run-make/issue-38237/baz.rs b/src/test/run-make/issue-38237/baz.rs new file mode 100644 index 0000000000000..c2a2c89db016f --- /dev/null +++ b/src/test/run-make/issue-38237/baz.rs @@ -0,0 +1,18 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +extern crate foo; +extern crate bar; + +pub struct Bar; +impl ::std::ops::Deref for Bar { + type Target = bar::S; + fn deref(&self) -> &Self::Target { unimplemented!() } +} diff --git a/src/test/run-make/issue-38237/foo.rs b/src/test/run-make/issue-38237/foo.rs new file mode 100644 index 0000000000000..6fb315731de17 --- /dev/null +++ b/src/test/run-make/issue-38237/foo.rs @@ -0,0 +1,19 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +#[proc_macro_derive(A)] +pub fn derive(ts: proc_macro::TokenStream) -> proc_macro::TokenStream { ts } + +#[derive(Debug)] +struct S; diff --git a/src/test/run-make/rustc-macro-dep-files/bar.rs b/src/test/run-make/rustc-macro-dep-files/bar.rs index a2db98049d287..03330c3d1700d 100644 --- a/src/test/run-make/rustc-macro-dep-files/bar.rs +++ b/src/test/run-make/rustc-macro-dep-files/bar.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(proc_macro)] - #[macro_use] extern crate foo; diff --git a/src/test/run-make/rustc-macro-dep-files/foo.rs b/src/test/run-make/rustc-macro-dep-files/foo.rs index bd9e9158c5052..2f2524f6ef115 100644 --- a/src/test/run-make/rustc-macro-dep-files/foo.rs +++ b/src/test/run-make/rustc-macro-dep-files/foo.rs @@ -9,8 +9,6 @@ // except according to those terms. #![crate_type = "proc-macro"] -#![feature(proc_macro)] -#![feature(proc_macro_lib)] extern crate proc_macro; diff --git a/src/test/run-pass-fulldeps/proc-macro/add-impl.rs b/src/test/run-pass-fulldeps/proc-macro/add-impl.rs index e82282f3d8c58..7ea7ceafc2876 100644 --- a/src/test/run-pass-fulldeps/proc-macro/add-impl.rs +++ b/src/test/run-pass-fulldeps/proc-macro/add-impl.rs @@ -10,8 +10,6 @@ // aux-build:add-impl.rs -#![feature(proc_macro)] - #[macro_use] extern crate add_impl; diff --git a/src/test/run-pass-fulldeps/proc-macro/append-impl.rs b/src/test/run-pass-fulldeps/proc-macro/append-impl.rs index f062111df9daf..591f3331d28c0 100644 --- a/src/test/run-pass-fulldeps/proc-macro/append-impl.rs +++ b/src/test/run-pass-fulldeps/proc-macro/append-impl.rs @@ -10,7 +10,6 @@ // aux-build:append-impl.rs -#![feature(proc_macro)] #![allow(warnings)] #[macro_use] diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/add-impl.rs b/src/test/run-pass-fulldeps/proc-macro/auxiliary/add-impl.rs index 1d34049db249f..3959eccd81e35 100644 --- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/add-impl.rs +++ b/src/test/run-pass-fulldeps/proc-macro/auxiliary/add-impl.rs @@ -11,8 +11,6 @@ // no-prefer-dynamic #![crate_type = "proc-macro"] -#![feature(proc_macro)] -#![feature(proc_macro_lib)] extern crate proc_macro; diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/append-impl.rs b/src/test/run-pass-fulldeps/proc-macro/auxiliary/append-impl.rs index 7260bc4a5e7bb..fdce709e5bad6 100644 --- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/append-impl.rs +++ b/src/test/run-pass-fulldeps/proc-macro/auxiliary/append-impl.rs @@ -11,8 +11,6 @@ // force-host // no-prefer-dynamic -#![feature(proc_macro)] -#![feature(proc_macro_lib)] #![crate_type = "proc-macro"] extern crate proc_macro; diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-a.rs b/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-a.rs index eaada5542274c..a253c6224aa68 100644 --- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-a.rs +++ b/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-a.rs @@ -11,8 +11,6 @@ // no-prefer-dynamic #![crate_type = "proc-macro"] -#![feature(proc_macro)] -#![feature(proc_macro_lib)] extern crate proc_macro; diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-atob.rs b/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-atob.rs index a942adc4c8020..713fb7d10f2fd 100644 --- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-atob.rs +++ b/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-atob.rs @@ -11,8 +11,6 @@ // no-prefer-dynamic #![crate_type = "proc-macro"] -#![feature(proc_macro)] -#![feature(proc_macro_lib)] extern crate proc_macro; diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-b.rs b/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-b.rs index a02b798c8023e..c18cda895325b 100644 --- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-b.rs +++ b/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-b.rs @@ -11,8 +11,6 @@ // no-prefer-dynamic #![crate_type = "proc-macro"] -#![feature(proc_macro)] -#![feature(proc_macro_lib)] extern crate proc_macro; diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-ctod.rs b/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-ctod.rs index 50f1a390b2939..19caafd17b5f3 100644 --- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-ctod.rs +++ b/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-ctod.rs @@ -11,8 +11,6 @@ // no-prefer-dynamic #![crate_type = "proc-macro"] -#![feature(proc_macro)] -#![feature(proc_macro_lib)] extern crate proc_macro; diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-nothing.rs b/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-nothing.rs new file mode 100644 index 0000000000000..cfe428bf5f323 --- /dev/null +++ b/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-nothing.rs @@ -0,0 +1,22 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_derive(Nothing)] +pub fn nothing(input: TokenStream) -> TokenStream { + "".parse().unwrap() +} diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-reexport.rs b/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-reexport.rs index 05a6cbec69c5a..fae2d27ab6b75 100644 --- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-reexport.rs +++ b/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-reexport.rs @@ -10,7 +10,7 @@ // ignore-test -#![feature(macro_reexport, proc_macro)] +#![feature(macro_reexport)] #[macro_reexport(A)] extern crate derive_a; diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-same-struct.rs b/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-same-struct.rs index bc8a0d575913b..a2c25ae50e8ec 100644 --- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-same-struct.rs +++ b/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-same-struct.rs @@ -11,9 +11,6 @@ // no-prefer-dynamic // compile-flags:--crate-type proc-macro -#![feature(proc_macro)] -#![feature(proc_macro_lib)] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/double.rs b/src/test/run-pass-fulldeps/proc-macro/auxiliary/double.rs index 969ed91f595e6..f4404b737f952 100644 --- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/double.rs +++ b/src/test/run-pass-fulldeps/proc-macro/auxiliary/double.rs @@ -11,8 +11,6 @@ // no-prefer-dynamic #![crate_type = "proc-macro"] -#![feature(proc_macro)] -#![feature(proc_macro_lib)] extern crate proc_macro; diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/expand-with-a-macro.rs b/src/test/run-pass-fulldeps/proc-macro/auxiliary/expand-with-a-macro.rs index 50eaf035962f1..e6831b6bfdf65 100644 --- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/expand-with-a-macro.rs +++ b/src/test/run-pass-fulldeps/proc-macro/auxiliary/expand-with-a-macro.rs @@ -11,8 +11,6 @@ // no-prefer-dynamic #![crate_type = "proc-macro"] -#![feature(proc_macro)] -#![feature(proc_macro_lib)] #![deny(warnings)] extern crate proc_macro; diff --git a/src/test/run-pass-fulldeps/proc-macro/crate-var.rs b/src/test/run-pass-fulldeps/proc-macro/crate-var.rs index d19b49ab18c07..ba1417ecb56e4 100644 --- a/src/test/run-pass-fulldeps/proc-macro/crate-var.rs +++ b/src/test/run-pass-fulldeps/proc-macro/crate-var.rs @@ -10,7 +10,6 @@ // aux-build:double.rs -#![feature(proc_macro)] #![allow(unused)] #[macro_use] diff --git a/src/test/run-pass-fulldeps/proc-macro/derive-b.rs b/src/test/run-pass-fulldeps/proc-macro/derive-b.rs index f5bb93f012490..f1e1626ddf8ca 100644 --- a/src/test/run-pass-fulldeps/proc-macro/derive-b.rs +++ b/src/test/run-pass-fulldeps/proc-macro/derive-b.rs @@ -11,8 +11,6 @@ // aux-build:derive-b.rs // ignore-stage1 -#![feature(proc_macro)] - #[macro_use] extern crate derive_b; diff --git a/src/test/run-pass-fulldeps/proc-macro/derive-same-struct.rs b/src/test/run-pass-fulldeps/proc-macro/derive-same-struct.rs index 608f86bca5768..ce3ba60b0ecf4 100644 --- a/src/test/run-pass-fulldeps/proc-macro/derive-same-struct.rs +++ b/src/test/run-pass-fulldeps/proc-macro/derive-same-struct.rs @@ -10,8 +10,6 @@ // aux-build:derive-same-struct.rs -#![feature(proc_macro)] - #[macro_use] extern crate derive_same_struct; diff --git a/src/test/run-pass-fulldeps/proc-macro/derive-test.rs b/src/test/run-pass-fulldeps/proc-macro/derive-test.rs index 2f44515a873de..a07e8b6cd7e64 100644 --- a/src/test/run-pass-fulldeps/proc-macro/derive-test.rs +++ b/src/test/run-pass-fulldeps/proc-macro/derive-test.rs @@ -12,8 +12,6 @@ // compile-flags: --test #![crate_type = "proc-macro"] -#![feature(proc_macro)] -#![feature(proc_macro, proc_macro_lib)] extern crate proc_macro; diff --git a/src/test/run-pass-fulldeps/proc-macro/expand-with-a-macro.rs b/src/test/run-pass-fulldeps/proc-macro/expand-with-a-macro.rs index 16f3535adae3b..4ccd4615fb609 100644 --- a/src/test/run-pass-fulldeps/proc-macro/expand-with-a-macro.rs +++ b/src/test/run-pass-fulldeps/proc-macro/expand-with-a-macro.rs @@ -11,7 +11,6 @@ // aux-build:expand-with-a-macro.rs // ignore-stage1 -#![feature(proc_macro)] #![deny(warnings)] #[macro_use] diff --git a/src/test/run-pass-fulldeps/proc-macro/load-two.rs b/src/test/run-pass-fulldeps/proc-macro/load-two.rs index 431c8c5902749..d15a83a2cbe43 100644 --- a/src/test/run-pass-fulldeps/proc-macro/load-two.rs +++ b/src/test/run-pass-fulldeps/proc-macro/load-two.rs @@ -11,8 +11,6 @@ // aux-build:derive-atob.rs // aux-build:derive-ctod.rs -#![feature(proc_macro)] - #[macro_use] extern crate derive_atob; #[macro_use] diff --git a/src/test/run-pass-fulldeps/proc-macro/smoke.rs b/src/test/run-pass-fulldeps/proc-macro/smoke.rs index cd7edb726447b..54d651df1f9af 100644 --- a/src/test/run-pass-fulldeps/proc-macro/smoke.rs +++ b/src/test/run-pass-fulldeps/proc-macro/smoke.rs @@ -11,8 +11,6 @@ // aux-build:derive-a.rs // ignore-stage1 -#![feature(proc_macro)] - #[macro_use] extern crate derive_a; diff --git a/src/test/run-pass-fulldeps/proc-macro/struct-field-macro.rs b/src/test/run-pass-fulldeps/proc-macro/struct-field-macro.rs new file mode 100644 index 0000000000000..c9056e08d4426 --- /dev/null +++ b/src/test/run-pass-fulldeps/proc-macro/struct-field-macro.rs @@ -0,0 +1,26 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:derive-nothing.rs +// ignore-stage1 + +#[macro_use] +extern crate derive_nothing; + +macro_rules! int { + () => { i32 } +} + +#[derive(Nothing)] +struct S { + x: int!(), +} + +fn main() {} diff --git a/src/test/run-pass-fulldeps/proc-macro/use-reexport.rs b/src/test/run-pass-fulldeps/proc-macro/use-reexport.rs index 7f09d8faebbb5..f0a1bfe652857 100644 --- a/src/test/run-pass-fulldeps/proc-macro/use-reexport.rs +++ b/src/test/run-pass-fulldeps/proc-macro/use-reexport.rs @@ -11,8 +11,6 @@ // aux-build:derive-a.rs // aux-build:derive-reexport.rs -#![feature(proc_macro)] - #[macro_use] extern crate derive_reexport; diff --git a/src/test/compile-fail-fulldeps/proc-macro/feature-gate-1.rs b/src/test/run-pass/auxiliary/issue_38715.rs similarity index 82% rename from src/test/compile-fail-fulldeps/proc-macro/feature-gate-1.rs rename to src/test/run-pass/auxiliary/issue_38715.rs index f5618fc6425e2..cad3996eadbfb 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/feature-gate-1.rs +++ b/src/test/run-pass/auxiliary/issue_38715.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: the `proc-macro` crate type is experimental +#[macro_export] +macro_rules! foo { ($i:ident) => {} } -#![crate_type = "proc-macro"] +#[macro_export] +macro_rules! foo { () => {} } diff --git a/src/test/compile-fail-fulldeps/proc-macro/feature-gate-3.rs b/src/test/run-pass/issue-37991.rs similarity index 79% rename from src/test/compile-fail-fulldeps/proc-macro/feature-gate-3.rs rename to src/test/run-pass/issue-37991.rs index bb6b575962250..cacc653871ad5 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/feature-gate-3.rs +++ b/src/test/run-pass/issue-37991.rs @@ -8,8 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![crate_type = "proc-macro"] +#![feature(const_fn)] -#[proc_macro_derive(Foo)] //~ ERROR: is an experimental feature -pub fn foo() { +const fn foo() -> i64 { + 3 +} + +fn main() { + let val = &(foo() % 2); + assert_eq!(*val, 1); } diff --git a/src/test/compile-fail-fulldeps/proc-macro/feature-gate-4.rs b/src/test/run-pass/issue-38715.rs similarity index 73% rename from src/test/compile-fail-fulldeps/proc-macro/feature-gate-4.rs rename to src/test/run-pass/issue-38715.rs index 6a8fcdf4ab782..054785e62b8ea 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/feature-gate-4.rs +++ b/src/test/run-pass/issue-38715.rs @@ -8,10 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// aux-build:derive-a.rs +// aux-build:issue_38715.rs + +// Test that `#[macro_export] macro_rules!` shadow earlier `#[macro_export] macro_rules!` #[macro_use] -extern crate derive_a; +extern crate issue_38715; -#[derive(A)] //~ ERROR custom derive macros are experimentally supported -struct S; +fn main() { + foo!(); +} diff --git a/src/test/rustdoc/rustc-macro-crate.rs b/src/test/rustdoc/rustc-macro-crate.rs index fe80a90955045..dc28732b55ee2 100644 --- a/src/test/rustdoc/rustc-macro-crate.rs +++ b/src/test/rustdoc/rustc-macro-crate.rs @@ -10,8 +10,6 @@ // no-prefer-dynamic -#![feature(proc_macro)] -#![feature(proc_macro_lib)] #![crate_type = "proc-macro"] extern crate proc_macro;