@@ -11,8 +11,9 @@ extern crate syn;
11
11
use proc_macro2:: Span ;
12
12
use syn:: {
13
13
parse:: { self , Parse } ,
14
+ punctuated:: Punctuated ,
14
15
spanned:: Spanned ,
15
- FnArg , ItemFn , LitInt , LitStr , PatType , PathArguments , ReturnType , Type , Visibility ,
16
+ FnArg , ItemFn , LitInt , LitStr , PatType , ReturnType , Type , Visibility ,
16
17
} ;
17
18
18
19
use proc_macro:: TokenStream ;
@@ -67,10 +68,10 @@ pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream {
67
68
. into ( ) ;
68
69
}
69
70
70
- fn check_simple_type ( argument : & PatType , ty : & str ) -> Option < TokenStream > {
71
+ fn check_correct_type ( argument : & PatType , ty : & str ) -> Option < TokenStream > {
71
72
let inv_type_message = format ! ( "argument type must be {}" , ty) ;
72
73
73
- if !is_simple_type ( & argument. ty , ty) {
74
+ if !is_correct_type ( & argument. ty , ty) {
74
75
let error = parse:: Error :: new ( argument. ty . span ( ) , inv_type_message) ;
75
76
76
77
Some ( error. to_compile_error ( ) . into ( ) )
@@ -83,7 +84,7 @@ pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream {
83
84
let argument_error = argument_error. to_compile_error ( ) . into ( ) ;
84
85
85
86
match argument {
86
- FnArg :: Typed ( argument) => check_simple_type ( argument, ty) ,
87
+ FnArg :: Typed ( argument) => check_correct_type ( argument, ty) ,
87
88
FnArg :: Receiver ( _) => Some ( argument_error) ,
88
89
}
89
90
}
@@ -101,7 +102,7 @@ pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream {
101
102
}
102
103
#[ cfg( feature = "u-boot" ) ]
103
104
if let Some ( argument) = f. sig . inputs . get ( 1 ) {
104
- if let Some ( message) = check_argument_type ( argument, "usize " ) {
105
+ if let Some ( message) = check_argument_type ( argument, "*const *const c_char " ) {
105
106
return message;
106
107
}
107
108
}
@@ -151,17 +152,32 @@ pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream {
151
152
. into ( )
152
153
}
153
154
154
- #[ allow( unused) ]
155
- fn is_simple_type ( ty : & Type , name : & str ) -> bool {
156
- if let Type :: Path ( p) = ty {
157
- if p. qself . is_none ( ) && p. path . leading_colon . is_none ( ) && p. path . segments . len ( ) == 1 {
158
- let segment = p. path . segments . first ( ) . unwrap ( ) ;
159
- if segment. ident == name && segment. arguments == PathArguments :: None {
160
- return true ;
161
- }
155
+ fn strip_type_path ( ty : & Type ) -> Option < Type > {
156
+ match ty {
157
+ Type :: Ptr ( ty) => {
158
+ let mut ty = ty. clone ( ) ;
159
+ ty. elem = Box :: new ( strip_type_path ( & ty. elem ) ?) ;
160
+ Some ( Type :: Ptr ( ty) )
162
161
}
162
+ Type :: Path ( ty) => {
163
+ let mut ty = ty. clone ( ) ;
164
+ let last_segment = ty. path . segments . last ( ) . unwrap ( ) . clone ( ) ;
165
+ ty. path . segments = Punctuated :: new ( ) ;
166
+ ty. path . segments . push_value ( last_segment) ;
167
+ Some ( Type :: Path ( ty) )
168
+ }
169
+ _ => None ,
170
+ }
171
+ }
172
+
173
+ #[ allow( unused) ]
174
+ fn is_correct_type ( ty : & Type , name : & str ) -> bool {
175
+ let correct: Type = syn:: parse_str ( name) . unwrap ( ) ;
176
+ if let Some ( ty) = strip_type_path ( ty) {
177
+ ty == correct
178
+ } else {
179
+ false
163
180
}
164
- false
165
181
}
166
182
167
183
/// Attribute to mark which function will be called at the beginning of the reset handler.
0 commit comments