Skip to content

Commit 99307ff

Browse files
committed
Handle nested syn::Type:::Group
Currently, rustc does not pass the exact original TokenStream to proc-macros in several cases. This has many undesirable effects, such as losing correct location information in error message. See rust-lang/rust#43081 for more details In the future, rustc will begin passing the correct TokenStream to proc-macros. As a result, `syn` may wrap a type in one or more `syn::Type::Group`s (if the proc-macro input came from a `macro_rules!` expansion). I've determined that this can cause `oauth1-request-derive` to fail to match a `Type::Path`. This PR should properly handle nested groups, allowing your crate to work with both old and new input. If you have any questions, feel free to ask me. See rust-lang/rust#72622 for more details.
1 parent 97c90e4 commit 99307ff

File tree

2 files changed

+9
-19
lines changed

2 files changed

+9
-19
lines changed

oauth1-request-derive/src/method_body.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,11 @@ impl<'a> ToTokens for MethodBody<'a> {
4747
}
4848

4949
let ty_is_option = f.meta.option.get().map(|v| **v).unwrap_or_else(|| {
50-
if let Type::Path(ref ty_path) = f.ty {
50+
let mut ty = &f.ty;
51+
while let Type::Group(g) = ty {
52+
ty = &g.elem;
53+
}
54+
if let Type::Path(ref ty_path) = ty {
5155
let path = &ty_path.path;
5256
path.leading_colon.is_none()
5357
&& path.segments.len() == 1

oauth1-request-derive/tests/compile-fail/typeck.rs

+4-18
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,8 @@ use std::fmt::{self, Formatter};
22

33
#[derive(oauth1_request_derive::Authorize)]
44
//~^ ERROR: mismatched types
5-
//~| expected u8, found ()
6-
//~^^^ ERROR: mismatched types
7-
//~| expected (), found u8
8-
//~^^^^^ ERROR: `()` doesn't implement `std::fmt::Display`
9-
//~^^^^^^ ERROR: the trait bound `(): std::convert::AsRef<str>` is not satisfied
10-
//~^^^^^^^ ERROR: the trait bound `u8: std::convert::AsRef<str>` is not satisfied
11-
// FIXME: move these errors to (1) to (5) respectively
5+
//~| ERROR: `()` doesn't implement `std::fmt::Display`
6+
//~| ERROR: mismatched types
127
struct Test {
138
not_display: (),
149
//^ (3)
@@ -20,31 +15,26 @@ struct Test {
2015

2116
#[oauth1(fmt = "fmt_arg_not_ref")]
2217
//~^ ERROR: mismatched types
23-
//~| expected reference, found ()
2418
fmt_arg_not_ref: (),
2519

2620
#[oauth1(fmt = "fmt_arg_mismatch")]
27-
//^ (1)
2821
fmt_arg_mismatch: (),
2922

3023
#[oauth1(fmt = "fmt_trait_bound_unsatisfied")]
31-
//^ (4)
24+
//~^ the trait bound `(): std::convert::AsRef<str>`
3225
fmt_trait_bound_unsatisfied: (),
3326

3427
#[oauth1(fmt = "fmt_ret_mismatch")]
3528
//~^ ERROR: mismatched types
36-
//~| expected struct `std::fmt::Error`, found ()
3729
fmt_ret_mismatch: (),
3830

3931
#[oauth1(fmt = "NOT_FN")]
4032
//~^ ERROR: mismatched types
41-
//~| expected fn pointer, found ()
4233
fmt_not_fn: (),
4334

4435
#[oauth1(option = "true")]
4536
option_not_option: u8,
4637
//~^ ERROR: mismatched types
47-
//~| expected enum `std::option::Option`, found u8
4838

4939
#[oauth1(skip_if = "skip_if_too_many_args")]
5040
//~^ ERROR: mismatched types
@@ -53,25 +43,21 @@ struct Test {
5343

5444
#[oauth1(skip_if = "skip_if_arg_not_ref")]
5545
//~^ ERROR: mismatched types
56-
//~| expected reference, found u8
5746
skip_if_arg_not_ref: u8,
5847

5948
#[oauth1(skip_if = "skip_if_arg_mismatch")]
60-
//^ (2)
6149
skip_if_arg_mismatch: u8,
6250

6351
#[oauth1(skip_if = "skip_if_trait_bound_unsatisfied")]
64-
//- (5)
52+
//~^ ERROR: the trait bound `u8: std::convert::AsRef<str>`
6553
skip_if_trait_bound_unsatisfied: u8,
6654

6755
#[oauth1(skip_if = "skip_if_ret_mismatch")]
6856
//~^ ERROR: mismatched types
69-
//~| expected bool, found enum `std::option::Option`
7057
skip_if_ret_mismatch: u8,
7158

7259
#[oauth1(skip_if = "NOT_FN")]
7360
//~^ ERROR: mismatched types
74-
//~| expected fn pointer, found ()
7561
skip_if_not_fn: u8,
7662
}
7763

0 commit comments

Comments
 (0)