From 44bf6b6f55be89926d9f18b4d90a9eaefb84d02c Mon Sep 17 00:00:00 2001 From: David Wood Date: Sat, 20 Jul 2019 10:49:02 +0100 Subject: [PATCH] tests: Add minimal reproduction of #61963. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit adds a reproduction of the error reported in servo which demonstrates the current, incorrect behaviour. Co-authored-by: Rémy Rakić --- .../ui/suggestions/auxiliary/issue-61963-1.rs | 40 ++++++++++++++++++ .../ui/suggestions/auxiliary/issue-61963.rs | 41 +++++++++++++++++++ src/test/ui/suggestions/issue-61963.rs | 25 +++++++++++ src/test/ui/suggestions/issue-61963.stderr | 20 +++++++++ 4 files changed, 126 insertions(+) create mode 100644 src/test/ui/suggestions/auxiliary/issue-61963-1.rs create mode 100644 src/test/ui/suggestions/auxiliary/issue-61963.rs create mode 100644 src/test/ui/suggestions/issue-61963.rs create mode 100644 src/test/ui/suggestions/issue-61963.stderr diff --git a/src/test/ui/suggestions/auxiliary/issue-61963-1.rs b/src/test/ui/suggestions/auxiliary/issue-61963-1.rs new file mode 100644 index 000000000000..6c2df7e84e07 --- /dev/null +++ b/src/test/ui/suggestions/auxiliary/issue-61963-1.rs @@ -0,0 +1,40 @@ +// force-host +// no-prefer-dynamic +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::{Group, TokenStream, TokenTree}; + +// This macro exists as part of a reproduction of #61963 but without using quote/syn/proc_macro2. + +#[proc_macro_derive(DomObject)] +pub fn expand_token_stream(input: TokenStream) -> TokenStream { + // Construct a dummy span - `#0 bytes(0..0)` - which is present in the input because + // of the specially crafted generated tokens in the `attribute-crate` proc-macro. + let dummy_span = input.clone().into_iter().nth(0).unwrap().span(); + + // Define what the macro would output if constructed properly from the source using syn/quote. + let output: TokenStream = "impl Bar for ((), Qux >) { } + impl Bar for ((), Box) { }".parse().unwrap(); + + let mut tokens: Vec<_> = output.into_iter().collect(); + // Adjust token spans to match the original crate (which would use `quote`). Some of the + // generated tokens point to the dummy span. + for token in tokens.iter_mut() { + if let TokenTree::Group(group) = token { + let mut tokens: Vec<_> = group.stream().into_iter().collect(); + for token in tokens.iter_mut().skip(2) { + token.set_span(dummy_span); + } + + let mut stream = TokenStream::new(); + stream.extend(tokens); + *group = Group::new(group.delimiter(), stream); + } + } + + let mut output = TokenStream::new(); + output.extend(tokens); + output +} diff --git a/src/test/ui/suggestions/auxiliary/issue-61963.rs b/src/test/ui/suggestions/auxiliary/issue-61963.rs new file mode 100644 index 000000000000..e86f1610ab0d --- /dev/null +++ b/src/test/ui/suggestions/auxiliary/issue-61963.rs @@ -0,0 +1,41 @@ +// force-host +// no-prefer-dynamic +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::{Group, Spacing, Punct, TokenTree, TokenStream}; + +// This macro exists as part of a reproduction of #61963 but without using quote/syn/proc_macro2. + +#[proc_macro_attribute] +pub fn dom_struct(_: TokenStream, input: TokenStream) -> TokenStream { + // Construct the expected output tokens - the input but with a `#[derive(DomObject)]` applied. + let attributes: TokenStream = + "#[derive(DomObject)]".to_string().parse().unwrap(); + let output: TokenStream = attributes.into_iter() + .chain(input.into_iter()).collect(); + + let mut tokens: Vec<_> = output.into_iter().collect(); + // Adjust the spacing of `>` tokens to match what `quote` would produce. + for token in tokens.iter_mut() { + if let TokenTree::Group(group) = token { + let mut tokens: Vec<_> = group.stream().into_iter().collect(); + for token in tokens.iter_mut() { + if let TokenTree::Punct(p) = token { + if p.as_char() == '>' { + *p = Punct::new('>', Spacing::Alone); + } + } + } + + let mut stream = TokenStream::new(); + stream.extend(tokens); + *group = Group::new(group.delimiter(), stream); + } + } + + let mut output = TokenStream::new(); + output.extend(tokens); + output +} diff --git a/src/test/ui/suggestions/issue-61963.rs b/src/test/ui/suggestions/issue-61963.rs new file mode 100644 index 000000000000..540a7c42d2fd --- /dev/null +++ b/src/test/ui/suggestions/issue-61963.rs @@ -0,0 +1,25 @@ +// aux-build:issue-61963.rs +// aux-build:issue-61963-1.rs +#![deny(bare_trait_objects)] + +#[macro_use] +extern crate issue_61963; +#[macro_use] +extern crate issue_61963_1; + +// This test checks that the bare trait object lint does not trigger on macro attributes that +// generate code which would trigger the lint. + +pub struct Baz; +pub trait Bar { } +pub struct Qux(T); + +#[dom_struct] +//~^ ERROR trait objects without an explicit `dyn` are deprecated [bare_trait_objects] +pub struct Foo { + qux: Qux>, + bar: Box, + //~^ ERROR trait objects without an explicit `dyn` are deprecated [bare_trait_objects] +} + +fn main() {} diff --git a/src/test/ui/suggestions/issue-61963.stderr b/src/test/ui/suggestions/issue-61963.stderr new file mode 100644 index 000000000000..261b384ca571 --- /dev/null +++ b/src/test/ui/suggestions/issue-61963.stderr @@ -0,0 +1,20 @@ +error: trait objects without an explicit `dyn` are deprecated + --> $DIR/issue-61963.rs:21:14 + | +LL | bar: Box, + | ^^^ help: use `dyn`: `dyn Bar` + | +note: lint level defined here + --> $DIR/issue-61963.rs:3:9 + | +LL | #![deny(bare_trait_objects)] + | ^^^^^^^^^^^^^^^^^^ + +error: trait objects without an explicit `dyn` are deprecated + --> $DIR/issue-61963.rs:17:1 + | +LL | #[dom_struct] + | ^^^^^^^^^^^^^ help: use `dyn`: `dyn #[dom_struct]` + +error: aborting due to 2 previous errors +