Skip to content

[red-knot] Meta data for Type::Todo #14500

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

Merged
merged 2 commits into from
Nov 21, 2024
Merged

[red-knot] Meta data for Type::Todo #14500

merged 2 commits into from
Nov 21, 2024

Conversation

sharkdp
Copy link
Contributor

@sharkdp sharkdp commented Nov 20, 2024

Summary

Adds meta information to Type::Todo, allowing developers to easily trace back the origin of a particular @Todo type they encounter.

Instead of Type::Todo, we now write either type_todo!() which creates a @Todo[path/to/source.rs:123] type with file and line information, or using type_todo!("PEP 604 unions not supported"), which creates a variant with a custom message.

Type::Todo now contains a TodoType field. In release mode, this is just a zero-sized struct, in order not to create any overhead. In debug mode, this is an enum that contains the meta information.

Type implements Copy, which means that TodoType also needs to be copyable. This limits the design space. We could intern TodoType, but I discarded this option, as it would require us to have access to the salsa DB everywhere we want to use Type::Todo. And it would have made the macro invocations less ergonomic (requiring us to pass db).

So for now, the meta information is simply a &'static str / u32 for the file/line variant, or a &'static str for the custom message. Anything involving a chain/backtrace of several @Todos or similar is therefore currently not implemented. Also because we currently don't see any direct use cases for this, and because all of this will eventually go away.

Note that the size of Type increases from 16 to 24 bytes, but only in debug mode.

Test Plan

  • Observed the changes in Markdown tests.
  • Added custom messages for all Type::Todos that were revealed in the tests
  • Ran red knot in release and debug mode on the following Python file:
    def f(x: int) -> int:
        reveal_type(x)
    Prints @Todo in release mode and @Todo(function parameter type) in debug mode.

@sharkdp sharkdp added internal An internal refactor or improvement ty Multi-file analysis & type inference labels Nov 20, 2024
Copy link
Contributor

github-actions bot commented Nov 20, 2024

ruff-ecosystem results

Linter (stable)

✅ ecosystem check detected no linter changes.

Linter (preview)

✅ ecosystem check detected no linter changes.

Copy link
Member

@MichaReiser MichaReiser left a comment

Choose a reason for hiding this comment

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

Clever!

@sharkdp sharkdp force-pushed the david/todo-type-metadata branch from 30b7e60 to a02a96a Compare November 20, 2024 21:41
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.

This is great! Will make debugging so much nicer.

}
Type::Todo => Type::Todo.into(),
Type::Todo(_) => todo_type!().into(),
Copy link
Contributor

Choose a reason for hiding this comment

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

I guess there are some judgment calls about when to propagate a Todo vs create a new one. This could propagate, like we do below in to_instance and to_meta_type, but maybe an attribute of a todo feels more like a new todo than an extension of the previous one? Not sure what will be more useful in practice.

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'm going to assume for now that the original todo is more interesting, so I changed the logic here to propagate the incoming todo.

Comment on lines +3636 to +3655
assert!(todo1.is_equivalent_to(&db, todo2));
assert!(todo3.is_equivalent_to(&db, todo4));
assert!(todo1.is_equivalent_to(&db, todo3));

assert!(todo1.is_subtype_of(&db, todo2));
assert!(todo2.is_subtype_of(&db, todo1));

assert!(todo3.is_subtype_of(&db, todo4));
assert!(todo4.is_subtype_of(&db, todo3));

assert!(todo1.is_subtype_of(&db, todo3));
assert!(todo3.is_subtype_of(&db, todo1));
Copy link
Contributor

Choose a reason for hiding this comment

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

I think these are all not actually correct (as discussed in Discord today), but that's orthogonal to this PR; these assertions are consistent with our current handling. So I think it makes sense to leave them as-is for this PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh, I was about to read that discussion again tomorrow. I thought it was unrelated to my change 😄. I can look into it (not here).

Copy link
Contributor

Choose a reason for hiding this comment

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

It is unrelated to your change, except that you added some explicit tests that Todo (which is supposed to be a dynamic type just like Any or Unknown) is equivalent to and a subtype of itself, which I don't think we had explicitly tested before, and is not really right. So that makes it related :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Okay yes, this is what I understood after your first comment. I'll address this in a follow-up and fix these tests accordingly.

Adds meta information to `Type::Todo`, allowing developers to easily
trace back the origin of a particular `@Todo` type they encounter.

Instead of `Type::Todo`, we now write either `type_todo!()` which
creates a `@Todo[path/to/source.rs:123]` type with file and line
information, or using `type_todo!("PEP 604 unions not supported")`,
which creates a variant with a custom message.

`Type::Todo` now contains a `TodoType` field. In release mode, this is
just a zero-sized struct, in order not to create any overhead. In debug
mode, this is an `enum` that contains the meta information.

`Type` implements `Copy`, which means that `TodoType` also needs to be
copyable. This limits the design space. We could intern `TodoType`, but
I discarded this option, as it would require us to have access to the
salsa DB everywhere we want to use `Type::Todo`. And it would have made
the macro invocations less ergonomic (requiring us to pass `db`).

So for now, the meta information is simply a `&'static str` / u32 for
the file/line variant, or a `&'static str` for the custom message.
Anything involving a chain/backtrace of several `@Todo`s or similar is
therefore currently not implemented. Also because we currently don't see
any direct use cases for this, and because all of this will eventually
go away.

Note that the size of `Type` increases from 16 to 24 bytes, but only in
debug mode.
@sharkdp sharkdp force-pushed the david/todo-type-metadata branch from de3f90d to 8f66ee3 Compare November 21, 2024 08:52
@sharkdp sharkdp merged commit 47f39ed into main Nov 21, 2024
20 checks passed
@sharkdp sharkdp deleted the david/todo-type-metadata branch November 21, 2024 08:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
internal An internal refactor or improvement ty Multi-file analysis & type inference
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants