1
1
#![ feature(
2
2
proc_macro_tracked_env, // Used for `DEBUG_DERIVE`
3
+ proc_macro_span, // Used for source file ids
3
4
) ]
4
5
extern crate proc_macro;
5
6
@@ -151,6 +152,20 @@ impl Default for TypeAttrs {
151
152
}
152
153
}
153
154
}
155
+ fn span_file_loc ( span : Span ) -> String {
156
+ /*
157
+ * Source file identifiers in the form `<file_name>:<lineno>`
158
+ */
159
+ let internal = span. unwrap ( ) ;
160
+ let sf = internal. source_file ( ) ;
161
+ let path = sf. path ( ) ;
162
+ let file_name = if sf. is_real ( ) { path. file_name ( ) } else { None }
163
+ . map ( std:: ffi:: OsStr :: to_string_lossy)
164
+ . map ( String :: from)
165
+ . unwrap_or_else ( || String :: from ( "<fake>" ) ) ;
166
+ let lineno = internal. start ( ) . line ;
167
+ format ! ( "{}:{}" , file_name, lineno)
168
+ }
154
169
impl Parse for TypeAttrs {
155
170
fn parse ( raw_input : ParseStream ) -> Result < Self , Error > {
156
171
let input;
@@ -338,14 +353,14 @@ impl Parse for TypeAttrs {
338
353
339
354
#[ proc_macro]
340
355
pub fn unsafe_gc_impl ( input : proc_macro:: TokenStream ) -> proc_macro:: TokenStream {
341
- let cloned_impl = input. clone ( ) ;
342
356
let parsed = parse_macro_input ! ( input as macros:: MacroInput ) ;
343
357
let res = parsed. expand_output ( )
344
358
. unwrap_or_else ( |e| e. to_compile_error ( ) ) ;
359
+ let span_loc = span_file_loc ( Span :: call_site ( ) ) ;
345
360
debug_derive (
346
361
"unsafe_gc_impl!" ,
347
- & "" ,
348
- & format_args ! ( "#[ unsafe_gc_impl {{ {} }} " , cloned_impl ) ,
362
+ & span_loc ,
363
+ & format_args ! ( "unsafe_gc_impl! @ {}" , span_loc ) ,
349
364
& res
350
365
) ;
351
366
res. into ( )
@@ -359,7 +374,7 @@ pub fn derive_trace(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
359
374
. unwrap_or_else ( |e| e. to_compile_error ( ) ) ) ;
360
375
debug_derive (
361
376
"derive(Trace)" ,
362
- & input. ident ,
377
+ & input. ident . to_string ( ) ,
363
378
& format_args ! ( "#[derive(Trace) for {}" , input. ident) ,
364
379
& res
365
380
) ;
@@ -1084,22 +1099,22 @@ fn debug_derive(key: &str, target: &dyn ToString, message: &dyn Display, value:
1084
1099
let target = target. to_string ( ) ;
1085
1100
// TODO: Use proc_macro::tracked_env::var
1086
1101
match :: proc_macro:: tracked_env:: var ( "DEBUG_DERIVE" ) {
1087
- Ok ( ref var) if var == "*" => { }
1102
+ Ok ( ref var) if var == "*" || var == "1" || var. is_empty ( ) => { }
1103
+ Ok ( ref var) if var == "0" => { return /* disabled */ }
1088
1104
Ok ( var) => {
1105
+ let target_parts = std:: iter:: once ( key)
1106
+ . chain ( target. split ( ":" ) ) . collect :: < Vec < _ > > ( ) ;
1089
1107
for pattern in var. split_terminator ( "," ) {
1090
- let parts = pattern. split ( ":" ) . collect :: < Vec < _ > > ( ) ;
1091
- let ( desired_key, desired_target) = match * parts {
1092
- [ desired_key, desired_target] => ( desired_key, Some ( desired_target) ) ,
1093
- [ desired_key] => ( desired_key, None ) ,
1094
- _ => {
1095
- panic ! ( "Invalid pattern for debug derive: {}" , pattern)
1108
+ let pattern_parts = pattern. split ( ":" ) . collect :: < Vec < _ > > ( ) ;
1109
+ if pattern_parts. len ( ) > target_parts. len ( ) { continue }
1110
+ for ( & pattern_part, & target_part) in pattern_parts. iter ( )
1111
+ . chain ( std:: iter:: repeat ( & "*" ) ) . zip ( & target_parts) {
1112
+ if pattern_part == "*" {
1113
+ continue // Wildcard matches anything: Keep checking
1114
+ }
1115
+ if pattern_part != target_part {
1116
+ return // Pattern mismatch
1096
1117
}
1097
- } ;
1098
- if desired_key != key && desired_key != "*" { return }
1099
- if let Some ( desired_target) = desired_target {
1100
- if desired_target != target && desired_target != "*" {
1101
- return
1102
- }
1103
1118
}
1104
1119
}
1105
1120
// Fallthrough -> enable this debug
0 commit comments