4497: Create LowerCtx on the fly r=matklad a=edwin0cheng
Previously we create `LowerCtx` at the beginning of lowering, however, the hygiene content is in fact changing between macro expression expanding.
This PR change it to create the `LowerCtx` on the fly to fix above bug.
However, #4465 is not fixed by this PR, the goto-def is still not work yet. It only fixed the infer part.
Co-authored-by: Edwin Cheng <edwin0cheng@gmail.com>
4394: Simplify r=matklad a=Veetaha
4414: Highlighting improvements r=matklad a=matthewjasper
- `static mut`s are highlighted as `mutable`.
- The name of the macro declared by `macro_rules!` is now highlighted.
Co-authored-by: veetaha <veetaha2@gmail.com>
Co-authored-by: Matthew Jasper <mjjasper1@gmail.com>
This fixes an issue where the following code sample would fail to infer
the type contained in the option:
```rust
fn main() {
let mut end = None; // TODO: Fix inference for this in RA
loop {
end = Some(true);
}
}
```
4175: Introduce HirDisplay method for rendering source code & use it in add_function assist r=flodiebold a=TimoFreiberg
Next feature for #3639.
So far the only change in the new `HirDisplay` method is that paths are qualified, but more changes will be necessary (omitting the function name from function types, returning an error instead of printing `"{unknown}"`, probably more).
Is that approach okay?
Co-authored-by: Timo Freiberg <timo.freiberg@gmail.com>
E.g. in
```rust
match x {
1 => function1,
2 => function2,
}
```
we need to try coercing both to pointers. Turns out this is a special case in
rustc as well (see the link in the comment).
Divergence here means that for some reason, the end of a block will not be
reached. We tried to model this just using the never type, but that doesn't work
fully (e.g. in `let x = { loop {}; "foo" };` x should still have type `&str`);
so this introduces a `diverges` flag that the type checker keeps track of, like
rustc does.
4173: Use core instead of std for builtin derive macros r=edwin0cheng a=edwin0cheng
Fixed#4087.
We can't use `$crate` here right now because :
1. We have to able to detect `macro` 2.0 in collecting phase for finding `rustc_builtin_macro` attrs.
2. And we have to make hygiene works for builtin derive macro.
r= @flodiebold
Co-authored-by: Edwin Cheng <edwin0cheng@gmail.com>
So e.g. if we have `fn foo<T: SomeTrait<u32>>() -> T::Item`, we want to lower
that to `<T as SomeTrait<u32>>::Item` and not `<T as SomeTrait<_>>::Item`.
4106: Fix wrong substitution code r=matklad a=flodiebold
We need to shift in when we're substituting inside a binder.
This should fix#4053 (it doesn't fix the occasional overflow that also occurs on the Diesel codebase though).
Co-authored-by: Florian Diebold <flodiebold@gmail.com>
We need to shift in when we're substituting inside a binder.
This should fix#4053 (it doesn't fix the occasional overflow that also occurs
on the Diesel codebase though).
4023: Fix another crash from wrong binders r=matklad a=flodiebold
Basically, if we had something like `dyn Trait<T>` (where `T` is a type parameter) in an impl we lowered that to `dyn Trait<^0.0>`, when it should be `dyn Trait<^1.0>` because the `dyn` introduces a new binder. With one type parameter, that's just wrong, with two, it'll lead to crashes.
Co-authored-by: Florian Diebold <flodiebold@gmail.com>
Basically, if we had something like `dyn Trait<T>` (where `T` is a type
parameter) in an impl we lowered that to `dyn Trait<^0.0>`, when it should be
`dyn Trait<^1.0>` because the `dyn` introduces a new binder. With one type
parameter, that's just wrong, with two, it'll lead to crashes.
Fixes a lot of false type mismatches.
(And as always when touching the unification code, I have to say I'm looking
forward to replacing it by Chalk's...)
It's not entirely clear what subnode ranges should mean in the
presence of macros, so let's leave them out for now. We are not using
them heavily anyway.
3979: fix missing match arm false positive for enum with no variants r=flodiebold a=JoshMcguigan
fixes#3974
Co-authored-by: Josh Mcguigan <joshmcg88@gmail.com>
3966: Add support for bounds on associated types in trait definitions r=matklad a=flodiebold
E.g.
```rust
trait Trait {
type Item: SomeOtherTrait;
}
```
Note that these don't simply desugar to where clauses; as I understand it, where clauses have to be proved by the *user* of the trait, but these bounds are proved by the *implementor*. (Also, where clauses on associated types are unstable.)
(Another one from my recursive solver branch...)
3968: Remove format from syntax_bridge hot path r=matklad a=edwin0cheng
Although only around 1% speed up by running:
```
Measure-Command {start-process .\target\release\rust-analyzer "analysis-stats -q ." -NoNewWindow -wait}
```
Co-authored-by: Florian Diebold <flodiebold@gmail.com>
Co-authored-by: Edwin Cheng <edwin0cheng@gmail.com>
3964: Nicer Chalk debug logs r=matklad a=flodiebold
I'm looking at a lot of Chalk debug logs at the moment, so here's a few changes to make them slightly nicer...
3965: Implement inline associated type bounds r=matklad a=flodiebold
Like `Iterator<Item: SomeTrait>`.
This is an unstable feature, but it's used in the standard library e.g. in the definition of Flatten, so we can't get away with not implementing it :)
(This is cherry-picked from my recursive solver branch, where it works better, but I did manage to write a test that works with the current Chalk solver as well...)
3967: Handle `Self::Type` in trait definitions when referring to own associated type r=matklad a=flodiebold
It was implemented for other generic parameters for the trait, but not for `Self`.
(Last one off my recursive solver branch 😄 )
Co-authored-by: Florian Diebold <flodiebold@gmail.com>
E.g.
```
trait Trait {
type Item: SomeOtherTrait;
}
```
Note that these don't simply desugar to where clauses; as I understand it, where
clauses have to be proved by the *user* of the trait, but these bounds are proved
by the *implementor*. (Also, where clauses on associated types are unstable.)
Like `Iterator<Item: SomeTrait>`.
This is an unstable feature, but it's used in the standard library e.g. in the
definition of Flatten, so we can't get away with not implementing it :)
3938: fix missing match arm false positive r=flodiebold a=JoshMcguigan
This fixes#3932 by skipping the missing match arm diagnostic in the case any of the match arms don't type check properly against the match expression.
I think this is the appropriate behavior for this diagnostic, since `is_useful` relies on all match arms being well formed, and the case of a malformed match arm should probably be handled by a different diagnostic.
Co-authored-by: Josh Mcguigan <joshmcg88@gmail.com>
3905: add ellipsis field to hir pat record r=matklad a=JoshMcguigan
This PR corrects a `fixme`, adding an `ellipsis` field to the hir `Pat::Record` type. It will also be unlock some useful follow on work for #3894.
Additionally it adds a diagnostic for missing fields in record patterns.
~~Marking as a draft because I don't have any tests, and a small amount of manual testing on my branch from #3894 suggests it might *not* be working. Any thoughts on how I can best test this, or else pointers on where I might be going wrong?~~
Co-authored-by: Josh Mcguigan <joshmcg88@gmail.com>
Chalk now panics if we don't implement these methods and run with CHALK_DEBUG,
so I thought I'd try to implement them 'properly'. Sadly, it seems impossible to
do without transmuting lifetimes somewhere. The problem is that we need a `&dyn
HirDatabase` to get names etc., which we can't just put into TLS. I thought I
could just use `scoped-tls`, but that doesn't support references to unsized
types. So I put the `&dyn` into another struct and put the reference to *that*
into the TLS, but I have to transmute the lifetime to 'static for that to work.
3918: Add support for feature attributes in struct literal r=matklad a=bnjjj
As promised here is the next PR to solve 2 different scenarios with feature flag on struct literal.
close#3870
Co-authored-by: Benjamin Coenen <5719034+bnjjj@users.noreply.github.com>
The big change here is counting binders, not
variables (https://github.com/rust-lang/chalk/pull/360). We have to adapt to the
same scheme for our `Ty::Bound`. It's mostly fine though, even makes some things
more clear.
We treat macro calls as expressions (there's appropriate Into impl),
which causes problem if there's expresison and non-expression macro in
the same node (like in the match arm).
We fix this problem by nesting macor patterns into another node (the
same way we nest path into PathExpr or PathPat). Ideally, we probably
should add a similar nesting for macro expressions, but that needs
some careful thinking about macros in blocks: `{ am_i_expression!() }`.
It improves compile time in `--release` mode quite a bit, it doesn't
really slow things down and, conceptually, it seems closer to what we
want the physical architecture to look like (we don't want to
monomorphise EVERYTHING in a single leaf crate).
3549: Implement env! macro r=matklad a=edwin0cheng
This PR implements `env!` macro by adding following things:
1. Added `additional_outdirs` settings in vscode. (naming to be bikeshed)
2. Added `ExternSourceId` which is a wrapping for SourceRootId but only used in extern sources. It is because `OUT_DIR` is not belonged to any crate and we have to access it behind an `AstDatabase`.
3. This PR does not implement the `OUT_DIR` parsing from `cargo check`. I don't have general design about this, @kiljacken could we reuse some cargo watch code for that ?
~~Block on [#3536]~~
PS: After this PR , we (kind of) completed the `include!(concat!(env!('OUT_DIR'), "foo.rs")` macro call combo. [Exodia Obliterate!](https://www.youtube.com/watch?v=RfqNH3FoGi0)
Co-authored-by: Edwin Cheng <edwin0cheng@gmail.com>
To test whether the receiver type matches for the impl, we unify the given self
type (in this case `HashSet<{unknown}>`) with the self type of the
impl (`HashSet<?0>`), but if the given self type contains Unknowns, they won't
be unified with the variables in those places. So we got a receiver type that
was different from the expected one, and concluded the impl doesn't match.
The fix is slightly hacky; if after the unification, our variables are still
there, we make them fall back to Unknown. This does make some sense though,
since we don't want to 'leak' the variables.
Fixes#3547.