Rework "point at arg" suggestions to be more accurate
Fixes#100560
Introduce a new set of `ObligationCauseCode`s which have additional bookeeping for what expression caused the obligation, and which predicate caused the obligation. This allows us to look at the _unsubstituted_ signature to find out which parameter or generic type argument caused an obligaton to fail.
This means that (in most cases) we significantly improve the likelihood of pointing out the right argument that causes a fulfillment error. Also, since this logic isn't happening in just the `select_where_possible_and_mutate_fulfillment()` calls in the argument checking code, but instead during all trait selection in `FnCtxt`, we are also able to point out the correct argument even if inference means that we don't know whether an obligation has failed until well after a call expression has been checked.
r? `@ghost`
Don't fix builtin index when Where clause is found
Where clause shadows blanket impl for `Index` which causes normalization to not occur, which causes ICE to happen when we typeck.
r? `@compiler-errors`
Fixes#91633
Do not allow `Drop` impl on foreign fundamental types
`Drop` should not be implemented on `Pin<T>` even if `T` is local.
This does not trigger regular orphan rules is because `Pin` is `#[fundamental]`... but we don't allow specialized `Drop` impls anyways, so these rules are not sufficient to prevent this impl on stable. Let's just choose even stricter rules, since we shouldn't be implementing `Drop` on a foreign ADT ever.
Fixes#99575
Migrate lint reports in typeck::check_unused to LintDiagnostic
In this PR, I migrate two lint reports in `typeck::check_unused` by `LintDiagnostic`, all of which is about extern crates.
```@rustbot``` label +A-translation
r? rust-lang/diagnostics
Make must_not_suspend lint see through references when drop tracking is enabled
See #97333.
With drop tracking enabled, sometimes values that were previously linted are now considered dropped and not linted. This change makes must_not_suspend traverse through references to still catch these values.
Unfortunately, this leads to duplicate warnings in some cases (e.g. [dedup.rs](9a74608543/src/test/ui/lint/must_not_suspend/dedup.rs (L4))), so we only use the new behavior when drop tracking is enabled.
cc ``@guswynn``
Remove deferred sized checks (make them eager)
Improves diagnostics spans... this doesn't seem to be the case anymore:
```rust
// Some additional `Sized` obligations badly affect type inference.
// These obligations are added in a later stage of typeck.
pub(super) deferred_sized_obligations:
RefCell<Vec<(Ty<'tcx>, Span, traits::ObligationCauseCode<'tcx>)>>,
```
when there are 3 or more return statements in the loop
emit the first 3 errors and duplicated diagnostic information
modified: compiler/rustc_typeck/src/check/coercion.rs
new file: src/test/ui/typeck/issue-100285.rs
new file: src/test/ui/typeck/issue-100285.stderr
emit the first 3 errors and duplicated diagnostic information
using take of iterator for the first third return
modified: compiler/rustc_typeck/src/check/coercion.rs
new file: src/test/ui/typeck/issue-100285.rs
new file: src/test/ui/typeck/issue-100285.stderr
Rollup of 6 pull requests
Successful merges:
- #100211 (Refuse to codegen an upstream static.)
- #100277 (Simplify format_args builtin macro implementation.)
- #100483 (Point to generic or arg if it's the self type of unsatisfied projection predicate)
- #100506 (change `InlineAsmCtxt` to not talk about `FnCtxt`)
- #100534 (Make code slightly more uniform)
- #100566 (Use `create_snapshot_for_diagnostic` instead of `clone` for `Parser`)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
change `InlineAsmCtxt` to not talk about `FnCtxt`
wip for https://github.com/rust-lang/compiler-team/issues/529. this currently uses both the `FnCtxt` and is used by `check_mod_item_types`. This should be the only thing blocking that MCP afaict.
I am still unsure whether `rustc_hir_typeck` should depend on `rustc_hir_analysis` to use the `InlineAsmCtxt`. I think that's the best solution for now, so that's what I will go for
r? `@compiler-errors`
Point to generic or arg if it's the self type of unsatisfied projection predicate
We do this for `TraitPredicate`s in `point_at_type_arg_instead_of_call_if_possible` and `point_at_arg_instead_of_call_if_possible`, so also do it for `ProjectionPredicate`.
Improves spans for a lot of unit tests.
Visit attributes in more places.
This adds 3 loosely related changes (I can split PRs if desired):
- Attribute checking on pattern struct fields.
- Attribute checking on struct expression fields.
- Lint level visiting on pattern struct fields, struct expression fields, and generic parameters.
There are still some lints which ignore lint levels in various positions. This is a consequence of how the lints themselves are implemented. For example, lint levels on associated consts don't work with `unused_braces`.
Argument type error improvements
Motivated by this interesting code snippet:
```rust
#[derive(Copy, Clone)]
struct Wrapper<T>(T);
fn foo(_: fn(i32), _: Wrapper<i32>) {}
fn f(_: u32) {}
fn main() {
let w = Wrapper::<isize>(1isize);
foo(f, w);
}
```
Which currently errors like:
```
error[E0308]: arguments to this function are incorrect
--> src/main.rs:10:5
|
10 | foo(f, w);
| ^^^ - - expected `i32`, found `isize`
| |
| expected `i32`, found `u32`
|
= note: expected fn pointer `fn(i32)`
found fn item `fn(u32) {f}`
= note: expected struct `Wrapper<i32>`
found struct `Wrapper<isize>`
note: function defined here
--> src/main.rs:4:4
|
4 | fn foo(_: fn(i32), _: Wrapper<i32>) {}
| ^^^ ---------- ---------------
```
Specifically, that double `expected .. found ..` which is very difficult to correlate to the types in the arguments. Also, the fact that "expected `i32`, found `isize`" and the other argument mismatch label don't even really explain what's going on here.
After this PR:
```
error[E0308]: arguments to this function are incorrect
--> $DIR/two-mismatch-notes.rs:10:5
|
LL | foo(f, w);
| ^^^
|
note: expected fn pointer, found fn item
--> $DIR/two-mismatch-notes.rs:10:9
|
LL | foo(f, w);
| ^
= note: expected fn pointer `fn(i32)`
found fn item `fn(u32) {f}`
note: expected struct `Wrapper`, found a different struct `Wrapper`
--> $DIR/two-mismatch-notes.rs:10:12
|
LL | foo(f, w);
| ^
= note: expected struct `Wrapper<i32>`
found struct `Wrapper<isize>`
note: function defined here
--> $DIR/two-mismatch-notes.rs:4:4
|
LL | fn foo(_: fn(i32), _: Wrapper<i32>) {}
| ^^^ ---------- ---------------
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.
```
Yeah, it's a bit verbose, but much clearer IMO.
---
Open to discussions about how this could be further improved. Motivated by `@jyn514's` [tweet](https://mobile.twitter.com/joshuayn514/status/1558042020601634816) here.