`impl Default for EarlyDiagCtxt`
for small rustc_driver programs, most of their imports will currently be related to diagnostics. this change simplifies their code so it's more clear what in the driver is modified from the default.
this is especially important for external drivers which are out of tree and not updated in response to breaking changes. for these drivers, each import is a liability for future code, since it can be broken when refactors happen.
here is an example driver which is simplified by these changes:
```diff
diff --git a/src/main.rs b/src/main.rs
index f81aa3e..11e5f18 100644
--- a/src/main.rs
+++ b/src/main.rs
`@@` -1,16 +1,8 `@@`
#![feature(rustc_private)]
extern crate rustc_driver;
extern crate rustc_interface;
-extern crate rustc_errors;
-extern crate rustc_session;
use rustc_driver::Callbacks;
-use rustc_errors::{emitter::HumanReadableErrorType, ColorConfig};
use rustc_interface::interface;
-use rustc_session::config::ErrorOutputType;
-use rustc_session::EarlyDiagCtxt;
struct DisableSafetyChecks;
`@@` -26,11 +18,7 `@@` fn main() {
"https://github.com/jyn514/jyn514.github.io/issues/new",
|_| (),
);
- let handler = EarlyDiagCtxt::new(ErrorOutputType::HumanReadable(
- HumanReadableErrorType::Default,
- ColorConfig::Auto,
- ));
- rustc_driver::init_rustc_env_logger(&handler);
+ rustc_driver::init_rustc_env_logger(&Default::default());
std::process::exit(rustc_driver::catch_with_exit_code(move || {
let args: Vec<String> = std::env::args().collect();
rustc_driver::RunCompiler::new(&args, &mut DisableSafetyChecks).run()
```
remove `Ty::is_copy_modulo_regions`
Using these functions is likely incorrect if an `InferCtxt` is available, I moved this function to `TyCtxt` (and added it to `LateContext`) and added a note to the documentation that one should prefer `Infer::type_is_copy_modulo_regions` instead.
I didn't yet move `is_sized` and `is_freeze`, though I think we should move these as well.
r? `@compiler-errors` cc #132279
Eliminate magic numbers from expression precedence
Context: see https://github.com/rust-lang/rust/pull/133140.
This PR continues on backporting Syn's expression precedence design into rustc. Rustc's design used mysterious integer quantities represented variously as `i8` or `usize` (e.g. `PREC_CLOSURE = -40i8`), a special significance around `0` that is never named, and an extra `PREC_FORCE_PAREN` precedence level that does not correspond to any expression. Syn's design uses a C-like enum with variants that clearly correspond to specific sets of expression kinds.
This PR is a refactoring that has no intended behavior change on its own, but it unblocks other precedence work that rustc's precedence design was poorly suited to accommodate.
- Asymmetrical precedence, so that a pretty-printer can tell `(return 1) + 1` needs parens but `1 + return 1` does not.
- Squashing the `Closure` and `Jump` cases into a single precedence level.
- Numerous remaining false positives and false negatives in rustc pretty-printer's parenthesization of macro metavariables, for example in `$e < rhs` where $e is `lhs as Thing<T>`.
FYI `@fmease` — you don't need to review if rustbot picks someone else, but you mentioned being interested in the followup PRs.
check local cache even if global is usable
we store overflow errors locally, even if we can otherwise use the global cache for this goal. should fix#133616, didn't test it locally yet as diesel tends to hit an unrelated debug assertion in rustdoc.
r? types
for small rustc_driver programs, most of their imports will currently be related to diagnostics. this change simplifiers their code so it's more clear what in the driver is modified from the default.
this is especially important for external drivers which are out of tree and not updated in response to breaking changes. for these drivers, each import is a liability for future code, since it can be broken when refactors happen.
here is an example driver which is simplified by these changes:
```
diff --git a/src/main.rs b/src/main.rs
index f81aa3e..11e5f18 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,16 +1,8 @@
#![feature(rustc_private)]
extern crate rustc_driver;
extern crate rustc_interface;
-extern crate rustc_errors;
-extern crate rustc_session;
use rustc_driver::Callbacks;
-use rustc_errors::{emitter::HumanReadableErrorType, ColorConfig};
use rustc_interface::interface;
-use rustc_session::config::ErrorOutputType;
-use rustc_session::EarlyDiagCtxt;
struct DisableSafetyChecks;
@@ -26,11 +18,7 @@ fn main() {
"https://github.com/jyn514/jyn514.github.io/issues/new",
|_| (),
);
- let handler = EarlyDiagCtxt::new(ErrorOutputType::HumanReadable(
- HumanReadableErrorType::Default,
- ColorConfig::Auto,
- ));
- rustc_driver::init_rustc_env_logger(&handler);
+ rustc_driver::init_rustc_env_logger(&Default::default());
std::process::exit(rustc_driver::catch_with_exit_code(move || {
let args: Vec<String> = std::env::args().collect();
rustc_driver::RunCompiler::new(&args, &mut DisableSafetyChecks).run()
```
Remove `hir::ArrayLen`
This refactoring removes `hir::ArrayLen`, replacing it with `hir::ConstArg`. To represent inferred array lengths (previously `hir::ArrayLen::Infer`), a new variant `ConstArgKind::Infer` is added.
r? `@BoxyUwU`
coverage: Use a query to identify which counter/expression IDs are used
Given that we already have a query to identify the highest-numbered counter ID in a MIR body, we can extend that query to also build bitsets of used counter/expression IDs. That lets us avoid some messy coverage bookkeeping during the main MIR traversal for codegen.
This does mean that we fail to treat some IDs as used in certain MIR-inlining scenarios, but I think that's fine, because it means that the results will be consistent across all instantiations of a function.
---
There's some more cleanup I want to do in the function coverage collector, since it isn't really collecting anything any more, but I'll leave that for future work.
Only error raw lifetime followed by `\'` in edition 2021+
Fixes#133479
cc #132341
I think this fixes a purely theoretical regression since it only affects edition 2015 (who is using that?) and only in the very rare case of a raw lifetime followed immediately by a lifetime like `'r#a'r`.
Make `adjust_fulfillment_errors` work with `HostEffectPredicate` and `const_conditions`
Greatly improves the spans for reporting unsatisfied `~const` bounds :)
r? project-const-traits or maybe ``@lcnr`` (if you want to deal with a diagnostics PR lmao)
Properly pass linker arguments that contain commas
When linking with the system C compiler, we sometimes want to forward certain arguments unchanged to the linker. This can be done with `-Wl,arg1,arg2` or `-Xlinker arg1 -Xlinker arg2`. `-Wl` is used when possible, since it is more compact, but it does not support commas in the argument itself - in those cases, we need to use `-Xlinker`, and that is what this PR implements.
This also fixes using sanitizers on macOS with `-Clinker-flavor=ld`, as those were previously manually using `-Wl`/`-Xlinker` (probably since the support wasn't present in the `link_args` function).
Note that there has been [a previous PR for this](https://github.com/rust-lang/rust/pull/38798), but it only implemented this in certain cases when passing `-rpath`.
r? compiler
Rollup of 8 pull requests
Successful merges:
- #128184 (std: refactor `pthread`-based synchronization)
- #132047 (Robustify and genericize return-type-notation resolution in `resolve_bound_vars`)
- #133515 (fix: hurd build, stat64.st_fsid was renamed to st_dev)
- #133602 (fix: fix codeblocks in `PathBuf` example)
- #133622 (update link to "C++ Exceptions under the hood" blog)
- #133660 (Do not create trait object type if missing associated types)
- #133686 (Add diagnostic item for `std::ops::ControlFlow`)
- #133689 (Fixed typos by changing `happend` to `happened`)
r? `@ghost`
`@rustbot` modify labels: rollup
Add diagnostic item for `std::ops::ControlFlow`
This will be used in Clippy to detect useless conversions done through `ControlFlow::map_break()` and `ControlFlow::map_continue()`.
Robustify and genericize return-type-notation resolution in `resolve_bound_vars`
#129629 implemented return-type-notation (RTN) in its path form, like `where T::method(..): Bound`. As part of lowering, we must record the late-bound vars for the where clause introduced by the method (namely, its early- and late-bound lifetime arguments, since `where T::method(..)` turns into a higher-ranked where clause over all of the lifetimes according to [RFC 3654](https://rust-lang.github.io/rfcs/3654-return-type-notation.html#converting-to-higher-ranked-trait-bounds)).
However, this logic was only looking at the where clauses of the parent item that the `T::method(..)` bound was written on, and not any parent items. This PR generalizes that logic to look at the parent item (i.e. the outer impl or trait) instead and fixes a (debug only) assertion as an effect.
This logic is also more general and likely easier to adapt to more interesting (though likely very far off) cases like non-lifetime binder `for<T: Trait> T::method(..): Send` bounds.
Tracking:
- https://github.com/rust-lang/rust/issues/109417
Respect verify-llvm-ir option in the backend
We are currently unconditionally verifying the LLVM IR in the backend (twice), ignoring the value of the verify-llvm-ir option. This has substantial compile-time impact for debug builds.
Make `compare_impl_item` into a query
Turns `compare_impl_item` into a query (generalizing the existing query for `compare_impl_const`), and uses that in `Instance::resolve` to fail resolution when an implementation is incompatible with the trait it comes from.
Fixes#119701Fixes#121127Fixes#121411Fixes#129075Fixes#129127Fixes#129214Fixes#131294
Eliminate print_expr_maybe_paren function from pretty printers
This PR is part of backporting Syn's expression precedence design into rustc. (See #133603 for other work on this.)
In Syn, our version of `print_expr_cond_paren` is called `print_subexpression` and it is called from 19 places. Of those calls, 12 of them need a "custom" behavior for the `needs_paren` argument, whereas only 7 use a "standard" behavior resembling `print_subexpression($e, $e.precedence() < Precedence::$Variant, ...)`. In other words the behavior that rustc_ast_pretty's `print_expr_maybe_paren` implements is actually not what you want most of the time. The current usage you see in rustc is overuse.
<details>
<summary>Aside: am I confident about the correctness of Syn's parenthesization? Yes. Click for details.</summary>
---
The behavior is constrained by the following pair of tests which both run over every Rust source file of rustc and the standard library and tools and test suites:
- To rule out **false positives**: for every expression in every source file, print the expression, parse it back, and verify that not a single new parenthesis got added. Since these are expressions parsed from source code, not macro-generated syntax trees, we know they must never need automatic parenthesis insertion. Rustc's pretty printer does not pass this.
Pseudocode: `assert(expr == parse(print(expr)))`
- To rule out **false negatives**: for every expression in every source file, replace every Expr::Paren node in the syntax tree with just its contents, i.e. stripping the parentheses but otherwise preserving the syntax tree structure. Then print the stripped expression performing parenthesis insertion wherever needed, and reparse it. Verify that the reparsed expression has identical structure to the original, despite there being no parentheses in the original prior to printing, i.e. all the right parentheses got re-inserted by the printer to preserve the expression's structure. Rustc's pretty printer does not pass this. See https://github.com/dtolnay/syn/pull/1788 which reveals multiple rustc_ast_pretty bugs.
Pseudocode: `assert(unparenthesize(expr) == unparenthesize(parse(print(unparenthesize(expr)))))`
---
</details>
If `print_expr_maybe_paren` is usually not correct, is there harm in keeping it for the minority of cases where it is correct? I think the answer is yes and Syn doesn't use any equivalent of this helper function. The problems with it are:
- Having both `print_expr_maybe_paren` and `print_expr_cond_paren` applies counterproductive inertia against moving from the first to the second. When looking at a call site like `print_expr_maybe_paren(e, Precedence::$Variant, ...)` with parentheses not being inserted where they should be, anyone's first inclination would be to solve the bug by tweaking $Variant because that is the only knob that visibly appears in the function call. For example to pass "prec + 1", like tweaking the code to conditionally pass `Precedence::Prefix` instead of `Precedence::Cast`.
Experience in Syn shows this is (almost?) never what you want the person to do. In a call `print_expr_cond_paren(e, e.precedence() < ExprPrecedence::$Variant, ...)` almost always the best fix involves one of:
- Changing `e.precedence()`, e.g. to `fixup.leading_precedence(e)` and `fixup.trailing_precedence(e)` in cases of asymmetrical precedence (`(return 1) + 1` vs `1 + return 1`).
- Changing `<` to `<=`, to handle associativity and other grammar restrictions like chained comparisons (which rustc gets wrong today).
- Adding `||` and/or `&&` clauses to the condition.
By using these 3 better knobs instead of $Variant, it upholds the property that any time we talk about precedence, it is always the precedence of some actual expression that our code is actively manipulating, instead of a value standing in for some imaginary precedence level that would exist between two consecutive [real levels](https://doc.rust-lang.org/1.83.0/reference/expressions.html#expression-precedence). For example consider that "`Cast` + 1" might be `Prefix` today, but only until some new Rust syntax ends up adding a level between those.
- The `print_expr_maybe_paren` call sites look shorter, but they are not clearer. For myself, a function argument that says "does this subexpression need parenthesization" is a concrete thing that is easy to think about, while a function argument that is "what is the effective precedence level associated with this subexpression's placement inside its parent expression" is abstract and tricky to even state a precise meaning for. I expect that for someone less familiar with the pretty printer working on adding a new expression kind (like postfix match, recently), having every subexpression consistently printed using `print_expr_cond_paren` will be more beneficial, for the same reason, than having `print_expr_maybe_paren` available.
r? ``@lcnr``
Mark visionOS as supporting `std`
Cargo's -Zbuild-std has recently started checking this field, which causes it to fail to compile even though we have full support for the standard library on these targets.
[Example of failed build](https://github.com/rust-random/getrandom/actions/runs/12069033154/job/33655430622).
Affected targets: `aarch64-apple-visionos` and `aarch64-apple-visionos-sim`.
r? Noratrieb (because you've worked with `rustc` target metadata IIRC)
``@rustbot`` label O-visionos
use stores of the correct size to set discriminants
Resolves an old HACK /FIXME.
Note that I haven't worked much with codegen so I'm not sure if I'm using the functions correctly and I was surprised seeing out-of-range values being fed into `const_uint_big` but apparently they're wrapped implicitly? By making it explicit we can pass in-range values instead.
Support input/output in vector registers of PowerPC inline assembly
This extends currently clobber-only vector registers (`vreg`) support to allow passing `#[repr(simd)]` types as input/output.
| Architecture | Register class | Target feature | Allowed types |
| ------------ | -------------- | -------------- | -------------- |
| PowerPC | `vreg` | `altivec` | `i8x16`, `i16x8`, `i32x4`, `f32x4` |
| PowerPC | `vreg` | `vsx` | `f32`, `f64`, `i64x2`, `f64x2` |
In addition to floats and `core::simd` types listed above, `core::arch` types and custom `#[repr(simd)]` types of the same size and type are also allowed. All allowed types and relevant target features are currently unstable.
r? `@Amanieu`
`@rustbot` label +O-PowerPC +A-inline-assembly