Better method call error messages
Rebase/continuation of #71827
~Based on #92360~
~Based on #93118~
There's a decent description in #71827 that I won't copy here (for now at least)
In addition to rebasing, I've tried to restore most of the original suggestions for invalid arguments. Unfortunately, this does make some of the errors a bit verbose. To fix this will require a bit of refactoring to some of the generalized error suggestion functions, and I just don't have the time to go into it right now.
I think this is in a state that the error messages are overall better than before without a reduction in the suggestions given.
~I've tried to split out some of the easier and self-contained changes into separate commits (mostly in #92360, but also one here). There might be more than can be done here, but again just lacking time.~
r? `@estebank` as the original reviewer of #71827
This attempts to bring better error messages to invalid method calls, by applying some heuristics to identify common mistakes.
The algorithm is inspired by Levenshtein distance and longest common sub-sequence. In essence, we treat the types of the function, and the types of the arguments you provided as two "words" and compute the edits to get from one to the other.
We then modify that algorithm to detect 4 cases:
- A function input is missing
- An extra argument was provided
- The type of an argument is straight up invalid
- Two arguments have been swapped
- A subset of the arguments have been shuffled
(We detect the last two as separate cases so that we can detect two swaps, instead of 4 parameters permuted.)
It helps to understand this argument by paying special attention to terminology: "inputs" refers to the inputs being *expected* by the function, and "arguments" refers to what has been provided at the call site.
The basic sketch of the algorithm is as follows:
- Construct a boolean grid, with a row for each argument, and a column for each input. The cell [i, j] is true if the i'th argument could satisfy the j'th input.
- If we find an argument that could satisfy no inputs, provided for an input that can't be satisfied by any other argument, we consider this an "invalid type".
- Extra arguments are those that can't satisfy any input, provided for an input that *could* be satisfied by another argument.
- Missing inputs are inputs that can't be satisfied by any argument, where the provided argument could satisfy another input
- Swapped / Permuted arguments are identified with a cycle detection algorithm.
As each issue is found, we remove the relevant inputs / arguments and check for more issues. If we find no issues, we match up any "valid" arguments, and start again.
Note that there's a lot of extra complexity:
- We try to stay efficient on the happy path, only computing the diagonal until we find a problem, and then filling in the rest of the matrix.
- Closure arguments are wrapped in a tuple and need to be unwrapped
- We need to resolve closure types after the rest, to allow the most specific type constraints
- We need to handle imported C functions that might be variadic in their inputs.
I tried to document a lot of this in comments in the code and keep the naming clear.
Implement sym operands for global_asm!
Tracking issue: #93333
This PR is pretty much a complete rewrite of `sym` operand support for inline assembly so that the same implementation can be shared by `asm!` and `global_asm!`. The main changes are:
- At the AST level, `sym` is represented as a special `InlineAsmSym` AST node containing a path instead of an `Expr`.
- At the HIR level, `sym` is split into `SymStatic` and `SymFn` depending on whether the path resolves to a static during AST lowering (defaults to `SynFn` if `get_early_res` fails).
- `SymFn` is just an `AnonConst`. It runs through typeck and we just collect the resulting type at the end. An error is emitted if the type is not a `FnDef`.
- `SymStatic` directly holds a path and the `DefId` of the `static` that it is pointing to.
- The representation at the MIR level is mostly unchanged. There is a minor change to THIR where `SymFn` is a constant instead of an expression.
- At the codegen level we need to apply the target's symbol mangling to the result of `tcx.symbol_name()` depending on the target. This is done by calling the LLVM name mangler, which handles all of the details.
- On Mach-O, all symbols have a leading underscore.
- On x86 Windows, different mangling is used for cdecl, stdcall, fastcall and vectorcall.
- No mangling is needed on other platforms.
r? `@nagisa`
cc `@eddyb`
Optimize RcInnerPtr::inc_strong()/inc_weak() instruction count
Inspired by this internals thread: https://internals.rust-lang.org/t/rc-optimization-on-64-bit-targets/16362
[The generated assembly is a bit smaller](https://rust.godbolt.org/z/TeTnf6144) and is a more efficient usage of the CPU's instruction cache. `unlikely` doesn't impact any of the small artificial tests I've done, but I've included it in case it might help more complex scenarios when this is inlined.
Rollup of 11 pull requests
Successful merges:
- #94457 (Stabilize `derive_default_enum`)
- #94461 (Create (unstable) 2024 edition)
- #94849 (Check var scope if it exist)
- #95194 (remove find_use_placement)
- #95749 (only downgrade selection Error -> Ambiguous if type error is in predicate)
- #96026 (couple of clippy::complexity fixes)
- #96027 (remove function parameters only used in recursion)
- #96034 ([test] Add test cases of untested functions for BTreeSet )
- #96040 (Use u32 instead of i32 for futexes.)
- #96062 (docs: Update tests chapter for Termination stabilization)
- #96065 (Refactor: Use `format-args-capture` and remove unnecessary nested blocks in rustc_typeck)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
docs: Update tests chapter for Termination stabilization
A small update for the docs of `#[test]` functions as a result of the `Termination` stabilization in #93840.
Use u32 instead of i32 for futexes.
This changes futexes from i32 to u32. The [Linux man page](https://man7.org/linux/man-pages/man2/futex.2.html) uses `uint32_t` for them, so I'm not sure why I used i32 for them. Maybe because I first used them for thread parkers, where I used -1, 0, and 1 as the states.
(Wasm's `memory.atomic.wait32` does use `i32`, because wasm doesn't support `u32`.)
It doesn't matter much, but using the unsigned type probably results in fewer surprises when shifting bits around or using comparison operators.
r? ```@Amanieu```
only downgrade selection Error -> Ambiguous if type error is in predicate
That is, we don't care if there's a TypeError type in the ParamEnv.
Fixes#95408
remove find_use_placement
A more robust solution to finding where to place use suggestions was added in #94584.
The algorithm uses the AST to find the span for the suggestion so we pass this span
down to the HIR during lowering and use it instead of calling `find_use_placement`
Fixes#94941
Check var scope if it exist
Fixes#92893.
Added helper function to check the scope of a variable, if it doesn't have a scope call delay_span_bug, which avoids us trying to get a block/scope that doesn't exist.
Had to increase `ROOT_ENTRY_LIMIT` was getting tidy error
Create (unstable) 2024 edition
[On Zulip](https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/Deprecating.20macro.20scoping.20shenanigans/near/272860652), there was a small aside regarding creating the 2024 edition now as opposed to later. There was a reasonable amount of support and no stated opposition.
This change creates the 2024 edition in the compiler and creates a prelude for the 2024 edition. There is no current difference between the 2021 and 2024 editions. Cargo and other tools will need to be updated separately, as it's not in the same repository. This change permits the vast majority of work towards the next edition to proceed _now_ instead of waiting until 2024.
For sanity purposes, I've merged the "hello" UI tests into a single file with multiple revisions. Otherwise we'd end up with a file per edition, despite them being essentially identical.
````@rustbot```` label +T-lang +S-waiting-on-review
Not sure on the relevant team, to be honest.
Stabilize `derive_default_enum`
This stabilizes `#![feature(derive_default_enum)]`, as proposed in [RFC 3107](https://github.com/rust-lang/rfcs/pull/3107) and tracked in #87517. In short, it permits you to `#[derive(Default)]` on `enum`s, indicating what the default should be by placing a `#[default]` attribute on the desired variant (which must be a unit variant in the interest of forward compatibility).
```````@rustbot``````` label +S-waiting-on-review +T-lang
Windows: Use a pipe relay for chaining pipes
Fixes#95759
This fixes the issue by chaining pipes synchronously and manually pumping messages between them. It's not ideal but it has the advantage of not costing anything if pipes are not chained ("don't pay for what you don't use") and it also avoids breaking existing code that rely on our end of the pipe being asynchronous (which includes rustc's own testing framework).
Libraries can avoid needing this by using their own pipes to chain commands.
Rustdoc doesn't require the build artifacts to generate the docs, and
especially in the case of rustc, it greatly increases the time needed to
run the build.
- Statically ensure that only the top_stage of a tool is documented
If another part of rustbuild tried to document a different stage, it
would run into errors because `check::Rustc` unconditionally uses the
top stage.
- Try building rustc instead of checking to avoid duplicate artifacts
Tries to workaround the following error:
```
error[E0464]: multiple matching crates for `rustc_ast`
--> src/librustdoc/lib.rs:40:1
|
40 | extern crate rustc_ast;
| ^^^^^^^^^^^^^^^^^^^^^^^
|
= note: candidates:
crate `rustc_ast`: /checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_ast-6d7c193782263d89.rlib
crate `rustc_ast`: /checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_ast-e5d09eda5beb759c.rmeta
```
when checking pointee metadata, canonicalize the `Sized` check
Use `infcx.predicate_must_hold_modulo_regions` with a `Sized` obligation instead of just calling `ty.is_sized`, because the latter does not canonicalize region and type vars (and in the test case I added in this PR, there's a region var in the `ParamEnv`).
Fixes#95311
Update cargo
11 commits in e2e2dddebe66dfc1403a312653557e332445308b..dba5baf4345858c591517b24801902a062c399f8
2022-04-05 17:04:53 +0000 to 2022-04-13 21:58:27 +0000
- Part 6 of RFC2906 - Switch the inheritance source from `workspace` to… (rust-lang/cargo#10564)
- Part 5 of RFC2906 - Add support for inheriting `rust-version` (rust-lang/cargo#10563)
- Add support for rustc --check-cfg well known names and values (rust-lang/cargo#10486)
- Reserve filename `Cargo.toml.orig` in `cargo package` (rust-lang/cargo#10551)
- Retry command invocation with argfile (rust-lang/cargo#10546)
- Add a progress indicator for `cargo clean` (rust-lang/cargo#10236)
- Ensure host units don't depend on Docscrape units, fixesrust-lang/cargo#10545 (rust-lang/cargo#10549)
- Fix docs: Bindeps env vars are passed to build script at runtime (rust-lang/cargo#10550)
- Part 4 of RFC2906 - Add support for inheriting `readme` (rust-lang/cargo#10548)
- Part 3 of RFC2906 - Add support for inheriting `license-path`, and `depednency.path` (rust-lang/cargo#10538)
- Bump to 0.63.0, update changelog (rust-lang/cargo#10544)
Remove `<mbe::TokenTree as Clone>`
`mbe::TokenTree` doesn't really need to implement `Clone`, and getting rid of that impl leads to some speed-ups.
r? `@petrochenkov`
errors: lazily load fallback fluent bundle
Addresses (hopefully) https://github.com/rust-lang/rust/pull/95667#issuecomment-1094794087.
Loading the fallback bundle in compilation sessions that won't go on to emit any errors unnecessarily degrades compile time performance, so lazily create the Fluent bundle when it is first required.
r? `@ghost` (just for perf initially)
Update stdarch
library/stdarch bcbe0106...d215afe9 (7):
- Add the rdm target feature to the sqrdmlsh intrinsic. (rust-lang/stdarch#1285)
- Remove use of `#[rustc_deprecated]`
- Remove feature gates for stabilized features
- Change remaining _undefined_ functions to zero-init
- Use SPDX license format and update packed_simd crate link (rust-lang/stdarch#1297)
- Fix broken links (rust-lang/stdarch#1294)
- Import the asm macro in std_detect (rust-lang/stdarch#1290)