Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[red-knot] Improve symbol-lookup tracing #14907

Merged
merged 1 commit into from
Jan 7, 2025
Merged

Conversation

sharkdp
Copy link
Contributor

@sharkdp sharkdp commented Dec 11, 2024

Summary

When debugging, I frequently want to know which symbols are being looked up. symbol_by_id adds tracing information, but it only shows the ScopedSymbolId. Since symbol_by_id is only called from symbol, it seems reasonable to move the tracing call one level up from symbol_by_id to symbol, where we can also show the name of the symbol.

Before:

6      └─┐red_knot_python_semantic::types::infer::infer_expression_types{expression=Id(60de), file=/home/shark/tomllib_modified/_parser.py}
6        └─┐red_knot_python_semantic::types::symbol_by_id{symbol=ScopedSymbolId(33)}
6        ┌─┘
6        └─┐red_knot_python_semantic::types::symbol_by_id{symbol=ScopedSymbolId(123)}
6        ┌─┘
6        └─┐red_knot_python_semantic::types::symbol_by_id{symbol=ScopedSymbolId(54)}
6        ┌─┘
6        └─┐red_knot_python_semantic::types::symbol_by_id{symbol=ScopedSymbolId(122)}
6        ┌─┘
6        └─┐red_knot_python_semantic::types::symbol_by_id{symbol=ScopedSymbolId(165)}
6        ┌─┘
6      ┌─┘
6      └─┐red_knot_python_semantic::types::symbol_by_id{symbol=ScopedSymbolId(32)}
6      ┌─┘
6      └─┐red_knot_python_semantic::types::symbol_by_id{symbol=ScopedSymbolId(232)}
6      ┌─┘
6    ┌─┘
6  ┌─┘
6┌─┘

After:

5      └─┐red_knot_python_semantic::types::infer::infer_expression_types{expression=Id(60de), file=/home/shark/tomllib_modified/_parser.py}
5        └─┐red_knot_python_semantic::types::symbol{name="dict"}
5        ┌─┘
5        └─┐red_knot_python_semantic::types::symbol{name="dict"}
5        ┌─┘
5        └─┐red_knot_python_semantic::types::symbol{name="list"}
5        ┌─┘
5        └─┐red_knot_python_semantic::types::symbol{name="list"}
5        ┌─┘
5        └─┐red_knot_python_semantic::types::symbol{name="isinstance"}
5        ┌─┘
5        └─┐red_knot_python_semantic::types::symbol{name="isinstance"}
5        ┌─┘
5      ┌─┘
5      └─┐red_knot_python_semantic::types::symbol{name="ValueError"}
5      ┌─┘
5      └─┐red_knot_python_semantic::types::symbol{name="ValueError"}
5      ┌─┘
5    ┌─┘
5  ┌─┘
5┌─┘

Test Plan

cargo run --bin red_knot -- --current-directory path/to/tomllib -vvv

