[red-knot] Use arena-allocated association lists for narrowing constraints (#16306)

This PR adds an implementation of [association
lists](https://en.wikipedia.org/wiki/Association_list), and uses them to
replace the previous `BitSet`/`SmallVec` representation for narrowing
constraints.

An association list is a linked list of key/value pairs. We additionally
guarantee that the elements of an association list are sorted (by their
keys), and that they do not contain any entries with duplicate keys.

Association lists have fallen out of favor in recent decades, since you
often need operations that are inefficient on them. In particular,
looking up a random element by index is O(n), just like a linked list;
and looking up an element by key is also O(n), since you must do a
linear scan of the list to find the matching element. Luckily we don't
need either of those operations for narrowing constraints!

The typical implementation also suffers from poor cache locality and
high memory allocation overhead, since individual list cells are
typically allocated separately from the heap. We solve that last problem
by storing the cells of an association list in an `IndexVec` arena.

---------

Co-authored-by: Carl Meyer <carl@astral.sh>
This commit is contained in:
Douglas Creager 2025-02-25 10:58:56 -05:00 committed by GitHub
parent 5c007db7e2
commit fa76f6cbb2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 1073 additions and 322 deletions

View file

@ -27,7 +27,6 @@ pub(crate) mod symbol;
pub mod types;
mod unpack;
mod util;
mod visibility_constraints;
type FxOrderSet<V> = ordermap::set::OrderSet<V, BuildHasherDefault<FxHasher>>;