Skip to content

Commit 288f357

Browse files
committed
Start to implment a unsafe_gc_impl procedural macro
This is incomplete, but pretty darn awesome The core crate now depends on zerogc-derive and syn-full
1 parent da9130a commit 288f357

File tree

7 files changed

+422
-253
lines changed

7 files changed

+422
-253
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ readme = "README.md"
1414
# gives zerogc 'batteries included' support.
1515
indexmap = { version = "1.6", optional = true }
1616
# Used for macros
17-
zerogc-derive = { version = "0.2.0-alpha.1" }
17+
zerogc-derive = { path = "libs/derive", version = "0.2.0-alpha.1" }
1818

1919
[workspace]
2020
members = ["libs/simple", "libs/derive", "libs/context"]

libs/derive/src/lib.rs

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#![feature(
22
proc_macro_tracked_env, // Used for `DEBUG_DERIVE`
3+
proc_macro_span, // Used for source file ids
34
)]
45
extern 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+
}
154169
impl 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]
340355
pub 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

Comments
 (0)