Previously these would be treated like integer literals and default to
`i32` if a type could not be determined. To allow for
forward-compatibility with `str` constants in the future, this PR
changes type inference to use an unbound type variable instead.
The actual type checking is deferred until after typeck where we still
ensure that the final type for the `const` operand is an integer type.
Uplift most type-system related error reporting from `rustc_infer` to `rustc_trait_selection`
Completes the major part of #127492. The only cleanup that's needed afterwards is to actually use normalization in favor of the callback where needed, and deleting `can_eq_shallow`.
r? lcnr
Sorry for the large diff! Would prefer if comments can be handled in a follow-up (unless they're absolutely dealbreakers) because it seems bitrotty to let this sit.
Just totally fully deny late-bound consts
Kinda don't care about supporting this until we have where clauses on binders. They're super busted and should be reworked in due time, and they are approximately 100% useless until then 😸Fixes#127970Fixes#127009
r? ``@BoxyUwU``
Forbid borrows and unsized types from being used as the type of a const generic under `adt_const_params`
Fixes#112219Fixes#112124Fixes#112125
### Motivation
Currently the `adt_const_params` feature allows writing `Foo<const N: [u8]>` this is entirely useless as it is not possible to write an expression which evaluates to a type that is not `Sized`. In order to actually use unsized types in const generics they are typically written as `const N: &[u8]` which *is* possible to provide a value of.
Unfortunately allowing the types of const parameters to contain references is non trivial (#120961) as it introduces a number of difficult questions about how equality of references in the type system should behave. References in the types of const generics is largely only useful for using unsized types in const generics.
This PR introduces a new feature gate `unsized_const_parameters` and moves support for `const N: [u8]` and `const N: &...` from `adt_const_params` into it. The goal here hopefully is to experiment with allowing `const N: [u8]` to work without references and then eventually completely forbid references in const generics.
Splitting this out into a new feature gate means that stabilization of `adt_const_params` does not have to resolve#120961 which is the only remaining "big" blocker for the feature. Remaining issues after this are a few ICEs and naming bikeshed for `ConstParamTy`.
### Implementation
The implementation is slightly subtle here as we would like to ensure that a stabilization of `adt_const_params` is forwards compatible with any outcome of `unsized_const_parameters`. This is inherently tricky as we do not support unstable trait implementations and we determine whether a type is valid as the type of a const parameter via a trait bound.
There are a few constraints here:
- We would like to *allow for the possibility* of adding a `Sized` supertrait to `ConstParamTy` in the event that we wind up opting to not support unsized types and instead requiring people to write the 'sized version', e.g. `const N: [u8; M]` instead of `const N: [u8]`.
- Crates should be able to enable `unsized_const_parameters` and write trait implementations of `ConstParamTy` for `!Sized` types without downstream crates that only enable `adt_const_params` being able to observe this (required for std to be able to `impl<T> ConstParamTy for [T]`
Ultimately the way this is accomplished is via having two traits (sad), `ConstParamTy` and `UnsizedConstParamTy`. Depending on whether `unsized_const_parameters` is enabled or not we change which trait is used to check whether a type is allowed to be a const parameter.
Long term (when stabilizing `UnsizedConstParamTy`) it should be possible to completely merge these traits (and derive macros), only having a single `trait ConstParamTy` and `macro ConstParamTy`.
Under `adt_const_params` it is now illegal to directly refer to `ConstParamTy` it is only used as an internal impl detail by `derive(ConstParamTy)` and checking const parameters are well formed. This is necessary in order to ensure forwards compatibility with all possible future directions for `feature(unsized_const_parameters)`.
Generally the intuition here should be that `ConstParamTy` is the stable trait that everything uses, and `UnsizedConstParamTy` is that plus unstable implementations (well, I suppose `ConstParamTy` isn't stable yet :P).
Avoid ref when using format! in compiler
Clean up a few minor refs in `format!` macro, as it has a performance cost. Apparently the compiler is unable to inline `format!("{}", &variable)`, and does a run-time double-reference instead (format macro already does one level referencing). Inlining format args prevents accidental `&` misuse.
See also https://github.com/rust-lang/rust-clippy/issues/10851
Clean up a few minor refs in `format!` macro, as it has a performance cost. Apparently the compiler is unable to inline `format!("{}", &variable)`, and does a run-time double-reference instead (format macro already does one level referencing). Inlining format args prevents accidental `&` misuse.
Lazy type aliases: Diagostics: Detect bivariant ty params that are only used recursively
Follow-up to errs's #127871. Extends the logic to cover LTAs, too, not just ADTs.
This change only takes effect with the next-gen solver enabled as cycle errors like
the one we have here are fatal in the old solver. That's my explanation anyways.
r? compiler-errors
Use structured suggestions for unconstrained generic parameters on impl blocks
I did not deduplicate with `UnusedGenericParameter`, because in contrast to type declarations, just using a generic parameter in an impl isn't enough, it must be used with the right variance and not just as part of a projection.
`C-cmse-nonsecure-call`: improved error messages
tracking issue: #81391
issue for the error messages (partially implemented by this PR): #81347
related, in that it also deals with CMSE: https://github.com/rust-lang/rust/pull/127766
When using the `C-cmse-nonsecure-call` ABI, both the arguments and return value must be passed via registers. Previously, when violating this constraint, an ugly LLVM error would be shown. Now, the rust compiler itself will print a pretty message and link to more information.
Rollup of 7 pull requests
Successful merges:
- #121533 (Handle .init_array link_section specially on wasm)
- #127825 (Migrate `macos-fat-archive`, `manual-link` and `archive-duplicate-names` `run-make` tests to rmake)
- #127891 (Tweak suggestions when using incorrect type of enum literal)
- #127902 (`collect_tokens_trailing_token` cleanups)
- #127928 (Migrate `lto-smoke-c` and `link-path-order` `run-make` tests to rmake)
- #127935 (Change `binary_asm_labels` to only fire on x86 and x86_64)
- #127953 ([compiletest] Search *.a when getting dynamic libraries on AIX)
r? `@ghost`
`@rustbot` modify labels: rollup
Represent type-level consts with new-and-improved `hir::ConstArg`
### Summary
This is a step toward `min_generic_const_exprs`. We now represent all const
generic arguments using an enum that differentiates between const *paths*
(temporarily just bare const params) and arbitrary anon consts that may perform
computations. This will enable us to cleanly implement the `min_generic_const_args`
plan of allowing the use of generics in paths used as const args, while
disallowing their use in arbitrary anon consts. Here is a summary of the salient
aspects of this change:
- Add `current_def_id_parent` to `LoweringContext`
This is needed to track anon const parents properly once we implement
`ConstArgKind::Path` (which requires moving anon const def-creation
outside of `DefCollector`).
- Create `hir::ConstArgKind` enum with `Path` and `Anon` variants. Use it in the
existing `hir::ConstArg` struct, replacing the previous `hir::AnonConst` field.
- Use `ConstArg` for all instances of const args. Specifically, use it instead
of `AnonConst` for assoc item constraints, array lengths, and const param
defaults.
- Some `ast::AnonConst`s now have their `DefId`s created in
rustc_ast_lowering rather than `DefCollector`. This is because in some
cases they will end up becoming a `ConstArgKind::Path` instead, which
has no `DefId`. We have to solve this in a hacky way where we guess
whether the `AnonConst` could end up as a path const since we can't
know for sure until after name resolution (`N` could refer to a free
const or a nullary struct). If it has no chance as being a const
param, then we create a `DefId` in `DefCollector` -- otherwise we
decide during ast_lowering. This will have to be updated once all path
consts use `ConstArgKind::Path`.
- We explicitly use `ConstArgHasType` for array lengths, rather than
implicitly relying on anon const type feeding -- this is due to the
addition of `ConstArgKind::Path`.
- Some tests have their outputs changed, but the changes are for the
most part minor (including removing duplicate or almost-duplicate
errors). One test now ICEs, but it is for an incomplete, unstable
feature and is now tracked at https://github.com/rust-lang/rust/issues/127009.
### Followup items post-merge
- Use `ConstArgKind::Path` for all const paths, not just const params.
- Fix (no github dont close this issue) #127009
- If a path in generic args doesn't resolve as a type, try to resolve as a const
instead (do this in rustc_resolve). Then remove the special-casing from
`rustc_ast_lowering`, so that all params will automatically be lowered as
`ConstArgKind::Path`.
- (?) Consider making `const_evaluatable_unchecked` a hard error, or at least
trying it in crater
r? `@BoxyUwU`
Tweak suggestions when using incorrect type of enum literal
More accurate suggestions when writing wrong style of enum variant literal:
```
error[E0533]: expected value, found struct variant `E::Empty3`
--> $DIR/empty-struct-braces-expr.rs:18:14
|
LL | let e3 = E::Empty3;
| ^^^^^^^^^ not a value
|
help: you might have meant to create a new value of the struct
|
LL | let e3 = E::Empty3 {};
| ++
```
```
error[E0533]: expected value, found struct variant `E::V`
--> $DIR/struct-literal-variant-in-if.rs:10:13
|
LL | if x == E::V { field } {}
| ^^^^ not a value
|
help: you might have meant to create a new value of the struct
|
LL | if x == (E::V { field }) {}
| + +
```
```
error[E0618]: expected function, found enum variant `Enum::Unit`
--> $DIR/suggestion-highlights.rs:15:5
|
LL | Unit,
| ---- enum variant `Enum::Unit` defined here
...
LL | Enum::Unit();
| ^^^^^^^^^^--
| |
| call expression requires function
|
help: `Enum::Unit` is a unit enum variant, and does not take parentheses to be constructed
|
LL - Enum::Unit();
LL + Enum::Unit;
|
```
```
error[E0599]: no variant or associated item named `tuple` found for enum `Enum` in the current scope
--> $DIR/suggestion-highlights.rs:36:11
|
LL | enum Enum {
| --------- variant or associated item `tuple` not found for this enum
...
LL | Enum::tuple;
| ^^^^^ variant or associated item not found in `Enum`
|
help: there is a variant with a similar name
|
LL | Enum::Tuple(/* i32 */);
| ~~~~~~~~~~~~~~~~;
|
```
Tweak "field not found" suggestion when giving struct literal for tuple struct type:
```
error[E0560]: struct `S` has no field named `x`
--> $DIR/nested-non-tuple-tuple-struct.rs:8:19
|
LL | pub struct S(f32, f32);
| - `S` defined here
...
LL | let _x = (S { x: 1.0, y: 2.0 }, S { x: 3.0, y: 4.0 });
| ^ field does not exist
|
help: `S` is a tuple struct, use the appropriate syntax
|
LL | let _x = (S(/* f32 */, /* f32 */), S { x: 3.0, y: 4.0 });
| ~~~~~~~~~~~~~~~~~~~~~~~
Handle .init_array link_section specially on wasm
Given that wasm-ld now has support for [.init_array](8f2bd8ae68/llvm/lib/MC/WasmObjectWriter.cpp (L1852)), it appears we can easily implement that section by falling through to the normal path rather than taking the typical custom_section path for wasm.
The wasm-ld appears to have a bunch of limitations. Only one static with the `link_section` in a crate or else you hit the fatal error in the link above "only one .init_array section fragment supported". They do not get merged.
You can still call multiple constructors by setting it to an array.
```
unsafe extern "C" fn ctor() {
println!("foo");
}
#[used]
#[link_section = ".init_array"]
static FOO: [unsafe extern "C" fn(); 2] = [ctor, ctor];
```
Another issue appears to be that if crate *A* depends on crate *B*, but *A* doesn't call any symbols from *B* and *B* doesn't `#[export_name = ...]` any symbols, then crate *B*'s constructor will not be called. The workaround to this is to provide an exported symbol in crate *B*.
Use more accurate span for `addr_of!` suggestion
Use a multipart suggestion instead of a single whole-span replacement:
```
error[E0796]: creating a shared reference to a mutable static
--> $DIR/reference-to-mut-static-unsafe-fn.rs:10:18
|
LL | let _y = &X;
| ^^ shared reference to mutable static
|
= note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
help: use `addr_of!` instead to create a raw pointer
|
LL | let _y = addr_of!(X);
| ~~~~~~~~~ +
```
Mention that type parameters are used recursively on bivariance error
Right now when a type parameter is used recursively, even with indirection (so it has a finite size) we say that the type parameter is unused:
```
struct B<T>(Box<B<T>>);
```
This is confusing, because the type parameter is *used*, it just doesn't have its variance constrained. This PR tweaks that message to mention that it must be used *non-recursively*.
Not sure if we should actually mention "variance" here, but also I'd somewhat prefer we don't keep the power users in the dark w.r.t the real underlying issue, which is that the variance isn't constrained. That technical detail is reserved for a note, though.
cc `@fee1-dead`
Fixes#118976Fixes#26283Fixes#53191Fixes#105740Fixes#110466
Use a multipart suggestion instead of a single whole-span replacement:
```
error[E0796]: creating a shared reference to a mutable static
--> $DIR/reference-to-mut-static-unsafe-fn.rs:10:18
|
LL | let _y = &X;
| ^^ shared reference to mutable static
|
= note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
help: use `addr_of!` instead to create a raw pointer
|
LL | let _y = addr_of!(X);
| ~~~~~~~~~ +
```
```
error[E0533]: expected value, found struct variant `E::Empty3`
--> $DIR/empty-struct-braces-expr.rs:18:14
|
LL | let e3 = E::Empty3;
| ^^^^^^^^^ not a value
|
help: you might have meant to create a new value of the struct
|
LL | let e3 = E::Empty3 {};
| ++
```
```
error[E0533]: expected value, found struct variant `E::V`
--> $DIR/struct-literal-variant-in-if.rs:10:13
|
LL | if x == E::V { field } {}
| ^^^^ not a value
|
help: you might have meant to create a new value of the struct
|
LL | if x == (E::V { field }) {}
| + +
```
```
error[E0618]: expected function, found enum variant `Enum::Unit`
--> $DIR/suggestion-highlights.rs:15:5
|
LL | Unit,
| ---- enum variant `Enum::Unit` defined here
...
LL | Enum::Unit();
| ^^^^^^^^^^--
| |
| call expression requires function
|
help: `Enum::Unit` is a unit enum variant, and does not take parentheses to be constructed
|
LL - Enum::Unit();
LL + Enum::Unit;
|
```
```
error[E0599]: no variant or associated item named `tuple` found for enum `Enum` in the current scope
--> $DIR/suggestion-highlights.rs:36:11
|
LL | enum Enum {
| --------- variant or associated item `tuple` not found for this enum
...
LL | Enum::tuple;
| ^^^^^ variant or associated item not found in `Enum`
|
help: there is a variant with a similar name
|
LL | Enum::Tuple(/* i32 */);
| ~~~~~~~~~~~~~~~~;
|
```
More accurate span for type parameter suggestion
After:
```
error[E0229]: associated item constraints are not allowed here
--> $DIR/impl-block-params-declared-in-wrong-spot-issue-113073.rs:3:10
|
LL | impl Foo<T: Default> for String {}
| ^^^^^^^^^^ associated item constraint not allowed here
|
help: declare the type parameter right after the `impl` keyword
|
LL - impl Foo<T: Default> for String {}
LL + impl<T: Default> Foo<T> for String {}
|
```
Before:
```
error[E0229]: associated item constraints are not allowed here
--> $DIR/impl-block-params-declared-in-wrong-spot-issue-113073.rs:3:10
|
LL | impl Foo<T: Default> for String {}
| ^^^^^^^^^^ associated item constraint not allowed here
|
help: declare the type parameter right after the `impl` keyword
|
LL | impl<T: Default> Foo<T> for String {}
| ++++++++++++ ~
```
Fix associated item removal suggestion
We were previously telling people to write what was already there, instead of removal (treating it as a `help`). We now properly suggest to remove the code that needs to be removed.
```
error[E0229]: associated item constraints are not allowed here
--> $DIR/E0229.rs:13:25
|
LL | fn baz<I>(x: &<I as Foo<A = Bar>>::A) {}
| ^^^^^^^ associated item constraint not allowed here
|
help: consider removing this associated item binding
|
LL - fn baz<I>(x: &<I as Foo<A = Bar>>::A) {}
LL + fn baz<I>(x: &<I as Foo>::A) {}
|
```
After:
```
error[E0229]: associated item constraints are not allowed here
--> $DIR/impl-block-params-declared-in-wrong-spot-issue-113073.rs:3:10
|
LL | impl Foo<T: Default> for String {}
| ^^^^^^^^^^ associated item constraint not allowed here
|
help: declare the type parameter right after the `impl` keyword
|
LL - impl Foo<T: Default> for String {}
LL + impl<T: Default> Foo<T> for String {}
|
```
Before:
```
error[E0229]: associated item constraints are not allowed here
--> $DIR/impl-block-params-declared-in-wrong-spot-issue-113073.rs:3:10
|
LL | impl Foo<T: Default> for String {}
| ^^^^^^^^^^ associated item constraint not allowed here
|
help: declare the type parameter right after the `impl` keyword
|
LL | impl<T: Default> Foo<T> for String {}
| ++++++++++++ ~
```
We were previously telling people to write what was already there, instead of removal.
```
error[E0229]: associated item constraints are not allowed here
--> $DIR/E0229.rs:13:25
|
LL | fn baz<I>(x: &<I as Foo<A = Bar>>::A) {}
| ^^^^^^^ associated item constraint not allowed here
|
help: consider removing this associated item binding
|
LL - fn baz<I>(x: &<I as Foo<A = Bar>>::A) {}
LL + fn baz<I>(x: &<I as Foo>::A) {}
|
```
This is a very large commit since a lot needs to be changed in order to
make the tests pass. The salient changes are:
- `ConstArgKind` gets a new `Path` variant, and all const params are now
represented using it. Non-param paths still use `ConstArgKind::Anon`
to prevent this change from getting too large, but they will soon use
the `Path` variant too.
- `ConstArg` gets a distinct `hir_id` field and its own variant in
`hir::Node`. This affected many parts of the compiler that expected
the parent of an `AnonConst` to be the containing context (e.g., an
array repeat expression). They have been changed to check the
"grandparent" where necessary.
- Some `ast::AnonConst`s now have their `DefId`s created in
rustc_ast_lowering rather than `DefCollector`. This is because in some
cases they will end up becoming a `ConstArgKind::Path` instead, which
has no `DefId`. We have to solve this in a hacky way where we guess
whether the `AnonConst` could end up as a path const since we can't
know for sure until after name resolution (`N` could refer to a free
const or a nullary struct). If it has no chance as being a const
param, then we create a `DefId` in `DefCollector` -- otherwise we
decide during ast_lowering. This will have to be updated once all path
consts use `ConstArgKind::Path`.
- We explicitly use `ConstArgHasType` for array lengths, rather than
implicitly relying on anon const type feeding -- this is due to the
addition of `ConstArgKind::Path`.
- Some tests have their outputs changed, but the changes are for the
most part minor (including removing duplicate or almost-duplicate
errors). One test now ICEs, but it is for an incomplete, unstable
feature and is now tracked at #127009.
Automatically taint when reporting errors from ItemCtxt
This isn't very robust yet, as you need to use `itemctxt.dcx()` instead of `tcx.dcx()` for it to take effect, but it's at least more convenient than sprinkling `set_tainted_by_errors` calls in individual places.
based on https://github.com/rust-lang/rust/pull/127357
r? `@fmease`
Move trait selection error reporting to its own top-level module
This effectively moves `rustc_trait_selection::traits::error_reporting` to `rustc_trait_selection::error_reporting::traits`. There are only a couple of actual changes to the code, like moving the `pretty_impl_header` fn out of the specialization module for privacy reasons.
This is quite pointless on its own, but having `error_reporting` as a top-level module in `rustc_trait_selection` is very important to make sure we have a meaningful file structure for when we move **type** error reporting (and region error reporting, with which it's incredibly entangled currently) into `rustc_trait_selection`. I've opened a tracking issue here: #127492
r? lcnr
Uplift elaboration into `rustc_type_ir`
Allows us to deduplicate and consolidate elaboration (including these stupid elaboration duplicate fns i added for pretty printing like 3 years ago) so I'm pretty hyped about this change :3
r? lcnr
Make `can_eq` process obligations (almost) everywhere
Move `can_eq` to an extension trait on `InferCtxt` in `rustc_trait_selection`, and change it so that it processes obligations. This should strengthen it to be more accurate in some cases, but is most important for the new trait solver which delays relating aliases to `AliasRelate` goals. Without this, we always basically just return true when passing aliases to `can_eq`, which can lead to weird errors, for example #127149.
I'm not actually certain if we should *have* `can_eq` be called on the good path. In cases where we need `can_eq`, we probably should just be using a regular probe.
Fixes#127149
r? lcnr
Remove a use of `StructuredDiag`, which is incompatible with automatic error tainting and error translations
fixes#127219
I want to remove all of `StructuredDiag`, but it's a bit more involved as it is also used from the `ItemCtxt`, which doesn't support tainting yet.
Introduce a `rustc_` attribute to dump all the `DefId` parents of a `DefId`
We've run into a bunch of issues with anon consts having the wrong generics and it would have been incredibly helpful to be able to quickly slap a `rustc_` attribute to check what `tcx.parent(` will return on the relevant DefIds.
I wasn't sure of a better way to make this work for anon consts than requiring the attribute to be on the enclosing item and then walking the inside of it to look for any anon consts. This particular method will honestly break at some point when we stop having a `DefId` available for anon consts in hir but that's for another day...
r? ``@compiler-errors``
Rollup of 9 pull requests
Successful merges:
- #123237 (Various rustc_codegen_ssa cleanups)
- #126960 (Improve error message in tidy)
- #127002 (Implement `x perf` as a separate tool)
- #127081 (Add a run-make test that LLD is not being used by default on the x64 beta/stable channel)
- #127106 (Improve unsafe extern blocks diagnostics)
- #127110 (Fix a error suggestion for E0121 when using placeholder _ as return types on function signature.)
- #127114 (fix: prefer `(*p).clone` to `p.clone` if the `p` is a raw pointer)
- #127118 (Show `used attribute`'s kind for user when find it isn't applied to a `static` variable.)
- #127122 (Remove uneccessary condition in `div_ceil`)
r? `@ghost`
`@rustbot` modify labels: rollup
Fix a error suggestion for E0121 when using placeholder _ as return types on function signature.
Recommit after refactoring based on comment:
https://github.com/rust-lang/rust/pull/126017#issuecomment-2189149361
But when changing return type's lifetime to `ReError` will affect the subsequent borrow check process and cause test11 in typeck_type_placeholder_item.rs to lost E0515 message.
```rust
fn test11(x: &usize) -> &_ {
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
&x //~ ERROR cannot return reference to function parameter(this E0515 msg will disappear)
}
```
fixes#125488
r? ``@pnkfelix``
Implement new effects desugaring
cc `@rust-lang/project-const-traits.` Will write down notes once I have finished.
* [x] See if we want `T: Tr` to desugar into `T: Tr, T::Effects: Compat<true>`
* [x] Fix ICEs on `type Assoc: ~const Tr` and `type Assoc<T: ~const Tr>`
* [ ] add types and traits to minicore test
* [ ] update rustc-dev-guide
Fixes#119717Fixes#123664Fixes#124857Fixes#126148
Recommit after refactoring based on comment:
https://github.com/rust-lang/rust/pull/126017#issuecomment-2189149361
But when changing return type's lifetime to `ReError` will affect the subsequent borrow check process and cause test11 in typeck_type_placeholder_item.rs to lost E0515 message.
```rust
fn test11(x: &usize) -> &_ {
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
&x //~ ERROR cannot return reference to function parameter(this E0515 msg will disappear)
}
```
Don't ICE during RPITIT refinement checking for resolution errors after normalization
#126670 shows a case where resolution errors after normalization can happen during RPITIT refinement checking. Our tests didn't reach this path before, and we explicitly ICEd until we had a test. We can now delay a bug since we're sure it is reachable and have the test from the isue.
The comment I added likely still needs more expert wordsmithing.
r? ``@compiler-errors`` who's making me work during vacation (j/k).
Fixes#126670
Remove use of const traits (and `feature(effects)`) from stdlib
The current uses are already unsound because they are using non-const impls in const contexts. We can reintroduce them by reverting the commit in this PR, after #120639 lands.
Also, make `effects` an incomplete feature.
cc `@rust-lang/project-const-traits`
r? `@compiler-errors`
Clean up some comments near `use` declarations
#125443 will reformat all `use` declarations in the repository. There are a few edge cases involving comments on `use` declarations that require care. This PR cleans up some clumsy comment cases, taking us a step closer to #125443 being able to merge.
r? ``@lqd``
Actually taint InferCtxt when a fulfillment error is emitted
And avoid checking the global error counter
fixes#122044fixes#123255fixes#123276fixes#125799
Place tail expression behind terminating scope
This PR implements #123739 so that we can do further experiments in nightly.
A little rewrite has been applied to `for await` lowering. It was previously `unsafe { Pin::unchecked_new(into_async_iter(..)) }`. Under the edition 2024 rule, however, `into_async_iter` gets dropped at the end of the `unsafe` block. This presumably the first Edition 2024 migration rule goes by hoisting `into_async_iter(..)` into `match` one level above, so it now looks like the following.
```rust
match into_async_iter($iter_expr) {
ref mut iter => match unsafe { Pin::unchecked_new(iter) } {
...
}
}
```
Add `f16` and `f128` inline ASM support for `x86` and `x86-64`
This PR adds `f16` and `f128` input and output support to inline ASM on `x86` and `x86-64`. `f16` vector sizes are taken from [here](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html).
Relevant issue: #125398
Tracking issue: #116909
``@rustbot`` label +F-f16_and_f128
`E0229`: Suggest Moving Type Constraints to Type Parameter Declaration
Fixes#113073
This PR suggests `impl<T: Bound> Trait<T> for Foo` when finding `impl Trait<T: Bound> for Foo`. Tangentially, it also improves a handful of other error messages.
It accomplishes this in two steps:
1. Check if constrained arguments and parameter names appear in the same order and delay emitting "incorrect number of generic arguments" error because it can be confusing for the programmer to see `0 generic arguments provided` when there are `n` constrained generic arguments.
2. Inside `E0229`, suggest declaring the type parameter right after the `impl` keyword by finding the relevant impl block's span for type parameter declaration. This also handles lifetime declarations correctly.
Also, the multi part suggestion doesn't use the fluent error mechanism because translating all the errors to fluent style feels outside the scope of this PR. I will handle it in a separate PR if this gets approved.
Fix outdated predacates_of.rs comments
<!--
If this PR is related to an unstable feature or an otherwise tracked effort,
please link to the relevant tracking issue here. If you don't know of a related
tracking issue or there are none, feel free to ignore this.
This PR will get automatically assigned to a reviewer. In case you would like
a specific user to review your work, you can assign it to them by using
r? <reviewer name>
-->
Provide correct parent for nested anon const
Fixes#126147
99% of this PR is just comments explaining what the issue is.
`tcx.parent(` and `hir().get_parent_item(` give different results as the hir owner for all the hir of anon consts is the enclosing function. I didn't attempt to change that as being a hir owner requires a `DefId` and long term we want to stop creating anon consts' `DefId`s before hir ty lowering.
So i just opted to change `generics_of` to use `tcx.parent` to get the parent for `AnonConst`'s. I'm not entirely sure about this being what we want, it does seem weird that we have two ways of getting the parent of an `AnonConst` and they both give different results.
Alternatively we could just go ahead and make `const_evaluatable_unchecked` a hard error and stop providing generics to repeat exprs. Then this isn't an issue. (The FCW has been around for almost 4 years now)
r? ````@compiler-errors````
Rollup of 16 pull requests
Successful merges:
- #123374 (DOC: Add FFI example for slice::from_raw_parts())
- #124514 (Recommend to never display zero disambiguators when demangling v0 symbols)
- #125978 (Cleanup: HIR ty lowering: Consolidate the places that do assoc item probing & access checking)
- #125980 (Nvptx remove direct passmode)
- #126187 (For E0277 suggest adding `Result` return type for function when using QuestionMark `?` in the body.)
- #126210 (docs(core): make more const_ptr doctests assert instead of printing)
- #126249 (Simplify `[T; N]::try_map` signature)
- #126256 (Add {{target}} substitution to compiletest)
- #126263 (Make issue-122805.rs big endian compatible)
- #126281 (set_env: State the conclusion upfront)
- #126286 (Make `storage-live.rs` robust against rustc internal changes.)
- #126287 (Update a cranelift patch file for formatting changes.)
- #126301 (Use `tidy` to sort crate attributes for all compiler crates.)
- #126305 (Make PathBuf less Ok with adding UTF-16 then `into_string`)
- #126310 (Migrate run make prefer rlib)
- #126314 (fix RELEASES: we do not support upcasting to auto traits)
r? `@ghost`
`@rustbot` modify labels: rollup
Use `tidy` to sort crate attributes for all compiler crates.
We already do this for a number of crates, e.g. `rustc_middle`, `rustc_span`, `rustc_metadata`, `rustc_span`, `rustc_errors`.
For the ones we don't, in many cases the attributes are a mess.
- There is no consistency about order of attribute kinds (e.g. `allow`/`deny`/`feature`).
- Within attribute kind groups (e.g. the `feature` attributes), sometimes the order is alphabetical, and sometimes there is no particular order.
- Sometimes the attributes of a particular kind aren't even grouped all together, e.g. there might be a `feature`, then an `allow`, then another `feature`.
This commit extends the existing sorting to all compiler crates, increasing consistency. If any new attribute line is added there is now only one place it can go -- no need for arbitrary decisions.
Exceptions:
- `rustc_log`, `rustc_next_trait_solver` and `rustc_type_ir_macros`, because they have no crate attributes.
- `rustc_codegen_gcc`, because it's quasi-external to rustc (e.g. it's ignored in `rustfmt.toml`).
r? `@davidtwco`
Cleanup: HIR ty lowering: Consolidate the places that do assoc item probing & access checking
Use `probe_assoc_item` (for hygienically probing an assoc item and checking if it's accessible wrt. visibility and stability) for assoc item constraints, too, not just for assoc type paths and make the privacy error translatable.
We already do this for a number of crates, e.g. `rustc_middle`,
`rustc_span`, `rustc_metadata`, `rustc_span`, `rustc_errors`.
For the ones we don't, in many cases the attributes are a mess.
- There is no consistency about order of attribute kinds (e.g.
`allow`/`deny`/`feature`).
- Within attribute kind groups (e.g. the `feature` attributes),
sometimes the order is alphabetical, and sometimes there is no
particular order.
- Sometimes the attributes of a particular kind aren't even grouped
all together, e.g. there might be a `feature`, then an `allow`, then
another `feature`.
This commit extends the existing sorting to all compiler crates,
increasing consistency. If any new attribute line is added there is now
only one place it can go -- no need for arbitrary decisions.
Exceptions:
- `rustc_log`, `rustc_next_trait_solver` and `rustc_type_ir_macros`,
because they have no crate attributes.
- `rustc_codegen_gcc`, because it's quasi-external to rustc (e.g. it's
ignored in `rustfmt.toml`).
Revert: create const block bodies in typeck via query feeding
as per the discussion in https://github.com/rust-lang/rust/pull/125806#discussion_r1622563948
It was a mistake to try to shoehorn const blocks and some specific anon consts into the same box and feed them during typeck. It turned out not simplifying anything (my hope was that we could feed `type_of` to start avoiding the huge HIR matcher, but that didn't work out), but instead making a few things more fragile.
reverts the const-block-specific parts of https://github.com/rust-lang/rust/pull/124650
`@bors` rollup=never had a small perf impact previously
fixes https://github.com/rust-lang/rust/issues/125846
r? `@compiler-errors`
`ct_infer` and `lower_ty` will correctly result in an error constant or type respectively, as they go through a `HirTyLowerer` method (just like `HirTyLowerer::allow_infer` is a method implemented by both implementors
Silence follow-up errors directly based on error types and regions
During type_of, we used to just return an error type if there were any errors encountered. This is problematic, because it means a struct declared as `struct Foo<'static>` will end up not finding any inherent or trait impls because those impl blocks' `Self` type will be `{type error}` instead of `Foo<'re_error>`. Now it's the latter, silencing nonsensical follow-up errors about `Foo` not having any methods.
Unfortunately that now allows for new follow-up errors, because borrowck treats `'re_error` as `'static`, causing nonsensical errors about non-error lifetimes not outliving `'static`. So what I also did was to just strip all outlives bounds that borrowck found, thus never letting it check them. There are probably more nuanced ways to do this, but I worried there would be other nonsensical errors if some outlives bounds were missing. Also from the test changes, it looked like an improvement everywhere.
Align `Term` methods with `GenericArg` methods, add `Term::expect_*`
* `Term::ty` -> `Term::as_type`.
* `Term::ct` -> `Term::as_const`.
* Adds `Term::expect_type` and `Term::expect_const`, and uses them in favor of `.ty().unwrap()`, etc.
I could also shorten these to `as_ty` and then do `GenericArg::as_ty` as well, but I do think the `as_` is important to signal that this is a conversion method, and not a getter, like `Const::ty` is.
r? types
Make `WHERE_CLAUSES_OBJECT_SAFETY` a regular object safety violation
#### The issue
In #50781, we have known about unsound `where` clauses in function arguments:
```rust
trait Impossible {}
trait Foo {
fn impossible(&self)
where
Self: Impossible;
}
impl Foo for &() {
fn impossible(&self)
where
Self: Impossible,
{}
}
// `where` clause satisfied for the object, meaning that the function now *looks* callable.
impl Impossible for dyn Foo {}
fn main() {
let x: &dyn Foo = &&();
x.impossible();
}
```
... which currently segfaults at runtime because we try to call a method in the vtable that doesn't exist. :(
#### What did u change
This PR removes the `WHERE_CLAUSES_OBJECT_SAFETY` lint and instead makes it a regular object safety violation. I choose to make this into a hard error immediately rather than a `deny` because of the time that has passed since this lint was authored, and the single (1) regression (see below).
That means that it's OK to mention `where Self: Trait` where clauses in your trait, but making such a trait into a `dyn Trait` object will report an object safety violation just like `where Self: Sized`, etc.
```rust
trait Impossible {}
trait Foo {
fn impossible(&self)
where
Self: Impossible; // <~ This definition is valid, just not object-safe.
}
impl Foo for &() {
fn impossible(&self)
where
Self: Impossible,
{}
}
fn main() {
let x: &dyn Foo = &&(); // <~ THIS is where we emit an error.
}
```
#### Regressions
From a recent crater run, there's only one crate that relies on this behavior: https://github.com/rust-lang/rust/pull/124305#issuecomment-2122381740. The crate looks unmaintained and there seems to be no dependents.
#### Further
We may later choose to relax this (e.g. when the where clause is implied by the supertraits of the trait or something), but this is not something I propose to do in this FCP.
For example, given:
```
trait Tr {
fn f(&self) where Self: Blanket;
}
impl<T: ?Sized> Blanket for T {}
```
Proving that some placeholder `S` implements `S: Blanket` would be sufficient to prove that the same (blanket) impl applies for both `Concerete: Blanket` and `dyn Trait: Blanket`.
Repeating here that I don't think we need to implement this behavior right now.
----
r? lcnr
Use parenthetical notation for `Fn` traits
Always use the `Fn(T) -> R` format when printing closure traits instead of `Fn<(T,), Output = R>`.
Address #67100:
```
error[E0277]: expected a `Fn()` closure, found `F`
--> file.rs:6:13
|
6 | call_fn(f)
| ------- ^ expected an `Fn()` closure, found `F`
| |
| required by a bound introduced by this call
|
= note: wrap the `F` in a closure with no arguments: `|| { /* code */ }`
note: required by a bound in `call_fn`
--> file.rs:1:15
|
1 | fn call_fn<F: Fn() -> ()>(f: &F) {
| ^^^^^^^^^^ required by this bound in `call_fn`
help: consider further restricting this bound
|
5 | fn call_any<F: std::any::Any + Fn()>(f: &F) {
| ++++++
```
Implement `needs_async_drop` in rustc and optimize async drop glue
This PR expands on #121801 and implements `Ty::needs_async_drop` which works almost exactly the same as `Ty::needs_drop`, which is needed for #123948.
Also made compiler's async drop code to look more like compiler's regular drop code, which enabled me to write an optimization where types which do not use `AsyncDrop` can simply forward async drop glue to `drop_in_place`. This made size of the async block from the [async_drop test](67980dd6fb/tests/ui/async-await/async-drop.rs) to decrease by 12%.
Fold item bounds before proving them in `check_type_bounds` in new solver
Vaguely confident that this is sufficient to prevent rust-lang/trait-system-refactor-initiative#46 and rust-lang/trait-system-refactor-initiative#62.
This is not the "correct" solution, but will probably suffice until coinduction, at which point we implement the right solution (`check_type_bounds` must prove `Assoc<...> alias-eq ConcreteType`, normalizing requires proving item bounds).
r? lcnr
Rename HIR `TypeBinding` to `AssocItemConstraint` and related cleanup
Rename `hir::TypeBinding` and `ast::AssocConstraint` to `AssocItemConstraint` and update all items and locals using the old terminology.
Motivation: The terminology *type binding* is extremely outdated. "Type bindings" not only include constraints on associated *types* but also on associated *constants* (feature `associated_const_equality`) and on RPITITs of associated *functions* (feature `return_type_notation`). Hence the word *item* in the new name. Furthermore, the word *binding* commonly refers to a mapping from a binder/identifier to a "value" for some definition of "value". Its use in "type binding" made sense when equality constraints (e.g., `AssocTy = Ty`) were the only kind of associated item constraint. Nowadays however, we also have *associated type bounds* (e.g., `AssocTy: Bound`) for which the term *binding* doesn't make sense.
---
Old terminology (HIR, rustdoc):
```
`TypeBinding`: (associated) type binding
├── `Constraint`: associated type bound
└── `Equality`: (associated) equality constraint (?)
├── `Ty`: (associated) type binding
└── `Const`: associated const equality (constraint)
```
Old terminology (AST, abbrev.):
```
`AssocConstraint`
├── `Bound`
└── `Equality`
├── `Ty`
└── `Const`
```
New terminology (AST, HIR, rustdoc):
```
`AssocItemConstraint`: associated item constraint
├── `Bound`: associated type bound
└── `Equality`: associated item equality constraint OR associated item binding (for short)
├── `Ty`: associated type equality constraint OR associated type binding (for short)
└── `Const`: associated const equality constraint OR associated const binding (for short)
```
r? compiler-errors
Make `body_owned_by` return the `Body` instead of just the `BodyId`
fixes#125677
Almost all `body_owned_by` callers immediately called `body`, too, so just return `Body` directly.
This makes the inline-const query feeding more robust, as all calls to `body_owned_by` will now yield a body for inline consts, too.
I have not yet figured out a good way to make `tcx.hir().body()` return an inline-const body, but that can be done as a follow-up
Always use the `Fn(T) -> R` format when printing closure traits instead of `Fn<(T,), Output = R>`.
Fix#67100:
```
error[E0277]: expected a `Fn()` closure, found `F`
--> file.rs:6:13
|
6 | call_fn(f)
| ------- ^ expected an `Fn()` closure, found `F`
| |
| required by a bound introduced by this call
|
= note: wrap the `F` in a closure with no arguments: `|| { /* code */ }`
note: required by a bound in `call_fn`
--> file.rs:1:15
|
1 | fn call_fn<F: Fn() -> ()>(f: &F) {
| ^^^^^^^^^^ required by this bound in `call_fn`
help: consider further restricting this bound
|
5 | fn call_any<F: std::any::Any + Fn()>(f: &F) {
| ++++++
```
Uplift `EarlyBinder` into `rustc_type_ir`
We also need to give `EarlyBinder` a `'tcx` param, so that we can carry the `Interner` in the `EarlyBinder` too. This is necessary because otherwise we have an unconstrained `I: Interner` parameter in many of the `EarlyBinder`'s inherent impls.
I also generally think that this is desirable to have, in case we later want to track some state in the `EarlyBinder`.
r? lcnr
[perf] Delay the construction of early lint diag structs
Attacks some of the perf regressions from https://github.com/rust-lang/rust/pull/124417#issuecomment-2123700666.
See individual commits for details. The first three commits are not strictly necessary.
However, the 2nd one (06bc4fc671, *Remove `LintDiagnostic::msg`*) makes the main change way nicer to implement.
It's also pretty sweet on its own if I may say so myself.
Remove `DefId` from `EarlyParamRegion`
Currently we represent usages of `Region` parameters via the `ReEarlyParam` or `ReLateParam` variants. The `ReEarlyParam` is effectively equivalent to `TyKind::Param` and `ConstKind::Param` (i.e. it stores a `Symbol` and a `u32` index) however it also stores a `DefId` for the definition of the lifetime parameter.
This was used in roughly two places:
- Borrowck diagnostics instead of threading the appropriate `body_id` down to relevant locations. Interestingly there were already some places that had to pass down a `DefId` manually.
- Some opaque type checking logic was using the `DefId` field to track captured lifetimes
I've split this PR up into a commit for generate rote changes to diagnostics code to pass around a `DefId` manually everywhere, and another commit for the opaque type related changes which likely require more careful review as they might change the semantics of lints/errors.
Instead of manually passing the `DefId` around everywhere I previously tried to bundle it in with `TypeErrCtxt` but ran into issues with some call sites of `infcx.err_ctxt` being unable to provide a `DefId`, particularly places involved with trait solving and normalization. It might be worth investigating adding some new wrapper type to pass this around everywhere but I think this might be acceptable for now.
This pr also has the effect of reducing the size of `EarlyParamRegion` from 16 bytes -> 8 bytes. I wouldn't expect this to have any direct performance improvement however, other variants of `RegionKind` over `8` bytes are all because they contain a `BoundRegionKind` which is, as far as I know, mostly there for diagnostics. If we're ever able to remove this it would shrink the `RegionKind` type from `24` bytes to `12` (and with clever bit packing we might be able to get it to `8` bytes). I am curious what the performance impact would be of removing interning of `Region`'s if we ever manage to shrink `RegionKind` that much.
Sidenote: by removing the `DefId` the `Debug` output for `Region` has gotten significantly nicer. As an example see this opaque type debug print before vs after this PR:
`Opaque(DefId(0:13 ~ impl_trait_captures[aeb9]::foo::{opaque#0}), [DefId(0:9 ~ impl_trait_captures[aeb9]::foo::'a)_'a/#0, T, DefId(0:9 ~ impl_trait_captures[aeb9]::foo::'a)_'a/#0])`
`Opaque(DefId(0:13 ~ impl_trait_captures[aeb9]::foo::{opaque#0}), ['a/#0, T, 'a/#0])`
r? `@compiler-errors` (I would like someone who understands the opaque type setup to atleast review the type system commit, but the rest is likely reviewable by anyone)
Expand `for_loops_over_fallibles` lint to lint on fallibles behind references.
Extends the scope of the (warn-by-default) lint `for_loops_over_fallibles` from just `for _ in x` where `x: Option<_>/Result<_, _>` to also cover `x: &(mut) Option<_>/Result<_>`
```rs
fn main() {
// Current lints
for _ in Some(42) {}
for _ in Ok::<_, i32>(42) {}
// New lints
for _ in &Some(42) {}
for _ in &mut Some(42) {}
for _ in &Ok::<_, i32>(42) {}
for _ in &mut Ok::<_, i32>(42) {}
// Should not lint
for _ in Some(42).into_iter() {}
for _ in Some(42).iter() {}
for _ in Some(42).iter_mut() {}
for _ in Ok::<_, i32>(42).into_iter() {}
for _ in Ok::<_, i32>(42).iter() {}
for _ in Ok::<_, i32>(42).iter_mut() {}
}
```
<details><summary><code>cargo build</code> diff</summary>
```diff
diff --git a/old.out b/new.out
index 84215aa..ca195a7 100644
--- a/old.out
+++ b/new.out
`@@` -1,33 +1,93 `@@`
warning: for loop over an `Option`. This is more readably written as an `if let` statement
--> src/main.rs:3:14
|
3 | for _ in Some(42) {}
| ^^^^^^^^
|
= note: `#[warn(for_loops_over_fallibles)]` on by default
help: to check pattern in a loop use `while let`
|
3 | while let Some(_) = Some(42) {}
| ~~~~~~~~~~~~~~~ ~~~
help: consider using `if let` to clear intent
|
3 | if let Some(_) = Some(42) {}
| ~~~~~~~~~~~~ ~~~
warning: for loop over a `Result`. This is more readably written as an `if let` statement
--> src/main.rs:4:14
|
4 | for _ in Ok::<_, i32>(42) {}
| ^^^^^^^^^^^^^^^^
|
help: to check pattern in a loop use `while let`
|
4 | while let Ok(_) = Ok::<_, i32>(42) {}
| ~~~~~~~~~~~~~ ~~~
help: consider using `if let` to clear intent
|
4 | if let Ok(_) = Ok::<_, i32>(42) {}
| ~~~~~~~~~~ ~~~
-warning: `for-loops-over-fallibles` (bin "for-loops-over-fallibles") generated 2 warnings
- Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.04s
+warning: for loop over a `&Option`. This is more readably written as an `if let` statement
+ --> src/main.rs:7:14
+ |
+7 | for _ in &Some(42) {}
+ | ^^^^^^^^^
+ |
+help: to check pattern in a loop use `while let`
+ |
+7 | while let Some(_) = &Some(42) {}
+ | ~~~~~~~~~~~~~~~ ~~~
+help: consider using `if let` to clear intent
+ |
+7 | if let Some(_) = &Some(42) {}
+ | ~~~~~~~~~~~~ ~~~
+
+warning: for loop over a `&mut Option`. This is more readably written as an `if let` statement
+ --> src/main.rs:8:14
+ |
+8 | for _ in &mut Some(42) {}
+ | ^^^^^^^^^^^^^
+ |
+help: to check pattern in a loop use `while let`
+ |
+8 | while let Some(_) = &mut Some(42) {}
+ | ~~~~~~~~~~~~~~~ ~~~
+help: consider using `if let` to clear intent
+ |
+8 | if let Some(_) = &mut Some(42) {}
+ | ~~~~~~~~~~~~ ~~~
+
+warning: for loop over a `&Result`. This is more readably written as an `if let` statement
+ --> src/main.rs:9:14
+ |
+9 | for _ in &Ok::<_, i32>(42) {}
+ | ^^^^^^^^^^^^^^^^^
+ |
+help: to check pattern in a loop use `while let`
+ |
+9 | while let Ok(_) = &Ok::<_, i32>(42) {}
+ | ~~~~~~~~~~~~~ ~~~
+help: consider using `if let` to clear intent
+ |
+9 | if let Ok(_) = &Ok::<_, i32>(42) {}
+ | ~~~~~~~~~~ ~~~
+
+warning: for loop over a `&mut Result`. This is more readably written as an `if let` statement
+ --> src/main.rs:10:14
+ |
+10 | for _ in &mut Ok::<_, i32>(42) {}
+ | ^^^^^^^^^^^^^^^^^^^^^
+ |
+help: to check pattern in a loop use `while let`
+ |
+10 | while let Ok(_) = &mut Ok::<_, i32>(42) {}
+ | ~~~~~~~~~~~~~ ~~~
+help: consider using `if let` to clear intent
+ |
+10 | if let Ok(_) = &mut Ok::<_, i32>(42) {}
+ | ~~~~~~~~~~ ~~~
+
+warning: `for-loops-over-fallibles` (bin "for-loops-over-fallibles") generated 6 warnings
+ Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.02s
```
</details>
-----
Question:
* ~~Currently, the article `an` is used for `&Option`, and `&mut Option` in the lint diagnostic, since that's what `Option` uses. Is this okay or should it be changed? (likewise, `a` is used for `&Result` and `&mut Result`)~~ The article `a` is used for `&Option`, `&mut Option`, `&Result`, `&mut Result` and (as before) `Result`. Only `Option` uses `an` (as before).
`@rustbot` label +A-lint
* instead simply set the primary message inside the lint decorator functions
* it used to be this way before [#]101986 which introduced `msg` to prevent
good path delayed bugs (which no longer exist) from firing under certain
circumstances when lints were suppressed / silenced
* this is no longer necessary for various reasons I presume
* it shaves off complexity and makes further changes easier to implement
Pattern types: Prohibit generic args on const params
Addresses https://github.com/rust-lang/rust/pull/123689/files#r1562676629.
NB: Technically speaking, *not* prohibiting generics args on const params is not a bug as `pattern_types` is an *internal* feature and as such any uncaught misuses of it are considered to be the fault of the user. However, permitting this makes me slightly uncomfortable esp. since we might want to make pattern types available to the public at some point and I don't want this oversight to be able to slip into the language (for comparison, ICEs triggered by the use of internal features are like super fine).
Furthermore, this is an ad hoc fix. A more general fix would be changing the representation of the pattern part of pattern types in such a way that it can reuse preexisting lowering routines for exprs / anon consts. See also this [Zulip discussion](https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/pattern.20type.20HIR.20nodes/near/432410768) and #124650.
Also note that we currently don't properly typeck the pattern of pat tys. This however is out of scope for this PR.
cc ``@oli-obk``
r? ``@spastorino`` as discussed
Rename Unsafe to Safety
Alternative to #124455, which is to just have one Safety enum to use everywhere, this opens the posibility of adding `ast::Safety::Safe` that's useful for unsafe extern blocks.
This leaves us today with:
```rust
enum ast::Safety {
Unsafe(Span),
Default,
// Safe (going to be added for unsafe extern blocks)
}
enum hir::Safety {
Unsafe,
Safe,
}
```
We would convert from `ast::Safety::Default` into the right Safety level according the context.
Split out `ty::AliasTerm` from `ty::AliasTy`
Splitting out `AliasTerm` (for use in project and normalizes goals) and `AliasTy` (for use in `ty::Alias`)
r? lcnr
Rename some `FulfillmentErrorCode`/`ObligationCauseCode` variants to be less redundant
1. Rename some `FulfillmentErrorCode` variants.
2. Always use `ObligationCauseCode::` to prefix a code, rather than using a glob import and naming them through `traits::`.
3. Rename some `ObligationCauseCode` variants -- I wasn't particularly thorough with thinking of a new names for these, so could workshop them if necessary.
4. Misc stuff from renaming.
r? lcnr
Rename `Generics::params` to `Generics::own_params`
I hope this makes it slightly more obvious that `generics.own_params` is insufficient when considering nested items. I didn't actually audit any of the usages, for the record.
r? lcnr
`InferCtxt::next_{ty,const}_var*` all take an origin, but the
`param_def_id` is almost always `None`. This commit changes them to just
take a `Span` and build the origin within the method, and adds new
methods for the rare cases where `param_def_id` might not be `None`.
This avoids a lot of tedious origin building.
Specifically:
- next_ty_var{,_id_in_universe,_in_universe}: now take `Span` instead of
`TypeVariableOrigin`
- next_ty_var_with_origin: added
- next_const_var{,_in_universe}: takes Span instead of ConstVariableOrigin
- next_const_var_with_origin: added
- next_region_var, next_region_var_in_universe: these are unchanged,
still take RegionVariableOrigin
The API inconsistency (ty/const vs region) seems worth it for the
large conciseness improvements.
The starting point for this was identical comments on two different
fields, in `ast::VariantData::Struct` and `hir::VariantData::Struct`:
```
// FIXME: investigate making this a `Option<ErrorGuaranteed>`
recovered: bool
```
I tried that, and then found that I needed to add an `ErrorGuaranteed`
to `Recovered::Yes`. Then I ended up using `Recovered` instead of
`Option<ErrorGuaranteed>` for these two places and elsewhere, which
required moving `ErrorGuaranteed` from `rustc_parse` to `rustc_ast`.
This makes things more consistent, because `Recovered` is used in more
places, and there are fewer uses of `bool` and
`Option<ErrorGuaranteed>`. And safer, because it's difficult/impossible
to set `recovered` to `Recovered::Yes` without having emitted an error.
Do not ICE on `AnonConst`s in `diagnostic_hir_wf_check`
Fixes#122989
Below is the snippet from #122989 that ICEs:
```rust
trait Traitor<const N: N<2> = 1, const N: N<2> = N> {
fn N(&N) -> N<2> {
M
}
}
trait N<const N: Traitor<2> = 12> {}
```
The `AnonConst` that triggers the ICE is the `2` in the param `const N: N<2> = 1`. The currently existing code in `diagnostic_hir_wf_check` deals only with `AnonConst`s that are default values of some param, but the `2` is not a default value. It is just an `AnonConst` HIR node inside a `TraitRef` HIR node corresponding to `N<2>`. Therefore the existing code cannot handle it and this PR ensures that it does.
Make `Bounds.clauses` private
Construct it through `Bounds::default()`, then consume the clauses via the method `Bounds::clauses()`.
This helps with effects desugaring where `clauses()` is not only the clauses within the `clauses` field.
Some hir cleanups
It seemed odd to not put `AnonConst` in the arena, compared with the other types that we did put into an arena. This way we can also give it a `Span` without growing a lot of other HIR data structures because of the extra field.
r? compiler
Use `tcx.types.unit` instead of `Ty::new_unit(tcx)`
I don't think there is any need for the function, given that we can just access the `.types`, similarly to all other primitives?
Cleanup: Replace item names referencing GitHub issues or error codes with something more meaningful
**lcnr** in https://github.com/rust-lang/rust/pull/117164#pullrequestreview-1969935387:
> […] while I know that there's precendent to name things `Issue69420`, I really dislike this as it requires looking up the issue to figure out the purpose of such a variant. Actually referring to the underlying issue, e.g. `AliasMayNormToUncovered` or whatever and then linking to the issue in a doc comment feels a lot more desirable to me. We should ideally rename all the functions and enums which currently use issue numbers.
I've grepped through `compiler/` like crazy and think that I've found all instances of this pattern.
However, I haven't renamed `compute_2229_migrations_*`. Should I?
The first commit introduces an abhorrent and super long name for an item because naming is hard but also scary looking / unwelcoming names are good for things related to temporary-ish backcompat hacks. I'll let you discover it by yourself.
Contains a bit of drive-by cleanup and a diag migration bc that was the simplest option.
r? lcnr or compiler
Lazily normalize inside trait ref during orphan check & consider ty params in rigid alias types to be uncovered
Fixes#99554, fixesrust-lang/types-team#104.
Fixes#114061.
Supersedes #100555.
Tracking issue for the future compatibility lint: #124559.
r? lcnr
delegation: Support renaming, and async, const, extern "ABI" and C-variadic functions
Also allow delegating to functions with opaque types (`impl Trait`).
The delegation item will refer to the original opaque type from the callee, fresh opaque type won't be created, which seems like a reasonable behavior.
(Such delegation items will cause query cycles when used in trait impls, but it can be fixed later.)
Part of https://github.com/rust-lang/rust/issues/118212.
Also allow `impl Trait` in delegated functions.
The delegation item will refer to the original opaque type from the callee, fresh opaque type won't be created.
Rollup of 3 pull requests
Successful merges:
- #124003 (Dellvmize some intrinsics (use `u32` instead of `Self` in some integer intrinsics))
- #124169 (Don't fatal when calling `expect_one_of` when recovering arg in `parse_seq`)
- #124286 (Subtree sync for rustc_codegen_cranelift)
r? `@ghost`
`@rustbot` modify labels: rollup
Dellvmize some intrinsics (use `u32` instead of `Self` in some integer intrinsics)
This implements https://github.com/rust-lang/compiler-team/issues/693 minus what was implemented in #123226.
Note: I decided to _not_ change `shl`/... builder methods, as it just doesn't seem worth it.
r? ``@scottmcm``
Do `check_coroutine_obligations` once per typeck root
We only need to do `check_coroutine_obligations` once per typeck root, especially since the new solver can't really (easily) associate which obligations correspond to which coroutines.
This requires us to move the checks for sized coroutine fields into `mir_coroutine_witnesses`, but that's fine imo.
r? lcnr
Suggest using type args directly instead of equality constraint
When type arguments are written erroneously using an equality constraint we suggest specifying them directly without the equality constraint.
Fixes#122162
Changes the diagnostic in the issue from:
```rust
error[E0229]: associated type bindings are not allowed here
9 | impl std::cmp::PartialEq<Rhs = T> for S {
| ^^^^^^^ associated type not allowed here
|
```
to
```rust
error[E0229]: associated type bindings are not allowed here
9 | impl std::cmp::PartialEq<Rhs = T> for S {
| ^^^^^^^ associated type not allowed here
|
help: to use `T` as a generic argument specify it directly
|
| impl std::cmp::PartialEq<T> for S {
| ~
```
weak lang items are not allowed to be #[track_caller]
For instance the panic handler will be called via this import
```rust
extern "Rust" {
#[lang = "panic_impl"]
fn panic_impl(pi: &PanicInfo<'_>) -> !;
}
```
A `#[track_caller]` would add an extra argument and thus make this the wrong signature.
The 2nd commit is a consistency rename; based on the docs [here](https://doc.rust-lang.org/unstable-book/language-features/lang-items.html) and [here](https://rustc-dev-guide.rust-lang.org/lang-items.html) I figured "lang item" is more widely used. (In the compiler output, "lang item" and "language item" seem to be pretty even.)
fix normalizing in different `ParamEnv`s with the same `InferCtxt`
This PR changes the key of the projection cache from just `AliasTy` to `(AliasTy, ParamEnv)` to allow normalizing in different `ParamEnv`s without resetting caches. Previously, normalizing the same alias in different param envs would always reuse the cached result from the first normalization, which is incorrect if the projection clauses in the param env have changed.
Fixing this bug allows us to get rid of `InferCtxt::clear_caches`, which was only used by the `AutoTraitFinder`, because it requires normalizing in different param envs.
r? `@fmease`
Fix capturing duplicated lifetimes via parent in `precise_captures` (`impl use<'...>`)
For technical reasons related to the way that `Self` and `T::Assoc` are lowered from HIR -> `rustc_middle::ty`, an opaque may mention in its bounds both the original early-bound lifetime from the parent `impl`/`fn`, *and* the *duplicated* early-bound lifetime on the opaque.
This is fine -- and has been fine since `@cjgillot` rewrote the way we handled opaque lifetime captures, and we went further to allow this behavior explicitly in https://github.com/rust-lang/rust/pull/115659. It's worthwhile to read this PR's technical section to recall how this duplication works and when it acts surprisingly.
The problem here is that the check that make sure that `impl use<'a, 'b>` lists all of the opaque's captured lifetimes wasn't smart enough to consider both these captured lifetimes and the original lifetimes they're duplicated from to be equal. This PR fixes that.
r? oli-obk
Don't repeatedly duplicate TAIT lifetimes for each subsequently nested TAIT
Make it so that nested TAITs inherit the lifetimes from their parent item, not their parent TAIT. This is because we don't need to re-duplicate lifetimes for nested TAITs over and over, since the only lifetimes they can capture are from the parent item anyways.
This mirrors how RPITs work. This is **not** a functional change that should be observable, since the whole point of duplicating lifetimes and marking the shadowed ones (and uncaptured ones) as bivariant is designed to *not* be observable.
r? oli-obk
Match ergonomics 2024: miscellaneous code cleanups
- Store `ByRef` instead of `BindingAnnotation` in `PatInfo`
- Rename `BindingAnnotation` to `BindingMode`
r? ``@Nadrieril``
cc #123076
``@rustbot`` label A-patterns
Delay span bug when `Self` kw resolves to `DefKind::{Mod,Trait}`
Catch the case where `kw::Self` is recovered in the parser and causes us to subsequently resolve `&self`'s implicit type to something that's not a type.
This check could be made more accurate, though I'm not sure how hard we have to try here.
Fixes#123988
Implement syntax for `impl Trait` to specify its captures explicitly (`feature(precise_capturing)`)
Implements `impl use<'a, 'b, T, U> Sized` syntax that allows users to explicitly list the captured parameters for an opaque, rather than inferring it from the opaque's bounds (or capturing *all* lifetimes under 2024-edition capture rules). This allows us to exclude some implicit captures, so this syntax may be used as a migration strategy for changes due to #117587.
We represent this list of captured params as `PreciseCapturingArg` in AST and HIR, resolving them between `rustc_resolve` and `resolve_bound_vars`. Later on, we validate that the opaques only capture the parameters in this list.
We artificially limit the feature to *require* mentioning all type and const parameters, since we don't currently have support for non-lifetime bivariant generics. This can be relaxed in the future.
We also may need to limit this to require naming *all* lifetime parameters for RPITIT, since GATs have no variance. I have to investigate this. This can also be relaxed in the future.
r? `@oli-obk`
Tracking issue:
- https://github.com/rust-lang/rust/issues/123432
Fix pretty HIR for anon consts in diagnostics
This removes the `NoAnn` printer which skips over nested bodies altogether, which is confusing, and requires users of `{ty|qpath|pat}_to_string` to pass in `&tcx` which now impleemnts `hir_pretty::PpAnn`.
There's one case where this "regresses" by actually printing out the body of the anon const -- we could suppress that, but I don't expect people to actually get anon consts like that unless they're fuzzing, tbh.
r? estebank
Remove `TypeVariableOriginKind` and `ConstVariableOriginKind`
It's annoying to have to import `TypeVariableOriginKind` just to fill it with `MiscVariable` for almost every use. Every other usage other than `TypeParameterDefinition` wasn't even used -- I can see how it may have been useful once for debugging, but I do quite a lot of typeck debugging and I've never really needed it.
So let's just remove it, and keep around the only useful thing which is the `DefId` of the param for `var_for_def`.
This is based on #123006, which removed the special use of `TypeVariableOriginKind::OpaqueInference`, which I'm pretty sure I was the one that added.
r? lcnr or re-roll to types
Fix various bugs in `ty_kind_suggestion`
Consolidates two implementations of `ty_kind_suggestion`
Fixes some misuse of the empty param-env
Fixes a problem where we suggested `(42)` instead of `(42,)` for tuple suggestions
Suggest a value when `return;`, making it consistent with `break;`
Fixes#123906
Call lower_const_param instead of duplicating the code
Follow up of #123689
r? `@oli-obk`
I had this commit in my old branch that I had forgotten about, `@fmease` pointed about this in #123689
I've left the branches that are not `Range` as do nothing as that's what we are currently doing but maybe we want to err or something.
Tweak value suggestions in `borrowck` and `hir_analysis`
Unify the output of `suggest_assign_value` and `ty_kind_suggestion`.
Ideally we'd make these a single function, but doing so would likely require modify the crate dependency tree.
Propagate temporary lifetime extension into if and match.
This PR makes this work:
```rust
let a = if true {
..;
&temp() // used to error, but now gets lifetime extended
} else {
..;
&temp() // used to error, but now gets lifetime extended
};
```
and
```rust
let a = match () {
_ => {
..;
&temp() // used to error, but now gets lifetime extended
}
};
```
to make it consistent with:
```rust
let a = {
..;
&temp() // lifetime is extended
};
```
This is one small part of [the temporary lifetimes work](https://github.com/rust-lang/lang-team/issues/253).
This part is backwards compatible (so doesn't need be edition-gated), because all code affected by this change previously resulted in a hard error.
Unify the output of `suggest_assign_value` and `ty_kind_suggestion`.
Ideally we'd make these a single function, but doing so would likely require modify the crate dependency tree.
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