@sharkdp sharkdp added the red-knot Multi-file analysis & type inference label Dec 11, 2024
@@ -64,8 +64,6 @@ pub fn check_types(db: &dyn Db, file: File) -> TypeCheckDiagnostics {

/// Infer the public type of a symbol (its type as seen from outside its scope).
fn symbol_by_id<'db>(db: &'db dyn Db, scope: ScopeId<'db>, symbol: ScopedSymbolId) -> Symbol<'db> {
let _span = tracing::trace_span!("symbol_by_id", ?symbol).entered();
Copy link
Member

Choose a reason for hiding this comment

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

I'm inclined to inline the entire symbol_by_id function into symbol to avoid "missing" symbol lookups in tracing because a symbol gets looked up by its id.

Copy link
Contributor Author

@sharkdp sharkdp Jan 7, 2025

Choose a reason for hiding this comment

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

symbol_by_id is now #[salsa::tracked], so I can't inline it trivially. Also, it feels a bit wrong to inline that nicely encapsulated into this lambda here:

let table = symbol_table(db, scope);
table
.symbol_id_by_name(name)
.map(|symbol| symbol_by_id(db, scope, symbol))
.unwrap_or(Symbol::Unbound)

I now pushed a version where I nested symbol_by_id inside symbol. I'm not a huge fan, but it solves your concern as well. What do you think @MichaReiser?

(The diff is horrible. The only thing I did was to move symbol_by_id inside symbol and adapted the doc comments. No code has been changed except for the removed/added tracing::trace_span line.

Copy link
Member

Choose a reason for hiding this comment

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

(The diff is horrible. The only thing I did was to move symbol_by_id inside symbol and adapted the doc comments. No code has been changed except for the removed/added tracing::trace_span line.

fyi if you click the gear icon at the top of the diff view, you can check "Hide whitespace", which makes this particular diff much cleaner

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks! I know about hide-whitespace, but somehow didn't think of enabling it for this changeset 👍

Copy link
Contributor

github-actions bot commented Dec 11, 2024

ruff-ecosystem results

Linter (stable)

✅ ecosystem check detected no linter changes.

Linter (preview)

✅ ecosystem check detected no linter changes.

Copy link
Member

@AlexWaygood AlexWaygood left a comment

Choose a reason for hiding this comment

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

I agree with Micha's comment, but LGTM otherwise. (Wow, that output is so much more useful!)

Copy link
Contributor

@carljm carljm left a comment

Choose a reason for hiding this comment

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

So much better, thank you!

@sharkdp sharkdp force-pushed the david/tracing-symbol-lookups branch from c16c17e to 5529405 Compare January 7, 2025 09:25
When debugging, I frequently want to know which symbols are be looked
up. `symbol_by_id` adds tracing information, but it only shows the
`ScopedSymbolId`. Since `symbol_by_id` is only called from `symbol`, it
seems reasonable to move the tracing call to `symbol` where we can also
show the name of the symbol.

**Before**:

```
6      └─┐red_knot_python_semantic::types::infer::infer_expression_types{expression=Id(60de), file=/home/shark/tomllib_modified/_parser.py}
6        └─┐red_knot_python_semantic::types::symbol_by_id{symbol=ScopedSymbolId(33)}
6        ┌─┘
6        └─┐red_knot_python_semantic::types::symbol_by_id{symbol=ScopedSymbolId(123)}
6        ┌─┘
6        └─┐red_knot_python_semantic::types::symbol_by_id{symbol=ScopedSymbolId(54)}
6        ┌─┘
6        └─┐red_knot_python_semantic::types::symbol_by_id{symbol=ScopedSymbolId(122)}
6        ┌─┘
6        └─┐red_knot_python_semantic::types::symbol_by_id{symbol=ScopedSymbolId(165)}
6        ┌─┘
6      ┌─┘
6      └─┐red_knot_python_semantic::types::symbol_by_id{symbol=ScopedSymbolId(32)}
6      ┌─┘
6      └─┐red_knot_python_semantic::types::symbol_by_id{symbol=ScopedSymbolId(232)}
6      ┌─┘
6    ┌─┘
6  ┌─┘
6┌─┘
```

**After**:

```
5      └─┐red_knot_python_semantic::types::infer::infer_expression_types{expression=Id(60de), file=/home/shark/tomllib_modified/_parser.py}
5        └─┐red_knot_python_semantic::types::symbol{name="dict"}
5        ┌─┘
5        └─┐red_knot_python_semantic::types::symbol{name="dict"}
5        ┌─┘
5        └─┐red_knot_python_semantic::types::symbol{name="list"}
5        ┌─┘
5        └─┐red_knot_python_semantic::types::symbol{name="list"}
5        ┌─┘
5        └─┐red_knot_python_semantic::types::symbol{name="isinstance"}
5        ┌─┘
5        └─┐red_knot_python_semantic::types::symbol{name="isinstance"}
5        ┌─┘
5      ┌─┘
5      └─┐red_knot_python_semantic::types::symbol{name="ValueError"}
5      ┌─┘
5      └─┐red_knot_python_semantic::types::symbol{name="ValueError"}
5      ┌─┘
5    ┌─┘
5  ┌─┘
5┌─┘
```
@sharkdp sharkdp force-pushed the david/tracing-symbol-lookups branch from 5529405 to 897c307 Compare January 7, 2025 09:30
#[salsa::tracked]
fn symbol_by_id<'db>(
db: &'db dyn Db,
scope: ScopeId<'db>,
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 tried to remove this (and use scope from the outer scope), but it seems to be required in order to make this salsa_tracked.

Copy link
Member

Choose a reason for hiding this comment

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

This works for me. Thanks

@sharkdp sharkdp merged commit ce9c496 into main Jan 7, 2025
21 checks passed
@sharkdp sharkdp deleted the david/tracing-symbol-lookups branch January 7, 2025 09:41
dcreager added a commit that referenced this pull request Jan 7, 2025
* main:
  Use uv consistently throughout the documentation (#15302)
  [red-knot] Eagerly normalize `type[]` types (#15272)
  [`pyupgrade`] Split `UP007` to two individual rules for `Union` and `Optional` (`UP007`, `UP045`) (#15313)
  [red-knot] Improve symbol-lookup tracing (#14907)
  [red-knot] improve type shrinking coverage in red-knot property tests (#15297)
  [`flake8-return`] Recognize functions returning `Never` as non-returning (`RET503`) (#15298)
  [`flake8-bugbear`] Implement `class-as-data-structure` (`B903`) (#9601)
  Avoid treating newline-separated sections as sub-sections (#15311)
  Remove call when removing final argument from `format` (#15309)
  Don't enforce `object-without-hash-method` in stubs (#15310)
  Don't special-case class instances in binary expression inference (#15161)
  Upgrade zizmor to the latest version in CI (#15300)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
red-knot Multi-file analysis & type inference
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants