Rollup of 8 pull requests
Successful merges:
- #107062 (Do some cleanup of doc/index.md)
- #107890 (Lint against `Iterator::map` receiving a callable that returns `()`)
- #108431 (Add regression test for #107918)
- #108432 (test: drop unused deps)
- #108436 (make "proc macro panicked" translatable)
- #108444 (docs/test: add UI test and docs for `E0476`)
- #108449 (Do not lint ineffective unstable trait impl for unresolved trait)
- #108456 (Complete migrating `ast_passes` to derive diagnostics)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
docs/test: add UI test and docs for `E0476`
Final undocumented error code. Not entirely sure about wording in the docs.
Part of https://github.com/rust-lang/rust/issues/61137.
r? ```@compiler-errors```
cc ```@compiler-errors```
Implement -Zlink-directives=yes/no
`-Zlink-directives=no` will ignored `#[link]` directives while compiling a crate, so nothing is emitted into the crate's metadata. The assumption is that the build system already knows about the crate's native dependencies and can provide them at link time without these directives.
This is another way to address issue # #70093, which is currently addressed by `-Zlink-native-libraries` (implemented in #70095). The latter is implemented at link time, which has the effect of ignoring `#[link]` in *every* crate. This makes it a very large hammer as it requires all native dependencies to be known to the build system to be at all usable, including those in sysroot libraries. I think this means its effectively unused, and definitely under-used.
Being able to control this on a crate-by-crate basis should make it much easier to apply when needed.
I'm not sure if we need both mechanisms, but we can decide that later.
cc `@pcwalton` `@cramertj`
[breaking change] Remove a rustdoc back compat warning
This warning was introduced in https://github.com/rust-lang/rust/pull/62855 for users who use `rustdoc` directly on proc macro crates (instead of using `cargo doc`) without passing `--crate-type proc-macro` (which `cargo doc` passed automatically).
Wrap missing provider message correctly
Fixes#108429
```
error: internal compiler error: compiler/rustc_middle/src/ty/query.rs:441:1: `tcx.trigger_delay_span_bug(DefId(0:3 ~ test[78c5]::main))` is not supported for local crate;
hint: Queries can be either made to the local crate, or the external crate. This error means you tried to use it for one that's not supported.
If that's not the case, trigger_delay_span_bug was likely never assigned to a provider function.
thread 'rustc' panicked at 'Box<dyn Any>', /home/ec2-user/rust3/compiler/rustc_errors/src/lib.rs:1651:9
stack backtrace:
0: 0x7f51870926d7 - std::backtrace_rs::backtrace::libunwind::trace::hb0876bb39e7adf0d
at /home/ec2-user/rust3/library/std/src/../../backtrace/src/backtrace/libunwind.rs:93:5
1: 0x7f51870926d7 - std::backtrace_rs::backtrace::trace_unsynchronized::h1bcab1313827007b
at /home/ec2-user/rust3/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
2: 0x7f5187077e07 - std::sys_common::backtrace::_print_fmt::h262d2a62279fa102
at /home/ec2-user/rust3/library/std/src/sys_common/backtrace.rs:65:5
```
Remove dead unwinds before drop elaboration
As a part of drop elaboration, we identify dead unwinds, i.e., unwind
edges on a drop terminators which are known to be unreachable, because
there is no need to drop anything.
Previously, the data flow framework was informed about the dead unwinds,
and it assumed those edges are absent from MIR. Unfortunately, the data
flow framework wasn't consistent in maintaining this assumption.
In particular, if a block was reachable only through a dead unwind edge,
its state was propagated to other blocks still. This became an issue in
the context of change removes DropAndReplace terminator, since it
introduces initialization into cleanup blocks.
To avoid this issue, remove unreachable unwind edges before the drop
elaboration, and elaborate only blocks that remain reachable.
cc `@Zeegomo`
diagnostics: remove inconsistent English article "this" from E0107
Consider [`tests/ui/const-generics/generic_const_exprs/issue-102768.stderr`][issue-102768.stderr], the error message where it gives additional notes about where the associated type is defined, and how the dead code lint doesn't have an article, like in [`tests/ui/lint/dead-code/issue-85255.stderr`][issue-85255.stderr]. They don't have articles, so it seems unnecessary to have one here.
[issue-102768.stderr]: 07c993eba8/tests/ui/const-generics/generic_const_exprs/issue-102768.stderr
[issue-85255.stderr]: 07c993eba8/tests/ui/lint/dead-code/issue-85255.stderr
parser: provide better suggestions and errors on closures with braces missing
We currently provide wrong suggestions and unhelpful errors on closure bodies with braces missing.
For example, given the following code:
```rust
fn main() {
let _x = Box::new(|x|x+1;);
}
```
the current output is:
```
error: expected expression, found `)`
--> ./main.rs:2:30
|
2 | let _x = Box::new(|x|x+1;);
| ^ expected expression
error: closure bodies that contain statements must be surrounded by braces
--> ./main.rs:2:25
|
2 | let _x = Box::new(|x|x+1;);
| ^
3 | }
| ^
|
note: statement found outside of a block
--> ./main.rs:2:29
|
2 | let _x = Box::new(|x|x+1;);
| ---^ this `;` turns the preceding closure into a statement
| |
| this expression is a statement because of the trailing semicolon
note: the closure body may be incorrectly delimited
--> ./main.rs:2:23
|
2 | let _x = Box::new(|x|x+1;);
| ^^^^^^ this is the parsed closure...
3 | }
| - ...but likely you meant the closure to end here
help: try adding braces
|
2 ~ let _x = Box::new(|x| {x+1;);
3 ~ }}
|
error: expected `;`, found `}`
--> ./main.rs:2:32
|
2 | let _x = Box::new(|x|x+1;);
| ^ help: add `;` here
3 | }
| - unexpected token
error: aborting due to 3 previous errors
```
We got 3 errors, but all but the second are unnecessary or just wrong.
This commit allows outputting correct suggestions and errors. The above code would output like this:
```
error: closure bodies that contain statements must be surrounded by braces
--> ./main.rs:2:25
|
2 | let _x = Box::new(|x|x+1;);
| ^ ^
|
note: statement found outside of a block
--> ./main.rs:2:29
|
2 | let _x = Box::new(|x|x+1;);
| ---^ this `;` turns the preceding closure into a statement
| |
| this expression is a statement because of the trailing semicolon
note: the closure body may be incorrectly delimited
--> ./main.rs:2:23
|
2 | let _x = Box::new(|x|x+1;);
| ^^^^^^ - ...but likely you meant the closure to end here
| |
| this is the parsed closure...
help: try adding braces
|
2 | let _x = Box::new(|x| {x+1;});
| + +
error: aborting due to previous error
```
Fixes https://github.com/rust-lang/rust/issues/107959.
r? diagnostics
Fix ICE in 'duplicate diagnostic item' diagnostic
Not sure how to add this in a test; I found it by mistakenly running `cargo fix --lib -p std` rather than `x fix` at the root.
implement const iterator using `rustc_do_not_const_check`
Previous experiment: #102225.
Explanation: rather than making all default methods work under `const` all at once, this uses `rustc_do_not_const_check` as a workaround to "trick" the compiler to not run any checks on those other default methods. Any const implementations are only required to implement the `next` method. Any actual calls to the trait methods other than `next` will either error in compile time (at CTFE runs), or run the methods correctly if they do not have any non-const operations. This is extremely easy to maintain, remove, or improve.
(This is a large commit. The changes to
`compiler/rustc_middle/src/ty/context.rs` are the most important ones.)
The current naming scheme is a mess, with a mix of `_intern_`, `intern_`
and `mk_` prefixes, with little consistency. In particular, in many
cases it's easy to use an iterator interner when a (preferable) slice
interner is available.
The guiding principles of the new naming system:
- No `_intern_` prefixes.
- The `intern_` prefix is for internal operations.
- The `mk_` prefix is for external operations.
- For cases where there is a slice interner and an iterator interner,
the former is `mk_foo` and the latter is `mk_foo_from_iter`.
Also, `slice_interners!` and `direct_interners!` can now be `pub` or
non-`pub`, which helps enforce the internal/external operations
division.
It's not perfect, but I think it's a clear improvement.
The following lists show everything that was renamed.
slice_interners
- const_list
- mk_const_list -> mk_const_list_from_iter
- intern_const_list -> mk_const_list
- substs
- mk_substs -> mk_substs_from_iter
- intern_substs -> mk_substs
- check_substs -> check_and_mk_substs (this is a weird one)
- canonical_var_infos
- intern_canonical_var_infos -> mk_canonical_var_infos
- poly_existential_predicates
- mk_poly_existential_predicates -> mk_poly_existential_predicates_from_iter
- intern_poly_existential_predicates -> mk_poly_existential_predicates
- _intern_poly_existential_predicates -> intern_poly_existential_predicates
- predicates
- mk_predicates -> mk_predicates_from_iter
- intern_predicates -> mk_predicates
- _intern_predicates -> intern_predicates
- projs
- intern_projs -> mk_projs
- place_elems
- mk_place_elems -> mk_place_elems_from_iter
- intern_place_elems -> mk_place_elems
- bound_variable_kinds
- mk_bound_variable_kinds -> mk_bound_variable_kinds_from_iter
- intern_bound_variable_kinds -> mk_bound_variable_kinds
direct_interners
- region
- intern_region (unchanged)
- const
- mk_const_internal -> intern_const
- const_allocation
- intern_const_alloc -> mk_const_alloc
- layout
- intern_layout -> mk_layout
- adt_def
- intern_adt_def -> mk_adt_def_from_data (unusual case, hard to avoid)
- alloc_adt_def(!) -> mk_adt_def
- external_constraints
- intern_external_constraints -> mk_external_constraints
Other
- type_list
- mk_type_list -> mk_type_list_from_iter
- intern_type_list -> mk_type_list
- tup
- mk_tup -> mk_tup_from_iter
- intern_tup -> mk_tup
All the slice interners have a wrapper that handles the empty slice
case. We can instead handle this in the `slice_interners!` macro,
avoiding the need for most of the wrappers, and allowing the interner
functions to be renamed from `_intern_foos` to `intern_foos`.
The two exceptions:
- intern_predicates: I kept this wrapper because there's a FIXME
comment about a possible future change.
- intern_poly_existential_predicates: I kept this wrapper because it
asserts that the slice is empty and sorted.
Consider `tests/ui/const-generics/generic_const_exprs/issue-102768.stderr`,
the error message where it gives additional notes about where the associated
type is defined, and how the dead code lint doesn't have an article,
like in `tests/ui/lint/dead-code/issue-85255.stderr`. They don't have
articles, so it seems unnecessary to have one here.
As a part of drop elaboration, we identify dead unwinds, i.e., unwind
edges on a drop terminators which are known to be unreachable, because
there is no need to drop anything.
Previously, the data flow framework was informed about the dead unwinds,
and it assumed those edges are absent from MIR. Unfortunately, the data
flow framework wasn't consistent in maintaining this assumption.
In particular, if a block was reachable only through a dead unwind edge,
its state was propagated to other blocks still. This became an issue in
the context of change removes DropAndReplace terminator, since it
introduces initialization into cleanup blocks.
To avoid this issue, remove unreachable unwind edges before the drop
elaboration, and elaborate only blocks that remain reachable.
We currently provide wrong suggestions and unhelpful errors on closure
bodies with braces missing. For example, given the following code:
```
fn main() {
let _x = Box::new(|x|x+1;);
}
```
the current output is like this:
```
error: expected expression, found `)`
--> ./main.rs:2:30
|
2 | let _x = Box::new(|x|x+1;);
| ^ expected expression
error: closure bodies that contain statements must be surrounded by braces
--> ./main.rs:2:25
|
2 | let _x = Box::new(|x|x+1;);
| ^
3 | }
| ^
|
...
help: try adding braces
|
2 ~ let _x = Box::new(|x| {x+1;);
3 ~ }}
...
error: expected `;`, found `}`
--> ./main.rs:2:32
|
2 | let _x = Box::new(|x|x+1;);
| ^ help: add `;` here
3 | }
| - unexpected token
error: aborting due to 3 previous errors
```
This commit allows outputting correct suggestions and errors. The above
code would output like this:
```
error: closure bodies that contain statements must be surrounded by braces
--> ./main.rs:2:25
|
2 | let _x = Box::new(|x|x+1;);
| ^ ^
|
note: statement found outside of a block
--> ./main.rs:2:29
|
2 | let _x = Box::new(|x|x+1;);
| ---^ this `;` turns the preceding closure into a statement
| |
| this expression is a statement because of the trailing semicolon
note: the closure body may be incorrectly delimited
--> ./main.rs:2:23
|
2 | let _x = Box::new(|x|x+1;);
| ^^^^^^ - ...but likely you meant the closure to end here
| |
| this is the parsed closure...
help: try adding braces
|
2 | let _x = Box::new(|x| {x+1;});
| + +
error: aborting due to previous error
```
Use `tcx.ty_error_with_guaranteed` in more places, rename variants
1. Use `ty_error_with_guaranteed` more so we don't delay so many span bugs
2. Rename `ty_error_with_guaranteed` to `ty_error`, `ty_error` to `ty_error_misc`. This is to incentivize using the former over the latter in cases where we already are witness to a `ErrorGuaranteed` token.
Second commit is just name replacement, so the first commit can be reviewed on its own with more scrutiny.
Use associated type bounds in some places in the compiler
Use associated type bounds for some nested `impl Trait<Assoc = impl Trait2>` cases. I'm generally keen to introduce new lang features that are more mature into the compiler, but maybe let's see what others think?
Side-note: I was surprised that the only use-cases of nested impl trait in the compiler are just iterator related?!
Correctly handle aggregates in DataflowConstProp
The previous implementation from https://github.com/rust-lang/rust/pull/107411 flooded target of an aggregate assignment with `Bottom`, corresponding to the `deinit` that the interpreter does.
As a consequence, when assigning `target = Enum::Variant#i(...)` all the `(target as Variant#j)` were at `Bottom` while they should have been `Top`.
This PR replaces that flooding with `Top`.
Aside, it corrects a second bug where the wrong place would be used to assign to enum variant fields, resulting to nothing happening.
Fixes https://github.com/rust-lang/rust/issues/108166
Ban associated type bounds in bad positions
We should not try to lower associated type bounds into TAITs in positions where `impl Trait` is not allowed (except for in `where` clauses, like `where T: Trait<Assoc: Bound>`).
This is achieved by using the same `rustc_ast_lowering` machinery as impl-trait does to characterize positions as universal/existential/disallowed.
Fixes#106077
Split out the first commit into #108066, since it's not really related.