Ensure we do not accidentally insert new early aborts in the analysis passes
pulling the infallible part out into a separate function makes sure that someone needs to change the signature in order to regress this.
We only want to stop compilation in the presence of errors after all analyses are done, but before we start running lints.
per-item we can still stop doing work if previous queries returned errors, but that's a separate story.
Pass list of defineable opaque types into canonical queries
This eliminates `DefiningAnchor::Bubble` for good and brings the old solver closer to the new one wrt cycles and nested obligations. At that point the difference between `DefiningAnchor::Bind([])` and `DefiningAnchor::Error` was academic. We only used the difference for some sanity checks, which actually had to be worked around in places, so I just removed `DefiningAnchor` entirely and just stored the list of opaques that may be defined.
fixes#108498
fixes https://github.com/rust-lang/rust/issues/116877
* [x] run crater
- https://github.com/rust-lang/rust/pull/122077#issuecomment-2013293931
Assert that args are actually compatible with their generics, rather than just their count
Right now we just check that the number of args is right, rather than actually checking the kinds. Uplift a helper fn that I wrote from trait selection to do just that. Found a couple bugs along the way.
r? `@lcnr` or `@fmease` (or anyone really lol)
Rename `expose_addr` to `expose_provenance`
`expose_addr` is a bad name, an address is just a number and cannot be exposed. The operation is actually about the provenance of the pointer.
This PR thus changes the name of the method to `expose_provenance` without changing its return type. There is sufficient precedence for returning a useful value from an operation that does something else without the name indicating such, e.g. [`Option::insert`](https://doc.rust-lang.org/nightly/std/option/enum.Option.html#method.insert) and [`MaybeUninit::write`](https://doc.rust-lang.org/nightly/std/mem/union.MaybeUninit.html#method.write).
Returning the address is merely convenient, not a fundamental part of the operation. This is implied by the fact that integers do not have provenance since
```rust
let addr = ptr.addr();
ptr.expose_provenance();
let new = ptr::with_exposed_provenance(addr);
```
must behave exactly like
```rust
let addr = ptr.expose_provenance();
let new = ptr::with_exposed_provenance(addr);
```
as the result of `ptr.expose_provenance()` and `ptr.addr()` is the same integer. Therefore, this PR removes the `#[must_use]` annotation on the function and updates the documentation to reflect the important part.
~~An alternative name would be `expose_provenance`. I'm not at all opposed to that, but it makes a stronger implication than we might want that the provenance of the pointer returned by `ptr::with_exposed_provenance`[^1] is the same as that what was exposed, which is not yet specified as such IIUC. IMHO `expose` does not make that connection.~~
A previous version of this PR suggested `expose` as name, libs-api [decided on](https://github.com/rust-lang/rust/pull/122964#issuecomment-2033194319) `expose_provenance` to keep the symmetry with `with_exposed_provenance`.
CC `@RalfJung`
r? libs-api
[^1]: I'm using the new name for `from_exposed_addr` suggested by #122935 here.
Assert `FnDef` kind
Only found one bug, where we were using the variant def id rather than its ctor def id to make the `FnDef` for a `type_of`
r? fmease
rename ptr::from_exposed_addr -> ptr::with_exposed_provenance
As discussed on [Zulip](https://rust-lang.zulipchat.com/#narrow/stream/136281-t-opsem/topic/To.20expose.20or.20not.20to.20expose/near/427757066).
The old name, `from_exposed_addr`, makes little sense as it's not the address that is exposed, it's the provenance. (`ptr.expose_addr()` stays unchanged as we haven't found a better option yet. The intended interpretation is "expose the provenance and return the address".)
The new name nicely matches `ptr::without_provenance`.
Make sure to insert `Sized` bound first into clauses list
#120323 made it so that we don't insert an implicit `Sized` bound whenever we see an *explicit* `Sized` bound. However, since the code that inserts implicit sized bounds puts the bound as the *first* in the list, that means that it had the **side-effect** of possibly meaning we check `Sized` *after* checking other trait bounds.
If those trait bounds result in ambiguity or overflow or something, it may change how we winnow candidates. (**edit: SEE** #123303) This is likely the cause for the regression in https://github.com/rust-lang/rust/issues/123279#issuecomment-2028899598, since the impl...
```rust
impl<T: Job + Sized> AsJob for T { // <----- changing this to `Sized + Job` or just `Job` (which turns into `Sized + Job`) will FIX the issue.
}
```
...looks incredibly suspicious.
Fixes [after beta-backport] #123279.
Alternative is to revert #120323. I don't have a strong opinion about this, but think it may be nice to keep the diagnostic changes around.
De-LLVM the unchecked shifts [MCP#693]
This is just one part of the MCP (https://github.com/rust-lang/compiler-team/issues/693), but it's the one that IMHO removes the most noise from the standard library code.
Seems net simpler this way, since MIR already supported heterogeneous shifts anyway, and thus it's not more work for backends than before.
r? WaffleLapkin
Add `Ord::cmp` for primitives as a `BinOp` in MIR
Update: most of this OP was written months ago. See https://github.com/rust-lang/rust/pull/118310#issuecomment-2016940014 below for where we got to recently that made it ready for review.
---
There are dozens of reasonable ways to implement `Ord::cmp` for integers using comparison, bit-ops, and branches. Those differences are irrelevant at the rust level, however, so we can make things better by adding `BinOp::Cmp` at the MIR level:
1. Exactly how to implement it is left up to the backends, so LLVM can use whatever pattern its optimizer best recognizes and cranelift can use whichever pattern codegens the fastest.
2. By not inlining those details for every use of `cmp`, we drastically reduce the amount of MIR generated for `derive`d `PartialOrd`, while also making it more amenable to MIR-level optimizations.
Having extremely careful `if` ordering to μoptimize resource usage on broadwell (#63767) is great, but it really feels to me like libcore is the wrong place to put that logic. Similarly, using subtraction [tricks](https://graphics.stanford.edu/~seander/bithacks.html#CopyIntegerSign) (#105840) is arguably even nicer, but depends on the optimizer understanding it (https://github.com/llvm/llvm-project/issues/73417) to be practical. Or maybe [bitor is better than add](https://discourse.llvm.org/t/representing-in-ir/67369/2?u=scottmcm)? But maybe only on a future version that [has `or disjoint` support](https://discourse.llvm.org/t/rfc-add-or-disjoint-flag/75036?u=scottmcm)? And just because one of those forms happens to be good for LLVM, there's no guarantee that it'd be the same form that GCC or Cranelift would rather see -- especially given their very different optimizers. Not to mention that if LLVM gets a spaceship intrinsic -- [which it should](https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/Suboptimal.20inlining.20in.20std.20function.20.60binary_search.60/near/404250586) -- we'll need at least a rustc intrinsic to be able to call it.
As for simplifying it in Rust, we now regularly inline `{integer}::partial_cmp`, but it's quite a large amount of IR. The best way to see that is with 8811efa88b (diff-d134c32d028fbe2bf835fef2df9aca9d13332dd82284ff21ee7ebf717bfa4765R113) -- I added a new pre-codegen MIR test for a simple 3-tuple struct, and this PR change it from 36 locals and 26 basic blocks down to 24 locals and 8 basic blocks. Even better, as soon as the construct-`Some`-then-match-it-in-same-BB noise is cleaned up, this'll expose the `Cmp == 0` branches clearly in MIR, so that an InstCombine (#105808) can simplify that to just a `BinOp::Eq` and thus fix some of our generated code perf issues. (Tracking that through today's `if a < b { Less } else if a == b { Equal } else { Greater }` would be *much* harder.)
---
r? `@ghost`
But first I should check that perf is ok with this
~~...and my true nemesis, tidy.~~
Use the `Align` type when parsing alignment attributes
Use the `Align` type in `rustc_attr::parse_alignment`, removing the need to call `Align::from_bytes(...).unwrap()` later in the compilation process.
This is just one part of the MCP, but it's the one that IMHO removes the most noise from the standard library code.
Seems net simpler this way, since MIR already supported heterogeneous shifts anyway, and thus it's not more work for backends than before.
Match ergonomics 2024: implement mutable by-reference bindings
Implements the mutable by-reference bindings portion of match ergonomics 2024 (#123076), with the `mut ref`/`mut ref mut` syntax, under feature gate `mut_ref`.
r? `@Nadrieril`
`@rustbot` label A-patterns A-edition-2024
Suggest associated type bounds on problematic associated equality bounds
Fixes#105056. TL;DR: Suggest `Trait<Ty: Bound>` on `Trait<Ty = Bound>` in Rust >=2021.
~~Blocked on #122055 (stabilization of `associated_type_bounds`), I'd say.~~ (merged)
Avoid some unnecessary query invocations.
Specifically this inlines `const_eval_poly` and avoids computing the generic params, the param env, normalizing the param env and erasing lifetimes on everything.
should fix the perf regression from https://github.com/rust-lang/rust/pull/121087
Delegation: fix ICE on `bound_vars` divergence
Fixes https://github.com/rust-lang/rust/issues/122550.
Bug was caused by divergence between lowered type and corresponding `bound_vars` in `late_bound_vars_map`. In this patch `bound_vars` calculation for delegation item is moved from `lower_fn_ty` to `resolve_bound_vars` query.
r? `@petrochenkov`
Mention Register Size in `#[warn(asm_sub_register)]`
Fixes#121593
Displays the register size information obtained from `suggest_modifier()` and `default_modifier()`.
refactor check_{lang,library}_ub: use a single intrinsic
This enacts the plan I laid out [here](https://github.com/rust-lang/rust/pull/122282#issuecomment-1996917998): use a single intrinsic, called `ub_checks` (in aniticpation of https://github.com/rust-lang/compiler-team/issues/725), that just exposes the value of `debug_assertions` (consistently implemented in both codegen and the interpreter). Put the language vs library UB logic into the library.
This makes it easier to do something like https://github.com/rust-lang/rust/pull/122282 in the future: that just slightly alters the semantics of `ub_checks` (making it more approximating when crates built with different flags are mixed), but it no longer affects whether these checks can happen in Miri or compile-time.
The first commit just moves things around; I don't think these macros and functions belong into `intrinsics.rs` as they are not intrinsics.
r? `@saethlin`
Rollup of 11 pull requests
Successful merges:
- #120577 (Stabilize slice_split_at_unchecked)
- #122698 (Cancel `cargo update` job if there's no updates)
- #122780 (Rename `hir::Local` into `hir::LetStmt`)
- #122915 (Delay a bug if no RPITITs were found)
- #122916 (docs(sync): normalize dot in fn summaries)
- #122921 (Enable more mir-opt tests in debug builds)
- #122922 (-Zprint-type-sizes: print the types of awaitees and unnamed coroutine locals.)
- #122927 (Change an ICE regression test to use the original reproducer)
- #122930 (add panic location to 'panicked while processing panic')
- #122931 (Fix some typos in the pin.rs)
- #122933 (tag_for_variant follow-ups)
r? `@ghost`
`@rustbot` modify labels: rollup
Rename `hir::Local` into `hir::LetStmt`
Follow-up of #122776.
As discussed on [zulip](https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/Improve.20naming.20of.20.60ExprKind.3A.3ALet.60.3F).
I made this change into a separate PR because I'm less sure about this change as is. For example, we have `visit_local` and `LocalSource` items. Is it fine to keep these two as is (I supposed it is but I prefer to ask) or not? Having `Node::Local(LetStmt)` makes things more explicit but is it going too far?
r? ```@oli-obk```
Let codegen decide when to `mem::swap` with immediates
Making `libcore` decide this is silly; the backend has so much better information about when it's a good idea.
Thus this PR introduces a new `typed_swap` intrinsic with a fallback body, and replaces that fallback implementation when swapping immediates or scalar pairs.
r? oli-obk
Replaces #111744, and means we'll never need more libs PRs like #111803 or #107140
Rollup of 8 pull requests
Successful merges:
- #114009 (compiler: allow transmute of ZST arrays with generics)
- #122195 (Note that the caller chooses a type for type param)
- #122651 (Suggest `_` for missing generic arguments in turbofish)
- #122784 (Add `tag_for_variant` query)
- #122839 (Split out `PredicatePolarity` from `ImplPolarity`)
- #122873 (Merge my contributor emails into one using mailmap)
- #122885 (Adjust better spastorino membership to triagebot's adhoc_groups)
- #122888 (add a couple more tests)
r? `@ghost`
`@rustbot` modify labels: rollup
Split out `PredicatePolarity` from `ImplPolarity`
Because having to deal with a third `Reservation` level in all the trait solver code is kind of weird.
r? `@lcnr` or `@oli-obk`
Suggest `_` for missing generic arguments in turbofish
The compiler may suggest unusable generic type names for missing generic arguments in an expression context:
```rust
fn main() {
(0..1).collect::<Vec>()
}
```
> help: add missing generic argument
>
> (0..1).collect::<Vec<T>>()
but `T` is not a valid name in this context, and this suggestion won't compile.
I've changed it to use `_` inside method calls (turbofish), so it will suggest `(0..1).collect::<Vec<_>>()` which _may_ compile.
It's possible that the suggested `_` will be ambiguous, but there is very extensive E0283 that will help resolve that, which is more helpful than a basic "cannot find type `T` in this scope" users would get otherwise.
Out of caution to limit scope of the change I've limited it to just turbofish, but I suspect `_` could be the better choice in more cases. Perhaps in all expressions?
Gracefully handle `AnonConst` in `diagnostic_hir_wf_check()`
Instead of running the WF check on the `AnonConst` itself we run it on the `ty` of the generic param of which the `AnonConst` is the default value.
Fixes#122199
This makes it easier to read the trait definition for newcomers:
Sorted from least “complex” to most “complex” followed by trivial “plumbing”
and grouped by area.
* Move `allow_infer` above all `*_infer` methods
* It's the least complex method of those
* Allows the `*_infer` to be placed right next to each other
* Move `probe_ty_param_bounds` further down right next to `lower_assoc_ty` and `probe_adt`
* It's more complex than the `infer` methods, it should come “later”
* Now all required lowering functions are grouped together
* Move the “plumbing” function `set_tainted_by_errors` further down
below any actual lowering methods.
* Provided method should come last
Most of the tracing calls didn't fully leverage the power of `tracing`.
For example, several of them used to hard-code method names / tracing spans
as well as variable names. Use `#[instrument]` and `?var` / `%var` (etc.) instead.
In my opinion, this is the proper way to migrate them from the old
AstConv nomenclature to the new HIR ty lowering one.
Several (doc) comments were super outdated or didn't provide enough context.
Some doc comments shoved everything in a single paragraph without respecting
the fact that the first paragraph should be a single sentence because rustdoc
treats these as item descriptions / synopses on module pages.
Split an item bounds and an item's super predicates
This is the moral equivalent of #107614, but instead for predicates this applies to **item bounds**. This PR splits out the item bounds (i.e. *all* predicates that are assumed to hold for the alias) from the item *super predicates*, which are the subset of item bounds which share the same self type as the alias.
## Why?
Much like #107614, there are places in the compiler where we *only* care about super-predicates, and considering predicates that possibly don't have anything to do with the alias is problematic. This includes things like closure signature inference (which is at its core searching for `Self: Fn(..)` style bounds), but also lints like `#[must_use]`, error reporting for aliases, computing type outlives predicates.
Even in cases where considering all of the `item_bounds` doesn't lead to bugs, unnecessarily considering irrelevant bounds does lead to a regression (#121121) due to doing extra work in the solver.
## Example 1 - Trait Aliases
This is best explored via an example:
```
type TAIT<T> = impl TraitAlias<T>;
trait TraitAlias<T> = A + B where T: C;
```
The item bounds list for `Tait<T>` will include:
* `Tait<T>: A`
* `Tait<T>: B`
* `T: C`
While `item_super_predicates` query will include just the first two predicates.
Side-note: You may wonder why `T: C` is included in the item bounds for `TAIT`? This is because when we elaborate `TraitAlias<T>`, we will also elaborate all the predicates on the trait.
## Example 2 - Associated Type Bounds
```
type TAIT<T> = impl Iterator<Item: A>;
```
The `item_bounds` list for `TAIT<T>` will include:
* `Tait<T>: Iterator`
* `<Tait<T> as Iterator>::Item: A`
But the `item_super_predicates` will just include the first bound, since that's the only bound that is relevant to the *alias* itself.
## So what
This leads to some diagnostics duplication just like #107614, but none of it will be user-facing. We only see it in the UI test suite because we explicitly disable diagnostic deduplication.
Regarding naming, I went with `super_predicates` kind of arbitrarily; this can easily be changed, but I'd consider better names as long as we don't block this PR in perpetuity.
Use hir::Node helper methods instead of repeating the same impl multiple times
I wanted to do something entirely different and stumbled upon a bunch of cleanups
Provide structured suggestion for `#![feature(foo)]`
```
error: `S2<'_>` is forbidden as the type of a const generic parameter
--> $DIR/lifetime-in-const-param.rs:5:23
|
LL | struct S<'a, const N: S2>(&'a ());
| ^^
|
= note: the only supported types are integers, `bool` and `char`
help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
|
LL + #![feature(adt_const_params)]
|
```
Fix#55941.
Reject overly generic assoc const binding types
Split off from #119385 to make #119385 easier to review.
---
In the *instantiated* type of assoc const bindings
1. reject **early-bound generic params**
* Provide a rich error message instead of ICE'ing ([#108271](https://github.com/rust-lang/rust/issues/108271)).
* This is a temporary and semi-artificial restriction until the arrival of *generic const generics*.
* It's quite possible that rustc could already perfectly support this subset of generic const generics if we just removed some checks (some `.no_bound_vars().expect(…)`) but even if that was the case, I'd rather gate it behind a new feature flag. Reporting an error instead of ICE'ing is a good first step towards an eventual feature gate error.
2. reject **escaping late-bound generic params**
* They lead to ICEs before & I'm pretty sure that they remain incorrect even in a world with *generic const generics*
---
Together with #118668 & #119385, this supersedes #118360.
Fixes#108271.
```
error: `S2<'_>` is forbidden as the type of a const generic parameter
--> $DIR/lifetime-in-const-param.rs:5:23
|
LL | struct S<'a, const N: S2>(&'a ());
| ^^
|
= note: the only supported types are integers, `bool` and `char`
help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
|
LL + #![feature(adt_const_params)]
|
```
Fix#55941.
Making `libcore` decide this is silly; the backend has so much better information about when it's a good idea.
So introduce a new `typed_swap` intrinsic with a fallback body, but replace that implementation for immediates and scalar pairs.
Remove obsolete parameter `speculative` from `instantiate_poly_trait_ref`
In #122527 I totally missed that `speculative` has become obsolete with the removal of `hir_trait_to_predicates` / due to #113671.
Fixes#114635.
r? `@compiler-errors`
Split refining_impl_trait lint into _reachable, _internal variants
As discussed in https://github.com/rust-lang/rust/issues/119535#issuecomment-1909352040:
> We discussed this today in triage and developed a consensus to:
>
> * Add a separate lint against impls that refine a return type defined with RPITIT even when the trait is not crate public.
> * Place that in a lint group along with the analogous crate public lint.
> * Create an issue to solicit feedback on these lints (or perhaps two separate ones).
> * Have the warnings displayed with each lint reference this issue in a similar manner to how we do that today with the required `Self: '0'` bound on GATs.
> * Make a note to review this feedback on 2-3 release cycles.
This points users to https://github.com/rust-lang/rust/issues/121718 to leave feedback.
hir: Remove `opt_local_def_id_to_hir_id` and `opt_hir_node_by_def_id`
Also replace a few `hir_node()` calls with `hir_node_by_def_id()`.
Follow up to https://github.com/rust-lang/rust/pull/120943.
Clean up AstConv
Split off from #120926 to make it only contain the renaming & (doc) comment updates.
Any changes other than that which have accumulated over time are now part of this PR.
Let's be disciplined ;) Inspired by https://github.com/rust-lang/rust/pull/120926#issuecomment-1997984483.
---
* Remove `hir_trait_to_predicates`
* Unused since #113671
* Inline `create_args_for_ast_trait_ref`
* Only had a single call site
* Having it as a separate method didn't gain us anything
* Use an if-let guard somewhere to avoid unwrapping
* Avoid explicit trait object lifetimes
* More legible, stylistic-only (the updated code is 100% semantically identical)
* Use explicitly elided lifetimes in impl headers, they get elaborated to distinct lifetimes
* Make use of [object lifetime defaulting](https://doc.rust-lang.org/reference/lifetime-elision.html#default-trait-object-lifetimes) for a trait object type inside of a reference type somewhere
* Use preexisting dedicated method `ItemCtxt::to_ty` over `<dyn AstConv<'_>>::ast_ty_to_ty`
* Use preexisting dedicated method `AstConv::astconv` over explicit coercions
* Simplify the function signature of `create_args_for_ast_path` and of `check_generic_arg_count`
* In both cases redundant information was passed rendering the call sites verbose and confusing
* No perf impact (tested in [#120926](https://github.com/rust-lang/rust/pull/120926))
* Move diagnostic method `report_ambiguous_associated_type` from `astconv` to `astconv::errors`
* The submodule `errors` exists specifically for that purpose
* Use it to keep the main module clean & short
Ensure RPITITs are created before def-id freezing
From the test:
```rust
// `ty::Error` in a trait ref will silence any missing item errors, but will also
// prevent the `associated_items` query from being called before def ids are frozen.
```
Essentially, the code that checks that `impl`s have all their items (`check_impl_items_against_trait`) is also (implicitly) responsible for fetching the `associated_items` query before, but since we early return here:
c2901f5435/compiler/rustc_hir_analysis/src/check/check.rs (L732-L737)
...that means that this never happens for trait refs that reference errors.
Fixes#122518
r? oli-obk
Create some minimal HIR for associated opaque types
`LocalDefId`s for opaque types in traits and impls are created after AST -> HIR lowering, so they don't have corresponding HIR and return their various properties through fed queries.
In this PR I also feed some core HIR-related queries for these `LocalDefId`s (which happen to be HIR owners).
As a result all `LocalDefId`s now have corresponding `HirId`s and HIR nodes, and "optional" methods like `opt_local_def_id_to_hir_id` and `opt_hir_node_by_def_id` can be removed.
Follow up to https://github.com/rust-lang/rust/pull/120206.
Make `DefiningAnchor::Bind` only store the opaque types that may be constrained, instead of the current infcx root item.
This makes `Bind` almost always be empty, so we can start forwarding it to queries, allowing us to remove `Bubble` entirely (not done in this PR)
The only behaviour change is in diagnostics.
r? `@lcnr` `@compiler-errors`
Rollup of 15 pull requests
Successful merges:
- #116791 (Allow codegen backends to opt-out of parallel codegen)
- #116793 (Allow targets to override default codegen backend)
- #117458 (LLVM Bitcode Linker: A self contained linker for nvptx and other targets)
- #119385 (Fix type resolution of associated const equality bounds (take 2))
- #121438 (std support for wasm32 panic=unwind)
- #121893 (Add tests (and a bit of cleanup) for interior mut handling in promotion and const-checking)
- #122080 (Clarity improvements to `DropTree`)
- #122152 (Improve diagnostics for parenthesized type arguments)
- #122166 (Remove the unused `field_remapping` field from `TypeLowering`)
- #122249 (interpret: do not call machine read hooks during validation)
- #122299 (Store backtrace for `must_produce_diag`)
- #122318 (Revision-related tweaks for next-solver tests)
- #122320 (Use ptradd for vtable indexing)
- #122328 (unix_sigpipe: Replace `inherit` with `sig_dfl` in syntax tests)
- #122330 (bootstrap readme: fix, improve, update)
r? `@ghost`
`@rustbot` modify labels: rollup
Fix type resolution of associated const equality bounds (take 2)
Instead of trying to re-resolve the type of assoc const bindings inside the `type_of` query impl in an incomplete manner, transfer the already (correctly) resolved type from `add_predicates_for_ast_type_binding` to `type_of`/`anon_type_of` through query feeding.
---
Together with #118668 (merged) and #121258, this supersedes #118360.
Fixes#118040.
r? ``@ghost``
Run a single huge par_body_owners instead of many small ones after each other.
This improves parallel rustc parallelism by avoiding the bottleneck after each individual `par_body_owners` (because it needs to wait for queries to finish, so if there is one long running one, a lot of cores will be idle while waiting for the single query).
This improves parallel rustc parallelism by avoiding the bottleneck after each individual `par_body_owners` (because it needs to wait for queries to finish, so if there is one long running one, a lot of cores will be idle while waiting for the single query).
Expose the Freeze trait again (unstably) and forbid implementing it manually
non-emoji version of https://github.com/rust-lang/rust/pull/121501
cc #60715
This trait is useful for generic constants (associated consts of generic traits). See the test (`tests/ui/associated-consts/freeze.rs`) added in this PR for a usage example. The builtin `Freeze` trait is the only way to do it, users cannot work around this issue.
It's also a useful trait for building some very specific abstrations, as shown by the usage by the `zerocopy` crate: https://github.com/google/zerocopy/issues/941
cc ```@RalfJung```
T-lang signed off on reexposing this unstably: https://github.com/rust-lang/rust/pull/121501#issuecomment-1969827742
Distinguish between library and lang UB in assert_unsafe_precondition
As described in https://github.com/rust-lang/rust/pull/121583#issuecomment-1963168186, `assert_unsafe_precondition` now explicitly distinguishes between language UB (conditions we explicitly optimize on) and library UB (things we document you shouldn't do, and maybe some library internals assume you don't do).
`debug_assert_nounwind` was originally added to avoid the "only at runtime" aspect of `assert_unsafe_precondition`. Since then the difference between the macros has gotten muddied. This totally revamps the situation.
Now _all_ preconditions shall be checked with `assert_unsafe_precondition`. If you have a precondition that's only checkable at runtime, do a `const_eval_select` hack, as done in this PR.
r? RalfJung
Don't ICE if we collect no RPITITs unless there are no unification errors
Move an assertion in `collect_return_position_impl_trait_in_trait_tys` to after the `ObligationCtxt::eq` calls, so that we only assert and ICE if we have unification errors.
Fixes#121468
Merge `collect_mod_item_types` query into `check_well_formed`
follow-up to https://github.com/rust-lang/rust/pull/121154
this removes more potential parallel-compiler bottlenecks and moves diagnostics for the same items next to each other, instead of grouping diagnostics by analysis kind
Use `ControlFlow` in visitors.
Follow up to #121256
This does have a few small behaviour changes in some diagnostic output where the visitor will now find the first match rather than the last match. The change in `find_anon_types.rs` has the only affected test. I don't see this being an issue as the last occurrence isn't any better of a choice than the first.
Make TAITs and ATPITs capture late-bound lifetimes in scope
This generalizes the behavior that RPITs have, where they duplicate their in-scope lifetimes so that they will always *reify* late-bound lifetimes that they capture. This allows TAITs and ATPITs to properly error when they capture in-scope late-bound lifetimes.
r? `@oli-obk` cc `@aliemjay`
Fixes#122093 and therefore https://github.com/rust-lang/rust/pull/120700#issuecomment-1981213868
Add asm goto support to `asm!`
Tracking issue: #119364
This PR implements asm-goto support, using the syntax described in "future possibilities" section of [RFC2873](https://rust-lang.github.io/rfcs/2873-inline-asm.html#asm-goto).
Currently I have only implemented the `label` part, not the `fallthrough` part (i.e. fallthrough is implicit). This doesn't reduce the expressive though, since you can use label-break to get arbitrary control flow or simply set a value and rely on jump threading optimisation to get the desired control flow. I can add that later if deemed necessary.
r? ``@Amanieu``
cc ``@ojeda``
Don't require specifying unrelated assoc types when trait alias is in `dyn` type
Object types must specify the associated types for all of the principal trait ref's supertraits. However, we weren't doing elaboration properly, so we incorrectly errored with erroneous suggestions to specify associated types that were unrelated to that principal trait ref. To fix this, use proper supertrait elaboration when expanding trait aliases in `conv_object_ty_poly_trait_ref`.
**NOTE**: Please use the ignore-whitespace option when reviewing. This only touches a handful of lines.
r? oli-obk or please feel free to reassign.
Fixes#122118
Apply `EarlyBinder` only to `TraitRef` in `ImplTraitHeader`
Resolves#121852
This PR
1. Moves `EarlyBinder` to `TraitRef` inside `ImplTraitHeader`,
2. Changes visibility of `coherence::builtin::check_trait` to `pub(super)` from `pub` as it seems not being re-exported from the `coherence` module.
silence mismatched types errors for implied projections
Currently, if a trait bound is not satisfied, then we suppress any errors for the trait's supertraits not being satisfied, but still report errors for super projections not being satisfied.
For example:
```rust
trait Super {
type Assoc;
}
trait Sub: Super<Assoc = ()> {}
```
Before this PR, if `T: Sub` is not satisfied, then errors for `T: Super` are suppressed, but errors for `<T as Super>::Assoc == ()` are still shown. This PR makes it so that errors about super projections not being satisfied are also suppressed.
The errors are only suppressed if the span of the trait obligation matches the span of the super predicate obligation to avoid silencing error that are not related. This PR removes some differences between the spans of supertraits and super projections to make the suppression work correctly.
This PR fixes the majority of the diagnostics fallout when making `Thin` a supertrait of `Sized` (in a future PR).
cc https://github.com/rust-lang/rust/pull/120354#issuecomment-1930585382
cc `@lcnr`
Uplift some feeding out of `associated_type_for_impl_trait_in_impl` and into queries
This PR moves the `type_of` and `generics_of` query feeding out of `associated_type_for_impl_trait_in_impl`, since eagerly feeding results in query cycles due to a subtle interaction with `resolve_bound_vars`.
Fixes#122019
r? spastorino
stricter hidden type wf-check [based on #115008]
Original work by `@aliemjay` in #115008. A huge thanks to them for originally figuring out this approach ❤️
Fixes https://github.com/rust-lang/rust/issues/114728
Fixes https://github.com/rust-lang/rust/issues/114572
Instead of adding the `WellFormed` obligations when relating opaque types, we now always emit such an obligation when defining the hidden type.
This causes nested opaque types which aren't wf to error, see the comment below for the described impact. I believe this change to be desirable as it significantly reduces complexity by removing special-cases.
It also caused an issue with RPITIT: in defaulted trait methods, we add a `Projection(synthetic_assoc, rpit_of_trait_method)` clause to the `param_env`. This clause is not added to the `ParamEnv` of the nested coroutines. This caused a normalization failure in `fn check_coroutine_obligations` with the new solver. I fixed that by using the env of the typeck root instead.
r? `@oli-obk`
Rollup of 9 pull requests
Successful merges:
- #121065 (Add basic i18n guidance for `Display`)
- #121744 (Stop using Bubble in coherence and instead emulate it with an intercrate check)
- #121829 (Dummy tweaks (attempt 2))
- #121857 (Implement async closure signature deduction)
- #121894 (const_eval_select: make it safe but be careful with what we expose on stable for now)
- #122014 (Change some attributes to only_local.)
- #122016 (will_wake tests fail on Miri and that is expected)
- #122018 (only set noalias on Box with the global allocator)
- #122028 (Remove some dead code)
r? `@ghost`
`@rustbot` modify labels: rollup
Rollup of 8 pull requests
Successful merges:
- #121202 (Limit the number of names and values in check-cfg diagnostics)
- #121301 (errors: share `SilentEmitter` between rustc and rustfmt)
- #121658 (Hint user to update nightly on ICEs produced from outdated nightly)
- #121846 (only compare ambiguity item that have hard error)
- #121961 (add test for #78894#71450)
- #121975 (hir_analysis: enums return `None` in `find_field`)
- #121978 (Fix duplicated path in the "not found dylib" error)
- #121991 (Merge impl_trait_in_assoc_types_defined_by query back into `opaque_types_defined_by`)
r? `@ghost`
`@rustbot` modify labels: rollup
const_eval_select: make it safe but be careful with what we expose on stable for now
As this is all still nightly-only I think `````@rust-lang/wg-const-eval````` can do that without involving t-lang.
r? `````@oli-obk`````
Cc `````@Nilstrieb````` -- the updated version of your RFC would basically say that we can remove these comments about not making behavior differences visible in stable `const fn`
Merge impl_trait_in_assoc_types_defined_by query back into `opaque_types_defined_by`
Instead, when we're collecting opaques for associated items, we choose the right collection mode depending on whether we're collecting for an associated item of a trait impl or not.
r? ```@compiler-errors```
follow up to https://github.com/rust-lang/rust/pull/121838
hir_analysis: enums return `None` in `find_field`
Fixes#121757.
Unnamed union fields with enums are checked for, but if `find_field` causes an ICE then the compiler won't get to that point.
Instead, when we're collecting opaques for associated items, we choose the right collection mode depending on whether we're collecting for an associated item of a trait impl or not.
Add a scheme for moving away from `extern "rust-intrinsic"` entirely
All `rust-intrinsic`s can become free functions now, either with a fallback body, or with a dummy body and an attribute, requiring backends to actually implement the intrinsic.
This PR demonstrates the dummy-body scheme with the `vtable_size` intrinsic.
cc https://github.com/rust-lang/rust/issues/63585
follow-up to #120500
MCP at https://github.com/rust-lang/compiler-team/issues/720
Existing names for values of this type are `sess`, `parse_sess`,
`parse_session`, and `ps`. `sess` is particularly annoying because
that's also used for `Session` values, which are often co-located, and
it can be difficult to know which type a value named `sess` refers to.
(That annoyance is the main motivation for this change.) `psess` is nice
and short, which is good for a name used this much.
The commit also renames some `parse_sess_created` values as
`psess_created`.
Unnamed union fields with enums are checked for, but if `find_field`
causes an ICE then the compiler won't get to that point.
Signed-off-by: David Wood <david@davidtw.co>
Rollup of 5 pull requests
Successful merges:
- #120761 (Add initial support for DataFlowSanitizer)
- #121622 (Preserve same vtable pointer when cloning raw waker, to fix Waker::will_wake)
- #121716 (match lowering: Lower bindings in a predictable order)
- #121731 (Now that inlining, mir validation and const eval all use reveal-all, we won't be constraining hidden types here anymore)
- #121841 (`f16` and `f128` step 2: intrinsics)
r? `@ghost`
`@rustbot` modify labels: rollup
`f16` and `f128` step 2: intrinsics
Continuation of https://github.com/rust-lang/rust/pull/121728, another portion of https://github.com/rust-lang/rust/pull/114607.
This PR adds `f16` and `f128` intrinsics, and hooks them up to both HIR and LLVM. This is all still unexposed to the frontend, which will probably be the next step. Also update itanium mangling per `@rcvalle's` in https://github.com/rust-lang/rust/pull/121728/files#r1506570300, and fix a typo from step 1.
Once these types are usable in code, I will add the codegen tests from #114607 (codegen is passing on that branch)
This does add more `unimplemented!`s to Clippy, but I still don't think we can do better until library support is added.
r? `@compiler-errors`
cc `@Nilstrieb`
`@rustbot` label +T-compiler +F-f16_and_f128
Handle stashing of delayed bugs
By just emitting them immediately, because it does happen in practice, when errors are downgraded to delayed bugs.
We already had one case in `lint.rs` where we handled this at the callsite. This commit changes things so it's handled within `stash_diagnostic` instead, because #121812 identified a second case, and it's possible there are more.
Fixes#121812.
r? ````@oli-obk````
By just emitting them immediately, because it does happen in practice,
when errors are downgraded to delayed bugs.
We already had one case in `lint.rs` where we handled this at the
callsite. This commit changes things so it's handled within
`stash_diagnostic` instead, because #121812 identified a second case,
and it's possible there are more.
Fixes#121812.
change equate for binders to not rely on subtyping
*summary by `@spastorino` and `@lcnr*`
### Context
The following code:
```rust
type One = for<'a> fn(&'a (), &'a ());
type Two = for<'a, 'b> fn(&'a (), &'b ());
mod my_api {
use std::any::Any;
use std::marker::PhantomData;
pub struct Foo<T: 'static> {
a: &'static dyn Any,
_p: PhantomData<*mut T>, // invariant, the type of the `dyn Any`
}
impl<T: 'static> Foo<T> {
pub fn deref(&self) -> &'static T {
match self.a.downcast_ref::<T>() {
None => unsafe { std::hint::unreachable_unchecked() },
Some(a) => a,
}
}
pub fn new(a: T) -> Foo<T> {
Foo::<T> {
a: Box::leak(Box::new(a)),
_p: PhantomData,
}
}
}
}
use my_api::*;
fn main() {
let foo = Foo::<One>::new((|_, _| ()) as One);
foo.deref();
let foo: Foo<Two> = foo;
foo.deref();
}
```
has UB from hitting the `unreachable_unchecked`. This happens because `TypeId::of::<One>()` is not the same as `TypeId::of::<Two>()` despite them being considered the same types by the type checker.
Currently the type checker considers binders to be equal if subtyping succeeds in both directions: `for<'a> T<'a> eq for<'b> U<'b>` holds if `for<'a> exists<'b> T<'b> <: T'<a> AND for<'b> exists<'a> T<'a> <: T<'b>` holds. This results in `for<'a> fn(&'a (), &'a ())` and `for<'a, 'b> fn(&'a (), &'b ())` being equal in the type system.
`TypeId` is computed by looking at the *structure* of a type. Even though these types are semantically equal, they have a different *structure* resulting in them having different `TypeId`. This can break invariants of unsafe code at runtime and is unsound when happening at compile time, e.g. when using const generics.
So as seen in `main`, we can assign a value of type `Foo::<One>` to a binding of type `Foo<Two>` given those are considered the same type but then when we call `deref`, it calls `downcast_ref` that relies on `TypeId` and we would hit the `None` arm as these have different `TypeId`s.
As stated in https://github.com/rust-lang/rust/issues/97156#issuecomment-1879030033, this causes the API of existing crates to be unsound.
## What should we do about this
The same type resulting in different `TypeId`s is a significant footgun, breaking a very reasonable assumptions by authors of unsafe code. It will also be unsound by itself once they are usable in generic contexts with const generics.
There are two options going forward here:
- change how the *structure* of a type is computed before relying on it. i.e. continue considering `for<'a> fn(&'a (), &'a ())` and `for<'a, 'b> fn(&'a (), &'b ())` to be equal, but normalize them to a common representation so that their `TypeId` are also the same.
- change how the semantic equality of binders to match the way we compute the structure of types. i.e. `for<'a> fn(&'a (), &'a ())` and `for<'a, 'b> fn(&'a (), &'b ())` still have different `TypeId`s but are now also considered to not be semantically equal.
---
Advantages of the first approach:
- with the second approach some higher ranked types stop being equal, even though they are subtypes of each other
General thoughts:
- changing the approach in the future will be breaking
- going from first to second may break ordinary type checking, as types which were previously equal are now distinct
- going from second to first may break coherence, because previously disjoint impls overlap as the used types are now equal
- both of these are quite unlikely. This PR did not result in any crater failures, so this should not matter too much
Advantages of the second approach:
- the soundness of the first approach requires more non-local reasoning. We have to make sure that changes to subtyping do not cause the representative computation to diverge from semantic equality
- e.g. we intend to consider higher ranked implied bounds when subtyping to [fix] https://github.com/rust-lang/rust/issues/25860, I don't know how this will interact and don't feel confident making any prediction here.
- computing a representative type is non-trivial and soundness critical, therefore adding complexity to the "core type system"
---
This PR goes with the second approach. A crater run did not result in any regressions. I am personally very hesitant about trying the first approach due to the above reasons. It feels like there are more unknowns when going that route.
### Changing the way we equate binders
Relating bound variables from different depths already results in a universe error in equate. We therefore only need to make sure that there is 1-to-1 correspondence between bound variables when relating binders. This results in concrete types being structurally equal after anonymizing their bound variables.
We implement this by instantiating one of the binder with placeholders and the other with inference variables and then equating the instantiated types. We do so in both directions.
More formally, we change the typing rules as follows:
```
for<'r0, .., 'rn> exists<'l0, .., 'ln> LHS<'l0, .., 'ln> <: RHS<'r0, .., 'rn>
for<'l0, .., 'ln> exists<'r0, .., 'rn> RHS<'r0, .., 'rn> <: LHS<'l0, .., 'ln>
--------------------------------------------------------------------------
for<'l0, .., 'ln> LHS<'l0, .., 'ln> eq for<'r0, .., 'rn> RHS<'r0, .., 'rn>
```
to
```
for<'r0, .., 'rn> exists<'l0, .., 'ln> LHS<'l0, .., 'ln> eq RHS<'r0, .., 'rn>
for<'l0, .., 'ln> exists<'r0, .., 'rn> RHS<'r0, .., 'rn> eq LHS<'l0, .., 'ln>
--------------------------------------------------------------------------
for<'l0, .., 'ln> LHS<'l0, .., 'ln> eq for<'r0, .., 'rn> RHS<'r0, .., 'rn>
```
---
Fixes#97156
r? `@lcnr`
Count stashed errors again
Stashed diagnostics are such a pain. Their "might be emitted, might not" semantics messes with lots of things.
#120828 and #121206 made some big changes to how they work, improving some things, but still leaving some problems, as seen by the issues caused by #121206. This PR aims to fix all of them by restricting them in a way that eliminates the "might be emitted, might not" semantics while still allowing 98% of their benefit. Details in the individual commit logs.
r? `@oli-obk`
Deeply normalize obligations in `refining_impl_trait`
We somewhat awkwardly use semantic comparison when checking the `refining_impl_trait` lint. This relies on us being able to normalize bounds eagerly to avoid cases where an unnormalized alias is not considered equal to a normalized alias. Since `normalize` in the new solver is a noop, let's use `deeply_normalize` instead.
r? lcnr
cc ``@tmandry,`` this should fix your bug lol
Stashed errors used to be counted as errors, but could then be
cancelled, leading to `ErrorGuaranteed` soundness holes. #120828 changed
that, closing the soundness hole. But it introduced other difficulties
because you sometimes have to account for pending stashed errors when
making decisions about whether errors have occured/will occur and it's
easy to overlook these.
This commit aims for a middle ground.
- Stashed errors (not warnings) are counted immediately as emitted
errors, avoiding the possibility of forgetting to consider them.
- The ability to cancel (or downgrade) stashed errors is eliminated, by
disallowing the use of `steal_diagnostic` with errors, and introducing
the more restrictive methods `try_steal_{modify,replace}_and_emit_err`
that can be used instead.
Other things:
- `DiagnosticBuilder::stash` and `DiagCtxt::stash_diagnostic` now both
return `Option<ErrorGuaranteed>`, which enables the removal of two
`delayed_bug` calls and one `Ty::new_error_with_message` call. This is
possible because we store error guarantees in
`DiagCtxt::stashed_diagnostics`.
- Storing the guarantees also saves us having to maintain a counter.
- Calls to the `stashed_err_count` method are no longer necessary
alongside calls to `has_errors`, which is a nice simplification, and
eliminates two more `span_delayed_bug` calls and one FIXME comment.
- Tests are added for three of the four fixed PRs mentioned below.
- `issue-121108.rs`'s output improved slightly, omitting a non-useful
error message.
Fixes#121451.
Fixes#121477.
Fixes#121504.
Fixes#121508.
Diagnostic renaming
Renaming various diagnostic types from `Diagnostic*` to `Diag*`. Part of https://github.com/rust-lang/compiler-team/issues/722. There are more to do but this is enough for one PR.
r? `@davidtwco`
Split rustc_type_ir to avoid rustc_ast from depending on it
unblocks #121576
and resolves a FIXME in `rustc_ast`'s `Cargo.toml`
The new crate is tiny, but it will get bigger in #121576
Delayed bug audit
I went through all the calls to `delayed_bug` and `span_delayed_bug` and found a few places where they could be avoided.
r? `@compiler-errors`
rename 'try' intrinsic to 'catch_unwind'
The intrinsic has nothing to do with `try` blocks, and corresponds to the stable `catch_unwind` function, so this makes a lot more sense IMO.
Also rename Miri's special function while we are at it, to reflect the level of abstraction it works on: it's an unwinding mechanism, on which Rust implements panics.
Fix more #121208 fallout (round 3)
#121208 converted lots of delayed bugs to bugs. Unsurprisingly, there were a few invalid conversion found via fuzzing.
r? `@lcnr`
Prevent cycle in implied predicates computation
Makes #65913 from hang -> fail. I believe fail is the correct state for this test to remain for the long term.
Add newtypes for bool fields/params/return types
Fixed all the cases of this found with some simple searches for `*/ bool` and `bool /*`; probably many more
Don't ICE on anonymous struct in enum variant
Fixes#121446
Computing `adt_def` for the anon struct calls `adt_def` on the parent to find its repr. If the parent is a non-item (e.g. an enum variant) we should have already emitted at least one error, so we just use the repr of the anonymous struct to avoid an ICE.
cc ``@frank-king``
Fix more #121208 fallout
#121208 converted lots of delayed bugs to bugs. Unsurprisingly, there were a few invalid conversion found via fuzzing.
r? `@lcnr`
Add "algebraic" fast-math intrinsics, based on fast-math ops that cannot return poison
Setting all of LLVM's fast-math flags makes our fast-math intrinsics very dangerous, because some inputs are UB. This set of flags permits common algebraic transformations, but according to the [LangRef](https://llvm.org/docs/LangRef.html#fastmath), only the flags `nnan` (no nans) and `ninf` (no infs) can produce poison.
And this uses the algebraic float ops to fix https://github.com/rust-lang/rust/issues/120720
cc `@orlp`
Convert `delayed_bug`s to `bug`s.
I have a suspicion that quite a few delayed bug paths are impossible to reach, so I did an experiment.
I converted every `delayed_bug` to a `bug`, ran the full test suite, then converted back every `bug` that was hit. A surprising number were never hit.
This is too dangerous to merge. Increased coverage (fuzzing or a crater run) would likely hit more cases. But it might be useful for people to look at and think about which paths are genuinely unreachable.
r? `@ghost`
Warn (or error) when `Self` ctor from outer item is referenced in inner nested item
This implements a warning `SELF_CONSTRUCTOR_FROM_OUTER_ITEM` when a self constructor from an outer impl is referenced in an inner nested item. This is a proper fix mentioned https://github.com/rust-lang/rust/pull/117246#discussion_r1374648388.
This warning is additionally bumped to a hard error when the self type references generic parameters, since it's almost always going to ICE, and is basically *never* correct to do.
This also reverts part of https://github.com/rust-lang/rust/pull/117246, since I believe this is the proper fix and we shouldn't need the helper functions (`opt_param_at`/`opt_type_param`) any longer, since they shouldn't really ever be used in cases where we don't have this problem.
I have a suspicion that quite a few delayed bug paths are impossible to
reach, so I did an experiment.
I converted every `delayed_bug` to a `bug`, ran the full test suite,
then converted back every `bug` that was hit. A surprising number were
never hit.
The next commit will convert some more back, based on human judgment.