The limit was introduced in https://github.com/rust-lang/rust-analyzer/pull/1408#discussion_r294059044 to avoid infinite cycles but it effectively caps the number of derefs to 10. Types like `ID3D12Device14` from the `windows` crate run into this because it derefs to `ID3D12Device13`, 13 to 12 and so on. Increasing it to 20 is a quick fix; a better cycle detection method would be nicer long term.
I expected this to be faster (due to less allocations and better cache locality), but benchmarked it is not (neither it is slower). Memory usage, however, drops by ~50mb (of `analysis-stats .`). I guess tt construction is just not hot.
This also simplifies using even less memory for token trees by compressing equal span, which I plan to do right after.
Some workflows are more easily expressed with a flat tt, while some are better expressed with a tree. With the right helpers, though (which was mostly a matter of trial and error), even the worst workflows become very easy indeed.
To be accurate, only their methods are excluded, the trait themselves are still available.
I also excluded a bunch of std traits by default. Some less opinionated, like `AsRef`, which should never be used directly except in generic scenarios (and won't be excluded there), some more opinionated, like the ops traits, which I know some users sometimes want to use directly. Either way it's configurable.
It should be pretty easy to extend support to excluding only specific methods, but I didn't do that currently.
Traits configured to be excluded are resolved in each completion request from scratch. If this proves too expensive, it is easy enough to cache them in the DB.
In particular, the symbol generation before this change creates a lot
of symbols with the same name for different definitions. This change
makes progress on symbol uniqueness, but does not fix a couple cases
where it was unclear to me how to fix (see TODOs in `scip.rs`)
Behavior changes:
* `scip` command now reports symbol information omitted due to symbol
collisions. Iterating with this on a large codebase (Zed!) resulted in
the other improvements in this change.
* Generally fixes providing the path to nested definitions in
symbols. Instead of having special cases for a couple limited cases of
nesting, implements `Definition::enclosing_definition` and uses this
to walk definitions.
* Parameter variables are now treated like locals.
- This fixes a bug where closure captures also received symbols
scoped to the containing function. To bring back parameter
symbols I would want a way to filter these out, since they can
cause symbol collisions.
- Having symbols for them seems to be intentional in
27e2eea54fbd1edeefa2b47ddd4f552a04b86582, but no particular use is
specified there. For the typical indexing purposes of SCIP I don't see
why parameter symbols are useful or sensible, as function parameters
are not referencable by anything but position. I can imagine they
might be useful in representing diagnostics or something.
* Inherent impls are now represented as `impl#[SelfType]` - a type
named `impl` which takes a single type parameter.
* Trait impls are now represented as `impl#[SelfType][TraitType]` - a
type named `impl` which takes two type parameters.
* Associated types in traits and impls are now treated like types
instead of type parameters, and so are now suffixed with `#` instead
of wrapped with `[]`. Treating them as type parameters seems to have
been intentional in 73d9c77f2aeed394cf131dce55807be2d3f54064 but it
doesn't make sense to me, so changing it.
* Static variables are now treated as terms instead of `Meta`, and so
receive `.` suffix instead of `:`.
* Attributes are now treated as `Meta` instead of `Macro`, and so
receive `:` suffix instead of `!`.
* `enclosing_symbol` is now provided for labels and generic params,
which are local symbols.
* Fixes a bug where presence of `'` causes a descriptor name to get
double wrapped in backticks, since both `fn new_descriptor` and
`scip::symbol::format_symbol` have logic for wrapping in
backticks. Solution is to simply delete the redundant logic.
* Deletes a couple tests in moniker.rs because the cases are
adequeately covered in scip.rs and the format for identifiers used in
moniker.rs is clunky with the new representation for trait impls