coverage: `llvm-cov` expects column numbers to be bytes, not code points
Normally the compiler emits column numbers as a 1-based number of Unicode code points.
But when we embed coverage mappings for `-Cinstrument-coverage`, those mappings will ultimately be read by the `llvm-cov` tool. That tool assumes that column numbers are 1-based numbers of *bytes*, and relies on that assumption when slicing up source code to apply highlighting (in HTML reports, and in text-based reports with colour).
For the very common case of all-ASCII source code, bytes and code points are the same, so the difference isn't noticeable. But for code that contains non-ASCII characters, emitting column numbers as code points will result in `llvm-cov` slicing strings in the wrong places, producing mangled output or fatal errors.
(See https://github.com/taiki-e/cargo-llvm-cov/issues/275 as an example of what can go wrong.)
Improved support of collapse_debuginfo attribute for macros.
Added walk_chain_collapsed function to consider collapse_debuginfo attribute in parent macros in call chain.
Fixed collapse_debuginfo attribute processing for cranelift (there was if/else branches error swap).
cc https://github.com/rust-lang/rust/issues/100758
Consuming `emit`
This PR makes `DiagnosticBuilder::emit` consuming, i.e. take `self` instead of `&mut self`. This is good because it doesn't make sense to emit a diagnostic twice.
This requires some changes to `DiagnosticBuilder` method changing -- every existing non-consuming chaining method gets a new consuming partner with a `_mv` suffix -- but permits a host of beneficial follow-up changes: more concise code through more chaining, removal of redundant diagnostic construction API methods, and removal of machinery to track the possibility of a diagnostic being emitted multiple times.
r? `@compiler-errors`
They are no longer used, because
`{DiagCtxt,DiagCtxtInner}::emit_diagnostic` are used everywhere instead.
This also means `track_diagnostic` can become consuming.
Currently it's used for two dynamic checks:
- When a diagnostic is emitted, has it been emitted before?
- When a diagnostic is dropped, has it been emitted/cancelled?
The first check is no longer need, because `emit` is consuming, so it's
impossible to emit a `DiagnosticBuilder` twice. The second check is
still needed.
This commit replaces `DiagnosticBuilderState` with a simpler
`Option<Box<Diagnostic>>`, which is enough for the second check:
functions like `emit` and `cancel` can take the `Diagnostic` and then
`drop` can check that the `Diagnostic` was taken.
The `DiagCtxt` reference from `DiagnosticBuilderState` is now stored as
its own field, removing the need for the `dcx` method.
As well as making the code shorter and simpler, the commit removes:
- One (deprecated) `ErrorGuaranteed::unchecked_claim_error_was_emitted`
call.
- Two `FIXME(eddyb)` comments that are no longer relevant.
- The use of a dummy `Diagnostic` in `into_diagnostic`.
Nice!
The existing uses are replaced in one of three ways.
- In a function that also has calls to `emit`, just rearrange the code
so that exactly one of `delay_as_bug` or `emit` is called on every
path.
- In a function returning a `DiagnosticBuilder`, use
`downgrade_to_delayed_bug`. That's good enough because it will get
emitted later anyway.
- In `unclosed_delim_err`, one set of errors is being replaced with
another set, so just cancel the original errors.
The old code was very hard to understand, involving an
`emit_without_consuming` call *and* a `delay_as_bug_without_consuming`
call.
With slight changes both calls can be avoided. Not creating the error
until later is crucial, as is the early return in the `if recovered`
block.
It took me some time to come up with this reworking -- it went through
intermediate states much further from the original code than this final
version -- and it's isn't obvious at a glance that it is equivalent. But
I think it is, and the unchanged test behaviour is good supporting
evidence.
The commit also changes `check_trailing_angle_brackets` to return
`Option<ErrorGuaranteed>`. This provides a stricter proof that it
emitted an error message than asserting `dcx.has_errors().is_some()`,
which would succeed if any error had previously been emitted anywhere.
It's not clear why this was here, because the created error is returned
as a normal error anyway.
Nor is it clear why removing the call works. The change doesn't affect
any tests; `tests/ui/parser/issues/issue-102182-impl-trait-recover.rs`
looks like the only test that could have been affected.
Instead of taking `seq` as a mutable reference,
`maybe_recover_struct_lit_bad_delims` now consumes `seq` on the recovery
path, and returns `seq` unchanged on the non-recovery path. The commit
also combines an `if` and a `match` to merge two identical paths.
Also change `recover_seq_parse_error` so it receives a `PErr` instead of
a `PResult`, because all the call sites now handle the `Ok`/`Err`
distinction themselves.
In this parsing recovery function, we only need to emit the previously
obtained error message and mark `expr` as erroneous in the case where we
actually recover.
This works for most of its call sites. This is nice, because `emit` very
much makes sense as a consuming operation -- indeed,
`DiagnosticBuilderState` exists to ensure no diagnostic is emitted
twice, but it uses runtime checks.
For the small number of call sites where a consuming emit doesn't work,
the commit adds `DiagnosticBuilder::emit_without_consuming`. (This will
be removed in subsequent commits.)
Likewise, `emit_unless` becomes consuming. And `delay_as_bug` becomes
consuming, while `delay_as_bug_without_consuming` is added (which will
also be removed in subsequent commits.)
All this requires significant changes to `DiagnosticBuilder`'s chaining
methods. Currently `DiagnosticBuilder` method chaining uses a
non-consuming `&mut self -> &mut Self` style, which allows chaining to
be used when the chain ends in `emit()`, like so:
```
struct_err(msg).span(span).emit();
```
But it doesn't work when producing a `DiagnosticBuilder` value,
requiring this:
```
let mut err = self.struct_err(msg);
err.span(span);
err
```
This style of chaining won't work with consuming `emit` though. For
that, we need to use to a `self -> Self` style. That also would allow
`DiagnosticBuilder` production to be chained, e.g.:
```
self.struct_err(msg).span(span)
```
However, removing the `&mut self -> &mut Self` style would require that
individual modifications of a `DiagnosticBuilder` go from this:
```
err.span(span);
```
to this:
```
err = err.span(span);
```
There are *many* such places. I have a high tolerance for tedious
refactorings, but even I gave up after a long time trying to convert
them all.
Instead, this commit has it both ways: the existing `&mut self -> Self`
chaining methods are kept, and new `self -> Self` chaining methods are
added, all of which have a `_mv` suffix (short for "move"). Changes to
the existing `forward!` macro lets this happen with very little
additional boilerplate code. I chose to add the suffix to the new
chaining methods rather than the existing ones, because the number of
changes required is much smaller that way.
This doubled chainging is a bit clumsy, but I think it is worthwhile
because it allows a *lot* of good things to subsequently happen. In this
commit, there are many `mut` qualifiers removed in places where
diagnostics are emitted without being modified. In subsequent commits:
- chaining can be used more, making the code more concise;
- more use of chaining also permits the removal of redundant diagnostic
APIs like `struct_err_with_code`, which can be replaced easily with
`struct_err` + `code_mv`;
- `emit_without_diagnostic` can be removed, which simplifies a lot of
machinery, removing the need for `DiagnosticBuilderState`.
macro_rules: Add an expansion-local cache to span marker
Most tokens in a macro body typically have the same syntax context.
So the cache should usually be hit.
This change can either be combined with https://github.com/rust-lang/rust/pull/119689, or serve as its alternative, depending on perf results.
Unions are not `PointerLike`
I introduced the `PointerLike` trait to enforce `dyn*` coercions only from types that share the same ABI as a pointer. On top of needing to be scalar, they also should not be unions, since CTFE chokes on scalar reads for union types.
Fixes#119695
Impl trait diagnostic tweaks
1. Tweak some names for `impl Trait` being used in the wrong position
2. Remove two helper functions that are no longer needed since RPITIT is stable, and which causes matches to be a bit obtuse.
3. Split and fix the part where the error notes that it's "only allowed in XX"
Fixes#119629
Exhaustiveness: remove `Matrix.wildcard_row`
To compute exhaustiveness, we check whether an extra row with a wildcard added at the end of the match expression would be reachable. We used to store an actual such row of patterns in the `Matrix`, but it's a bit redundant since we know it only contains wildcards. It was kept because we used it to get the type of each column (and relevancy). With this PR, we keep track of the types (and relevancy) directly.
This is part of me splitting up https://github.com/rust-lang/rust/pull/119581 for ease of review.
r? `@compiler-errors`
Populate `yield` and `resume` types in MIR body while body is being initialized
I found it weird that we went back and populated these types *after* the body was constructed. Let's just do it all at once.
Stop allowing `rustc::potential_query_instability` on all of
rustc_mir_transform and instead allow it on a case-by-case basis if it
is safe to do so. In this particular crate, all instances were safe to
allow.
rustc_span: More consistent span combination operations
Also add more tests for using `tt` in addition to `ident`, and some other minor tweaks, see individual commits.
This is a part of https://github.com/rust-lang/rust/pull/119412 that doesn't yet add side tables for metavariable spans.
rustc_mir_transform: Make DestinationPropagation stable for queries
By using `FxIndexMap` instead of `FxHashMap`, so that the order of visiting of locals is deterministic.
We also need to bless
`copy_propagation_arg.foo.DestinationPropagation.panic*.diff`. Do not review the diff of the diff. Instead look at the diff files before and after this commit. Both before and after this commit, 3 statements are replaced with nop. It's just that due to change in ordering, different statements are replaced. But the net result is the same. In other words, compare this diff (before fix):
* 090d5eac72/tests/mir-opt/dest-prop/copy_propagation_arg.foo.DestinationPropagation.panic-unwind.diff
With this diff (after fix):
* f603babd63/tests/mir-opt/dest-prop/copy_propagation_arg.foo.DestinationPropagation.panic-unwind.diff
and you can see that both before and after the fix, we replace 3 statements with `nop`s.
I find it _slightly_ surprising that the test this PR affects did not previously fail spuriously due to the indeterminism of `FxHashMap`, but I guess in can be explained with the predictability of small `FxHashMap`s with `usize` (`Local`) keys, or something along those lines.
This should fix [this](https://github.com/rust-lang/rust/pull/119252#discussion_r1436101791) comment, but I wanted to make a separate PR for this fix for a simpler development and review process.
Part of https://github.com/rust-lang/rust/issues/84447 which is E-help-wanted.
r? `@cjgillot` who is reviewer for the highly related PR https://github.com/rust-lang/rust/pull/119252.
rustc_span: Optimize syntax context comparisons
Including comparisons with root context.
- `eq_ctxt` doesn't require retrieving full `SpanData`, or taking the span interner lock twice.
- Checking `SyntaxContext` for "rootness" is cheaper than extracting a full outer `ExpnData` for it and checking *it* for rootness.
The internal lint for `eq_ctxt` is also tweaked to detect `a.ctxt() != b.ctxt()` in addition to `a.ctxt() == b.ctxt()`.
Avoid specialization in the metadata serialization code
With the exception of a perf-only specialization for byte slices and byte vectors.
This uses the same trick of introducing a new trait and having the Encodable and Decodable derives add a bound to it as used for TyEncoder/TyDecoder. The new code is clearer about which encoder/decoder uses which impl and it reduces the dependency of rustc on specialization, making it easier to remove support for specialization entirely or turn it into a construct that is only allowed for perf optimizations if we decide to do this.
Rollup of 9 pull requests
Successful merges:
- #119208 (coverage: Hoist some complex code out of the main span refinement loop)
- #119216 (Use diagnostic namespace in stdlib)
- #119414 (bootstrap: Move -Clto= setting from Rustc::run to rustc_cargo)
- #119420 (Handle ForeignItem as TAIT scope.)
- #119468 (rustdoc-search: tighter encoding for f index)
- #119628 (remove duplicate test)
- #119638 (fix cyle error when suggesting to use associated function instead of constructor)
- #119640 (library: Fix warnings in rtstartup)
- #119642 (library: Fix a symlink test failing on Windows)
r? `@ghost`
`@rustbot` modify labels: rollup
fix cyle error when suggesting to use associated function instead of constructor
Fixes https://github.com/rust-lang/rust/issues/119625.
The first commit fixes the infinite recursion and makes the cycle error actually show up. We do this by making the `Display` for `ty::Instance` impl respect `with_no_queries` so that it can be used in query descriptions.
The second commit fixes the cycle error `resolver_for_lowering` -> `normalize` -> `resolve_instance` (for evaluating const) -> `lang_items` (for `drop_in_place`) -> `resolver_for_lowering` (for collecting lang items). We do this by simply skipping the suggestion when encountering an unnormalized type.
Use diagnostic namespace in stdlib
This required a minor fix to have the diagnostics shown in third party crates when the `diagnostic_namespace` feature is not enabled. See 5d63f5d8d1 for details. I've opted for having a single PR for both changes as it's really not that much code. If it is required it should be easy to split up the change into several PR's.
r? `@compiler-errors`