Skip to content

Make all proc macros optional#425

Merged
nicoburns merged 7 commits intomainfrom
optional-proc-macros
Mar 11, 2026
Merged

Make all proc macros optional#425
nicoburns merged 7 commits intomainfrom
optional-proc-macros

Conversation

@nicoburns
Copy link
Contributor

@nicoburns nicoburns commented Mar 9, 2026

This PR makes all proc macros optional behind feature flags (and removes one completely, replacing it with const evaluation):

  • Replace the dummy_match_byte feature (which disables the optimised match_byte! macro and replaces it with a simple match statement) with a fast_match_byte feature which enables the optimised match_byte! macro. This feature is enabled by default, but means if you build with --no-default-features then you don't get the proc macro.
  • Replace the _cssparser_internal_max_len proc macro with const evaluation.
  • Building on the above two changes, make the cssparser-macros dep optional (only enabled by fast_match_byte feature)
  • Improve the syntax of the ascii_case_insensitive_phf_map! macro (see below) removed
  • Make phf optional for color keyword lookup. This is gated behind a fast_match_color feature flag. When the flag is disabled the

All of the new feature flags are enabled by default, so if you use cssparser with default features enabled there is no change except for the ascii_case_insensitive_phf_map! macro syntax.

I have also bumped MSRV from 1.68 to 1.71. This is not actually related to this PR, but is required by recent patch versions of syn (in fact, with this PR cssparser builds down to 1.63 with default features disabled, but I figure 1.71 is probably old enough?)

With this PR dependency tree with no default features is just:

cssparser v0.35.0 (/Users/nico/code/oss/cssparser)
├── dtoa-short v0.3.3
│   └── dtoa v0.4.8
├── itoa v1.0.6
└── smallvec v1.10.0

With default features it is:

cssparser v0.35.0 (/Users/nico/code/oss/cssparser)
├── cssparser-macros v0.6.1 (proc-macro) (/Users/nico/code/oss/cssparser/macros)
│   ├── quote v1.0.38
│   │   └── proc-macro2 v1.0.101
│   │       └── unicode-ident v1.0.8
│   └── syn v2.0.98
│       ├── proc-macro2 v1.0.101 (*)
│       ├── quote v1.0.38 (*)
│       └── unicode-ident v1.0.8
├── dtoa-short v0.3.3
│   └── dtoa v0.4.8
├── itoa v1.0.6
├── phf v0.13.1
│   ├── phf_macros v0.13.1 (proc-macro)
│   │   ├── phf_generator v0.13.1
│   │   │   ├── fastrand v2.3.0
│   │   │   └── phf_shared v0.13.1
│   │   │       └── siphasher v1.0.1
│   │   ├── phf_shared v0.13.1 (*)
│   │   ├── proc-macro2 v1.0.101 (*)
│   │   ├── quote v1.0.38 (*)
│   │   └── syn v2.0.98 (*)
│   └── phf_shared v0.13.1 (*)
└── smallvec v1.10.0
`ascii_case_insensitive_phf_map` syntax change removed

ascii_case_insensitive_phf_map syntax

The macro syntax was previously:

cssparser::ascii_case_insensitive_phf_map! {
    keywords -> (u8, u8, u8) = {
        "red" => (255, 0, 0),
        "green" => (0, 255, 0),
        "blue" => (0, 0, 255),
    }
}
cssparser::ascii_case_insensitive_phf_map! {
    static keywords : (u8, u8, u8) = {
        "red" => (255, 0, 0),
        "green" => (0, 255, 0),
        "blue" => (0, 0, 255),
    }
}

This uses the conventional Rust : syntax for defining a type. And also makes it clearer that the keywords bit is an ident that is being defined.

@nicoburns nicoburns force-pushed the optional-proc-macros branch 2 times, most recently from 0d65f79 to 7cad461 Compare March 9, 2026 18:15
@nicoburns nicoburns marked this pull request as ready for review March 9, 2026 18:27
@nicoburns nicoburns requested a review from emilio March 9, 2026 18:27
Copy link
Member

@emilio emilio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you split the less controversial patches into their own PR?

This patch breaks selectors and stylo pretty massively, btw... All of it fixable, but some of the fixes that are needed are a bit annoying, e.g.:

diff --git a/servo/components/style/media_queries/media_query.rs b/servo/components/style/media_queries/media_query.rs
index 9370c0a2a184..f0aad9b52ed4 100644
--- a/servo/components/style/media_queries/media_query.rs
+++ b/servo/components/style/media_queries/media_query.rs
@@ -50,7 +50,11 @@ impl MediaType {
         // Here we also perform the to-ascii-lowercase part of the serialization
         // algorithm: https://drafts.csswg.org/cssom/#serializing-media-queries
         match_ignore_ascii_case! { name,
-            "not" | "or" | "and" | "only" | "layer" => Err(()),
+            "not" => Err(()),
+            "or" => Err(()),
+            "and" => Err(()),
+            "only" => Err(()),
+            "layer" => Err(()),
             _ => Ok(MediaType(CustomIdent(Atom::from(string_as_ascii_lowercase(name))))),
         }
     }

src/macros.rs Outdated
$(
$( #[$meta: meta] )*
$( $pattern: pat )|+ $( if $guard: expr )? => $then: expr
$pattern: literal $( if $guard: expr )? => $then: expr
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a breaking change and one that makes the API a lot more annoying to use... That's a bit unfortunate?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I didn't realise that selectors/stylo were also using these macros. I think it might be possible to add the repetition back into the macro (although the pat -> literal change would need to stay). Let me give that a go first.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've reinstated the repetition in the macro. In my testing, stylo and selectors now compile against this PR without any changes at all.

@nicoburns nicoburns force-pushed the optional-proc-macros branch 2 times, most recently from 825219c to 355cf8f Compare March 9, 2026 21:56
@nicoburns nicoburns requested a review from emilio March 9, 2026 22:02
Copy link
Member

@emilio emilio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two nits, but looks good with those, thanks.

- 1.68.0
- 1.71.0
features:
- --no-default-features
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's keep testing the default features by default please. Instead, let's add --no-default-features below.

Signed-off-by: Nico Burns <nico@nicoburns.com>
@nicoburns nicoburns force-pushed the optional-proc-macros branch from c7671f5 to d5cabf3 Compare March 11, 2026 16:07
Copy link
Member

@emilio emilio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Consider squashing the "nits" commits into the relevant ones?

@nicoburns nicoburns force-pushed the optional-proc-macros branch from d5cabf3 to 8cf964d Compare March 11, 2026 16:12
@nicoburns nicoburns added this pull request to the merge queue Mar 11, 2026
Merged via the queue into main with commit 4d4568b Mar 11, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants