This is the conceptual opposite of the rust-cold calling convention and
is particularly useful in combination with the new `explicit_tail_calls`
feature.
For relatively tight loops implemented with tail calling (`become`) each
of the function with the regular calling convention is still responsible
for restoring the initial value of the preserved registers. So it is not
unusual to end up with a situation where each step in the tail call loop
is spilling and reloading registers, along the lines of:
foo:
push r12
; do things
pop r12
jmp next_step
This adds up quickly, especially when most of the clobberable registers
are already used to pass arguments or other uses.
I was thinking of making the name of this ABI a little less LLVM-derived
and more like a conceptual inverse of `rust-cold`, but could not come
with a great name (`rust-cold` is itself not a great name: cold in what
context? from which perspective? is it supposed to mean that the
function is rarely called?)
- Do not store the `MacroCallId` of the "real" expansion anywhere, so that the IDE layer could not expand it by mistake
- Fix a stupid bug where we used the directive of the `derive` itself instead of of the macro, leading us to re-expand it again and again.
It sees them as regular impls; the details are abstracted. It's beautiful for the IDE layer, and less beautiful for `hir`, so this is a big change.
Some small differences still exist:
- We show builtin derives impl (to the IDE layer) as if they have had no generic parameters. It is possible to show the parameters, but that means also having to handle fake impls in `TypeParam` etc., and the benefit is questionable.
- Getting the fn *def* type of a method of a builtin derive impl is not supported, as there is no real `FunctionId`, therefore no `CallableDefId`. The trait method is returned instead. Note: getting the fn *ptr* type of the method is supported well.
- Builtin derive impls and their methods do not fully support `HasSource`, because, well, they have no source (at least, not in the form of `ast::Impl` and `ast::Fn`). To support them, we use the derive's `TextRange` where possible, and the trait method's source when not.
It's important to note that the def map still records the `MacroCallId`. I have doubts over this, as this means it's very easy to create the queries we don't want to create, but it does make things more convenient. In particular, a nicety of this setup is that even "Expand macro recursively" works (it creates the macro input/output query, but given that they will only be created when the user invokes the command, that does not seem to be a problem).
Changes:
- `const_of_item()` was added to `Interner`, analogous to `type_of()`. No strongly-typed ID (yet).
- New solver trait lang item: `TrivialClone`.
- `TypeRelation` changed a bit, the code was copied from rustc.
So that we'll correctly treat it as an attribute.
I don't like that we have to register every builtin macro even if we don't need it, but that's what we got.
It cannot be exactly the same, because we have needs rustc doesn't have (namely, accurate enumeration of all methods, not just with a specific name, for completions etc., while rustc also needs a best-effort implementation for diagnostics) but it is closer than the previous impl.
In addition we rewrite the closely related handling of operator inference and impl collection.
This in turn necessitate changing some other parts of inference in order to retain behavior. As a result, the behavior more closely matches rustc and is also more correct.
This fixes 2 type mismatches on self (1 remains) and 4 diagnostics (1 remains), plus some unknown types.
`concat_idents!` was deprecated in [1] and will be removed in the near
future. rust-analyzer's support is independent of rustc's, so drop RA
support now to make syncing easier.
[1]: https://github.com/rust-lang/rust/pull/137653
Use `std::mem::{size_of, size_of_val, align_of, align_of_val}` from the
prelude instead of importing or qualifying them.
These functions were added to all preludes in Rust 1.80.