11#![ feature(
22 proc_macro_tracked_env, // Used for `DEBUG_DERIVE`
3+ proc_macro_span, // Used for source file ids
34) ]
45extern crate proc_macro;
56
@@ -151,6 +152,20 @@ impl Default for TypeAttrs {
151152 }
152153 }
153154}
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+ }
154169impl Parse for TypeAttrs {
155170 fn parse ( raw_input : ParseStream ) -> Result < Self , Error > {
156171 let input;
@@ -338,14 +353,14 @@ impl Parse for TypeAttrs {
338353
339354#[ proc_macro]
340355pub fn unsafe_gc_impl ( input : proc_macro:: TokenStream ) -> proc_macro:: TokenStream {
341- let cloned_impl = input. clone ( ) ;
342356 let parsed = parse_macro_input ! ( input as macros:: MacroInput ) ;
343357 let res = parsed. expand_output ( )
344358 . unwrap_or_else ( |e| e. to_compile_error ( ) ) ;
359+ let span_loc = span_file_loc ( Span :: call_site ( ) ) ;
345360 debug_derive (
346361 "unsafe_gc_impl!" ,
347- & "" ,
348- & format_args ! ( "#[ unsafe_gc_impl {{ {} }} " , cloned_impl ) ,
362+ & span_loc ,
363+ & format_args ! ( "unsafe_gc_impl! @ {}" , span_loc ) ,
349364 & res
350365 ) ;
351366 res. into ( )
@@ -359,7 +374,7 @@ pub fn derive_trace(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
359374 . unwrap_or_else ( |e| e. to_compile_error ( ) ) ) ;
360375 debug_derive (
361376 "derive(Trace)" ,
362- & input. ident ,
377+ & input. ident . to_string ( ) ,
363378 & format_args ! ( "#[derive(Trace) for {}" , input. ident) ,
364379 & res
365380 ) ;
@@ -1084,22 +1099,22 @@ fn debug_derive(key: &str, target: &dyn ToString, message: &dyn Display, value:
10841099 let target = target. to_string ( ) ;
10851100 // TODO: Use proc_macro::tracked_env::var
10861101 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 */ }
10881104 Ok ( var) => {
1105+ let target_parts = std:: iter:: once ( key)
1106+ . chain ( target. split ( ":" ) ) . collect :: < Vec < _ > > ( ) ;
10891107 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
10961117 }
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- }
11031118 }
11041119 }
11051120 // Fallthrough -> enable this debug
0 commit comments