From cb40c3cdd6dff1430bfde42b00ac3f81a3afc0fd Mon Sep 17 00:00:00 2001 From: Lukas Kalbertodt Date: Tue, 24 Jul 2018 23:45:24 +0200 Subject: [PATCH 01/13] Guard unstable `proc_macro` features behind "nightly` feature This is most of the work for #13. This crate now compiles in two modes: With "nightly" feature enable, `proc_macro_diagnostic` and `proc_macro_span` are enable to improve our error messages. Without the "nightly" feature, we don't use those unstable features and instead build a workaround for the lack of unstable features (something like a poly fill). Most of the workaround can be found in the `diag` module. The crate doesn't compile with the stable compiler quite yet. There are still three feature gates activated. But those three features will be stabilized for Rust 2018 and they are easy to remove by only rewriting a few lines in the whole crate. --- Cargo.toml | 6 +- src/analyze.rs | 23 +++++-- src/diag.rs | 171 ++++++++++++++++++++++++++++++++++++++++++++++++- src/gen.rs | 28 ++++---- src/lib.rs | 18 ++++-- src/proxy.rs | 10 +-- src/spanned.rs | 20 ++++-- 7 files changed, 237 insertions(+), 39 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index e103c71..b8c901b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,11 +17,15 @@ autotests = true [badges] travis-ci = { repository = "KodrAus/auto_impl" } + [lib] proc-macro = true +[features] +nightly = ["proc-macro2/nightly"] + [dependencies] -proc-macro2 = { version = "0.4.6", features = ["nightly"] } +proc-macro2 = { version = "0.4.6" } quote = "0.6.3" syn = { version = "0.14.4", features = ["full"] } diff --git a/src/analyze.rs b/src/analyze.rs index 32423aa..39e4dcb 100644 --- a/src/analyze.rs +++ b/src/analyze.rs @@ -1,6 +1,5 @@ use std::collections::HashSet; -use proc_macro::Span; use proc_macro2::Span as Span2; use syn::{ Ident, ItemTrait, Lifetime, Block, @@ -71,11 +70,6 @@ pub(crate) fn find_suitable_param_names(trait_def: &ItemTrait) -> (Ident, Lifeti visit_item_trait(&mut visitor, trait_def); - fn param_span() -> Span2 { - // TODO: change for stable builds - Span::def_site().into() - } - fn char_to_ident(c: u8) -> Ident { let arr = [c]; let s = ::std::str::from_utf8(&arr).unwrap(); @@ -101,3 +95,20 @@ pub(crate) fn find_suitable_param_names(trait_def: &ItemTrait) -> (Ident, Lifeti (ty_name, lt) } + +/// On nightly, we use `def_site` hygiene which puts our names into another +/// universe than the names of the user. This is not strictly required as our +/// name is already pretty much guaranteed to not conflict with another name, +/// but this is cleaner and just the correct thing to do. +#[cfg(feature = "nightly")] +fn param_span() -> Span2 { + ::proc_macro::Span::def_site().into() +} + +/// On stable, we use `call_site()` hygiene. That means that our names could +/// theoretically collide with names of the user. But we made sure this doesn't +/// happen. +#[cfg(not(feature = "nightly"))] +fn param_span() -> Span2 { + Span2::call_site() +} diff --git a/src/diag.rs b/src/diag.rs index 57d8395..e43b0dc 100644 --- a/src/diag.rs +++ b/src/diag.rs @@ -1,10 +1,26 @@ -use proc_macro::{Diagnostic, Span}; +//! This module has two purposes: +//! +//! 1. Provide the convenienve method `emit_with_attr_note` and add it via +//! extension trait to `Diagnostic`. +//! +//! 2. Make `Diagnostic` work on stable by providing an own `Diagnostic` type +//! that prints the messages in a less-nice way. That way, other modules +//! don't have to worry about the stable/nightly distinction. `SpanExt` is +//! an extension trait that adds the `err()` method to the `Span` type. That +//! method works exactly like `Span::error()` but returns "our" +//! `Diagnostic`. Other modules can simply `use diag::SpanExt` and use +//! `.err()` on spans. +//! +use proc_macro::{Span, TokenStream}; + +/// Extension trait that adds a convenience method to `Diagnostic`. This is +/// simply to reduce duplicate code in other modules. pub trait DiagnosticExt { /// Helper function to add a note to the diagnostic (with a span pointing - /// to the `auto_impl` attribute) and emit the error. Additionally, - /// `Err(())` is always returned. + /// to the `auto_impl` attribute) and emit the error. An `Err(())` is + /// always returned. fn emit_with_attr_note(self) -> Result; } @@ -16,3 +32,152 @@ impl DiagnosticExt for Diagnostic { Err(()) } } + + +// ============================================================== +// Logic for stable/nightly mode starts here. +// +// First, we define a `Diagnostic` type. If we compile with the `nightly` +// feature, it's simple a typedef to `proc_macro::Diagnostic`. If we don't +// compile in nightly mode, we can't use that type, since it's still unstable. +// So in that case, we define our own type that tries to mimic the original +// `Diagnostic`. + +#[cfg(feature = "nightly")] +pub(crate) type Diagnostic = ::proc_macro::Diagnostic; + +#[cfg(not(feature = "nightly"))] +pub(crate) struct Diagnostic { + span: Span, + msg: String, +} + +// We provide the methods that `proc_macro::Diagnostic` also has here. Or +// rather: we only implement the subset that this crate actually uses. +// +// When we're not on the nightly compiler, we can't show a nice error. So how +// do we show the error then? The idea is to generate a token stream that +// contains `compile_error!(msg)` macro invocations. This macro is part of the +// standard library and emits `msg` as error. This is fairly useful for our +// case. However, a big limitation is that we can only emit one message. So in +// order to also show notes later added to the `Diagnostic`, we simply add +// "note: {the_note}" to the error string. This is crude and ugly, but it +// works. +// +// What about spans? Good question! Spans are important, but without a proper +// `Diagnostic` API, we can't properly support spans on errors and notes. The +// compiler will point to the `compile_error!()` invocation we generate. But we +// can use another hack to improve the situation slightly! On the token stream +// (containing `compile_error!()`) we generate, we can modify the spans of the +// individual token trees. If we set all spans to the span the error originates +// from, the compiler thinks that the `compile_error!()` code snippet has the +// span from the actual error source. That means that the error message will +// point to the actual error source! +// +// There is only a small problem: this only works when we get a proper span. +// Sadly, on stable, we can only get correct spans for individual token trees, +// not even token streams. We can't combine spans. As a consequence, spans are +// only correct if they come directly from a `TokenTree`. In general, errors +// coming from the `proxy` module have proper spans while errors from other +// modules don't have proper spans (on stable!). "Not proper" means that the +// span is simply `call_site()` -- it points to the `#[auto_impl()]` attribute. +// +// It could be worse, but it's simply true: for good error messages, nightly is +// required. +#[cfg(not(feature = "nightly"))] +impl Diagnostic { + pub(crate) fn note(mut self, msg: impl Into) -> Diagnostic { + self.msg += &format!("\n\nnote: {}", msg.into()); + self + } + + pub(crate) fn span_note(mut self, _: Span, msg: impl Into) -> Diagnostic { + // With out span fake method, we can only handle one span. We take the + // one of the original error and ignore additional ones. + self.msg += &format!("\n\nnote: {}", msg.into()); + self + } + + pub(crate) fn emit(self) { + // Create the error token stream that contains the `compile_error!()` + // invocation. + let msg = &self.msg; + let tokens = TokenStream::from(quote! { + compile_error!(#msg); + }); + + // Set the span of each token tree to the span the error originates + // from. + let tokens = tokens.into_iter() + .map(|mut tt| { + tt.set_span(self.span); + tt + }) + .collect(); + + // Push it to the global list of error streams + ERROR_TOKENS.with(|toks| { + toks.borrow_mut().push(tokens) + }); + } +} + +// Another problem with our `Diagnostic` hack on stable: the real +// `Diagnostic::emit()` doesn't return anything and modifies global state (it +// prints directly to stdout). We can't simply print! In our case it would be +// correct to pass a `TokenStream` ass the `Err()` variant of a result back up +// the stack and display it at the end. Two problems with that approach: +// +// - That's not how this application was build. Instead, it's build with the +// future `proc_macro` API in mind. And we wouldn't want to change everything +// back once it's stable. +// - On nightly, we don't want to pass TokenStreams up the stack. We can't have +// a completely different structure on nightly vs. on stable. +// +// Thus, we just "simulate" the original `emit()` by also modifying global +// state. We simply have a list of error token streams. This list is added to +// the final token stream at the end (in case of an error). It's not a very +// nice solution, but it's only a hack while stable doesn't offer something +// proper. +#[cfg(not(feature = "nightly"))] +use std::cell::RefCell; + +#[cfg(not(feature = "nightly"))] +thread_local! { + static ERROR_TOKENS: RefCell> = RefCell::new(vec![]); +} + +/// On stable, we just copy the error token streams from the global variable. +#[cfg(not(feature = "nightly"))] +pub(crate) fn error_tokens() -> TokenStream { + ERROR_TOKENS.with(|toks| toks.borrow().iter().cloned().collect()) +} + +/// On nightly, we don't use and don't have a strange global variable. Instead, +/// we just return an empty token stream. That's not a problem because all of +/// our errors were already printed. +#[cfg(feature = "nightly")] +pub(crate) fn error_tokens() -> TokenStream { + TokenStream::new() +} + +/// Extension trait to add the `err()` method to `Span`. This makes it easy to +/// start a `Diagnostic` from a span. +pub(crate) trait SpanExt { + fn err(self, msg: impl Into) -> Diagnostic; +} + +impl SpanExt for Span { + #[cfg(feature = "nightly")] + fn err(self, msg: impl Into) -> Diagnostic { + Diagnostic::spanned(self, ::proc_macro::Level::Error, msg) + } + + #[cfg(not(feature = "nightly"))] + fn err(self, msg: impl Into) -> Diagnostic { + Diagnostic { + span: self, + msg: msg.into(), + } + } +} diff --git a/src/gen.rs b/src/gen.rs index d3529bf..599a1f0 100644 --- a/src/gen.rs +++ b/src/gen.rs @@ -8,7 +8,7 @@ use syn::{ use crate::{ analyze::{find_suitable_param_names}, - diag::DiagnosticExt, + diag::{DiagnosticExt, SpanExt}, proxy::ProxyType, spanned::Spanned }; @@ -141,7 +141,7 @@ fn gen_fn_type_for_trait( // If this requirement is not satisfied, we emit an error. if method.is_none() || trait_def.items.len() > 1 { return trait_def.span() - .error( + .err( "this trait cannot be auto-implemented for Fn-traits (only traits with exactly \ one method and no other items are allowed)" ) @@ -156,7 +156,7 @@ fn gen_fn_type_for_trait( // Check for forbidden modifier of the method if let Some(const_token) = sig.constness { return const_token.span() - .error(format!( + .err(format!( "the trait '{}' cannot be auto-implemented for Fn-traits: const methods are not \ allowed", trait_def.ident, @@ -166,7 +166,7 @@ fn gen_fn_type_for_trait( if let Some(unsafe_token) = &sig.unsafety { return unsafe_token.span() - .error(format!( + .err(format!( "the trait '{}' cannot be auto-implemented for Fn-traits: unsafe methods are not \ allowed", trait_def.ident, @@ -176,7 +176,7 @@ fn gen_fn_type_for_trait( if let Some(abi_token) = &sig.abi { return abi_token.span() - .error(format!( + .err(format!( "the trait '{}' cannot be implemented for Fn-traits: custom ABIs are not allowed", trait_def.ident, )) @@ -221,7 +221,7 @@ fn gen_fn_type_for_trait( allowed, ); - return method.sig.span().error(msg).emit_with_attr_note(); + return method.sig.span().err(msg).emit_with_attr_note(); } // ======================================================================= @@ -311,7 +311,7 @@ fn gen_items( // if it adds additional items to the trait. Thus, we have to // give up. mac.span() - .error( + .err( "traits with macro invocations in their bodies are not \ supported by auto_impl" ) @@ -321,7 +321,7 @@ fn gen_items( // I don't quite know when this happens, but it's better to // notify the user with a nice error instead of panicking. v.span() - .error("unexpected 'verbatim'-item (auto-impl doesn't know how to handle it)") + .err("unexpected 'verbatim'-item (auto-impl doesn't know how to handle it)") .emit_with_attr_note() } } @@ -342,7 +342,7 @@ fn gen_const_item( // A trait with associated consts cannot be implemented for Fn* types. if proxy_type.is_fn() { return item.span() - .error(format!( + .err(format!( "the trait `{}` cannot be auto-implemented for Fn-traits, because it has \ associated consts (only traits with a single method can be implemented \ for Fn-traits)", @@ -374,7 +374,7 @@ fn gen_type_item( // A trait with associated types cannot be implemented for Fn* types. if proxy_type.is_fn() { return item.span() - .error(format!( + .err(format!( "the trait `{}` cannot be auto-implemented for Fn-traits, because it has \ associated types (only traits with a single method can be implemented \ for Fn-traits)", @@ -488,7 +488,7 @@ fn check_receiver_compatible( (ProxyType::Ref, SelfType::Mut) | (ProxyType::Ref, SelfType::Value) => { sig_span - .error(format!( + .err(format!( "the trait `{}` cannot be auto-implemented for immutable references, because \ this method has a `{}` receiver (only `&self` and no receiver are \ allowed)", @@ -500,7 +500,7 @@ fn check_receiver_compatible( (ProxyType::RefMut, SelfType::Value) => { sig_span - .error(format!( + .err(format!( "the trait `{}` cannot be auto-implemented for mutable references, because \ this method has a `self` receiver (only `&self`, `&mut self` and no \ receiver are allowed)", @@ -520,7 +520,7 @@ fn check_receiver_compatible( }; sig_span - .error(format!( + .err(format!( "the trait `{}` cannot be auto-implemented for {}-smartpointer, because \ this method has a `{}` receiver (only `&self` and no receiver are \ allowed)", @@ -564,7 +564,7 @@ fn get_arg_list(inputs: impl Iterator) -> Result TokenStream { // compiler usually does some kind of error recovery to proceed. We // get the recovered tokens. Err(e) => { - let msg = "couldn't parse trait item"; - Diagnostic::spanned(Span::call_site(), Level::Error, msg) + // We have to take the detour through TokenStream2 to get a + // good span for the error. + TokenStream2::from(input.clone()).span() + .err("couldn't parse trait item") .note(e.to_string()) .note("the #[auto_impl] attribute can only be applied to traits!") .emit(); @@ -57,7 +63,7 @@ pub fn auto_impl(args: TokenStream, input: TokenStream) -> TokenStream { Err(()) } } - }().unwrap_or(TokenStream::new()); // If an error occured, we don't add any tokens. + }().unwrap_or_else(|_| diag::error_tokens()); // Combine the original token stream with the additional one containing the // generated impls (or nothing if an error occured). diff --git a/src/proxy.rs b/src/proxy.rs index ae48bb3..7929e42 100644 --- a/src/proxy.rs +++ b/src/proxy.rs @@ -2,6 +2,8 @@ use std::iter::Peekable; use proc_macro::{token_stream, TokenStream, TokenTree}; +use diag::SpanExt; + /// Types for which a trait can automatically be implemented. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub(crate) enum ProxyType { @@ -72,7 +74,7 @@ fn eat_type(iter: &mut Peekable) -> Result { group.span() - .error(format!("unexpected group. {}", EXPECTED_TEXT)) + .err(format!("unexpected group. {}", EXPECTED_TEXT)) .note(NOTE_TEXT) .emit(); @@ -81,7 +83,7 @@ fn eat_type(iter: &mut Peekable) -> Result { lit.span() - .error(format!("unexpected literal. {}", EXPECTED_TEXT)) + .err(format!("unexpected literal. {}", EXPECTED_TEXT)) .note(NOTE_TEXT) .emit(); @@ -92,7 +94,7 @@ fn eat_type(iter: &mut Peekable) -> Result) -> Result { let msg = format!("unexpected '{}'. {}", ident, EXPECTED_TEXT); ident.span() - .error(msg) + .err(msg) .note(NOTE_TEXT) .emit(); diff --git a/src/spanned.rs b/src/spanned.rs index 2c433d6..d192e14 100644 --- a/src/spanned.rs +++ b/src/spanned.rs @@ -27,11 +27,21 @@ impl Spanned for T { if tokens.is_empty() { Span::call_site() } else { - let mut iter = tokens.into_iter(); - let mut span = iter.next().unwrap().span(); - if let Some(last) = iter.last() { - span = span.join(last.span()).unwrap(); - } + // If we're on nightly, we can create a correct span. Otherwise we + // just point to the first token. + #[cfg(feature = "nightly")] + let span = { + let mut iter = tokens.into_iter(); + let mut span = iter.next().unwrap().span(); + if let Some(last) = iter.last() { + span = span.join(last.span()).unwrap(); + } + span + }; + + #[cfg(not(feature = "nightly"))] + let span = tokens.into_iter().next().unwrap().span(); + span } } From 3c9457cfc70e6ee898c872adf6f461dec390e94e Mon Sep 17 00:00:00 2001 From: Lukas Kalbertodt Date: Tue, 24 Jul 2018 23:52:46 +0200 Subject: [PATCH 02/13] Add two examples that fail to compile (to showcase error messages) The examples are a bit awkward for some reason: examples are compiled when one executes `cargo test`. This is nice, but we actually want those examples to fail. We can't just exclude them, so we only compile the interesting part when the `fail` cfg is set. I hope to find a better solution for this... --- examples/fail_invalid_proxy.rs | 32 ++++++++++++++++++++++++++++++++ examples/fail_on_struct.rs | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 examples/fail_invalid_proxy.rs create mode 100644 examples/fail_on_struct.rs diff --git a/examples/fail_invalid_proxy.rs b/examples/fail_invalid_proxy.rs new file mode 100644 index 0000000..6ed5ebe --- /dev/null +++ b/examples/fail_invalid_proxy.rs @@ -0,0 +1,32 @@ +//! Shows the error message for the case that `#[auto_impl]` was used with +//! incorrect proxy types. Only proxy types like `&` and `Box` are allowed. +//! +//! To build the example, run: +//! +//! ``` +//! $ cargo rustc --example fail_invalid_proxy -- --cfg fail +//! ``` +//! +//! To build it in nightly mode with better error message, run: +//! +//! ``` +//! $ cargo rustc --example fail_invalid_proxy --features nightly -- --cfg fail +//! ``` + +#![feature(use_extern_macros)] + + +#[cfg(fail)] +mod fail { + extern crate auto_impl; + use self::auto_impl::auto_impl; + + + #[auto_impl(Boxxi)] + trait Foo { + fn foo(&self) -> u32; + } +} + + +fn main() {} diff --git a/examples/fail_on_struct.rs b/examples/fail_on_struct.rs new file mode 100644 index 0000000..ae9c514 --- /dev/null +++ b/examples/fail_on_struct.rs @@ -0,0 +1,32 @@ +//! Shows the error message for the case the `#[auto_impl]` wasn't applied to +//! a valid trait (in this case a struct). +//! +//! To build the example, run: +//! +//! ``` +//! $ cargo rustc --example fail_on_struct -- --cfg fail +//! ``` +//! +//! To build it in nightly mode with better error message, run: +//! +//! ``` +//! $ cargo rustc --example fail_on_struct --features nightly -- --cfg fail +//! ``` + +#![feature(use_extern_macros)] + + +#[cfg(fail)] +mod fail { + extern crate auto_impl; + use self::auto_impl::auto_impl; + + + #[auto_impl(&, Box)] + struct Foo { + x: u32, + } +} + + +fn main() {} From 953a8e7aae1a18206d6a7750866cf317ca7db9dc Mon Sep 17 00:00:00 2001 From: Lukas Kalbertodt Date: Wed, 25 Jul 2018 11:25:37 +0200 Subject: [PATCH 03/13] Replace three individual feature flags by `rust_2018_preview` --- src/lib.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 235ee8d..fd2845d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,9 +3,7 @@ #![cfg_attr(feature = "nightly", feature(proc_macro_diagnostic, proc_macro_span))] -#![feature(crate_in_paths)] -#![feature(extern_prelude)] -#![feature(in_band_lifetimes)] +#![feature(rust_2018_preview)] extern crate proc_macro; From e558b5602c1a581c8bf7d236cb4d51fef7ad1d2c Mon Sep 17 00:00:00 2001 From: Lukas Kalbertodt Date: Wed, 25 Jul 2018 11:31:56 +0200 Subject: [PATCH 04/13] Use `crate::` prefixes in use paths everywhere --- src/gen.rs | 2 +- src/lib.rs | 6 ++++-- src/proxy.rs | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/gen.rs b/src/gen.rs index 599a1f0..399da2e 100644 --- a/src/gen.rs +++ b/src/gen.rs @@ -7,7 +7,7 @@ use syn::{ }; use crate::{ - analyze::{find_suitable_param_names}, + analyze::find_suitable_param_names, diag::{DiagnosticExt, SpanExt}, proxy::ProxyType, spanned::Spanned diff --git a/src/lib.rs b/src/lib.rs index fd2845d..f757991 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -21,8 +21,10 @@ mod gen; mod proxy; mod spanned; -use diag::SpanExt; -use spanned::Spanned; +use crate::{ + diag::SpanExt, + spanned::Spanned, +}; /// See crate documentation for more information. diff --git a/src/proxy.rs b/src/proxy.rs index 7929e42..feb2930 100644 --- a/src/proxy.rs +++ b/src/proxy.rs @@ -2,7 +2,7 @@ use std::iter::Peekable; use proc_macro::{token_stream, TokenStream, TokenTree}; -use diag::SpanExt; +use crate::diag::SpanExt; /// Types for which a trait can automatically be implemented. #[derive(Debug, Clone, Copy, PartialEq, Eq)] From ee0393777855d246f867c2462815437e0ea79a3c Mon Sep 17 00:00:00 2001 From: Lukas Kalbertodt Date: Wed, 25 Jul 2018 11:46:53 +0200 Subject: [PATCH 05/13] Use more Rust 2018 features - no extern crate anymore (except for quote because of #[macro_use]) - replace `pub(crate)` with `crate` - use lifetime elision in impl --- Cargo.toml | 3 +++ src/analyze.rs | 4 ++-- src/diag.rs | 16 ++++++++-------- src/gen.rs | 2 +- src/lib.rs | 4 ---- src/proxy.rs | 6 +++--- 6 files changed, 17 insertions(+), 18 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b8c901b..e959b62 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,3 +1,5 @@ +cargo-features = ["edition"] + [package] name = "auto_impl" version = "0.2.0" @@ -13,6 +15,7 @@ keywords = ["plugin"] categories = ["development-tools"] readme = "README.md" autotests = true +edition = '2018' [badges] travis-ci = { repository = "KodrAus/auto_impl" } diff --git a/src/analyze.rs b/src/analyze.rs index 39e4dcb..41f321d 100644 --- a/src/analyze.rs +++ b/src/analyze.rs @@ -37,14 +37,14 @@ const PROXY_LT_PARAM_NAME: &str = "'__auto_impl_proxy_lifetime"; /// name, we'll use the ugly `PROXY_TY_PARAM_NAME` and `PROXY_LT_PARAM_NAME`. /// /// This method returns two idents: (type_parameter, lifetime_parameter). -pub(crate) fn find_suitable_param_names(trait_def: &ItemTrait) -> (Ident, Lifetime) { +crate fn find_suitable_param_names(trait_def: &ItemTrait) -> (Ident, Lifetime) { // Define the visitor that just collects names struct IdentCollector<'ast> { ty_names: HashSet<&'ast Ident>, lt_names: HashSet<&'ast Ident>, } - impl<'ast> Visit<'ast> for IdentCollector<'ast> { + impl Visit<'ast> for IdentCollector<'ast> { fn visit_ident(&mut self, i: &'ast Ident) { self.ty_names.insert(i); } diff --git a/src/diag.rs b/src/diag.rs index e43b0dc..021a1a9 100644 --- a/src/diag.rs +++ b/src/diag.rs @@ -44,10 +44,10 @@ impl DiagnosticExt for Diagnostic { // `Diagnostic`. #[cfg(feature = "nightly")] -pub(crate) type Diagnostic = ::proc_macro::Diagnostic; +crate type Diagnostic = ::proc_macro::Diagnostic; #[cfg(not(feature = "nightly"))] -pub(crate) struct Diagnostic { +crate struct Diagnostic { span: Span, msg: String, } @@ -86,19 +86,19 @@ pub(crate) struct Diagnostic { // required. #[cfg(not(feature = "nightly"))] impl Diagnostic { - pub(crate) fn note(mut self, msg: impl Into) -> Diagnostic { + crate fn note(mut self, msg: impl Into) -> Diagnostic { self.msg += &format!("\n\nnote: {}", msg.into()); self } - pub(crate) fn span_note(mut self, _: Span, msg: impl Into) -> Diagnostic { + crate fn span_note(mut self, _: Span, msg: impl Into) -> Diagnostic { // With out span fake method, we can only handle one span. We take the // one of the original error and ignore additional ones. self.msg += &format!("\n\nnote: {}", msg.into()); self } - pub(crate) fn emit(self) { + crate fn emit(self) { // Create the error token stream that contains the `compile_error!()` // invocation. let msg = &self.msg; @@ -149,7 +149,7 @@ thread_local! { /// On stable, we just copy the error token streams from the global variable. #[cfg(not(feature = "nightly"))] -pub(crate) fn error_tokens() -> TokenStream { +crate fn error_tokens() -> TokenStream { ERROR_TOKENS.with(|toks| toks.borrow().iter().cloned().collect()) } @@ -157,13 +157,13 @@ pub(crate) fn error_tokens() -> TokenStream { /// we just return an empty token stream. That's not a problem because all of /// our errors were already printed. #[cfg(feature = "nightly")] -pub(crate) fn error_tokens() -> TokenStream { +crate fn error_tokens() -> TokenStream { TokenStream::new() } /// Extension trait to add the `err()` method to `Span`. This makes it easy to /// start a `Diagnostic` from a span. -pub(crate) trait SpanExt { +crate trait SpanExt { fn err(self, msg: impl Into) -> Diagnostic; } diff --git a/src/gen.rs b/src/gen.rs index 399da2e..d1816b4 100644 --- a/src/gen.rs +++ b/src/gen.rs @@ -17,7 +17,7 @@ use crate::{ /// Generates one complete impl of the given trait for each of the given proxy /// types. All impls are returned as token stream. -pub(crate) fn gen_impls( +crate fn gen_impls( proxy_types: &[ProxyType], trait_def: &syn::ItemTrait, ) -> Result<::proc_macro::TokenStream, ()> { diff --git a/src/lib.rs b/src/lib.rs index f757991..431ab54 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,12 +5,8 @@ #![cfg_attr(feature = "nightly", feature(proc_macro_diagnostic, proc_macro_span))] #![feature(rust_2018_preview)] - -extern crate proc_macro; -extern crate proc_macro2; #[macro_use] extern crate quote; -extern crate syn; use proc_macro::TokenStream; use proc_macro2::TokenStream as TokenStream2; diff --git a/src/proxy.rs b/src/proxy.rs index feb2930..7ac47ae 100644 --- a/src/proxy.rs +++ b/src/proxy.rs @@ -6,7 +6,7 @@ use crate::diag::SpanExt; /// Types for which a trait can automatically be implemented. #[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub(crate) enum ProxyType { +crate enum ProxyType { Ref, RefMut, Arc, @@ -18,7 +18,7 @@ pub(crate) enum ProxyType { } impl ProxyType { - pub(crate) fn is_fn(&self) -> bool { + crate fn is_fn(&self) -> bool { match *self { ProxyType::Fn | ProxyType::FnMut | ProxyType::FnOnce => true, _ => false, @@ -34,7 +34,7 @@ impl ProxyType { /// /// If the given TokenStream is not valid, errors are emitted as appropriate /// and `Err(())` is returned. -pub(crate) fn parse_types(args: TokenStream) -> Result, ()> { +crate fn parse_types(args: TokenStream) -> Result, ()> { let mut out = Vec::new(); let mut iter = args.into_iter().peekable(); From c3df31cf3e29db005f560c2c1d213eaef3b2ca33 Mon Sep 17 00:00:00 2001 From: Lukas Kalbertodt Date: Wed, 25 Jul 2018 11:50:14 +0200 Subject: [PATCH 06/13] Improve Travis-CI configuration - crate is tested with and without 'nightly' feature - warnings lead to a build failure --- .travis.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.travis.yml b/.travis.yml index c3065fb..396d127 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,4 +2,13 @@ language: rust rust: - nightly +script: + - cargo build --verbose + - cargo test --verbose + - cargo build --verbose --features=nightly + - cargo test --verbose --features=nightly + +env: + - RUST_FLAGS="--deny warnings" + cache: cargo From c43b93d2e055d93e95a6d290b3ef111fce41cbc3 Mon Sep 17 00:00:00 2001 From: Lukas Kalbertodt Date: Sun, 12 Aug 2018 14:42:37 +0200 Subject: [PATCH 07/13] Fix typo --- src/diag.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/diag.rs b/src/diag.rs index 021a1a9..1ffb0de 100644 --- a/src/diag.rs +++ b/src/diag.rs @@ -1,6 +1,6 @@ //! This module has two purposes: //! -//! 1. Provide the convenienve method `emit_with_attr_note` and add it via +//! 1. Provide the convenience method `emit_with_attr_note` and add it via //! extension trait to `Diagnostic`. //! //! 2. Make `Diagnostic` work on stable by providing an own `Diagnostic` type From 89f921d7d4bbab7e22aaea8fe116e755d618be08 Mon Sep 17 00:00:00 2001 From: Lukas Kalbertodt Date: Wed, 22 Aug 2018 10:52:50 +0200 Subject: [PATCH 08/13] Update to newest nightly - Do not use in-band lifetimes, as they are probably not stabilized in the current form (and thus are not part of Rust 2018) - Remove `#![feature(rust_2018_preview)]` as it's default now --- src/analyze.rs | 2 +- src/gen.rs | 2 +- src/lib.rs | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/analyze.rs b/src/analyze.rs index 41f321d..6c7cd06 100644 --- a/src/analyze.rs +++ b/src/analyze.rs @@ -44,7 +44,7 @@ crate fn find_suitable_param_names(trait_def: &ItemTrait) -> (Ident, Lifetime) { lt_names: HashSet<&'ast Ident>, } - impl Visit<'ast> for IdentCollector<'ast> { + impl<'ast> Visit<'ast> for IdentCollector<'ast> { fn visit_ident(&mut self, i: &'ast Ident) { self.ty_names.insert(i); } diff --git a/src/gen.rs b/src/gen.rs index d1816b4..0de0769 100644 --- a/src/gen.rs +++ b/src/gen.rs @@ -544,7 +544,7 @@ fn check_receiver_compatible( /// Generates a list of comma-separated arguments used to call the function. /// Currently, only simple names are valid and more complex pattern will lead /// to an error being emitted. `self` parameters are ignored. -fn get_arg_list(inputs: impl Iterator) -> Result { +fn get_arg_list<'a>(inputs: impl Iterator) -> Result { let mut args = TokenStream2::new(); for arg in inputs { diff --git a/src/lib.rs b/src/lib.rs index 431ab54..451c111 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,7 +3,6 @@ #![cfg_attr(feature = "nightly", feature(proc_macro_diagnostic, proc_macro_span))] -#![feature(rust_2018_preview)] #[macro_use] extern crate quote; From face55b04379d6c1d4b2a71964129d2e162cae38 Mon Sep 17 00:00:00 2001 From: Lukas Kalbertodt Date: Wed, 22 Aug 2018 10:55:33 +0200 Subject: [PATCH 09/13] Remove stabilized `use_extern_macro` feature from examples `extern crate auto_impl` could also be removed :) --- examples/fail_invalid_proxy.rs | 4 ---- examples/fail_on_struct.rs | 4 ---- examples/greet_closure.rs | 4 ---- examples/names.rs | 2 -- examples/refs.rs | 4 ---- 5 files changed, 18 deletions(-) diff --git a/examples/fail_invalid_proxy.rs b/examples/fail_invalid_proxy.rs index 6ed5ebe..43cb79c 100644 --- a/examples/fail_invalid_proxy.rs +++ b/examples/fail_invalid_proxy.rs @@ -13,12 +13,8 @@ //! $ cargo rustc --example fail_invalid_proxy --features nightly -- --cfg fail //! ``` -#![feature(use_extern_macros)] - - #[cfg(fail)] mod fail { - extern crate auto_impl; use self::auto_impl::auto_impl; diff --git a/examples/fail_on_struct.rs b/examples/fail_on_struct.rs index ae9c514..b6daeca 100644 --- a/examples/fail_on_struct.rs +++ b/examples/fail_on_struct.rs @@ -13,12 +13,8 @@ //! $ cargo rustc --example fail_on_struct --features nightly -- --cfg fail //! ``` -#![feature(use_extern_macros)] - - #[cfg(fail)] mod fail { - extern crate auto_impl; use self::auto_impl::auto_impl; diff --git a/examples/greet_closure.rs b/examples/greet_closure.rs index 8f3db35..2f8daf1 100644 --- a/examples/greet_closure.rs +++ b/examples/greet_closure.rs @@ -1,7 +1,3 @@ -#![feature(use_extern_macros)] - -extern crate auto_impl; - use auto_impl::auto_impl; diff --git a/examples/names.rs b/examples/names.rs index cd5cf56..a39da3b 100644 --- a/examples/names.rs +++ b/examples/names.rs @@ -29,9 +29,7 @@ // This code is really ugly on purpose... #![allow(non_snake_case, dead_code, unused_variables)] -#![feature(use_extern_macros)] -extern crate auto_impl; use auto_impl::auto_impl; diff --git a/examples/refs.rs b/examples/refs.rs index 0845ee9..bcd810e 100644 --- a/examples/refs.rs +++ b/examples/refs.rs @@ -1,7 +1,3 @@ -#![feature(use_extern_macros)] - -extern crate auto_impl; - use std::fmt::Display; use auto_impl::auto_impl; From e959aed838d842efecb4892fa347f6c5e5313ec7 Mon Sep 17 00:00:00 2001 From: Lukas Kalbertodt Date: Wed, 22 Aug 2018 11:01:11 +0200 Subject: [PATCH 10/13] Remove `#![feature(use_extern_macros)]` from tests --- tests/compile-fail/attr_on_enum.rs | 1 - tests/compile-fail/attr_on_fn.rs | 1 - tests/compile-fail/attr_on_impl_block.rs | 1 - tests/compile-fail/attr_on_struct.rs | 1 - tests/compile-fail/attr_on_type.rs | 1 - tests/compile-fail/attr_on_unit_struct.rs | 1 - tests/compile-fail/fn_associated_const.rs | 1 - tests/compile-fail/fn_associated_type.rs | 1 - tests/compile-fail/fn_multiple_methods.rs | 1 - tests/compile-fail/fn_unsafe_method.rs | 1 - tests/compile-fail/mut_self_for_arc.rs | 1 - tests/compile-fail/mut_self_for_immutable_ref.rs | 1 - tests/compile-fail/mut_self_for_rc.rs | 1 - tests/compile-fail/value_self_for_immutable_ref.rs | 1 - tests/compile-fail/value_self_for_mutable_ref.rs | 1 - tests/compile-pass/big_trait_for_all_refs.rs | 2 -- tests/compile-pass/big_trait_for_box.rs | 1 - tests/compile-pass/big_trait_where_bound_for_all_refs.rs | 1 - tests/compile-pass/fn_method_lifetimes.rs | 1 - tests/compile-pass/mut_self_for_fn.rs | 1 - tests/compile-pass/mut_self_for_fn_mut.rs | 1 - tests/compile-pass/ref_self_for_fn.rs | 1 - tests/compile-pass/trait_in_fn.rs | 1 - tests/compile-pass/trait_in_mods.rs | 1 - tests/compile-pass/value_self_for_fn.rs | 1 - tests/compile-pass/value_self_for_fn_mut.rs | 1 - tests/compile-pass/value_self_for_fn_once.rs | 1 - 27 files changed, 28 deletions(-) diff --git a/tests/compile-fail/attr_on_enum.rs b/tests/compile-fail/attr_on_enum.rs index 7ef3ddb..8e349f4 100644 --- a/tests/compile-fail/attr_on_enum.rs +++ b/tests/compile-fail/attr_on_enum.rs @@ -1,4 +1,3 @@ -#![feature(use_extern_macros)] extern crate auto_impl; use auto_impl::auto_impl; diff --git a/tests/compile-fail/attr_on_fn.rs b/tests/compile-fail/attr_on_fn.rs index 0edcdab..43e56dc 100644 --- a/tests/compile-fail/attr_on_fn.rs +++ b/tests/compile-fail/attr_on_fn.rs @@ -1,4 +1,3 @@ -#![feature(use_extern_macros)] extern crate auto_impl; use auto_impl::auto_impl; diff --git a/tests/compile-fail/attr_on_impl_block.rs b/tests/compile-fail/attr_on_impl_block.rs index 96a5b6e..112eccb 100644 --- a/tests/compile-fail/attr_on_impl_block.rs +++ b/tests/compile-fail/attr_on_impl_block.rs @@ -1,4 +1,3 @@ -#![feature(use_extern_macros)] extern crate auto_impl; use auto_impl::auto_impl; diff --git a/tests/compile-fail/attr_on_struct.rs b/tests/compile-fail/attr_on_struct.rs index 576f7ad..4754b38 100644 --- a/tests/compile-fail/attr_on_struct.rs +++ b/tests/compile-fail/attr_on_struct.rs @@ -1,4 +1,3 @@ -#![feature(use_extern_macros)] extern crate auto_impl; use auto_impl::auto_impl; diff --git a/tests/compile-fail/attr_on_type.rs b/tests/compile-fail/attr_on_type.rs index 1f6168f..aaec2ae 100644 --- a/tests/compile-fail/attr_on_type.rs +++ b/tests/compile-fail/attr_on_type.rs @@ -1,4 +1,3 @@ -#![feature(use_extern_macros)] extern crate auto_impl; use auto_impl::auto_impl; diff --git a/tests/compile-fail/attr_on_unit_struct.rs b/tests/compile-fail/attr_on_unit_struct.rs index 9ddf0f7..441e479 100644 --- a/tests/compile-fail/attr_on_unit_struct.rs +++ b/tests/compile-fail/attr_on_unit_struct.rs @@ -1,4 +1,3 @@ -#![feature(use_extern_macros)] extern crate auto_impl; use auto_impl::auto_impl; diff --git a/tests/compile-fail/fn_associated_const.rs b/tests/compile-fail/fn_associated_const.rs index 2600c5a..2171fdf 100644 --- a/tests/compile-fail/fn_associated_const.rs +++ b/tests/compile-fail/fn_associated_const.rs @@ -1,4 +1,3 @@ -#![feature(use_extern_macros)] extern crate auto_impl; use auto_impl::auto_impl; diff --git a/tests/compile-fail/fn_associated_type.rs b/tests/compile-fail/fn_associated_type.rs index d9a25f2..8193d53 100644 --- a/tests/compile-fail/fn_associated_type.rs +++ b/tests/compile-fail/fn_associated_type.rs @@ -1,4 +1,3 @@ -#![feature(use_extern_macros)] extern crate auto_impl; use auto_impl::auto_impl; diff --git a/tests/compile-fail/fn_multiple_methods.rs b/tests/compile-fail/fn_multiple_methods.rs index 47ec46b..8832de7 100644 --- a/tests/compile-fail/fn_multiple_methods.rs +++ b/tests/compile-fail/fn_multiple_methods.rs @@ -1,4 +1,3 @@ -#![feature(use_extern_macros)] extern crate auto_impl; use auto_impl::auto_impl; diff --git a/tests/compile-fail/fn_unsafe_method.rs b/tests/compile-fail/fn_unsafe_method.rs index 846e295..2096786 100644 --- a/tests/compile-fail/fn_unsafe_method.rs +++ b/tests/compile-fail/fn_unsafe_method.rs @@ -1,4 +1,3 @@ -#![feature(use_extern_macros)] extern crate auto_impl; use auto_impl::auto_impl; diff --git a/tests/compile-fail/mut_self_for_arc.rs b/tests/compile-fail/mut_self_for_arc.rs index acb602a..e93ad31 100644 --- a/tests/compile-fail/mut_self_for_arc.rs +++ b/tests/compile-fail/mut_self_for_arc.rs @@ -1,4 +1,3 @@ -#![feature(use_extern_macros)] extern crate auto_impl; diff --git a/tests/compile-fail/mut_self_for_immutable_ref.rs b/tests/compile-fail/mut_self_for_immutable_ref.rs index eef19be..d8a62d4 100644 --- a/tests/compile-fail/mut_self_for_immutable_ref.rs +++ b/tests/compile-fail/mut_self_for_immutable_ref.rs @@ -1,4 +1,3 @@ -#![feature(use_extern_macros)] extern crate auto_impl; diff --git a/tests/compile-fail/mut_self_for_rc.rs b/tests/compile-fail/mut_self_for_rc.rs index 44510c4..6e01983 100644 --- a/tests/compile-fail/mut_self_for_rc.rs +++ b/tests/compile-fail/mut_self_for_rc.rs @@ -1,4 +1,3 @@ -#![feature(use_extern_macros)] extern crate auto_impl; diff --git a/tests/compile-fail/value_self_for_immutable_ref.rs b/tests/compile-fail/value_self_for_immutable_ref.rs index 644786e..672dd32 100644 --- a/tests/compile-fail/value_self_for_immutable_ref.rs +++ b/tests/compile-fail/value_self_for_immutable_ref.rs @@ -1,4 +1,3 @@ -#![feature(use_extern_macros)] extern crate auto_impl; diff --git a/tests/compile-fail/value_self_for_mutable_ref.rs b/tests/compile-fail/value_self_for_mutable_ref.rs index 86f8936..b2b9381 100644 --- a/tests/compile-fail/value_self_for_mutable_ref.rs +++ b/tests/compile-fail/value_self_for_mutable_ref.rs @@ -1,4 +1,3 @@ -#![feature(use_extern_macros)] extern crate auto_impl; diff --git a/tests/compile-pass/big_trait_for_all_refs.rs b/tests/compile-pass/big_trait_for_all_refs.rs index d5ddf16..f276f46 100644 --- a/tests/compile-pass/big_trait_for_all_refs.rs +++ b/tests/compile-pass/big_trait_for_all_refs.rs @@ -1,5 +1,3 @@ -#![feature(use_extern_macros)] - extern crate auto_impl; use auto_impl::auto_impl; diff --git a/tests/compile-pass/big_trait_for_box.rs b/tests/compile-pass/big_trait_for_box.rs index 9f83f03..2118285 100644 --- a/tests/compile-pass/big_trait_for_box.rs +++ b/tests/compile-pass/big_trait_for_box.rs @@ -1,4 +1,3 @@ -#![feature(use_extern_macros)] extern crate auto_impl; use auto_impl::auto_impl; diff --git a/tests/compile-pass/big_trait_where_bound_for_all_refs.rs b/tests/compile-pass/big_trait_where_bound_for_all_refs.rs index f8291d9..dd95301 100644 --- a/tests/compile-pass/big_trait_where_bound_for_all_refs.rs +++ b/tests/compile-pass/big_trait_where_bound_for_all_refs.rs @@ -1,4 +1,3 @@ -#![feature(use_extern_macros)] extern crate auto_impl; use auto_impl::auto_impl; diff --git a/tests/compile-pass/fn_method_lifetimes.rs b/tests/compile-pass/fn_method_lifetimes.rs index 0a1e29f..28992a8 100644 --- a/tests/compile-pass/fn_method_lifetimes.rs +++ b/tests/compile-pass/fn_method_lifetimes.rs @@ -1,4 +1,3 @@ -#![feature(use_extern_macros)] extern crate auto_impl; use auto_impl::auto_impl; diff --git a/tests/compile-pass/mut_self_for_fn.rs b/tests/compile-pass/mut_self_for_fn.rs index 051c038..d5cb6ed 100644 --- a/tests/compile-pass/mut_self_for_fn.rs +++ b/tests/compile-pass/mut_self_for_fn.rs @@ -1,4 +1,3 @@ -#![feature(use_extern_macros)] extern crate auto_impl; use auto_impl::auto_impl; diff --git a/tests/compile-pass/mut_self_for_fn_mut.rs b/tests/compile-pass/mut_self_for_fn_mut.rs index 24ea9b4..e5af415 100644 --- a/tests/compile-pass/mut_self_for_fn_mut.rs +++ b/tests/compile-pass/mut_self_for_fn_mut.rs @@ -1,4 +1,3 @@ -#![feature(use_extern_macros)] extern crate auto_impl; use auto_impl::auto_impl; diff --git a/tests/compile-pass/ref_self_for_fn.rs b/tests/compile-pass/ref_self_for_fn.rs index 6900151..df68738 100644 --- a/tests/compile-pass/ref_self_for_fn.rs +++ b/tests/compile-pass/ref_self_for_fn.rs @@ -1,4 +1,3 @@ -#![feature(use_extern_macros)] extern crate auto_impl; use auto_impl::auto_impl; diff --git a/tests/compile-pass/trait_in_fn.rs b/tests/compile-pass/trait_in_fn.rs index 089b9bb..e9b8e75 100644 --- a/tests/compile-pass/trait_in_fn.rs +++ b/tests/compile-pass/trait_in_fn.rs @@ -1,4 +1,3 @@ -#![feature(use_extern_macros)] extern crate auto_impl; diff --git a/tests/compile-pass/trait_in_mods.rs b/tests/compile-pass/trait_in_mods.rs index cd7db98..f3f132e 100644 --- a/tests/compile-pass/trait_in_mods.rs +++ b/tests/compile-pass/trait_in_mods.rs @@ -1,4 +1,3 @@ -#![feature(use_extern_macros)] // Make sure that everything compiles even without the prelude. This basically // forces us to generate full paths for types of the standard/core library. diff --git a/tests/compile-pass/value_self_for_fn.rs b/tests/compile-pass/value_self_for_fn.rs index fe0dca9..0b9664e 100644 --- a/tests/compile-pass/value_self_for_fn.rs +++ b/tests/compile-pass/value_self_for_fn.rs @@ -1,4 +1,3 @@ -#![feature(use_extern_macros)] extern crate auto_impl; use auto_impl::auto_impl; diff --git a/tests/compile-pass/value_self_for_fn_mut.rs b/tests/compile-pass/value_self_for_fn_mut.rs index 444f4bd..38c16cc 100644 --- a/tests/compile-pass/value_self_for_fn_mut.rs +++ b/tests/compile-pass/value_self_for_fn_mut.rs @@ -1,4 +1,3 @@ -#![feature(use_extern_macros)] extern crate auto_impl; use auto_impl::auto_impl; diff --git a/tests/compile-pass/value_self_for_fn_once.rs b/tests/compile-pass/value_self_for_fn_once.rs index daf8697..ff58e0d 100644 --- a/tests/compile-pass/value_self_for_fn_once.rs +++ b/tests/compile-pass/value_self_for_fn_once.rs @@ -1,4 +1,3 @@ -#![feature(use_extern_macros)] extern crate auto_impl; use auto_impl::auto_impl; From 9b61ce819ba30de80e7cf96059bca512fe1d4fea Mon Sep 17 00:00:00 2001 From: Lukas Kalbertodt Date: Wed, 22 Aug 2018 11:01:31 +0200 Subject: [PATCH 11/13] Add `--edition=2018` flag for compiling tests --- tests/util/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/util/mod.rs b/tests/util/mod.rs index 158d0be..c58d6f3 100644 --- a/tests/util/mod.rs +++ b/tests/util/mod.rs @@ -111,6 +111,7 @@ pub(crate) fn run_rustc(file_path: &Path, dep_path: &Path) -> process::Output { .args(&["--crate-type", "lib"]) .args(&["-Z", "no-codegen"]) .args(&["--emit", "metadata"]) + .arg("--edition=2018") .arg("--out-dir").arg(&out_dir) .arg("--extern").arg(&extern_value) .output() From 53e68d9d5bb82c8b03fcaf999b12839b64ee5a93 Mon Sep 17 00:00:00 2001 From: Lukas Kalbertodt Date: Wed, 22 Aug 2018 11:05:40 +0200 Subject: [PATCH 12/13] Remove `extern crate auto_impl` from all tests --- tests/compile-fail/attr_on_enum.rs | 2 -- tests/compile-fail/attr_on_fn.rs | 2 -- tests/compile-fail/attr_on_impl_block.rs | 2 -- tests/compile-fail/attr_on_struct.rs | 2 -- tests/compile-fail/attr_on_type.rs | 2 -- tests/compile-fail/attr_on_unit_struct.rs | 2 -- tests/compile-fail/fn_associated_const.rs | 2 -- tests/compile-fail/fn_associated_type.rs | 2 -- tests/compile-fail/fn_multiple_methods.rs | 2 -- tests/compile-fail/fn_unsafe_method.rs | 2 -- tests/compile-fail/mut_self_for_arc.rs | 3 --- tests/compile-fail/mut_self_for_immutable_ref.rs | 3 --- tests/compile-fail/mut_self_for_rc.rs | 3 --- tests/compile-fail/value_self_for_immutable_ref.rs | 3 --- tests/compile-fail/value_self_for_mutable_ref.rs | 3 --- tests/compile-pass/big_trait_for_all_refs.rs | 1 - tests/compile-pass/big_trait_for_box.rs | 2 -- tests/compile-pass/big_trait_where_bound_for_all_refs.rs | 2 -- tests/compile-pass/fn_method_lifetimes.rs | 2 -- tests/compile-pass/mut_self_for_fn.rs | 2 -- tests/compile-pass/mut_self_for_fn_mut.rs | 2 -- tests/compile-pass/ref_self_for_fn.rs | 2 -- tests/compile-pass/trait_in_fn.rs | 3 --- tests/compile-pass/trait_in_mods.rs | 3 --- tests/compile-pass/value_self_for_fn.rs | 2 -- tests/compile-pass/value_self_for_fn_mut.rs | 2 -- tests/compile-pass/value_self_for_fn_once.rs | 2 -- 27 files changed, 60 deletions(-) diff --git a/tests/compile-fail/attr_on_enum.rs b/tests/compile-fail/attr_on_enum.rs index 8e349f4..79d4d01 100644 --- a/tests/compile-fail/attr_on_enum.rs +++ b/tests/compile-fail/attr_on_enum.rs @@ -1,5 +1,3 @@ - -extern crate auto_impl; use auto_impl::auto_impl; diff --git a/tests/compile-fail/attr_on_fn.rs b/tests/compile-fail/attr_on_fn.rs index 43e56dc..f37cbd1 100644 --- a/tests/compile-fail/attr_on_fn.rs +++ b/tests/compile-fail/attr_on_fn.rs @@ -1,5 +1,3 @@ - -extern crate auto_impl; use auto_impl::auto_impl; diff --git a/tests/compile-fail/attr_on_impl_block.rs b/tests/compile-fail/attr_on_impl_block.rs index 112eccb..5d8efa7 100644 --- a/tests/compile-fail/attr_on_impl_block.rs +++ b/tests/compile-fail/attr_on_impl_block.rs @@ -1,5 +1,3 @@ - -extern crate auto_impl; use auto_impl::auto_impl; diff --git a/tests/compile-fail/attr_on_struct.rs b/tests/compile-fail/attr_on_struct.rs index 4754b38..fa2b4fe 100644 --- a/tests/compile-fail/attr_on_struct.rs +++ b/tests/compile-fail/attr_on_struct.rs @@ -1,5 +1,3 @@ - -extern crate auto_impl; use auto_impl::auto_impl; diff --git a/tests/compile-fail/attr_on_type.rs b/tests/compile-fail/attr_on_type.rs index aaec2ae..caa5d30 100644 --- a/tests/compile-fail/attr_on_type.rs +++ b/tests/compile-fail/attr_on_type.rs @@ -1,5 +1,3 @@ - -extern crate auto_impl; use auto_impl::auto_impl; diff --git a/tests/compile-fail/attr_on_unit_struct.rs b/tests/compile-fail/attr_on_unit_struct.rs index 441e479..d356bc3 100644 --- a/tests/compile-fail/attr_on_unit_struct.rs +++ b/tests/compile-fail/attr_on_unit_struct.rs @@ -1,5 +1,3 @@ - -extern crate auto_impl; use auto_impl::auto_impl; diff --git a/tests/compile-fail/fn_associated_const.rs b/tests/compile-fail/fn_associated_const.rs index 2171fdf..97b28ff 100644 --- a/tests/compile-fail/fn_associated_const.rs +++ b/tests/compile-fail/fn_associated_const.rs @@ -1,5 +1,3 @@ - -extern crate auto_impl; use auto_impl::auto_impl; diff --git a/tests/compile-fail/fn_associated_type.rs b/tests/compile-fail/fn_associated_type.rs index 8193d53..829929d 100644 --- a/tests/compile-fail/fn_associated_type.rs +++ b/tests/compile-fail/fn_associated_type.rs @@ -1,5 +1,3 @@ - -extern crate auto_impl; use auto_impl::auto_impl; diff --git a/tests/compile-fail/fn_multiple_methods.rs b/tests/compile-fail/fn_multiple_methods.rs index 8832de7..fb0488b 100644 --- a/tests/compile-fail/fn_multiple_methods.rs +++ b/tests/compile-fail/fn_multiple_methods.rs @@ -1,5 +1,3 @@ - -extern crate auto_impl; use auto_impl::auto_impl; diff --git a/tests/compile-fail/fn_unsafe_method.rs b/tests/compile-fail/fn_unsafe_method.rs index 2096786..8e1e525 100644 --- a/tests/compile-fail/fn_unsafe_method.rs +++ b/tests/compile-fail/fn_unsafe_method.rs @@ -1,5 +1,3 @@ - -extern crate auto_impl; use auto_impl::auto_impl; diff --git a/tests/compile-fail/mut_self_for_arc.rs b/tests/compile-fail/mut_self_for_arc.rs index e93ad31..2efa899 100644 --- a/tests/compile-fail/mut_self_for_arc.rs +++ b/tests/compile-fail/mut_self_for_arc.rs @@ -1,6 +1,3 @@ - -extern crate auto_impl; - use auto_impl::auto_impl; diff --git a/tests/compile-fail/mut_self_for_immutable_ref.rs b/tests/compile-fail/mut_self_for_immutable_ref.rs index d8a62d4..5019cfd 100644 --- a/tests/compile-fail/mut_self_for_immutable_ref.rs +++ b/tests/compile-fail/mut_self_for_immutable_ref.rs @@ -1,6 +1,3 @@ - -extern crate auto_impl; - use auto_impl::auto_impl; diff --git a/tests/compile-fail/mut_self_for_rc.rs b/tests/compile-fail/mut_self_for_rc.rs index 6e01983..f828756 100644 --- a/tests/compile-fail/mut_self_for_rc.rs +++ b/tests/compile-fail/mut_self_for_rc.rs @@ -1,6 +1,3 @@ - -extern crate auto_impl; - use auto_impl::auto_impl; diff --git a/tests/compile-fail/value_self_for_immutable_ref.rs b/tests/compile-fail/value_self_for_immutable_ref.rs index 672dd32..81feb76 100644 --- a/tests/compile-fail/value_self_for_immutable_ref.rs +++ b/tests/compile-fail/value_self_for_immutable_ref.rs @@ -1,6 +1,3 @@ - -extern crate auto_impl; - use auto_impl::auto_impl; diff --git a/tests/compile-fail/value_self_for_mutable_ref.rs b/tests/compile-fail/value_self_for_mutable_ref.rs index b2b9381..0a6e49f 100644 --- a/tests/compile-fail/value_self_for_mutable_ref.rs +++ b/tests/compile-fail/value_self_for_mutable_ref.rs @@ -1,6 +1,3 @@ - -extern crate auto_impl; - use auto_impl::auto_impl; diff --git a/tests/compile-pass/big_trait_for_all_refs.rs b/tests/compile-pass/big_trait_for_all_refs.rs index f276f46..afeeda6 100644 --- a/tests/compile-pass/big_trait_for_all_refs.rs +++ b/tests/compile-pass/big_trait_for_all_refs.rs @@ -1,4 +1,3 @@ -extern crate auto_impl; use auto_impl::auto_impl; diff --git a/tests/compile-pass/big_trait_for_box.rs b/tests/compile-pass/big_trait_for_box.rs index 2118285..87570f4 100644 --- a/tests/compile-pass/big_trait_for_box.rs +++ b/tests/compile-pass/big_trait_for_box.rs @@ -1,5 +1,3 @@ - -extern crate auto_impl; use auto_impl::auto_impl; diff --git a/tests/compile-pass/big_trait_where_bound_for_all_refs.rs b/tests/compile-pass/big_trait_where_bound_for_all_refs.rs index dd95301..43c7dd4 100644 --- a/tests/compile-pass/big_trait_where_bound_for_all_refs.rs +++ b/tests/compile-pass/big_trait_where_bound_for_all_refs.rs @@ -1,5 +1,3 @@ - -extern crate auto_impl; use auto_impl::auto_impl; diff --git a/tests/compile-pass/fn_method_lifetimes.rs b/tests/compile-pass/fn_method_lifetimes.rs index 28992a8..8fced96 100644 --- a/tests/compile-pass/fn_method_lifetimes.rs +++ b/tests/compile-pass/fn_method_lifetimes.rs @@ -1,5 +1,3 @@ - -extern crate auto_impl; use auto_impl::auto_impl; diff --git a/tests/compile-pass/mut_self_for_fn.rs b/tests/compile-pass/mut_self_for_fn.rs index d5cb6ed..d4fbca2 100644 --- a/tests/compile-pass/mut_self_for_fn.rs +++ b/tests/compile-pass/mut_self_for_fn.rs @@ -1,5 +1,3 @@ - -extern crate auto_impl; use auto_impl::auto_impl; diff --git a/tests/compile-pass/mut_self_for_fn_mut.rs b/tests/compile-pass/mut_self_for_fn_mut.rs index e5af415..3e3cb83 100644 --- a/tests/compile-pass/mut_self_for_fn_mut.rs +++ b/tests/compile-pass/mut_self_for_fn_mut.rs @@ -1,5 +1,3 @@ - -extern crate auto_impl; use auto_impl::auto_impl; diff --git a/tests/compile-pass/ref_self_for_fn.rs b/tests/compile-pass/ref_self_for_fn.rs index df68738..5e46594 100644 --- a/tests/compile-pass/ref_self_for_fn.rs +++ b/tests/compile-pass/ref_self_for_fn.rs @@ -1,5 +1,3 @@ - -extern crate auto_impl; use auto_impl::auto_impl; diff --git a/tests/compile-pass/trait_in_fn.rs b/tests/compile-pass/trait_in_fn.rs index e9b8e75..913fa17 100644 --- a/tests/compile-pass/trait_in_fn.rs +++ b/tests/compile-pass/trait_in_fn.rs @@ -1,7 +1,4 @@ -extern crate auto_impl; - - fn foo() { use auto_impl::auto_impl; diff --git a/tests/compile-pass/trait_in_mods.rs b/tests/compile-pass/trait_in_mods.rs index f3f132e..33d4492 100644 --- a/tests/compile-pass/trait_in_mods.rs +++ b/tests/compile-pass/trait_in_mods.rs @@ -1,10 +1,7 @@ - // Make sure that everything compiles even without the prelude. This basically // forces us to generate full paths for types of the standard/core library. #![no_implicit_prelude] -extern crate auto_impl; - mod outer { use auto_impl::auto_impl; diff --git a/tests/compile-pass/value_self_for_fn.rs b/tests/compile-pass/value_self_for_fn.rs index 0b9664e..9f0d477 100644 --- a/tests/compile-pass/value_self_for_fn.rs +++ b/tests/compile-pass/value_self_for_fn.rs @@ -1,5 +1,3 @@ - -extern crate auto_impl; use auto_impl::auto_impl; diff --git a/tests/compile-pass/value_self_for_fn_mut.rs b/tests/compile-pass/value_self_for_fn_mut.rs index 38c16cc..702ff6a 100644 --- a/tests/compile-pass/value_self_for_fn_mut.rs +++ b/tests/compile-pass/value_self_for_fn_mut.rs @@ -1,5 +1,3 @@ - -extern crate auto_impl; use auto_impl::auto_impl; diff --git a/tests/compile-pass/value_self_for_fn_once.rs b/tests/compile-pass/value_self_for_fn_once.rs index ff58e0d..5ccfcc1 100644 --- a/tests/compile-pass/value_self_for_fn_once.rs +++ b/tests/compile-pass/value_self_for_fn_once.rs @@ -1,5 +1,3 @@ - -extern crate auto_impl; use auto_impl::auto_impl; From f81f1dc76c1d8f32dabea6c4baaaff04eba1f45d Mon Sep 17 00:00:00 2001 From: Lukas Kalbertodt Date: Wed, 22 Aug 2018 11:09:36 +0200 Subject: [PATCH 13/13] Remove cfg-magic from fail* examples Now, the user has to simply add a line that has been commented to see the error. A lot simpler. --- examples/error_messages.rs | 30 ++++++++++++++++++++++++++++++ examples/fail_invalid_proxy.rs | 28 ---------------------------- examples/fail_on_struct.rs | 28 ---------------------------- 3 files changed, 30 insertions(+), 56 deletions(-) create mode 100644 examples/error_messages.rs delete mode 100644 examples/fail_invalid_proxy.rs delete mode 100644 examples/fail_on_struct.rs diff --git a/examples/error_messages.rs b/examples/error_messages.rs new file mode 100644 index 0000000..1cc150d --- /dev/null +++ b/examples/error_messages.rs @@ -0,0 +1,30 @@ +//! This file showcases a few error messages emitted by `auto_impl`. You have +//! to add specific lines to see the error. Then simply compile with: +//! +//! ``` +//! cargo build --example error_messages +//! ``` +//! +//! If you want to see nicer error messages, add `--features=nightly`. +#![allow(unused_imports, dead_code)] + +use auto_impl::auto_impl; + + +// Shows the error message for the case that `#[auto_impl]` was used with +// incorrect proxy types. Only proxy types like `&` and `Box` are allowed. Add +// this next line to see the error! +//#[auto_impl(Boxxi)] +trait Foo { + fn foo(&self) -> u32; +} + +// Shows the error message for the case the `#[auto_impl]` wasn't applied to a +// valid trait (in this case a struct). Add this next line to see the error! +//#[auto_impl(&, Box)] +struct Bar { + x: u32, +} + + +fn main() {} diff --git a/examples/fail_invalid_proxy.rs b/examples/fail_invalid_proxy.rs deleted file mode 100644 index 43cb79c..0000000 --- a/examples/fail_invalid_proxy.rs +++ /dev/null @@ -1,28 +0,0 @@ -//! Shows the error message for the case that `#[auto_impl]` was used with -//! incorrect proxy types. Only proxy types like `&` and `Box` are allowed. -//! -//! To build the example, run: -//! -//! ``` -//! $ cargo rustc --example fail_invalid_proxy -- --cfg fail -//! ``` -//! -//! To build it in nightly mode with better error message, run: -//! -//! ``` -//! $ cargo rustc --example fail_invalid_proxy --features nightly -- --cfg fail -//! ``` - -#[cfg(fail)] -mod fail { - use self::auto_impl::auto_impl; - - - #[auto_impl(Boxxi)] - trait Foo { - fn foo(&self) -> u32; - } -} - - -fn main() {} diff --git a/examples/fail_on_struct.rs b/examples/fail_on_struct.rs deleted file mode 100644 index b6daeca..0000000 --- a/examples/fail_on_struct.rs +++ /dev/null @@ -1,28 +0,0 @@ -//! Shows the error message for the case the `#[auto_impl]` wasn't applied to -//! a valid trait (in this case a struct). -//! -//! To build the example, run: -//! -//! ``` -//! $ cargo rustc --example fail_on_struct -- --cfg fail -//! ``` -//! -//! To build it in nightly mode with better error message, run: -//! -//! ``` -//! $ cargo rustc --example fail_on_struct --features nightly -- --cfg fail -//! ``` - -#[cfg(fail)] -mod fail { - use self::auto_impl::auto_impl; - - - #[auto_impl(&, Box)] - struct Foo { - x: u32, - } -} - - -fn main() {}