Skip to content

Commit 44bf6b6

Browse files
davidtwcolqd
andcommitted
tests: Add minimal reproduction of rust-lang#61963.
This commit adds a reproduction of the error reported in servo which demonstrates the current, incorrect behaviour. Co-authored-by: Rémy Rakić <[email protected]>
1 parent e9d2227 commit 44bf6b6

File tree

4 files changed

+126
-0
lines changed

4 files changed

+126
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// force-host
2+
// no-prefer-dynamic
3+
#![crate_type = "proc-macro"]
4+
5+
extern crate proc_macro;
6+
7+
use proc_macro::{Group, TokenStream, TokenTree};
8+
9+
// This macro exists as part of a reproduction of #61963 but without using quote/syn/proc_macro2.
10+
11+
#[proc_macro_derive(DomObject)]
12+
pub fn expand_token_stream(input: TokenStream) -> TokenStream {
13+
// Construct a dummy span - `#0 bytes(0..0)` - which is present in the input because
14+
// of the specially crafted generated tokens in the `attribute-crate` proc-macro.
15+
let dummy_span = input.clone().into_iter().nth(0).unwrap().span();
16+
17+
// Define what the macro would output if constructed properly from the source using syn/quote.
18+
let output: TokenStream = "impl Bar for ((), Qux<Qux<Baz> >) { }
19+
impl Bar for ((), Box<Bar>) { }".parse().unwrap();
20+
21+
let mut tokens: Vec<_> = output.into_iter().collect();
22+
// Adjust token spans to match the original crate (which would use `quote`). Some of the
23+
// generated tokens point to the dummy span.
24+
for token in tokens.iter_mut() {
25+
if let TokenTree::Group(group) = token {
26+
let mut tokens: Vec<_> = group.stream().into_iter().collect();
27+
for token in tokens.iter_mut().skip(2) {
28+
token.set_span(dummy_span);
29+
}
30+
31+
let mut stream = TokenStream::new();
32+
stream.extend(tokens);
33+
*group = Group::new(group.delimiter(), stream);
34+
}
35+
}
36+
37+
let mut output = TokenStream::new();
38+
output.extend(tokens);
39+
output
40+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// force-host
2+
// no-prefer-dynamic
3+
#![crate_type = "proc-macro"]
4+
5+
extern crate proc_macro;
6+
7+
use proc_macro::{Group, Spacing, Punct, TokenTree, TokenStream};
8+
9+
// This macro exists as part of a reproduction of #61963 but without using quote/syn/proc_macro2.
10+
11+
#[proc_macro_attribute]
12+
pub fn dom_struct(_: TokenStream, input: TokenStream) -> TokenStream {
13+
// Construct the expected output tokens - the input but with a `#[derive(DomObject)]` applied.
14+
let attributes: TokenStream =
15+
"#[derive(DomObject)]".to_string().parse().unwrap();
16+
let output: TokenStream = attributes.into_iter()
17+
.chain(input.into_iter()).collect();
18+
19+
let mut tokens: Vec<_> = output.into_iter().collect();
20+
// Adjust the spacing of `>` tokens to match what `quote` would produce.
21+
for token in tokens.iter_mut() {
22+
if let TokenTree::Group(group) = token {
23+
let mut tokens: Vec<_> = group.stream().into_iter().collect();
24+
for token in tokens.iter_mut() {
25+
if let TokenTree::Punct(p) = token {
26+
if p.as_char() == '>' {
27+
*p = Punct::new('>', Spacing::Alone);
28+
}
29+
}
30+
}
31+
32+
let mut stream = TokenStream::new();
33+
stream.extend(tokens);
34+
*group = Group::new(group.delimiter(), stream);
35+
}
36+
}
37+
38+
let mut output = TokenStream::new();
39+
output.extend(tokens);
40+
output
41+
}
+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// aux-build:issue-61963.rs
2+
// aux-build:issue-61963-1.rs
3+
#![deny(bare_trait_objects)]
4+
5+
#[macro_use]
6+
extern crate issue_61963;
7+
#[macro_use]
8+
extern crate issue_61963_1;
9+
10+
// This test checks that the bare trait object lint does not trigger on macro attributes that
11+
// generate code which would trigger the lint.
12+
13+
pub struct Baz;
14+
pub trait Bar { }
15+
pub struct Qux<T>(T);
16+
17+
#[dom_struct]
18+
//~^ ERROR trait objects without an explicit `dyn` are deprecated [bare_trait_objects]
19+
pub struct Foo {
20+
qux: Qux<Qux<Baz>>,
21+
bar: Box<Bar>,
22+
//~^ ERROR trait objects without an explicit `dyn` are deprecated [bare_trait_objects]
23+
}
24+
25+
fn main() {}
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error: trait objects without an explicit `dyn` are deprecated
2+
--> $DIR/issue-61963.rs:21:14
3+
|
4+
LL | bar: Box<Bar>,
5+
| ^^^ help: use `dyn`: `dyn Bar`
6+
|
7+
note: lint level defined here
8+
--> $DIR/issue-61963.rs:3:9
9+
|
10+
LL | #![deny(bare_trait_objects)]
11+
| ^^^^^^^^^^^^^^^^^^
12+
13+
error: trait objects without an explicit `dyn` are deprecated
14+
--> $DIR/issue-61963.rs:17:1
15+
|
16+
LL | #[dom_struct]
17+
| ^^^^^^^^^^^^^ help: use `dyn`: `dyn #[dom_struct]`
18+
19+
error: aborting due to 2 previous errors
20+

0 commit comments

Comments
 (0)