UnreachableProp: Preserve unreachable branches for multiple targets
Before, UnreachablePropagation removed all unreachable branches. This was a pessimization, as it removed information about reachability that was used later in the optimization pipeline.
For example, this code
```rust
pub enum Two { A, B }
pub fn identity(x: Two) -> Two {
match x {
Two::A => Two::A,
Two::B => Two::B,
}
}
```
basically has `switchInt() -> [0: 0, 1: 1, otherwise: unreachable]` for the match. This allows it to be transformed into a simple `x`. If we remove the unreachable branch, the transformation becomes illegal.
This was the problem keeping `UnreachablePropagation` from being enabled, so we can enable it now.
Something similar already happened in #77800, but it did not show a perf improvement there. Let's try it again anyways!
Fixes#68105, although that issue has been fixed for a long time (see #77680).
Add guarantee that Vec::default() does not alloc
Currently `Vec::new()` is guaranteed to not allocate until elements are pushed onto the `Vec`, but such a guarantee is missing for `Vec`'s implementation of `Default::default`.
This adds such a guarantee for `Vec::default()` to the API reference.
See also [this discussion on URLO](https://users.rust-lang.org/t/guarantee-that-vec-default-does-not-allocate/79903).
Use pointer `is_aligned*` methods
This PR replaces some manual alignment checks with calls to `pointer::{is_aligned, is_aligned_to}` and removes a useless pointer cast.
r? `@scottmcm`
_split off from #100746_
Convert diagnostics in parser/expr to SessionDiagnostic
This migrates all the easy cases in `rustc_parse::parser::expr` to `SessionDiagnostic`s, I've left things such as `multipart_suggestion`s out for now in the hopes of a derive API being developed soon.
Guarantee `try_reserve` preserves the contents on error
Update doc comments to make the guarantee explicit. However, some
implementations does not have the statement though.
* `HashMap`, `HashSet`: require guarantees on hashbrown side.
* `PathBuf`: simply redirecting to `OsString`.
Fixes#99606.
Rework Ipv6Addr::is_global to check for global reachability rather than global scope - rebase
Rebasing of pull request #86634 off of master to try and get the feature "ip" stabilized.
I also found a test failure in the rebase that is_global was considering the benchmark space to be globally reachable.
This is related to my other rebasing pull request #99947
Make some const prop mir-opt tests `unit-test`s
Most of these have no or only tiny diffs beyond line numbers being changed (would it make sense to not have line numbers in mir-opt tests?). Some things changed a bit, but I think it should all be fine, not sure though.
Expand potential inner `Or` pattern for THIR
Code assumed there wouldn't be a deeper `Or` pattern inside expanded `PatStack` this fixes it by looking for the `Or` pattern inside expanded `PatStack`.
A more ideal solution would be recursively doing this but I haven't found a good way to do that.
_fixes #97898_
Show absolute line numbers if span is outside relative span
In the MIR pretty printing, it can sometimes happen that the span of the statement is outside the span of the body (for example through inlining). In this case, don't display a relative span but an absolute span. This will make the mir-opt-tests a little more prone to diffs again, but the impact should be small.
Fixes#99854
r? `@oli-obk`
In the MIR pretty printing, it can sometimes happen that the span of the
statement is outside the span of the body (for example through
inlining). In this case, don't display a relative span but an absolute
span. This will make the mir-opt-tests a little more prone to diffs
again, but the impact should be small.
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.
Currently `Vec::new()` is guaranteed to not allocate until elements are
pushed onto the `Vec`, but such a guarantee is missing for `Vec`'s
implementation of `Default::default`. This adds such a guarantee for
`Vec::default()` to the API reference.
Example error before:
error: name `generic_does_not_live_long_enough` does not start with the crate name
--> compiler/rustc_error_messages/src/lib.rs:33:17
|
33 | borrowck => "../locales/en-US/borrowck.ftl",
| ^^^^^^^^
|
= help: prepend `borrowck_` to the slug name: `borrowck_generic_does_not_live_long_enough`
after:
error: name `generic_does_not_live_long_enough` does not start with the crate name
--> compiler/rustc_error_messages/src/lib.rs:33:17
|
33 | borrowck => "../locales/en-US/borrowck.ftl",
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: prepend `borrowck_` to the slug name: `borrowck_generic_does_not_live_long_enough`
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`
Add tests that check `Vec::retain` predicate execution order.
This behaviour is documented for `Vec::retain` which means that there is code that rely on that but there weren't tests about that.
Std module docs improvements
My primary goal is to create a cleaner separation between primitive types and primitive type helper modules (fixes#92777). I also changed a few header lines in other top-level std modules (seen at https://doc.rust-lang.org/std/) for consistency.
Some conventions used/established:
* "The \`Box\<T>` type for heap allocation." - if a module mainly provides a single type, name it and summarize its purpose in the module header
* "Utilities for the _ primitive type." - this wording is used for the header of helper modules
* Documentation for primitive types themselves are removed from helper modules
* provided-by-core functionality of primitive types is documented in the primitive type instead of the helper module (such as the "Iteration" section in the slice docs)
I wonder if some content in `std::ptr` should be in `pointer` but I did not address this.
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`