Skip to content

Commit 3a08528

Browse files
committed
fix: include clippy symbols to be interned, remove duplicates, and improve docs
Turns out the compiler will ICE if there are multiple extra symbols with the same value. Additionally, `clippy_utils` depends on its extra symbols starting directly after `PREDEFINED_SYMBOLS_COUNT`, so we need to include it first.
1 parent f6b0645 commit 3a08528

File tree

2 files changed

+77
-11
lines changed

2 files changed

+77
-11
lines changed

bevy_lint/src/callback.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ impl Callbacks for BevyLintCallback {
8989
// Give the compiler a list of extra `Symbol`s to intern ahead of time. This helps us avoid
9090
// calling `Symbol::intern()` while linting. See the `sym` module for a more detailed
9191
// explanation.
92-
config.extra_symbols = crate::sym::EXTRA_SYMBOLS.to_vec();
92+
config.extra_symbols = crate::sym::extra_symbols();
9393
}
9494
}
9595

bevy_lint/src/sym.rs

Lines changed: 76 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,71 @@
11
//! Pre-interned [`Symbol`]s available in `const` contexts.
22
//!
33
//! [`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.
4+
//! cheap to store and compare (they're secretly [`u32`]s!). This module contains a list of pre-
5+
//! interned symbol constants that are used in the linter.
6+
//!
7+
//! # Symbol Offsets
8+
//!
9+
//! The linter allocates symbols in the following layout:
10+
//!
11+
//! <table>
12+
//! <thead>
13+
//! <tr>
14+
//! <th>Index</th>
15+
//! <th>Note</th>
16+
//! </tr>
17+
//! </thead>
18+
//! <tbody>
19+
//! <tr>
20+
//! <td>0</td>
21+
//! <td rowspan="4">Symbols in <code>rustc_span::sym</code></td>
22+
//! </tr>
23+
//! <tr>
24+
//! <td>1</td>
25+
//! </tr>
26+
//! <tr>
27+
//! <td>2</td>
28+
//! </tr>
29+
//! <tr>
30+
//! <td>...</td>
31+
//! </tr>
32+
//! <tr>
33+
//! <td><code>PREDEFINED_SYMBOLS_COUNT</code></td>
34+
//! <td rowspan="2">Symbols in <code>clippy_utils::sym</code></td>
35+
//! </tr>
36+
//! <tr>
37+
//! <td>...</td>
38+
//! </tr>
39+
//! <tr>
40+
//! <td><code>SYMBOL_OFFSET</code></td>
41+
//! <td rowspan="2">Symbols in <code>bevy_lint::sym</code></td>
42+
//! </tr>
43+
//! <tr>
44+
//! <td>...</td>
45+
//! </tr>
46+
//! </tbody>
47+
//! </table>
48+
//!
49+
//! Note that the order here is important. [`clippy_utils`] expects its symbols to start at
50+
//! [`PREDEFINED_SYMBOLS_COUNT`], which is why it's before Bevy's symbols.
751
852
#![allow(
953
non_upper_case_globals,
1054
reason = "Symbol constants are named as-is so it is easy to see what strings they represent."
1155
)]
1256

57+
use clippy_utils::sym::EXTRA_SYMBOLS as CLIPPY_SYMBOLS;
1358
use rustc_span::{Symbol, symbol::PREDEFINED_SYMBOLS_COUNT};
1459

60+
/// These are symbols that we use but are already interned by either the compiler or Clippy.
61+
pub use rustc_span::sym::{bevy_ecs, plugin, reflect};
62+
63+
/// The starting offset used for the first Bevy-specific symbol.
64+
///
65+
/// This is used instead of [`PREDEFINED_SYMBOLS_COUNT`] because this takes into account Clippy's
66+
/// pre-interned symbols as well.
67+
const SYMBOL_OFFSET: u32 = PREDEFINED_SYMBOLS_COUNT + CLIPPY_SYMBOLS.len() as u32;
68+
1569
/// A helper used by [`declare_bevy_symbols!`] to extract its input.
1670
///
1771
/// ```
@@ -27,7 +81,7 @@ macro_rules! extract_value {
2781
};
2882
}
2983

30-
/// Generates the [`Symbol`] constants and [`EXTRA_SYMBOLS`] from a list of name-value pairs.
84+
/// Generates the [`Symbol`] constants and [`BEVY_SYMBOLS`] from a list of name-value pairs.
3185
///
3286
/// # Example
3387
///
@@ -45,26 +99,27 @@ macro_rules! declare_bevy_symbols {
4599
} => {
46100
/// A list of strings that are pre-interned at the beginning of linting through
47101
/// [`Config::extra_symbols`](rustc_interface::interface::Config::extra_symbols).
48-
pub const EXTRA_SYMBOLS: &[&str] = &[
102+
const BEVY_SYMBOLS: &[&str] = &[
49103
$(
50104
extract_value!($name $(: $value)?)
51105
),*
52106
];
53107

54108
$(
55109
#[doc = concat!("A pre-interned [`Symbol`] for the string \"", extract_value!($name $(: $value)?), "\".")]
56-
pub const $name: Symbol = Symbol::new(PREDEFINED_SYMBOLS_COUNT + ${index()});
110+
pub const $name: Symbol = Symbol::new(SYMBOL_OFFSET + ${index()});
57111
)*
58112
};
59113
}
60114

115+
// Before adding a new symbol here, check that it doesn't exist yet in `rustc_span::sym` or
116+
// `clippy_utils::sym`. Having duplicate symbols will cause the compiler to ICE! Also please keep
117+
// this list alphabetically sorted :)
61118
declare_bevy_symbols! {
62-
// Keep this list alphabetically sorted :)
63119
app,
64120
App,
65121
base,
66122
bevy_app,
67-
bevy_ecs,
68123
bevy_ptr,
69124
bevy_reflect,
70125
bevy,
@@ -91,12 +146,10 @@ declare_bevy_symbols! {
91146
MutUntyped,
92147
NonSendMut,
93148
PartialReflect,
94-
plugin,
95149
Plugin,
96150
PtrMut,
97151
query,
98152
Query,
99-
reflect,
100153
Reflect,
101154
ResMut,
102155
resource,
@@ -111,3 +164,16 @@ declare_bevy_symbols! {
111164
world,
112165
World,
113166
}
167+
168+
/// Returns a list of strings that should be supplied to
169+
/// [`Config::extra_symbols`](rustc_interface::interface::Config::extra_symbols).
170+
pub fn extra_symbols() -> Vec<&'static str> {
171+
let mut symbols = Vec::with_capacity(CLIPPY_SYMBOLS.len() + BEVY_SYMBOLS.len());
172+
173+
// The Clippy symbols must be before the Bevy symbols, as `clippy_utils` depends on its
174+
// predefined symbols having specific values.
175+
symbols.extend_from_slice(CLIPPY_SYMBOLS);
176+
symbols.extend_from_slice(BEVY_SYMBOLS);
177+
178+
symbols
179+
}

0 commit comments

Comments
 (0)