get rid of `RefCell` in `TransitiveRelation`
This is one of the jobs in `Pending refactorings` in #48685. The parallel-compiler's work has been suspended for quite some time, but I think I can pick it up gradually. I think this PR should be a start.
Regarding the refactoring of `TransitiveRelation`, `@nikomatsakis` has proposed [two(three?) schemes](https://github.com/rust-lang/rust/pull/48587#issuecomment-369336651). In order to satisfy both compilation efficiency and robustness, I think adding the `freeze` method may be the best solution, although it requires relatively more code changes.
Migrate rustc_ast_passes diagnostics to `SessionDiagnostic` and translatable messages (first part)
Doing a full migration of the `rustc_ast_passes` crate.
Making a draft here since there's not yet a tracking issue for the migrations going on.
`@rustbot` label +A-translation
Recover keywords in trait bounds
(_this pr was inspired by [this tweet](https://twitter.com/Azumanga/status/1552982326409367561)_)
Recover keywords in trait bound, motivational example:
```rust
fn f(_: impl fn()) {} // mistyped, meant `Fn`
```
<details><summary>Current nightly (3 needless and confusing errors!)</summary>
<p>
```text
error: expected identifier, found keyword `fn`
--> ./t.rs:1:15
|
1 | fn _f(_: impl fn()) {}
| ^^ expected identifier, found keyword
|
help: escape `fn` to use it as an identifier
|
1 | fn _f(_: impl r#fn()) {}
| ++
error: expected one of `:` or `|`, found `)`
--> ./t.rs:1:19
|
1 | fn _f(_: impl fn()) {}
| ^ expected one of `:` or `|`
error: expected one of `!`, `(`, `)`, `,`, `?`, `for`, `~`, lifetime, or path, found keyword `fn`
--> ./t.rs:1:15
|
1 | fn _f(_: impl fn()) {}
| -^^ expected one of 9 possible tokens
| |
| help: missing `,`
error: at least one trait must be specified
--> ./t.rs:1:10
|
1 | fn _f(_: impl fn()) {}
| ^^^^
```
</p>
</details>
This PR:
```text
error: expected identifier, found keyword `fn`
--> ./t.rs:1:15
|
1 | fn _f(_: impl fn()) {}
| ^^ expected identifier, found keyword
|
help: escape `fn` to use it as an identifier
|
1 | fn _f(_: impl r#fn()) {}
| ++
error[E0405]: cannot find trait `r#fn` in this scope
--> ./t.rs:1:15
|
1 | fn _f(_: impl fn()) {}
| ^^ help: a trait with a similar name exists (notice the capitalization): `Fn`
|
::: /home/waffle/projects/repos/rust/library/core/src/ops/function.rs:74:1
|
74 | pub trait Fn<Args>: FnMut<Args> {
| ------------------------------- similarly named trait `Fn` defined here
```
It would be nice to have suggestion in the first error like "have you meant `Fn` trait", instead of a separate error, but the recovery is deep inside ident parsing, which makes it a lot harder to do.
r? `@compiler-errors`
implied bounds: explicitly state which types are assumed to be wf
Adds a new query which maps each definition to the types which that definition assumes to be well formed. The intent is to make it easier to reason about implied bounds.
This change should not influence the user-facing behavior of rustc. Notably, `borrowck` still only assumes that the function signature of associated functions is well formed while `wfcheck` assumes that the both the function signature and the impl trait ref is well formed. Not sure if that by itself can trigger UB or whether it's just annoying.
As a next step, we can add `WellFormed` predicates to `predicates_of` of these items and can stop adding the wf bounds at each place which uses them. I also intend to move the computation from `assumed_wf_types` to `implied_bounds` into the `param_env` computation. This requires me to take a deeper look at `compare_predicate_entailment` which is currently somewhat weird wrt implied bounds so I am not touching this here.
r? `@nikomatsakis`
Use `AttrVec` more
In some places we use `Vec<Attribute>` and some places we use
`ThinVec<Attribute>` (a.k.a. `AttrVec`). This results in various points
where we have to convert between `Vec` and `ThinVec`.
This commit changes the places that use `Vec<Attribute>` to use
`AttrVec`. A lot of this is mechanical and boring, but there are
some interesting parts:
- It adds a few new methods to `ThinVec`.
- It implements `MapInPlace` for `ThinVec`, and introduces a macro to
avoid the repetition of this trait for `Vec`, `SmallVec`, and
`ThinVec`.
Overall, it makes the code a little nicer, and has little effect on
performance. But it is a precursor to removing
`rustc_data_structures::ThinVec` and replacing it with
`thin_vec::ThinVec`, which is implemented more efficiently.
r? `@spastorino`
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`
In some places we use `Vec<Attribute>` and some places we use
`ThinVec<Attribute>` (a.k.a. `AttrVec`). This results in various points
where we have to convert between `Vec` and `ThinVec`.
This commit changes the places that use `Vec<Attribute>` to use
`AttrVec`. A lot of this is mechanical and boring, but there are
some interesting parts:
- It adds a few new methods to `ThinVec`.
- It implements `MapInPlace` for `ThinVec`, and introduces a macro to
avoid the repetition of this trait for `Vec`, `SmallVec`, and
`ThinVec`.
Overall, it makes the code a little nicer, and has little effect on
performance. But it is a precursor to removing
`rustc_data_structures::thin_vec::ThinVec` and replacing it with
`thin_vec::ThinVec`, which is implemented more efficiently.
Replace most uses of `pointer::offset` with `add` and `sub`
As PR title says, it replaces `pointer::offset` in compiler and standard library with `pointer::add` and `pointer::sub`. This generally makes code cleaner, easier to grasp and removes (or, well, hides) integer casts.
This is generally trivially correct, `.offset(-constant)` is just `.sub(constant)`, `.offset(usized as isize)` is just `.add(usized)`, etc. However in some cases we need to be careful with signs of things.
r? ````@scottmcm````
_split off from #100746_
some general mir typeck cleanup
this pr contains the parts of #95763 which already work correctly.
the remaining commits of that PR have some issues which are more complex to fix.
r? types
Minor syntax and formatting update to doc comment on `find_vtable_types_for_unsizing`
I noticed the code examples on this function weren't formatted as code, and also the that the syntax for trait objects was out of date (or just incorrect). This should bring it up to date.
Deriving SessionDiagnostic on a type no longer forces that diagnostic to
be one of warning, error, or fatal. The level is instead decided when
the struct is passed to the respective Handler::emit_*() method.