fix: Do not consider mutable usage of deref to `*mut T` as deref_mut
Fixes#15799
We are doing some heuristics for deciding whether the given deref is deref or deref_mut here;
5982d9c420/crates/hir-ty/src/infer/mutability.rs (L182-L200)
But this heuristic is erroneous if we are dereferencing to a mut ptr and normally those cases are filtered out here as builtin;
5982d9c420/crates/hir-ty/src/mir/lower/as_place.rs (L165-L177)
Howerver, this works not so well if the given dereferencing is double dereferencings like the case in the #15799.
```rust
struct WrapPtr(*mut u32);
impl core::ops::Deref for WrapPtr {
type Target = *mut u32;
fn deref(&self) -> &Self::Target {
&self.0
}
}
fn main() {
let mut x = 0u32;
let wrap = WrapPtr(&mut x);
unsafe {
**wrap = 6;
}
}
```
Here are two - outer and inner - dereferences here, and the outer dereference is marked as deref_mut because there is an assignment operation.
And this deref_mut marking is propagated into the inner dereferencing.
In the later MIR lowering, the outer dereference is filtered out as it's expr type is `*mut u32`, but the expr type in the inner dereference is an ADT, so this false-mutablility is not filtered out.
This PR cuts propagation of this false mutablilty chain if the expr type is mut ptr.
Since this happens before the resolve_all, it may have some limitations when the expr type is determined as mut ptr at the very end of inferencing, but I couldn't find simple fix for it 🤔
before, when formatting struct constructor for `struct S(usize, usize)` it would format as:
extern "rust-call" S(usize, usize) -> S
but after this change, we'll format as:
fn S(usize, usize) -> S
fix: Ambiguity with CamelCase diagnostic messages, align with rustc warnings
Fixed diagnostic messages so they say UpperCamelCase rather than CamelCase, as it is ambiguous.
Usually I'd call it PascalCase, but in the code base it is called UpperCamelCase so I left it with that naming choice.
`rustc` says `upper camel case` also when the case is wrong
```
warning: trait `testThing` should have an upper camel case name
--> src/main.rs:5:7
|
5 | trait testThing {
| ^^^^^^^^^ help: convert the identifier to upper camel case: `TestThing`
|
= note: `#[warn(non_camel_case_types)]` on by default
```
This is in line with the UPPER_SNAKE_CASE diagnostic messages.
546339a7be/crates/hir-ty/src/diagnostics/decl_check.rs (L60)546339a7be/crates/ide-diagnostics/src/handlers/incorrect_case.rs (L535)
fix: Extend `type_variable_table` when modifying index is larger than the table size
Fixes#18109
Whenever we create an inference variable in r-a, we extend `type_variable_table` to matching size here;
f4aca78c92/crates/hir-ty/src/infer/unify.rs (L378-L381)
But sometimes, an inference variable is [created from chalk](ab710e0c9b/chalk-solve/src/infer/unify.rs (L743)) and passed to r-a as a type of an expression or a pattern.
If r-a set diverging flag to this before the table is extended to a sufficient size, it panics here;
f4aca78c92/crates/hir-ty/src/infer/unify.rs (L275-L277)
I think that extending table when setting diverging flag is reasonable becase we are already doing such extending to a size that covers the inference vars created from chalk and this change only covers the order-dependent random cases that this might fail
Don't lint names of #[no_mangle] extern fns
[Rust doesn't run the `non_snake_case_name` lint on `extern fn`s with the `#[no_mangle]` attribute](https://github.com/rust-lang/rust/pull/44966).
The conditions are:
- The function must be `extern` and have a `#[no_mangle]` attribute.
- The function's ABI must not be explicitly set to "Rust".
This PR replicates that logic here.
Use more correct handling of lint attributes
The previous analysis was top-down, and worked on a single file (expanding macros). The new analysis is bottom-up, starting from the diagnostics and climbing up the syntax and module tree.
While this is more efficient (and in fact, efficiency was the motivating reason to work on this), unfortunately the code was already fast enough. But luckily, it also fixes a correctness problem: outline parent modules' attributes were not respected for the previous analysis. Case lints specifically did their own analysis to accommodate that, but it was limited to only them. The new analysis works on all kinds of lints, present and future.
It was basically impossible to fix the old analysis without rewriting it because navigating the module hierarchy must come bottom-up, and if we already have a bottom-up analysis (including syntax analysis because modules can be nested in other syntax elements, including macros), it makes sense to use only this kind of analysis.
Few other bugs (not fundamental to the previous analysis) are also fixed, e.g. overwriting of lint levels (i.e. `#[allow(lint)] mod foo { #[warn(lint)] mod bar; }`.
After this PR is merged I intend to work on an editor command that does workspace-wide diagnostics analysis (that is, `rust-analyzer diagnostics` but from your editor and without having to spawn a new process, which will have to analyze the workspace from scratch). This can be useful to users who do not want to enable check on save because of its overhead, but want to see workspace wide diagnostics from r-a (or to maintainers of rust-analyzer).
Closes#18086.
Closes#18081.
Fixes#18056.
The previous analysis was top-down, and worked on a single file (expanding macros). The new analysis is bottom-up, starting from the diagnostics and climbing up the syntax and module tree.
While this is more efficient (and in fact, efficiency was the motivating reason to work on this), unfortunately the code was already fast enough. But luckily, it also fixes a correctness problem: outline parent modules' attributes were not respected for the previous analysis. Case lints specifically did their own analysis to accommodate that, but it was limited to only them. The new analysis works on all kinds of lints, present and future.
It was basically impossible to fix the old analysis without rewriting it because navigating the module hierarchy must come bottom-up, and if we already have a bottom-up analysis (including syntax analysis because modules can be nested in other syntax elements, including macros), it makes sense to use only this kind of analysis.
Few other bugs (not fundamental ti the previous analysis) are also fixed, e.g. overwriting of lint levels (i.e. `#[allow(lint)] mod foo { #[warn(lint)] mod bar; }`.
Do not report missing unsafe on `addr_of[_mut]!(EXTERN_OR_MUT_STATIC)`
The compiler no longer does as well; see https://github.com/rust-lang/rust/pull/125834.
Also require unsafe when accessing `extern` `static` (other than by `addr_of!()`).
Fixes#17978.
feat: Create an assist to convert closure to freestanding fn
The assist converts all captures to parameters.
Closes#17920.
This was more work than I though, since it has to handle a bunch of edge cases...
Based on #17941. Needs to merge it first.