From fc8d5cb1649e341b496388eb0311d8befeadc32a Mon Sep 17 00:00:00 2001 From: Steven Wroblewski Date: Thu, 1 Oct 2026 13:18:26 +0200 Subject: [PATCH] =?UTF-8?q?Textw=C3=A4chter=20erkennt=20gruppierte=20std-I?= =?UTF-8?q?mporte=20und=20globale=20Sperren?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mit `use std::{fs, process};` und anschließendem `fs::remove_file(…)` kam bisher beides durch: Der Textwächter suchte `std::fs` wörtlich, und Clippy kennt nur die aufgelisteten Funktionen. Globaler veränderlicher Zustand über `static` mit Mutex, RwLock, OnceLock oder LazyLock wurde auch nicht erkannt. Neu in FORBIDDEN: `std::{` (gruppierte Importe verbergen dem Text die Modulnamen) sowie Mutex, RwLock, OnceLock und LazyLock. Der Kern in core/src nutzt nichts davon. Der Kommentar in core/clippy.toml behauptet jetzt nur noch, was Clippy leistet, und CLAUDE.md nennt die Regel, dass jeder std-Pfad in einer eigenen use-Zeile steht. Der bestehende Selbsttest every_forbidden_term_is_detected deckt die neuen Einträge ab. Co-Authored-By: Claude Sonnet 5.5 --- CLAUDE.md | 2 +- core/clippy.toml | 9 ++++++--- core/tests/forbidden_apis.rs | 8 ++++++++ 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index adb8e4f..a7aaeec 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -31,7 +31,7 @@ Alle Spieler simulieren die Welt selbst und tauschen nur Befehle aus (Gleichschr - Wo eine Rechnung im Spiel überlaufen kann, steht eine ausdrückliche Wahl: `saturating_`, `wrapping_` oder `checked_`. Taktzähler laufen praktisch nie über und werden normal addiert: Die Welt zählt in `u64`, eine Aufzeichnung in `u32`, was bei 20 Takten pro Sekunde für über sechs Jahre reicht. Takte aus geladenen Dateien begrenzt `MAX_RESTORABLE_TICK`. - Keine fremden Crates im Kern. -Drei Wächter prüfen das. `core/clippy.toml` sperrt Pfade wie `std::collections::HashMap` oder `std::fs::read`, auch über Aliase und gruppierte Importe. Der Test `core/tests/forbidden_apis.rs` durchsucht zusätzlich den Text nach verbotenen Begriffen; sie dürfen dort auch in Kommentaren nicht vorkommen. `core/tests/no_dependencies.rs` hält die Abhängigkeiten leer. +Drei Wächter prüfen das. `core/clippy.toml` sperrt Pfade wie `std::collections::HashMap` oder `std::fs::read`, auch über Aliase und gruppierte Importe. Der Test `core/tests/forbidden_apis.rs` durchsucht zusätzlich den Text nach verbotenen Begriffen; sie dürfen dort auch in Kommentaren nicht vorkommen. Gruppierte Importe aus `std` (`use std::{…}`) sind verboten, weil sie dem Text die Modulnamen verbergen: Jeder Pfad steht in einer eigenen `use`-Zeile. `core/tests/no_dependencies.rs` hält die Abhängigkeiten leer. ## Regeln für Brücke und Hülle diff --git a/core/clippy.toml b/core/clippy.toml index b9246ee..4a8c984 100644 --- a/core/clippy.toml +++ b/core/clippy.toml @@ -1,6 +1,9 @@ -# Paths the deterministic core must never use. Clippy resolves imports, so -# aliases and grouped imports such as `use std::{fs, env}` are caught too. -# The text search in core/tests/forbidden_apis.rs covers the rest. +# Paths the deterministic core must never use. Clippy resolves paths, so a +# listed path is caught under an alias or in a grouped import as well, for +# example `fs::read` after `use std::{fs, env}`. Only the paths listed below +# are checked. Everything else is the job of the text search in +# core/tests/forbidden_apis.rs, which forbids grouped imports from `std` +# because they hide module names from it. disallowed-types = [ { path = "std::collections::HashMap", reason = "iteration order differs between runs; use BTreeMap or Vec" }, diff --git a/core/tests/forbidden_apis.rs b/core/tests/forbidden_apis.rs index 3f56d59..0ddfbf2 100644 --- a/core/tests/forbidden_apis.rs +++ b/core/tests/forbidden_apis.rs @@ -42,12 +42,20 @@ const FORBIDDEN: &[(&str, &str)] = &[ "the core must not read or write streams; the shell does that", ), ("std::process", "the core must not start or end processes"), + ( + "std::{", + "grouped std imports hide forbidden modules from this search; import each path on its own line", + ), ("static mut", "global mutable state can differ between runs"), ( "thread_local", "global mutable state can differ between runs", ), ("Atomic", "global mutable state can differ between runs"), + ("Mutex", "global mutable state can differ between runs"), + ("RwLock", "global mutable state can differ between runs"), + ("OnceLock", "global mutable state can differ between runs"), + ("LazyLock", "global mutable state can differ between runs"), ("unsafe", "the core forbids unsafe code"), ];