Learn to write Rust procedural macros [Rust Latam conference, Montevideo Uruguay, March 2019]
This report summarizes scanner evidence for dtolnay/proc-macro-workshop, a Rust project with 4,864 GitHub stars. SynthScan examined 2,840 lines of code across 71 source files, recording 62 pattern matches distributed across 2 syntactic categories. The legacy adjusted pattern signal is 24.6 (Elevated pattern signal); it is not an authorship estimate.
Use the findings to ask whether maintainers can explain intent, verify dependencies, simplify unnecessary scaffolding, and focus review effort. Risk Payload v1 adds ownership, supply-chain, over-engineering, and review-effort vectors when available. These are prompts for human verification, not probabilities, security findings, or measured maintenance costs.
Use each vector to guide manual verification of the underlying findings.
Can maintainers explain intent, assumptions, and trade-offs? 58 finding(s).
Are imports declared and package/API names verified? 0 finding(s).
Are wrappers, guards, and repeated structures necessary? 4 finding(s).
Which changes need focused human review? 62 finding(s).
This chart tracks the legacy adjusted pattern score across scan runs. Changes can reflect source changes, scan coverage, or detector/scoring versions; they do not measure AI adoption or prove that a team refactored code. Compare runs only when their scoring versions are compatible. The dashed line tracks the raw pattern-hit count.
Groups findings by configured severity weight. Severity is not a confidence estimate, security rating, or proof that a package is missing. Verify imports against the project's manifests and inspect each finding in its local design context.
This horizontal bar chart shows where configured pattern scores accumulate across directories. Treat the bars as locations to inspect, not as evidence of authorship or code quality. Use the file-level findings to decide whether a directory needs a focused ownership, dependency, complexity, or review check.
The scanner identified 62 distinct pattern matches across 2 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a detector match to inspect in context. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.
Reading the findings table: The Severity column indicates the configured finding weight (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — legacy comment-context matches receive a ×1.5 score weight. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier under the legacy scoring model.
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | main.rs | 1 | // Write code here. | COMMENT |
| LOW | seq/tests/05-repeat-section.rs | 1 | // So far our macro has repeated the entire loop body. This is not sufficient | COMMENT |
| LOW | seq/tests/05-repeat-section.rs | 21 | // enum Interrupt { | COMMENT |
| LOW | seq/tests/03-expand-four-errors.rs | 1 | // Now construct the generated code! Produce the output TokenStream by repeating | COMMENT |
| LOW | seq/tests/01-parse-header.rs | 1 | // This test looks for a function-like macro with the right name to exist. For | COMMENT |
| LOW | seq/tests/02-parse-body.rs | 1 | // The macro invocation in the previous test case contained an empty loop body | COMMENT |
| LOW | seq/tests/08-ident-span.rs | 1 | // The procedural macro API uses a type called Span to attach source location | COMMENT |
| LOW | seq/tests/09-interaction-with-macrorules.rs | 1 | // Suppose we wanted a seq invocation in which the upper bound is given by the | COMMENT |
| LOW | seq/tests/progress.rs | 1 | #[test] | COMMENT |
| LOW | seq/tests/04-paste-ident.rs | 1 | // One of the big things callers will want to do with the sequential indices N | COMMENT |
| LOW | bitfield/tests/07-optional-discriminant.rs | 1 | // For bitfield use limited to a single binary, such as a space optimization for | COMMENT |
| LOW | bitfield/tests/01-specifier-types.rs | 1 | // Our design for #[bitfield] (see the readme) involves marker types B1 through | COMMENT |
| LOW | bitfield/tests/01-specifier-types.rs | 21 | // Physical = 0, | COMMENT |
| LOW | bitfield/tests/01-specifier-types.rs | 41 | // Create a trait called bitfield::Specifier with an associated constant BITS, | COMMENT |
| LOW | bitfield/tests/06-enums.rs | 1 | // For some bitfield members, working with them as enums will make more sense to | COMMENT |
| LOW | bitfield/tests/06-enums.rs | 21 | // explicit discriminant that is an integer literal. We will relax this | COMMENT |
| LOW | bitfield/tests/03-accessors.rs | 1 | // Generate getters and setters that manipulate the right range of bits | COMMENT |
| LOW | bitfield/tests/progress.rs | 1 | #[test] | COMMENT |
| LOW | bitfield/tests/12-accessors-edge.rs | 1 | // This test is equivalent to 03-accessors but with some fields spanning across | COMMENT |
| LOW | bitfield/tests/10-bits-attribute.rs | 1 | // One downside of the way we have implemented enum support so far is that it | COMMENT |
| LOW | bitfield/tests/04-multiple-of-8bits.rs | 1 | // Make it so that a bitfield with a size not a multiple of 8 bits will not | COMMENT |
| LOW | bitfield/tests/04-multiple-of-8bits.rs | 21 | // | COMMENT |
| LOW | bitfield/tests/02-storage.rs | 1 | // Write an attribute macro that replaces the struct in its input with a byte | COMMENT |
| LOW | bitfield/src/lib.rs | 1 | // Crates that have the "proc-macro" crate type are only allowed to export | COMMENT |
| LOW | sorted/tests/02-not-enum.rs | 1 | // The #[sorted] macro is only defined to work on enum types, so this is a test | COMMENT |
| LOW | sorted/tests/03-out-of-order.rs | 1 | // At this point we have an enum and we need to check whether the variants | COMMENT |
| LOW | sorted/tests/06-pattern-path.rs | 1 | // When we checked enum definitions for sortedness, it was sufficient to compare | COMMENT |
| LOW | sorted/tests/05-match-expr.rs | 1 | // Get ready for a challenging step -- this test case is going to be a much | COMMENT |
| LOW | sorted/tests/05-match-expr.rs | 21 | // | COMMENT |
| LOW | sorted/tests/05-match-expr.rs | 41 | // before. | COMMENT |
| LOW | sorted/tests/progress.rs | 1 | #[test] | COMMENT |
| LOW | sorted/tests/01-parse-enum.rs | 1 | // This test checks that an attribute macro #[sorted] exists and is imported | COMMENT |
| LOW | builder/tests/06-optional-field.rs | 1 | // Some fields may not always need to be specified. Typically these would be | COMMENT |
| LOW | builder/tests/06-optional-field.rs | 21 | // In the context of the current test case, all of this means that there isn't | COMMENT |
| LOW | builder/tests/06-optional-field.rs | 41 | // AngleBracketedGenericArguments { | COMMENT |
| LOW | builder/tests/09-redefined-prelude-types.rs | 1 | // Does your macro still work if some of the standard library prelude item names | COMMENT |
| LOW | builder/tests/02-create-builder.rs | 1 | // Have the macro produce a struct for the builder state, and a `builder` | COMMENT |
| LOW | builder/tests/02-create-builder.rs | 21 | // } | COMMENT |
| LOW | builder/tests/progress.rs | 1 | #[test] | COMMENT |
| LOW | builder/tests/08-unrecognized-attribute.rs | 1 | // Ensure that your macro reports a reasonable error message when the caller | COMMENT |
| LOW | builder/tests/07-repeated-field.rs | 1 | // The std::process::Command builder handles args in a way that is potentially | COMMENT |
| LOW | builder/tests/07-repeated-field.rs | 21 | // If the new one-at-a-time builder method is given the same name as the field, | COMMENT |
| LOW | builder/tests/03-call-setters.rs | 1 | // Generate methods on the builder for setting a value of each of the struct | COMMENT |
| LOW | builder/tests/01-parse.rs | 1 | // This test looks for a derive macro with the right name to exist. For now the | COMMENT |
| LOW | builder/tests/04-call-build.rs | 1 | // Generate a `build` method to go from builder to original struct. | COMMENT |
| LOW | debug/tests/07-associated-type.rs | 1 | // This test case covers one more heuristic that is often worth incorporating | COMMENT |
| LOW | debug/tests/04-type-parameter.rs | 1 | // Figure out what impl needs to be generated for the Debug impl of Field<T>. | COMMENT |
| LOW | debug/tests/08-escape-hatch.rs | 1 | // There are some cases where no heuristic would be sufficient to infer the | COMMENT |
| LOW | debug/tests/progress.rs | 1 | #[test] | COMMENT |
| LOW | debug/tests/05-phantom-data.rs | 1 | // Some generic types implement Debug even when their type parameters do not. | COMMENT |
| LOW | debug/tests/05-phantom-data.rs | 21 | // in other application-specific special cases. | COMMENT |
| LOW | debug/tests/03-custom-format.rs | 1 | // Look for a field attribute #[debug = "..."] on each field. If present, find a | COMMENT |
| LOW | debug/tests/02-impl-debug.rs | 1 | // Emit an implementation of std::fmt::Debug for a basic struct with named | COMMENT |
| LOW | debug/tests/01-parse.rs | 1 | // This test looks for a derive macro with the right name to exist. For now the | COMMENT |
| LOW | debug/tests/06-bound-trouble.rs | 1 | // This test case should not require any code change in your macro if you have | COMMENT |
| LOW | debug/tests/06-bound-trouble.rs | 21 | // T: Debug, | COMMENT |
| LOW | debug/tests/06-bound-trouble.rs | 41 | // | COMMENT |
| LOW | debug/tests/06-bound-trouble.rs | 61 | // --> | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | bitfield/tests/03-accessors.rs | 6 | // ╟───────────────╫───────────────╫───────────────╫───────────────╢ | COMMENT |
| MEDIUM | bitfield/tests/03-accessors.rs | 8 | // ╟─╫─────╫───────╫───────────────────────────────────────────────╢ | COMMENT |
| MEDIUM | bitfield/tests/12-accessors-edge.rs | 7 | // ╟───────────────╫───────────────╫───────────────╫───────────────╢ | COMMENT |
| MEDIUM | bitfield/tests/12-accessors-edge.rs | 9 | // ╟─────────────────╫───────────╫─────────────────────────╫───────╢ | COMMENT |