`collect_tokens_trailing_token` cleanups
More cleanups I made while understanding the code for processing `cfg_attr`, to fix test failures in #124141.
r? `@petrochenkov`
Tweak suggestions when using incorrect type of enum literal
More accurate suggestions when writing wrong style of enum variant literal:
```
error[E0533]: expected value, found struct variant `E::Empty3`
--> $DIR/empty-struct-braces-expr.rs:18:14
|
LL | let e3 = E::Empty3;
| ^^^^^^^^^ not a value
|
help: you might have meant to create a new value of the struct
|
LL | let e3 = E::Empty3 {};
| ++
```
```
error[E0533]: expected value, found struct variant `E::V`
--> $DIR/struct-literal-variant-in-if.rs:10:13
|
LL | if x == E::V { field } {}
| ^^^^ not a value
|
help: you might have meant to create a new value of the struct
|
LL | if x == (E::V { field }) {}
| + +
```
```
error[E0618]: expected function, found enum variant `Enum::Unit`
--> $DIR/suggestion-highlights.rs:15:5
|
LL | Unit,
| ---- enum variant `Enum::Unit` defined here
...
LL | Enum::Unit();
| ^^^^^^^^^^--
| |
| call expression requires function
|
help: `Enum::Unit` is a unit enum variant, and does not take parentheses to be constructed
|
LL - Enum::Unit();
LL + Enum::Unit;
|
```
```
error[E0599]: no variant or associated item named `tuple` found for enum `Enum` in the current scope
--> $DIR/suggestion-highlights.rs:36:11
|
LL | enum Enum {
| --------- variant or associated item `tuple` not found for this enum
...
LL | Enum::tuple;
| ^^^^^ variant or associated item not found in `Enum`
|
help: there is a variant with a similar name
|
LL | Enum::Tuple(/* i32 */);
| ~~~~~~~~~~~~~~~~;
|
```
Tweak "field not found" suggestion when giving struct literal for tuple struct type:
```
error[E0560]: struct `S` has no field named `x`
--> $DIR/nested-non-tuple-tuple-struct.rs:8:19
|
LL | pub struct S(f32, f32);
| - `S` defined here
...
LL | let _x = (S { x: 1.0, y: 2.0 }, S { x: 3.0, y: 4.0 });
| ^ field does not exist
|
help: `S` is a tuple struct, use the appropriate syntax
|
LL | let _x = (S(/* f32 */, /* f32 */), S { x: 3.0, y: 4.0 });
| ~~~~~~~~~~~~~~~~~~~~~~~
Handle .init_array link_section specially on wasm
Given that wasm-ld now has support for [.init_array](8f2bd8ae68/llvm/lib/MC/WasmObjectWriter.cpp (L1852)), it appears we can easily implement that section by falling through to the normal path rather than taking the typical custom_section path for wasm.
The wasm-ld appears to have a bunch of limitations. Only one static with the `link_section` in a crate or else you hit the fatal error in the link above "only one .init_array section fragment supported". They do not get merged.
You can still call multiple constructors by setting it to an array.
```
unsafe extern "C" fn ctor() {
println!("foo");
}
#[used]
#[link_section = ".init_array"]
static FOO: [unsafe extern "C" fn(); 2] = [ctor, ctor];
```
Another issue appears to be that if crate *A* depends on crate *B*, but *A* doesn't call any symbols from *B* and *B* doesn't `#[export_name = ...]` any symbols, then crate *B*'s constructor will not be called. The workaround to this is to provide an exported symbol in crate *B*.
Adding details, clarifying lots of little things, etc. In particular,
the commit adds details of an example. I find this very helpful, because
it's taken me a long time to understand how this code works.
Currently in `collect_tokens_trailing_token`, `start_pos` and `end_pos`
are 1-indexed by `replace_ranges` is 0-indexed, which is really
confusing. Making them both 0-indexed makes debugging much easier.
The `Option`s within the `ReplaceRange`s within the hashmap are always
`None`. This PR omits them and inserts them when they are extracted from
the hashmap.
Rollup of 8 pull requests
Successful merges:
- #127418 (Wrap too long type name)
- #127594 (Fuchsia status code match arm)
- #127835 (Fix ICE in suggestion caused by `⩵` being recovered as `==`)
- #127858 (match lowering: Rename `MatchPair` to `MatchPairTree`)
- #127871 (Mention that type parameters are used recursively on bivariance error)
- #127913 (remove `debug-logging` default from tools profile)
- #127925 (Remove tag field from `Relation`s)
- #127929 (Use more accurate span for `addr_of!` suggestion)
r? `@ghost`
`@rustbot` modify labels: rollup
There are three places where we currently check `force_collect` and call
`collect_tokens_no_attrs` for `ForceCollect::Yes` and a vanilla parsing
function for `ForceCollect::No`.
But we can instead just pass in `force_collect` and let
`collect_tokens_trailing_token` do the appropriate thing.
This is technically "not necessary", as we will "just" segfault instead
if we e.g. arrive inside the handler fn with the null altstack. However,
it seems incorrect to go about this hoping that segfaulting is okay,
seeing as how our purpose here is to mitigate stack overflow problems.
Make sure NEED_ALTSTACK syncs with PAGE_SIZE when we do.
Co-authored-by: Jonas Böttiger <jonasboettiger@icloud.com>
Use more accurate span for `addr_of!` suggestion
Use a multipart suggestion instead of a single whole-span replacement:
```
error[E0796]: creating a shared reference to a mutable static
--> $DIR/reference-to-mut-static-unsafe-fn.rs:10:18
|
LL | let _y = &X;
| ^^ shared reference to mutable static
|
= note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
help: use `addr_of!` instead to create a raw pointer
|
LL | let _y = addr_of!(X);
| ~~~~~~~~~ +
```
Remove tag field from `Relation`s
Can just use the relation name w/ `std::any::type_name`. Also changes some printing to use instrument. Also changes some instrument levels to `trace` since I expect relations are somewhat hot, so having them print on debug is probably noisy.
r? lcnr
remove `debug-logging` default from tools profile
`debug-logging` conflicts with `download-rustc` option, and doesn't really make sense to enable it for a profile that is used for tool development.
Mention that type parameters are used recursively on bivariance error
Right now when a type parameter is used recursively, even with indirection (so it has a finite size) we say that the type parameter is unused:
```
struct B<T>(Box<B<T>>);
```
This is confusing, because the type parameter is *used*, it just doesn't have its variance constrained. This PR tweaks that message to mention that it must be used *non-recursively*.
Not sure if we should actually mention "variance" here, but also I'd somewhat prefer we don't keep the power users in the dark w.r.t the real underlying issue, which is that the variance isn't constrained. That technical detail is reserved for a note, though.
cc `@fee1-dead`
Fixes#118976Fixes#26283Fixes#53191Fixes#105740Fixes#110466
match lowering: Rename `MatchPair` to `MatchPairTree`
In #120904, `MatchPair` became able to store other match pairs as children, forming a tree. That has made the old name confusing, so this patch renames the type to `MatchPairTree`.
This PR also includes a patch renaming the `test` method to `pick_test_for_match_pair`, since it would conflict with the main change.
r? `@Nadrieril`
Fix ICE in suggestion caused by `⩵` being recovered as `==`
The second suggestion shown here would previously incorrectly assume that the span corresponding to `⩵` was 2 bytes wide composed by 2 1 byte wide chars, so a span pointing at `==` could point only at one of the `=` to remove it. Instead, we now replace the whole thing (as we should have the whole time):
```
error: unknown start of token: \u{2a75}
--> $DIR/unicode-double-equals-recovery.rs:1:16
|
LL | const A: usize ⩵ 2;
| ^
|
help: Unicode character '⩵' (Two Consecutive Equals Signs) looks like '==' (Double Equals Sign), but it is not
|
LL | const A: usize == 2;
| ~~
error: unexpected `==`
--> $DIR/unicode-double-equals-recovery.rs:1:16
|
LL | const A: usize ⩵ 2;
| ^
|
help: try using `=` instead
|
LL | const A: usize = 2;
| ~
```
Fix#127823.
Fuchsia status code match arm
Adds a match arm for the Fuchsia status code upon a process abort. An additional change moves the Windows status code down into the match arm itself instead of being defined as a constant elsewhere.
r? tmandry
The link pointed to a closed issue. Create a new one and point the link
to it.
Also add a help message to hint what change the user could make.
Fixes: https://github.com/rust-lang/rust/issues/127821
In <https://github.com/rust-lang/rust/pull/126922>, the
`binary_asm_labels` lint was added which flags labels such as `0:` and
`1:`. Before that change, LLVM was giving a confusing error on
x86/x86_64 because of an incorrect interpretation.
However, targets other than x86 and x86_64 never had the error message
and have not been a problem. This means that the lint was causing code
that previously worked to start failing (e.g. `compiler_builtins`),
rather than only providing a more clear messages where there has always
been an error.
Adjust the lint to only fire on x86 and x86_64 assembly to avoid this
regression.
Use a multipart suggestion instead of a single whole-span replacement:
```
error[E0796]: creating a shared reference to a mutable static
--> $DIR/reference-to-mut-static-unsafe-fn.rs:10:18
|
LL | let _y = &X;
| ^^ shared reference to mutable static
|
= note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
help: use `addr_of!` instead to create a raw pointer
|
LL | let _y = addr_of!(X);
| ~~~~~~~~~ +
```
```
error[E0560]: struct `S` has no field named `x`
--> $DIR/nested-non-tuple-tuple-struct.rs:8:19
|
LL | pub struct S(f32, f32);
| - `S` defined here
...
LL | let _x = (S { x: 1.0, y: 2.0 }, S { x: 3.0, y: 4.0 });
| ^ field does not exist
|
help: `S` is a tuple struct, use the appropriate syntax
|
LL | let _x = (S(/* f32 */, /* f32 */), S { x: 3.0, y: 4.0 });
| ~~~~~~~~~~~~~~~~~~~~~~~
```
```
error[E0533]: expected value, found struct variant `E::Empty3`
--> $DIR/empty-struct-braces-expr.rs:18:14
|
LL | let e3 = E::Empty3;
| ^^^^^^^^^ not a value
|
help: you might have meant to create a new value of the struct
|
LL | let e3 = E::Empty3 {};
| ++
```
```
error[E0533]: expected value, found struct variant `E::V`
--> $DIR/struct-literal-variant-in-if.rs:10:13
|
LL | if x == E::V { field } {}
| ^^^^ not a value
|
help: you might have meant to create a new value of the struct
|
LL | if x == (E::V { field }) {}
| + +
```
```
error[E0618]: expected function, found enum variant `Enum::Unit`
--> $DIR/suggestion-highlights.rs:15:5
|
LL | Unit,
| ---- enum variant `Enum::Unit` defined here
...
LL | Enum::Unit();
| ^^^^^^^^^^--
| |
| call expression requires function
|
help: `Enum::Unit` is a unit enum variant, and does not take parentheses to be constructed
|
LL - Enum::Unit();
LL + Enum::Unit;
|
```
```
error[E0599]: no variant or associated item named `tuple` found for enum `Enum` in the current scope
--> $DIR/suggestion-highlights.rs:36:11
|
LL | enum Enum {
| --------- variant or associated item `tuple` not found for this enum
...
LL | Enum::tuple;
| ^^^^^ variant or associated item not found in `Enum`
|
help: there is a variant with a similar name
|
LL | Enum::Tuple(/* i32 */);
| ~~~~~~~~~~~~~~~~;
|
```