Skip to content

Commit 44671e2

Browse files
committed
feat: create sym module for symbol interning
1 parent a8bfcc8 commit 44671e2

File tree

3 files changed

+68
-0
lines changed

3 files changed

+68
-0
lines changed

bevy_lint/src/callback.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,15 @@ impl Callbacks for BevyLintCallback {
8181
}
8282
}
8383
}));
84+
85+
// There shouldn't be any existing extra symbols, as we should be the only callback
86+
// overriding them.
87+
debug_assert!(config.extra_symbols.is_empty());
88+
89+
// Give the compiler a list of extra `Symbol`s to intern ahead of time. This helps us avoid
90+
// calling `Symbol::intern()` while linting. See the `sym` module for a more detailed
91+
// explanation.
92+
config.extra_symbols = crate::sym::EXTRA_SYMBOLS.to_vec();
8493
}
8594
}
8695

bevy_lint/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
#![feature(rustc_private)]
1717
// Allows chaining `if let` multiple times using `&&`.
1818
#![feature(let_chains)]
19+
// Used to access the index of repeating macro input in `declare_bevy_symbols!`.
20+
#![feature(macro_metavar_expr)]
1921
// Warn on internal `rustc` lints that check for poor usage of internal compiler APIs. Note that
2022
// you also need to pass `-Z unstable-options` to `rustc` for this to be enabled:
2123
// `RUSTFLAGS="-Zunstable-options" cargo check`
@@ -46,6 +48,7 @@ mod config;
4648
mod lint;
4749
pub mod lints;
4850
mod paths;
51+
mod sym;
4952
mod utils;
5053

5154
pub use self::callback::BevyLintCallback;

bevy_lint/src/sym.rs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
//! Pre-interned [`Symbol`]s available in `const` contexts.
2+
//!
3+
//! [`Symbol`]s are [interned strings](https://en.wikipedia.org/wiki/String_interning) that are
4+
//! cheap to store and compare. This module contains a list of pre-interned symbol constants that
5+
//! are used in the linter. The only exception to this is the [`EXTRA_SYMBOLS`] constant, which
6+
//! contains a complete ordered list of all symbols to be pre-interned.
7+
8+
use rustc_span::{Symbol, symbol::PREDEFINED_SYMBOLS_COUNT};
9+
10+
/// A helper used by [`declare_bevy_symbols!`] to extract its input.
11+
///
12+
/// ```
13+
/// assert_eq!(extract_value!(Name), "Name");
14+
/// assert_eq!(extract_value!(Name: "value"), "value");
15+
/// ```
16+
macro_rules! extract_value {
17+
($name:ident) => {
18+
stringify!($name)
19+
};
20+
($name:ident: $value:literal) => {
21+
$value
22+
};
23+
}
24+
25+
/// Generates the [`Symbol`] constants and [`EXTRA_SYMBOLS`] from a list of name-value pairs.
26+
///
27+
/// # Example
28+
///
29+
/// ```
30+
/// declare_bevy_symbols! {
31+
/// // Interns the string "Hello, world" available as the constant named `Hello`.
32+
/// Hello: "Hello, world!",
33+
/// // Interns the string "bevy" available as the constant named `bevy`. This is the shorthand!
34+
/// bevy,
35+
/// }
36+
/// ```
37+
macro_rules! declare_bevy_symbols {
38+
{
39+
$($name:ident $(: $value:literal)?),* $(,)?
40+
} => {
41+
/// A list of strings that are pre-interned at the beginning of linting through
42+
/// [`Config::extra_symbols`](rustc_interface::interface::Config::extra_symbols).
43+
pub const EXTRA_SYMBOLS: &[&str] = &[
44+
$(
45+
extract_value!($name $(: $value)?)
46+
),*
47+
];
48+
49+
$(
50+
#[doc = concat!("A pre-interned [`Symbol`] for the string \"", extract_value!($name $(: $value)?), "\".")]
51+
pub const $name: Symbol = Symbol::new(PREDEFINED_SYMBOLS_COUNT + ${index()});
52+
)*
53+
};
54+
}
55+
56+
declare_bevy_symbols! {}

0 commit comments

Comments
 (0)