arrow_backRetour aux issues
repowise-dev/repowise
#1886
Débutant
Ouvrirarrow_forward
Débutant
Ouvrirarrow_forward
Débutant
Ouvrirarrow_forward
[Bug] A call site can resolve to a module, and a module is not callable
ecoDébutant
bug
help wanted
descriptionDescription
**Summary**
A call site can resolve to a symbol whose kind is `module`, and a module is not
callable in any language we index. The edge is minted at 0.85 or 0.50
confidence and points at a `mod` declaration.
Seen on bevy: `error!(` at `crates/bevy_pbr/src/render/mesh.rs:2907` resolves to
`crates/bevy_ecs/src/lib.rs::error`, which is line 36 of that file:
```rust
pub mod error;
```
There is no `macro_rules! error` anywhere in `bevy_ecs/src/lib.rs`. The real
target is tracing's logging macro, brought in by `mesh.rs:85`:
```rust
use tracing::{error, warn};
```
`mesh.rs` also imports from `bevy_ecs` (`mesh.rs:24-25`), so `bevy_ecs`'s
symbols are in the merged lookup, and the module named `error` is the one that
answers.
**Mechanism**
Two things combine, and each is independently a defect.
1. `_NON_CALLABLE_KINDS` in `packages/core/src/repowise/core/ingestion/call_resolver.py:129`
is `frozenset({"property"})`. `module` is not in it, so a module symbol is
treated as a legitimate call target everywhere.
2. That set is consulted on the global-unique tier only
(`call_resolver.py:1137`). The import tiers above it, `import_scoped` at
`:1109` and `import_merged` at `:1113-1115`, apply no kind filter at all, so
they can answer with a non-callable symbol even once the set is corrected.
The bevy site above goes through `import_merged`.
**Repro**
Three files, no external crates:
`src/lib.rs`
```rust
pub mod warn;
```
`src/warn/mod.rs`
```rust
pub fn helper() {}
```
`src/user.rs`
```rust
use crate::warn;
fn run() {
warn!("something happened");
}
```
Result on `main`:
```
calls src/user.rs::run -> src/lib.rs::warn | callee kind: module | origin: global_unique
```
`warn!` is the standard logging macro. The edge instead lands on a module
declaration. Note this repro fires on the global-unique tier, which does have
the filter, so it isolates half 1 above; the bevy site isolates half 2.
**Impact**
Unsized. It was found as the single wrong target in 30 rust call sites read
from source during a precision audit, so 1 in 30 on that sample and nothing
more is claimed. The first thing to measure is how many call sites across the
corpus resolve to a symbol whose kind is `module`, per language, since the
merged-import tier is language-agnostic and rust is unlikely to be the only one
affected.
Worth knowing: this is the same class as the fix in `dc797b36`, which taught
the global-unique tier that a struct field is not callable. That commit is the
model to copy, including its rule.
**Done looks like**
`module` is refused as a call target, and the refusal is applied on the import
tiers as well as the global-unique one.
Two constraints carried over from `dc797b36`, both load bearing:
* **Filter the answer, never the pool.** The refusal must sit after the
candidate has been chosen and must return rather than fall through, so the
tier can lose an edge and can never gain one. Filtering the candidate pool
before the uniqueness test re-uniquifies a name that two symbols share and
fires the tier where it used to refuse.
* **Grade removals per language.** A tier registered for one language family
does not share its premise elsewhere. Report what is removed per language
rather than in total.
Gate: removed edges read wrong on a sample from the population diff, controls
byte-identical on repositories with no module-kind symbols, and dead-code
findings unmoved. "Removes N, gains 0" is not sufficient on its own.
Tests: the repro above pinned as a parser or resolver test, plus one covering
the import-tier path, plus a control showing an ordinary free-function call in
the same file still resolves.
Issues similaires
calkit/calkit
star53
Poids du dépôt moyen
VS Code extension should be robust to YAML parser errors
Seeing this error: ``` Failed to read calkit.yaml: YAMLParseError: A block sequence may not be used as an implicit map…
Python
bug
good first issue
fu351/Doberman-Core
star211
Poids du dépôt léger
dash: a manual Refresh control
The dashboard polls: `refreshStats()` (`src/doberman/dash/app.py:408`) every 5 s and `refreshPending()` (`:546`) every …
Python
enhancement
good first issue
fu351/Doberman-Core
star211
Poids du dépôt léger
dash: "Copy details" button on each pending-approval card
Each pending-approval card in the dashboard (`renderPending`, `src/doberman/dash/app.py:448-544`) shows the risk badge,…
Python
enhancement
good first issue