Don't ICE on anonymous struct in enum variant
Fixes#121446
Computing `adt_def` for the anon struct calls `adt_def` on the parent to find its repr. If the parent is a non-item (e.g. an enum variant) we should have already emitted at least one error, so we just use the repr of the anonymous struct to avoid an ICE.
cc ``@frank-king``
mark `min_exhaustive_patterns` as complete
This is step 1 and 2 of my [proposal](https://github.com/rust-lang/rust/issues/119612#issuecomment-1918097361) to move `min_exhaustive_patterns` forward. The vast majority of in-tree use cases of `exhaustive_patterns` are covered by `min_exhaustive_patterns`. There are a few cases that still require `exhaustive_patterns` in tests and they're all behind references.
r? ``@ghost``
Allow for a missing `adt_def` in `NamePrivacyVisitor`.
This was caused by 72b172bdf6 in #121206. That commit removed an early return from `analysis` when there are stashed errors. As a result, it's possible to reach privacy analysis when there are stashed errors, which means more code paths can be reached. One such code path was handled in that commit, where a `span_bug` was changed to a `span_delayed_bug`.
This commit handles another such code path uncovered by fuzzing, in much the same way.
Fixes#121455.
r? `@oli-obk`
Fix more #121208 fallout
#121208 converted lots of delayed bugs to bugs. Unsurprisingly, there were a few invalid conversion found via fuzzing.
r? `@lcnr`
When encountering `<&T as Clone>::clone(x)` because `T: Clone`, suggest `#[derive(Clone)]`
CC #40699.
```
warning: call to `.clone()` on a reference in this situation does nothing
--> $DIR/noop-method-call.rs:23:71
|
LL | let non_clone_type_ref_clone: &PlainType<u32> = non_clone_type_ref.clone();
| ^^^^^^^^
|
= note: the type `PlainType<u32>` does not implement `Clone`, so calling `clone` on `&PlainType<u32>` copies the reference, which does not do anything and can be removed
help: remove this redundant call
|
LL - let non_clone_type_ref_clone: &PlainType<u32> = non_clone_type_ref.clone();
LL + let non_clone_type_ref_clone: &PlainType<u32> = non_clone_type_ref;
|
help: if you meant to clone `PlainType<u32>`, implement `Clone` for it
|
LL + #[derive(Clone)]
LL | struct PlainType<T>(T);
|
```
Move as many tests from tests/ui/numbers-arithmetic to tests/ui/lint as possible
Fixes#119851 , and also consolidates as many individual tests as possible from numbers-arithmetic. I might have moved the tests in too aggressively, so let me know
Provide suggestions through `rustc_confusables` annotations
Help with common API confusion, like asking for `push` when the data structure really has `append`.
```
error[E0599]: no method named `size` found for struct `Vec<{integer}>` in the current scope
--> $DIR/rustc_confusables_std_cases.rs:17:7
|
LL | x.size();
| ^^^^
|
help: you might have meant to use `len`
|
LL | x.len();
| ~~~
help: there is a method with a similar name
|
LL | x.resize();
| ~~~~~~
```
Fix#59450 (we can open subsequent tickets for specific cases).
Fix#108437:
```
error[E0599]: `Option<{integer}>` is not an iterator
--> f101.rs:3:9
|
3 | opt.flat_map(|val| Some(val));
| ^^^^^^^^ `Option<{integer}>` is not an iterator
|
::: /home/gh-estebank/rust/library/core/src/option.rs:571:1
|
571 | pub enum Option<T> {
| ------------------ doesn't satisfy `Option<{integer}>: Iterator`
|
= note: the following trait bounds were not satisfied:
`Option<{integer}>: Iterator`
which is required by `&mut Option<{integer}>: Iterator`
help: you might have meant to use `and_then`
|
3 | opt.and_then(|val| Some(val));
| ~~~~~~~~
```
On type error of method call arguments, look at confusables for suggestion. Fix#87212:
```
error[E0308]: mismatched types
--> f101.rs:8:18
|
8 | stuff.append(Thing);
| ------ ^^^^^ expected `&mut Vec<Thing>`, found `Thing`
| |
| arguments to this method are incorrect
|
= note: expected mutable reference `&mut Vec<Thing>`
found struct `Thing`
note: method defined here
--> /home/gh-estebank/rust/library/alloc/src/vec/mod.rs:2025:12
|
2025 | pub fn append(&mut self, other: &mut Self) {
| ^^^^^^
help: you might have meant to use `push`
|
8 | stuff.push(Thing);
| ~~~~
```
This test was already very close to being an ordinary codegen test, except that
it needed some extra logic to set a few variables based on (target) platform
characteristics.
Now that we have support for `//@ filecheck-flags:`, we can instead set those
variables using the normal test revisions mechanism.
This makes room for migrating over `tests/run-make/instrument-coverage`,
without increasing the number of top-level items in the codegen test directory.
This was caused by 72b172bdf6 in #121206. That commit removed an early
return from `analysis` when there are stashed errors. As a result, it's
possible to reach privacy analysis when there are stashed errors, which
means more code paths can be reached. One such code path was handled in
that commit, where a `span_bug` was changed to a `span_delayed_bug`.
This commit handles another such code path uncovered by fuzzing, in much
the same way.
Fixes#121455.
remove `sub_relations` from the `InferCtxt`
While doing so, I tried to remove the `delay_span_bug` in `rematch_impl` again, which lead me to discover another `freshen` bug, fixing that one in the second commit. See commit descriptions for the reasoning behind each change.
r? `@compiler-errors`
When given
```rust
trait Original {
fn f() -> impl Fn();
}
trait Erased {
fn f(&self) -> Box<dyn Fn()>;
}
impl<T: Original> Erased for T {
fn f(&self) -> Box<dyn Fn()> {
Box::new(<T as Original>::f())
}
}
```
avoid suggestion to restrict the `Trait::{opaque}` type in a `where` clause:
```
error[E0310]: the associated type `<T as Original>::{opaque#0}` may not live long enough
--> $DIR/missing-static-bound-from-impl.rs:11:9
|
LL | Box::new(<T as Original>::f())
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| the associated type `<T as Original>::{opaque#0}` must be valid for the static lifetime...
| ...so that the type `impl Fn()` will meet its required lifetime bounds
```
CC #119773.
Rollup of 8 pull requests
Successful merges:
- #120598 (No need to `validate_alias_bound_self_from_param_env` in `assemble_alias_bound_candidates`)
- #121386 (test that we do not support higher-ranked regions in opaque type inference)
- #121393 (match lowering: Introduce a `TestCase` enum to replace most matching on `PatKind`)
- #121401 (Fix typo in serialized.rs)
- #121427 (Fix panic when compiling `Rocket`.)
- #121439 (Fix typo in metadata.rs doc comment)
- #121441 (`DefId` to `LocalDefId`)
- #121452 (Add new maintainers to nto-qnx.md)
r? `@ghost`
`@rustbot` modify labels: rollup
Do not provide a structured suggestion when the arguments don't match.
```
error[E0599]: no method named `test_mut` found for struct `Vec<{integer}>` in the current scope
--> $DIR/auto-ref-slice-plus-ref.rs:7:7
|
LL | a.test_mut();
| ^^^^^^^^
|
= help: items from traits can only be used if the trait is implemented and in scope
note: `MyIter` defines an item `test_mut`, perhaps you need to implement it
--> $DIR/auto-ref-slice-plus-ref.rs:14:1
|
LL | trait MyIter {
| ^^^^^^^^^^^^
help: there is a method `get_mut` with a similar name, but with different arguments
--> $SRC_DIR/core/src/slice/mod.rs:LL:COL
```
Consider methods beyond inherent ones when suggesting typos.
```
error[E0599]: no method named `owned` found for reference `&dyn Foo` in the current scope
--> $DIR/object-pointer-types.rs:11:7
|
LL | fn owned(self: Box<Self>);
| --------- the method might not be found because of this arbitrary self type
...
LL | x.owned();
| ^^^^^ help: there is a method with a similar name: `to_owned`
```
Fix#101013.
```
error[E0308]: mismatched types
--> $DIR/rustc_confusables_std_cases.rs:20:14
|
LL | x.append(42);
| ------ ^^ expected `&mut Vec<{integer}>`, found integer
| |
| arguments to this method are incorrect
|
= note: expected mutable reference `&mut Vec<{integer}>`
found type `{integer}`
note: method defined here
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
help: you might have meant to use `push`
|
LL | x.push(42);
| ~~~~
```
Help with common API confusion, like asking for `push` when the data structure really has `append`.
```
error[E0599]: no method named `size` found for struct `Vec<{integer}>` in the current scope
--> $DIR/rustc_confusables_std_cases.rs:17:7
|
LL | x.size();
| ^^^^
|
help: you might have meant to use `len`
|
LL | x.len();
| ~~~
help: there is a method with a similar name
|
LL | x.resize();
| ~~~~~~
```
#59450
No need to `validate_alias_bound_self_from_param_env` in `assemble_alias_bound_candidates`
We already fully normalize the self type before we reach `assemble_alias_bound_candidates`, so there's no reason to double check that a projection is truly rigid by checking param-env bounds.
I think this is also blocked on us making sure to always normalize opaques: #120549.
r? lcnr
Without doing so we use the same candidate cache entry
for `?0: Trait<?1>` and `?0: Trait<?0>`. These goals are different
and we must not use the same entry for them.
we don't track them when canonicalizing or when freshening,
resulting in instable caching in the old solver, and issues when
instantiating query responses in the new one.
Improve codegen diagnostic handling
Clarify the workings of the temporary `Diagnostic` type used to send diagnostics from codegen threads to the main thread.
r? `@estebank`
intrinsics::simd: add missing functions, avoid UB-triggering fast-math
Turns out stdarch declares a bunch more SIMD intrinsics that are still missing from libcore.
I hope I got the docs and in particular the safety requirements right for these "unordered" and "nanless" intrinsics.
Many of these are unused even in stdarch, but they are implemented in the codegen backend, so we may as well list them here.
r? `@Amanieu`
Cc `@calebzulawski` `@workingjubilee`
- Make it more closely match `rustc_errors::Diagnostic`, by making the
field names match, and adding `children`, which requires adding
`rustc_codegen_ssa:🔙:write::Subdiagnostic`.
- Check that we aren't missing important info when converting
diagnostics.
- Add better comments.
- Tweak `rustc_errors::Diagnostic::replace_args` so that we don't need
to do any cloning when converting diagnostics.
coverage: Remove `pending_dups` from the span refiner
When extracting coverage spans from a function's MIR, we need to decide how to handle spans that are associated with more than one node (BCB) in the coverage control flow graph.
The existing code for managing those duplicate spans is very subtle and difficult to modify. But by eagerly deduplicating those extracted spans in a much simpler way, we can remove a massive chunk of complexity from the span refiner.
There is a tradeoff here, in that we no longer try to retain *all* nondominating BCBs that have the same span, only the last one in the (semi-arbitrary) dominance ordering. But in practice, this produces very little difference in our coverage tests, and the simplification is so significant that I think it's worthwhile.
``@rustbot`` label +A-code-coverage
rename ptr::invalid -> ptr::without_provenance
It has long bothered me that `ptr::invalid` returns a pointer that is actually valid for zero-sized memory accesses. In general, it doesn't even make sense to ask "is this pointer valid", you have to ask "is this pointer valid for a given memory access". We could say that a pointer is invalid if it is not valid for *any* memory access, but [the way this FCP is going](https://github.com/rust-lang/unsafe-code-guidelines/issues/472), it looks like *all* pointers will be valid for zero-sized memory accesses.
Two possible alternative names emerged as people's favorites:
1. Something involving `dangling`, in analogy to `NonNull::dangling`. To avoid inconsistency with the `NonNull` method, the address-taking method could be called `dangling_at(addr: usize) -> *const T`.
2. `without_provenance`, to be symmetric with the inverse operation `ptr.addr_without_provenance()` (currently still called `ptr.addr()` but probably going to be renamed)
I have no idea which one of these is better. I read [this comment](https://github.com/rust-lang/rust/pull/117658#issuecomment-1830934701) as expressing a slight preference for something like the second option, so I went for that. I'm happy to go with `dangling_at` as well.
Cc `@rust-lang/opsem`
Currently `emit_stashed_diagnostic` is called from four(!) different
places: `print_error_count`, `DiagCtxtInner::drop`, `abort_if_errors`,
and `compile_status`.
And `flush_delayed` is called from two different places:
`DiagCtxtInner::drop` and `Queries`.
This is pretty gross! Each one should really be called from a single
place, but there's a bunch of entanglements. This commit cleans up this
mess.
Specifically, it:
- Removes all the existing calls to `emit_stashed_diagnostic`, and adds
a single new call in `finish_diagnostics`.
- Removes the early `flush_delayed` call in `codegen_and_build_linker`,
replacing it with a simple early return if delayed bugs are present.
- Changes `DiagCtxtInner::drop` and `DiagCtxtInner::flush_delayed` so
they both assert that the stashed diagnostics are empty (i.e.
processed beforehand).
- Changes `interface::run_compiler` so that any errors emitted during
`finish_diagnostics` (i.e. late-emitted stashed diagnostics) are
counted and cannot be overlooked. This requires adding
`ErrorGuaranteed` return values to several functions.
- Removes the `stashed_err_count` call in `analysis`. This is possible
now that we don't have to worry about calling `flush_delayed` early
from `codegen_and_build_linker` when stashed diagnostics are pending.
- Changes the `span_bug` case in `handle_tuple_field_pattern_match` to a
`delayed_span_bug`, because it now can be reached due to the removal
of the `stashed_err_count` call in `analysis`.
- Slightly changes the expected output of three tests. If no errors are
emitted but there are delayed bugs, the error count is no longer
printed. This is because delayed bugs are now always printed after the
error count is printed (or not printed, if the error count is zero).
There is a lot going on in this commit. It's hard to break into smaller
pieces because the existing code is very tangled. It took me a long time
and a lot of effort to understand how the different pieces interact, and
I think the new code is a lot simpler and easier to understand.
Remove `diagnostic_builder.rs`
#120576 moved a big chunk of `DiagnosticBuilder`'s functionality out of `diagnostic_builder.rs` into `diagnostic.rs`, which left `DiagnosticBuilder` spread across the two files.
This PR fixes that messiness by merging what remains of `diagnostic_builder.rs` into `diagnostic.rs`.
This is part of https://github.com/rust-lang/compiler-team/issues/722.
r? `@davidtwco`
compiletest: support auxiliaries with auxiliaries
To test behaviour that depends on the extern options of intermediate crates, compiletest auxiliaries must have their own auxiliaries.
Auxiliary compilation previously did not trigger compilation of any auxiliaries in the auxiliary's headers. In addition, those auxiliaries would need to be in an `auxiliary/auxiliary` directory, which is unnecessary and makes some crate graphs harder to write tests for, such as when A depends on B and C, and B depends on C.
For a test `tests/ui/$path/root.rs`, with the following crate graph:
```
root
|-- grandparent
`-- parent
`-- grandparent
```
then the intermediate outputs from compiletest will be:
```
build/$target/test/ui/$path/
|-- auxiliary
| |-- libgrandparent.dylib
| |-- libparent.dylib
| |-- grandparent
| | |-- grandparent.err
| | `-- grandparent.out
| `-- parent
| |-- parent.err
| `-- parent.out
|-- libroot.rmeta
|-- root.err
`-- root.out
```
Support async trait bounds in macros
r? fmease
This is similar to your work on const trait bounds. This theoretically regresses `impl async $ident:ident` in macros, but I doubt this is occurring in practice.
To test behaviour that depends on the extern options of intermediate
crates, compiletest auxiliaries must have their own auxiliaries.
Auxiliary compilation previously did not trigger compilation of any
auxiliaries in the auxiliary's headers. In addition, those auxiliaries
would need to be in an `auxiliary/auxiliary` directory, which is
unnecessary and makes some crate graphs harder to write tests for,
such as when A depends on B and C, and B depends on C.
For a test `tests/ui/$path/root.rs`, with the following crate graph:
```
root
|-- grandparent
`-- parent
`-- grandparent
```
then the intermediate outputs from compiletest will be:
```
build/$target/test/ui/$path/
|-- auxiliary
| |-- libgrandparent.dylib
| |-- libparent.dylib
| |-- grandparent
| | |-- grandparent.err
| | `-- grandparent.out
| `-- parent
| |-- parent.err
| `-- parent.out
|-- libroot.rmeta
|-- root.err
`-- root.out
```
Signed-off-by: David Wood <david@davidtw.co>
Add "algebraic" fast-math intrinsics, based on fast-math ops that cannot return poison
Setting all of LLVM's fast-math flags makes our fast-math intrinsics very dangerous, because some inputs are UB. This set of flags permits common algebraic transformations, but according to the [LangRef](https://llvm.org/docs/LangRef.html#fastmath), only the flags `nnan` (no nans) and `ninf` (no infs) can produce poison.
And this uses the algebraic float ops to fix https://github.com/rust-lang/rust/issues/120720
cc `@orlp`
Downgrade ambiguous_wide_pointer_comparisons suggestions to MaybeIncorrect
In certain cases like #121330, it is possible to have more than one suggestion from the `ambiguous_wide_pointer_comparisons` lint (which before this PR are `MachineApplicable`). When this gets passed to rustfix, rustfix makes *multiple* changes according to the suggestions which result in incorrect code.
This is a temporary workaround. The real long term solution to problems like these is to address <https://github.com/rust-lang/rust/issues/53934>.
This PR also includes a drive-by edit to the panic message emitted by compiletest because "ui" test suite now uses `//`@`` directives.
Fixes#121330.
Make --verbose imply -Z write-long-types-to-disk=no
When shortening the type it is necessary to take into account the `--verbose` flag, if it is activated, we must always show the entire type and not write it in a file.
Fixes: https://github.com/rust-lang/rust/issues/119130
Convert `delayed_bug`s to `bug`s.
I have a suspicion that quite a few delayed bug paths are impossible to reach, so I did an experiment.
I converted every `delayed_bug` to a `bug`, ran the full test suite, then converted back every `bug` that was hit. A surprising number were never hit.
This is too dangerous to merge. Increased coverage (fuzzing or a crater run) would likely hit more cases. But it might be useful for people to look at and think about which paths are genuinely unreachable.
r? `@ghost`
match lowering: simplify empty candidate selection
In match lowering, `match_simplified_candidates` is tasked with removing candidates that are fully matched and linking them up properly. The code that does that was needlessly complicated; this PR simplifies it.
The overall change isn't big but I split it up into tiny commits to convince myself that I was correctly preserving behavior. The test changes are all due to the first commit. Let me know if you'd prefer me to split up the PR to make reviewing easier.
r? `@matthewjasper`
match lowering: eagerly simplify match pairs
This removes one important complication from match lowering. Before this, match pair simplification (which includes collecting bindings and type ascriptions) was intertwined with the whole match lowering algorithm.
I'm avoiding this by storing in each `MatchPair` the sub-`MatchPair`s that correspond to its subfields. This makes it possible to simplify everything (except or-patterns) in `Candidate::new()`.
This should open up further simplifications. It will also give us proper control over the order of bindings.
r? `@matthewjasper`
Because:
- `diagnostic_builder.rs` is small (282 lines),
- `Diagnostic` and `DiagnosticBuilder` are closely related types, and
- there's already an `impl DiagnosticBuilder` block in `diagnostic.rs`.
At the same time, reorder a few of things already in `diagnostic.rs`,
e.g. move `struct Diagnostic` just before `impl Diagnostic`.
This commit only moves code around. There are no functional changes.
Fix stray trait mismatch in `resolve_associated_item` for `AsyncFn`
Copy-paste error meant that we were calling `fn_trait_kind_from_def_id` instead of `async_fn_trait_kind_from_def_id`. But turns out we don't even need to do that, since we already matched the trait def id above.
Fixes#121306
r? oli-obk
Don't use raw parameter types in `find_builder_fn`
We shouldn't really ever be using `EarlyBinder::skip_binder` then performing type equality, since param types will never be equal to other types. When checking compatibility with the signature, we instead create some fresh args.
Fixes#121314
Don't ICE when hitting overflow limit in fulfillment loop in next solver
As the title says, let's not ICE when hitting the overflow limit in fulfill. On the other hand, we don't want to treat these as true errors, since it means that whether something is considered a true error or an ambiguity is dependent on overflow handling in the solver, which seems not worth it.
Now that we use the presence of true errors in fulfillment for implicit negative coherence, we especially don't want to tie together coherence and overflow.
I guess I could also drain these errors out of fulfillment and put them into some `ambiguities` storage so we could return them in `select_all_or_error` without having to re-process them every time we call `select_where_possible`. Let me know if that's desired.
r? lcnr
It is possible to have more than one valid suggestion, which when
applied together via rustfix causes the code to no longer compile.
This is a temporary workaround; the real long term solution to these
issues is to solve <https://github.com/rust-lang/rust/issues/53934>.
Trigger `unsafe_code` lint on invocations of `global_asm`
`unsafe_code` already warns about things that don't involve the `unsafe` keyword, e.g. `#[no_mangle]`. This makes it warn on `core::arch::global_asm` too.
Fixes#103078
Use intrinsics::debug_assertions in debug_assert_nounwind
This is the first item in https://github.com/rust-lang/rust/issues/120848.
Based on the benchmarking in this PR, it looks like, for the programs in our benchmark suite, enabling all these additional checks does not introduce significant compile-time overhead, with the single exception of `Alignment::new_unchecked`. Therefore, I've added `#[cfg(debug_assertions)]` to that one call site, so that it remains compiled out in the distributed standard library.
The trailing commas in the previous calls to `debug_assert_nounwind!` were causing the macro to expand to `panic_nouwnind_fmt`, which requires more work to set up its arguments, and that overhead alone is measured between this perf run and the next: https://github.com/rust-lang/rust/pull/120863#issuecomment-1937423502
Overhaul `Diagnostic` and `DiagnosticBuilder`
Implements the first part of https://github.com/rust-lang/compiler-team/issues/722, which moves functionality and use away from `Diagnostic`, onto `DiagnosticBuilder`.
Likely follow-ups:
- Move things around, because this PR was written to minimize diff size, so some things end up in sub-optimal places. E.g. `DiagnosticBuilder` has impls in both `diagnostic.rs` and `diagnostic_builder.rs`.
- Rename `Diagnostic` as `DiagInner` and `DiagnosticBuilder` as `Diag`.
r? `@davidtwco`
Always evaluate free constants and statics, even if previous errors occurred
work towards https://github.com/rust-lang/rust/issues/79738
We will need to evaluate static items before the `definitions.freeze()` below, as we will start creating new `DefId`s (for nested allocations) within the `eval_static_initializer` query.
But even without that motivation, this is a good change. Hard errors should always be reported and not silenced if other errors happened earlier.