ruff/crates/red_knot_python_semantic/src
David Peter 6964eef369
[red knot] add Type::is_disjoint_from and intersection simplifications (#13775)
## Summary

- Add `Type::is_disjoint_from` as a way to test whether two types
overlap
- Add a first set of simplification rules for intersection types
  - `S & T = S` for `S <: T`
  - `S & ~T = Never` for `S <: T`
  - `~S & ~T = ~T` for `S <: T`
  - `A & ~B = A` for `A` disjoint from `B`
  - `A & B = Never` for `A` disjoint from `B`
  - `bool & ~Literal[bool] = Literal[!bool]`

resolves one item in #12694

## Open questions:

- Can we somehow leverage the (anti) symmetry between `positive` and
`negative` contributions? I could imagine that there would be a way if
we had `Type::Not(type)`/`Type::Negative(type)`, but with the
`positive`/`negative` architecture, I'm not sure. Note that there is a
certain duplication in the `add_positive`/`add_negative` functions (e.g.
`S & ~T = Never` is implemented twice), but other rules are actually not
perfectly symmetric: `S & T = S` vs `~S & ~T = ~T`.
- I'm not particularly proud of the way `add_positive`/`add_negative`
turned out. They are long imperative-style functions with some
mutability mixed in (`to_remove`). I'm happy to look into ways to
improve this code *if we decide to go with this approach* of
implementing a set of ad-hoc rules for simplification.
- ~~Is it useful to perform simplifications eagerly in
`add_positive`/`add_negative`? (@carljm)~~ This is what I did for now.

## Test Plan

- Unit tests for `Type::is_disjoint_from`
- Observe changes in Markdown-based tests
- Unit tests for `IntersectionBuilder::build()`

---------

Co-authored-by: Carl Meyer <carl@astral.sh>
2024-10-18 21:34:43 +00:00
..
module_resolver Upgrade salsa (#13757) 2024-10-15 11:06:32 +00:00
semantic_index [red-knot] Use the right scope when considering class bases (#13766) 2024-10-17 22:29:46 +00:00
types [red knot] add Type::is_disjoint_from and intersection simplifications (#13775) 2024-10-18 21:34:43 +00:00
ast_node_ref.rs Add definitions for match statement (#13147) 2024-09-02 14:40:09 +05:30
db.rs Rename the ruff_vendored crate to red_knot_vendored (#13586) 2024-10-01 16:16:59 +01:00
lib.rs Use an empty vendored file system in Ruff (#13436) 2024-09-21 16:31:42 +00:00
module_name.rs [red-knot] Add support for relative imports (#12910) 2024-08-16 12:35:27 +01:00
node_key.rs Implement AstNode for Identifier (#13207) 2024-09-02 16:27:12 +05:30
program.rs Eagerly validate typeshed versions (#12786) 2024-08-21 15:49:53 +00:00
python_version.rs Add Python version support to ruff analyze CLI (#13426) 2024-09-20 15:40:47 -04:00
semantic_index.rs [red-knot] Infer target types for unpacked tuple assignment (#13316) 2024-10-15 19:07:11 +00:00
semantic_model.rs Upgrade salsa (#13757) 2024-10-15 11:06:32 +00:00
site_packages.rs Use backticks for code in red-knot messages (#13599) 2024-10-02 03:14:28 +00:00
stdlib.rs [red-knot] don't include Unknown in the type for a conditionally-defined import (#13563) 2024-10-16 13:46:03 -07:00
types.rs [red knot] add Type::is_disjoint_from and intersection simplifications (#13775) 2024-10-18 21:34:43 +00:00