make `compare_const_impl` a query and use it in `instance.rs`
Fixes#88365
the bug in #88365 was caused by some `instance.rs` code using the `PartialEq` impl on `Ty` to check that the type of the associated const in an impl is the same as the type of the associated const in the trait definition. This was wrong for two reasons:
- the check typeck does is that the impl type is a subtype of the trait definition's type (see `mismatched_impl_ty_2.rs` which [was ICEing](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=f6d60ebe6745011f0d52ab2bc712025d) before this PR on stable)
- it assumes that if two types are equal then the `PartialEq` impl will reflect that which isnt true for higher ranked types or type level constants when `feature(generic_const_exprs)` is enabled (see `mismatched_impl_ty_3.rs` for higher ranked types which was [ICEing on stable](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=d7af131a655ed515b035624626c62c71))
r? `@lcnr`
Suggest `==` to wrong assign expr
Given the following code:
```rust
fn main() {
let x = 3;
let y = 3;
if x == x && y = y {
println!("{}", x);
}
}
```
Current output is:
```
error[E0308]: mismatched types
--> src/main.rs:4:18
|
4 | if x == x && y = y {
| ^ expected `bool`, found integer
error[E0308]: mismatched types
--> src/main.rs:4:8
|
4 | if x == x && y = y {
| ^^^^^^^^^^^^^^^ expected `bool`, found `()`
```
This adds a suggestion:
```diff
error[E0308]: mismatched types
--> src/main.rs:6:18
|
6 | if x == x && y = y {
| ^ expected `bool`, found integer
error[E0308]: mismatched types
--> src/main.rs:6:8
|
6 | if x == x && y = y {
| ^^^^^^^^^^^^^^^ expected `bool`, found `()`
|
+ help: you might have meant to compare for equality
+ |
+ 6 | if x == x && y == y {
+ | +
```
And this fixes a part of #97469
Suggest calling method if fn does not exist
I tried to split this up into two commits, the first where we stash the resolution error until typeck (which causes a bunch of diagnostics changes because the ordering of error messages change), then the second commit is the actual logic that actually implements the suggestion.
I am not in love with the presentation of the suggestion, so I could use some advice for how to format the actual messaging.
r? diagnostics
Fixes#102518
Suggest `.into()` when all other coercion suggestions fail
Also removes some bogus suggestions because we now short-circuit when offering coercion suggestions(instead of, for example, suggesting every one that could possibly apply)
Fixes#102415
Slightly improve no return for returning function error
Fixes#100607
The rationale is that absolute beginners will be slightly confused as to why certain lines of code in a function does not require a semicolon. (I have actually witness a beginner having this confusion). Hence, a slight rationale is added "to return this value", which signals to the user that after removing said semicolon the value is returned resolving that error.
However, if this is not desirable, I welcome any other suggestions. Thanks.
Rollup of 7 pull requests
Successful merges:
- #102441 (Suggest unwrap_or_else when a closure is given)
- #102547 (Migrate CSS theme for search results)
- #102567 (Delay evaluating lint primary message until after it would be suppressed)
- #102624 (rustdoc: remove font family CSS on `.rustdoc-toggle summary::before`)
- #102628 (Change the parameter name of From::from to `value`)
- #102637 (Ignore fuchsia on two compiler tests)
- #102639 (Improve spans when splitting multi-char operator tokens for proc macros.)
Failed merges:
- #102496 (Suggest `.into()` when all other coercion suggestions fail)
r? `@ghost`
`@rustbot` modify labels: rollup
errors: rename `typeck.ftl` to `hir_analysis.ftl`
In #102306, `rustc_typeck` was renamed to `rustc_hir_analysis` but the diagnostic resources were not renamed - which is what this pull request changes.
In #102306, `rustc_typeck` was renamed to `rustc_hir_analysis` but the
diagnostic resources were not renamed - which is what this commit
changes.
Signed-off-by: David Wood <david.wood@huawei.com>
Remove `expr_parentheses_needed` from `ParseSess`
Not sure why this method needed to exist on `ParseSess`, but we can achieve the same behavior by just inlining it everywhere.
Move lint level source explanation to the bottom
So, uhhhhh
r? `@estebank`
## User-facing change
"note: `#[warn(...)]` on by default" and such are moved to the bottom of the diagnostic:
```diff
- = note: `#[warn(unsupported_calling_conventions)]` on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
+ = note: `#[warn(unsupported_calling_conventions)]` on by default
```
Why warning is enabled is the least important thing, so it shouldn't be the first note the user reads, IMO.
## Developer-facing change
`struct_span_lint` and similar methods have a different signature.
Before: `..., impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>)`
After: `..., impl Into<DiagnosticMessage>, impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>) -> &'b mut DiagnosticBuilder<'a, ()>`
The reason for this is that `struct_span_lint` needs to edit the diagnostic _after_ `decorate` closure is called. This also makes lint code a little bit nicer in my opinion.
Another option is to use `impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>) -> DiagnosticBuilder<'a, ()>` altough I don't _really_ see reasons to do `let lint = lint.build(message)` everywhere.
## Subtle problem
By moving the message outside of the closure (that may not be called if the lint is disabled) `format!(...)` is executed earlier, possibly formatting `Ty` which may call a query that trims paths that crashes the compiler if there were no warnings...
I don't think it's that big of a deal, considering that we move from `format!(...)` to `fluent` (which is lazy by-default) anyway, however this required adding a workaround which is unfortunate.
## P.S.
I'm sorry, I do not how to make this PR smaller/easier to review. Changes to the lint API affect SO MUCH 😢
Split out the error reporting logic into a separate function
I was trying to read the function and got distracted by the huge block of code in the middle of it. Turns out it only reports diagnostics and all paths within it end in an error. The main function is now more readable imo.
Fix associated type bindings with anon const in GAT position
The first commit formats `type_of.rs`, which is really hard to maintain since it uses a bunch of features like `let`-chains and `if let` match arm bindings. Best if you just review the second two diffs.
Fixes#102333
`Res::SelfTy` currently has two `Option`s. When the second one is `Some`
the first one is never consulted. So we can split it into two variants,
`Res::SelfTyParam` and `Res::SelfTyAlias`, reducing the size of `Res`
from 24 bytes to 12. This then shrinks `hir::Path` and
`hir::PathSegment`, which are the HIR types that take up the most space.
Add `#[rustc_safe_intrinsic]`
This PR adds the `#[rustc_safe_intrinsic]` attribute as mentionned on Zulip. The goal of this attribute is to avoid keeping a list of symbols as the source for stable intrinsics, and instead rely on an attribute. This is similar to `#[rustc_const_stable]` and `#[rustc_const_unstable]`, which among other things, are used to mark the constness of intrinsic functions.
Do not overwrite lifetime binders for another HirId.
This PR makes higher-ranked bounds in where clauses a bit more principled.
We used to conflate `for<'a> T: Trait` with `(for<'a> T): Trait`.
This PR separates both binders.
This caused issued with fn types, which have their own binder, causing us to overwrite the predicates's binders with `fn`'s binders, ICEing.
Fixes https://github.com/rust-lang/rust/issues/98594
Deny associated type bindings within associated type bindings
Fixes#102335
This was made worse by #100865, which unified the way we generate substs for GATs and non-generic associated types. However, the issue was not _caused_ by #100865, evidenced by the test I added for GATs:
```rust
trait T {
type A: S<C<(), i32 = ()> = ()>;
//~^ ERROR associated type bindings are not allowed here
}
trait Q {}
trait S {
type C<T>: Q;
}
fn main() {}
```
^ which passes on beta (where GATs are stable) and presumably ever since GATs support was added to `create_substs_for_associated_item` in astconv.