Fix enzyme build errors
After [this PR](https://github.com/rust-lang/rust/pull/136428) was merged, I switched to master and attempted building `./x.py build --stage 1 library` with the config mentioned in the enzyme rustbook but it resulted in some errors tho the config.example.toml build succeeded
The errors were re:
### 1. Use of ref in match patterns
The errors were related to match ergonomics in Rust 2024, where ref is no longer needed when matching on references. Examples:
```
error: binding modifiers may only be written when the default binding mode is `move`
--> compiler/rustc_builtin_macros/src/autodiff.rs:136:31
|
136 | Annotatable::Item(ref iitem) => {
| ^^^ binding modifier not allowed under `ref` default binding mode
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> compiler/rustc_builtin_macros/src/autodiff.rs:136:13
|
136 | Annotatable::Item(ref iitem) => {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&_`
help: remove the unnecessary binding modifier
|
136 - Annotatable::Item(ref iitem) => {
136 + Annotatable::Item(iitem) => {
|
error: binding modifiers may only be written when the default binding mode is `move`
--> compiler/rustc_builtin_macros/src/autodiff.rs:146:36
|
146 | Annotatable::AssocItem(ref assoc_item, _) => {
| ^^^ binding modifier not allowed under `ref` default binding mode
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> compiler/rustc_builtin_macros/src/autodiff.rs:146:13
|
146 | Annotatable::AssocItem(ref assoc_item, _) => {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&_`
help: remove the unnecessary binding modifier
|
146 - Annotatable::AssocItem(ref assoc_item, _) => {
146 + Annotatable::AssocItem(assoc_item, _) => {
|
error: binding modifiers may only be written when the default binding mode is `move`
--> compiler/rustc_builtin_macros/src/autodiff.rs:174:31
|
174 | ... Annotatable::Item(ref iitem) => (iitem.vis.clone(), iitem.ide...
| ^^^ binding modifier not allowed under `ref` default binding mode
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> compiler/rustc_builtin_macros/src/autodiff.rs:174:13
|
174 | ... Annotatable::Item(ref iitem) => (iitem.vis.clone(), iitem.ident.c...
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&_`
help: remove the unnecessary binding modifier
|
174 - Annotatable::Item(ref iitem) => (iitem.vis.clone(), iitem.ident.clone()),
174 + Annotatable::Item(iitem) => (iitem.vis.clone(), iitem.ident.clone()),
|
error: binding modifiers may only be written when the default binding mode is `move`
--> compiler/rustc_builtin_macros/src/autodiff.rs:175:36
|
175 | Annotatable::AssocItem(ref assoc_item, _) => {
| ^^^ binding modifier not allowed under `ref` default binding mode
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> compiler/rustc_builtin_macros/src/autodiff.rs:175:13
|
175 | Annotatable::AssocItem(ref assoc_item, _) => {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&_`
help: remove the unnecessary binding modifier
|
175 - Annotatable::AssocItem(ref assoc_item, _) => {
175 + Annotatable::AssocItem(assoc_item, _) => {
|
error: could not compile `rustc_builtin_macros` (lib) due to 4 previous errors
warning: build failed, waiting for other jobs to finish...
Build completed unsuccessfully in 0:19:39
```
### 2. the use of external C blocks without unsafe in compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs (I don't have the error message handy)
The first commit fixes the errors above
---
## Additional Improvement:
`@ZuseZ4` suggested we consolidate the variants under `#[cfg(llvm_enzyme)]` and `#[cfg(not(llvm_enzyme))]` by conditionally checking for `cfg!(llvm_enzyme)` instead. This way, the autodiff code is compiled but not executed avoiding such regressions
r? `@ZuseZ4`
cc: `@oli-obk`
Clean up TypeckResults::extract_binding_mode
- Remove the `Option` from the result type, as `None` is never returned.
- Document the difference from the `BindingMode` in `PatKind::Binding`.
solver cycles are coinductive once they have one coinductive step
Implements the new cycle semantics in the new solver, dealing with the fallout from https://github.com/rust-lang/trait-system-refactor-initiative/issues/10.
The first commit has been extensively fuzzed via https://github.com/lcnr/search_graph_fuzz.
A trait solver cycle is now coinductive if it has at least one *coinductive step*. A step is only considered coinductive if it's a where-clause of an impl of a coinductive trait. The only coinductive traits are `Sized` and auto traits.
This differs from the current stable because where a cycle had to consist of exclusively coinductive goals. This is overly limiting and wasn't properly enforced as it (mostly) ignored all non-trait goals.
A more in-depth explanation of my reasoning can be found in this separate doc: https://gist.github.com/lcnr/c49d887bbd34f5d05c36d1cf7a1bf5a5. A summary:
- imagine using dictionary passing style: map where-bounds to additional "dictonary" fn arguments instead of monomorphization
- impls are the only source of truth and introduce a *constructor* of the dictionary type
- a trait goal holds if mapping its proof tree to dictionary passing style results in a valid corecursive function
- a corecursive function is valid if it is guarded: matching on it should result in a constructor in a finite amount of time. This property should recursively hold for all fields of the constructor
- a function is guarded if the recursive call is *behind* a constructor
- **and** this constructor is not *moved out of*, e.g. by accessing a field of the dictionary
- the "not moved out of" condition is difficult to guarantee in general, e.g. for item bounds of associated types. However, there is no way to *move out* of an auto trait as there is no information you can get from *the inside of* an auto trait bound in the trait system
- if we encounter a cycle/recursive call which involves an auto trait, we can always convert the proof tree into a non-recursive function which calls a corecursive function whose first step is the construction of the auto trait dict and which only recursively depends on itself (by inlining the original function until they reach the uses of the auto trait)
**we can therefore make any cycle during which we step into an auto trait (or `Sized`) impl coinductive**
----
To fix https://github.com/rust-lang/trait-system-refactor-initiative/issues/10 we could go with a more restrictive version which tries to restrict cycles to only allow code already supported on stable, potentially forcing cycles to be ambiguous if they step through an impl-where clause of a non-coinductive trait.
`PathKind` should be a strictly ordered set to allow merging paths without worry. We could therefore add another variant `PathKind::ForceUnknown` which is greater than `PathKind::Coinductive`. We already have to add such a third `PathKind` in #137314 anyways.
I am not doing this here due to multiple reasons:
- I cannot think of a principled reason why cycles using an impl to normalize differ in any way from simply using that impl to prove a trait bound. It feels unnecessary and like it makes it more difficult to reason about our cycle semantics :<
- This PR does not affect stable as coherence doesn't care about whether a goal holds or is ambiguous. So we don't yet have to make a final decision
r? `@compiler-errors` `@nikomatsakis`
fix: overflowing bin hex
**Overview:**
- This PR fixes#135404.
**Testing**
- Tested the updated functionality.
- previously emitted diagnostics:
```bash
error: literal out of range for `i32`
--> src/main.rs:2:9
|
2 | _ = 0x8FFF_FFFF_FFFF_FFFE;
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: the literal `0x8FFF_FFFF_FFFF_FFFE` (decimal `10376293541461622782`) does not fit into the type `i32` and will become `-2i32`
= help: consider using the type `i128` instead
= note: `#[deny(overflowing_literals)]` on by default
help: to use as a negative number (decimal `-2`), consider using the type `u32` for the literal and cast it to `i32`
|
2 | _ = 0x8FFF_FFFF_FFFF_FFFEu32 as i32;
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
```
- current diagnostics:
```bash
error: literal out of range for `i32`
--> ../temp.rs:2:13
|
2 | let x = 0x8FFF_FFFF_FFFF_FFFE;
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: the literal `0x8FFF_FFFF_FFFF_FFFE` (decimal `10376293541461622782`) does not fit into the type `i32` and will become `-2i32`
= help: consider using the type `u64` instead
= note: `#[deny(overflowing_literals)]` on by default
help: to use as a negative number (decimal `-2`), consider using the type `u64` for the literal and cast it to `i32`
|
2 | let x = 0x8FFF_FFFF_FFFF_FFFEu64 as i32;
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
```
A cycle was previously coinductive if all steps were coinductive.
Change this to instead considerm cycles to be coinductive if they
step through at least one where-bound of an impl of a coinductive
trait goal.
Rollup of 8 pull requests
Successful merges:
- #136542 ([`compiletest`-related cleanups 4/7] Make the distinction between root build directory vs test suite specific build directory in compiletest less confusing)
- #136579 (Fix UB in ThinVec::flat_map_in_place)
- #136688 (require trait impls to have matching const stabilities as the traits)
- #136846 (Make `AssocOp` more like `ExprKind`)
- #137304 (add `IntoBounds::intersect` and `RangeBounds::is_empty`)
- #137455 (Reuse machinery from `tail_expr_drop_order` for `if_let_rescope`)
- #137480 (Return unexpected termination error instead of panicing in `Thread::join`)
- #137694 (Spruce up `AttributeKind` docs)
r? `@ghost`
`@rustbot` modify labels: rollup
Don't infer attributes of virtual calls based on the function body
Fixes (after backport) #137646.
Since we don't know the exact implementation of the virtual call, it might write to parameters, we can't infer the readonly attribute.
Note: there was an existing code path involving `Interpolated` in
`MetaItem::from_tokens` that was dead. This commit transfers that to the
new form, but puts an `unreachable!` call inside it.
The one notable test change is `tests/ui/macros/trace_faulty_macros.rs`.
This commit removes the complicated `Interpolated` handling in
`expected_expression_found` that results in a longer error message. But
I think the new, shorter message is actually an improvement.
The original complaint was in #71039, when the error message started
with "error: expected expression, found `1 + 1`". That was confusing
because `1 + 1` is an expression. Other than that, the reporter said
"the whole error message is not too bad if you ignore the first line".
Subsequently, extra complexity and wording was added to the error
message. But I don't think the extra wording actually helps all that
much. In particular, it still says of the `1+1` that "this is expected
to be expression". This repeats the problem from the original complaint!
This commit removes the extra complexity, reverting to a simpler error
message. This is primarily because the traversal is a pain without
`Interpolated` tokens. Nonetheless, I think the error message is
*improved*. It now starts with "expected expression, found `pat`
metavariable", which is much clearer and the real problem. It also
doesn't say anything specific about `1+1`, which is good, because the
`1+1` isn't really relevant to the error -- it's the `$e:pat` that's
important.
Spruce up `AttributeKind` docs
- Remove dead link to `rustc_attr` crate.
- Add link to `rustc_attr_parsing` crate.
- Split up first paragraph so it looks better at crate-level summary
r? `@jdonszelmann`
Reuse machinery from `tail_expr_drop_order` for `if_let_rescope`
Namely, it defines its own `extract_component_with_significant_dtor` which is a bit more accurate than `Ty::has_significant_drop`, since it has a hard-coded list of types from the ecosystem which are opted out of the lint.[^a]
Also, since we extract the dtors themselves, adopt the same *label* we use in `tail_expr_drop_order` to point out the destructor impl. This makes it much clear what's actually being dropped, so it should be clearer to know when it's a false positive.
This conflicts with #137444, but I will rebase whichever lands first.
[^a]: Side-note, it's kinda a shame that now there are two functions that presumably do the same thing. But this isn't my circus, nor are these my monkeys.
require trait impls to have matching const stabilities as the traits
This resolves https://github.com/rust-lang/project-const-traits/issues/5 by implementing the suggested solution in the given thread
r? ``@RalfJung``
cc ``@rust-lang/project-const-traits``
Fix UB in ThinVec::flat_map_in_place
`thin_vec.as_ptr()` goes through the `Deref` impl of `ThinVec`, which will not allow access to any memory as we did call `set_len(0)` first.
Found in the process of investigating https://github.com/rust-lang/rust/issues/135870.
It mirrors `ExprKind::Binary`, and contains a `BinOpKind`. This makes
`AssocOp` more like `ExprKind`. Note that the variants removed from
`AssocOp` are all named differently to `BinOpToken`, e.g. `Multiply`
instead of `Mul`, so that's an inconsistency removed.
The commit adds `precedence` and `fixity` methods to `BinOpKind`, and
calls them from the corresponding methods in `AssocOp`. This avoids the
need to create an `AssocOp` from a `BinOpKind` in a bunch of places, and
`AssocOp::from_ast_binop` is removed.
`AssocOp::to_ast_binop` is also no longer needed.
Overall things are shorter and nicer.
`AssocOp::AssignOp` contains a `BinOpToken`. `ExprKind::AssignOp`
contains a `BinOpKind`. Given that `AssocOp` is basically a cut-down
version of `ExprKind`, it makes sense to make `AssocOp` more like
`ExprKind`. Especially given that `AssocOp` and `BinOpKind` use semantic
operation names (e.g. `Mul`, `Div`), but `BinOpToken` uses syntactic
names (e.g. `Star`, `Slash`).
This results in more concise code, and removes the need for various
conversions. (Note that the removed functions `hirbinop2assignop` and
`astbinop2assignop` are semantically identical, because `hir::BinOp` is
just a synonum for `ast::BinOp`!)
The only downside to this is that it allows the possibility of some
nonsensical combinations, such as `AssocOp::AssignOp(BinOpKind::Lt)`.
But `ExprKind::AssignOp` already has that problem. The problem can be
fixed for both types in the future with some effort, by introducing an
`AssignOpKind` type.
- Remove dead link to `rustc_attr` crate.
- Add link to `rustc_attr_parsing` crate.
- Split up first paragraph so it looks better at crate-level summary
Make -Z unpretty=mir suggest -Z dump-mir as well for discoverability
While debugging something else, I got quite annoyed with `-Z unpretty=mir` showing me post-processed MIR instead of the one just after it is built. I ended up asking on Zulip and got pointed to `-Z dump-mir`. While this feature is documented in the rustc dev guide, I think it'd be good if the possibility of making use of it was staring you in the face while you need it.
Don't suggest constraining unstable associated types
Fixes#137624
This could be made a bit more specific, considering the local crate's stability or nightly status or something, but I think in general we should not be suggesting associated type bounds on unstable associated items.
Teach structured errors to display short `Ty<'_>`
Make it so that in every structured error annotated with `#[derive(Diagnostic)]` that has a field of type `Ty<'_>`, the printing of that value into a `String` will look at the thread-local storage `TyCtxt` in order to shorten to a length appropriate with the terminal width. When this happen, the resulting error will have a note with the file where the full type name was written to.
```
error[E0618]: expected function, found `((..., ..., ..., ...), ..., ..., ...)``
--> long.rs:7:5
|
6 | fn foo(x: D) { //~ `x` has type `(...
| - `x` has type `((..., ..., ..., ...), ..., ..., ...)`
7 | x(); //~ ERROR expected function, found `(...
| ^--
| |
| call expression requires function
|
= note: the full name for the type has been written to 'long.long-type-14182675702747116984.txt'
= note: consider using `--verbose` to print the full type name to the console
```
Follow up to and response to the comments on #136898.
r? ``@oli-obk``
Change interners to start preallocated with an increased capacity
Inspired by https://github.com/rust-lang/rust/issues/137005.
Added a `with_capacity` function to `InternedSet`. Changed the `CtxtInterners` to start with `InternedSets` preallocated with a capacity.
This *does* increase memory usage at very slightly(by ~1 MB at the start), altough that increase quickly disaperars for larger crates(since they require such capacity anyway).
A local perf run indicates this improves compiletimes for small crates(like `ripgrep`), without a negative effect on larger ones.
hir_analysis: skip self type of host effect preds in variances_of
Discovered as part of an implementation of rust-lang/rfcs#3729 - w/out this then when introducing const trait bounds: many more interesting tests change with different output, missing errors, new errors, etc related to this but they all depend on feature flags and are much more complex than this test.
r? ``@oli-obk``
trait_sel: resolve vars in host effects
In the standard library, the `Extend` impl for `Iterator` (specialised with `TrustedLen`) has a parameter which is constrained by a projection predicate. This projection predicate provides a value for an inference variable but - if the default bound is `const Sized` instead of `Sized` - host effect evaluation wasn't resolving variables first. Added a test that doesn't depend on a rust-lang/rfcs#3729 implementation.
Adding the extra resolve can the number of errors in some tests when they gain host effect predicates, but this is not unexpected as calls to `resolve_vars_if_possible` can cause more error tainting to happen.
codegen_llvm: avoid `Deref` impls w/ extern type
`rustc_codegen_llvm` relied on `Deref` impls where `Deref::Target` was or contained an extern type - in my experimental implementation of rust-lang/rfcs#3729, this isn't possible as the `Target` associated type's `?Sized` bound cannot be relaxed backwards compatibly (unless we come up with some way of doing this).
In later pull requests with the rust-lang/rfcs#3729 implementation, breakage like this could only occur for nightly users relying on the `extern_types` feature.
Upstreaming this to avoid needing to keep carrying this patch locally, and I think it'll necessarily need to change eventually.
ssa/mono: deduplicate `type_has_metadata`
The implementation of the `type_has_metadata` function is duplicated in `rustc_codegen_ssa` and `rustc_monomorphize`, so move this to `rustc_middle`.