- `check-pass` test for a MRE of #135020
- fail test for #135138
- switch to `TooGeneric` for checking CMSE fn signatures
- switch to `TooGeneric` for compute `SizeSkeleton` (for transmute)
- fix broken tests
Properly report error when object type param default references self
I accidentally broke this error for cases where a type parameter references `Self` via a projection (i.e. `trait Foo<Arg = Self::Bar> {}`). This PR fixes that, and also makes the error a bit easier to understand.
Fixes#135918
Forbid usage of `hir` `Infer` const/ty variants in ambiguous contexts
The feature `generic_arg_infer` allows providing `_` as an argument to const generics in order to infer them. This introduces a syntactic ambiguity as to whether generic arguments are type or const arguments. In order to get around this we introduced a fourth `GenericArg` variant, `Infer` used to represent `_` as an argument to generic parameters when we don't know if its a type or a const argument.
This made hir visitors that care about `TyKind::Infer` or `ConstArgKind::Infer` very error prone as checking for `TyKind::Infer`s in `visit_ty` would find *some* type infer arguments but not *all* of them as they would sometimes be lowered to `GenericArg::Infer` instead.
Additionally the `visit_infer` method would previously only visit `GenericArg::Infer` not *all* infers (e.g. `TyKind::Infer`), this made it very easy to override `visit_infer` and expect it to visit all infers when in reality it would only visit *some* infers.
---
This PR aims to fix those issues by making the `TyKind` and `ConstArgKind` types generic over whether the infer types/consts are represented by `Ty/ConstArgKind::Infer` or out of line (e.g. by a `GenericArg::Infer` or accessible by overiding `visit_infer`). We then make HIR Visitors convert all const args and types to the versions where infer vars are stored out of line and call `visit_infer` in cases where a `Ty`/`Const` would previously have had a `Ty/ConstArgKind::Infer` variant:
API Summary
```rust
enum AmbigArg {}
enum Ty/ConstArgKind<Unambig = ()> {
...
Infer(Unambig),
}
impl Ty/ConstArg {
fn try_as_ambig_ty/ct(self) -> Option<Ty/ConstArg<AmbigArg>>;
}
impl Ty/ConstArg<AmbigArg> {
fn as_unambig_ty/ct(self) -> Ty/ConstArg;
}
enum InferKind {
Ty(Ty),
Const(ConstArg),
Ambig(InferArg),
}
trait Visitor {
...
fn visit_ty/const_arg(&mut self, Ty/ConstArg<AmbigArg>) -> Self::Result;
fn visit_infer(&mut self, id: HirId, sp: Span, kind: InferKind) -> Self::Result;
}
// blanket impl'd, not meant to be overriden
trait VisitorExt {
fn visit_ty/const_arg_unambig(&mut self, Ty/ConstArg) -> Self::Result;
}
fn walk_unambig_ty/const_arg(&mut V, Ty/ConstArg) -> Self::Result;
fn walk_ty/const_arg(&mut V, Ty/ConstArg<AmbigArg>) -> Self::Result;
```
The end result is that `visit_infer` visits *all* infer args and is also the *only* way to visit an infer arg, `visit_ty` and `visit_const_arg` can now no longer encounter a `Ty/ConstArgKind::Infer`. Representing this in the type system means that it is now very difficult to mess things up, either accessing `TyKind::Infer` "just works" and you won't miss *some* type infers- or it doesn't work and you have to look at `visit_infer` or some `GenericArg::Infer` which forces you to think about the full complexity involved.
Unfortunately there is no lint right now about explicitly matching on uninhabited variants, I can't find the context for why this is the case 🤷♀️
I'm not convinced the framing of un/ambig ty/consts is necessarily the right one but I'm not sure what would be better. I somewhat like calling them full/partial types based on the fact that `Ty<Partial>`/`Ty<Full>` directly specifies how many of the type kinds are actually represented compared to `Ty<Ambig>` which which leaves that to the reader to figure out based on the logical consequences of it the type being in an ambiguous position.
---
tool changes have been modified in their own commits for easier reviewing by anyone getting cc'd from subtree changes. I also attempted to split out "bug fixes arising from the refactoring" into their own commit so they arent lumped in with a big general refactor commit
Fixes#112110
For E0223, suggest associated functions that are similar to the path, even if the base type has multiple inherent impl blocks.
Currently, the "help: there is an associated function with a similar name `from_utf8`" suggestion for `String::from::utf8` is only given if `String` has exactly one inherent `impl` item. This PR makes the suggestion be emitted even if the base type has multiple inherent `impl` items.
Example:
```rust
struct Foo;
impl Foo {
fn bar_baz() {}
}
impl Foo {} // load-bearing
fn main() {
Foo::bar::baz;
}
```
Nightly/stable output:
```rust
error[E0223]: ambiguous associated type
--> f.rs:7:5
|
7 | Foo::bar::baz;
| ^^^^^^^^
|
help: if there were a trait named `Example` with associated type `bar` implemented for `Foo`, you could use the fully-qualified path
|
7 | <Foo as Example>::bar::baz;
| ~~~~~~~~~~~~~~~~~~~~~
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0223`.
```
Output with this PR, or without the load-bearing empty impl on nightly/stable:
```rust
error[E0223]: ambiguous associated type
--> f.rs:7:5
|
7 | Foo::bar::baz;
| ^^^^^^^^
|
help: there is an associated function with a similar name: `bar_baz`
|
7 | Foo::bar_baz;
| ~~~~~~~
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0223`.
```
Ideally, this suggestion would also work for non-ADT types like ~~`str::char::indices`~~ (edit: latest commit makes this work with primitives) or `<dyn Any>::downcast::mut_unchecked`, but that seemed to be a harder change.
`@rustbot` label +A-diagnostics
Always lower to `GenericArg::Infer`
Update `PlaceholderCollector`
Update closure lifetime binder infer var visitor
Fallback visitor handle ambig infer args
Ensure type infer args have their type recorded
Use `structurally_normalize` instead of manual `normalizes-to` goals in alias relate errors
r? `@lcnr`
I added `structurally_normalize_term` so that code that is generic over ty or const can use the structurally normalize helpers. See `tests/ui/traits/next-solver/diagnostics/alias_relate_error_uses_structurally_normalize.rs` for a description of the reason for the (now fixed) ICEs
This CL makes a number of small changes to dyn compatibility errors:
- "object safety" has been renamed to "dyn-compatibility" throughout
- "Convert to enum" suggestions are no longer generated when there
exists a type-generic impl of the trait or an impl for `dyn OtherTrait`
- Several error messages are reorganized for user readability
Additionally, the dyn compatibility error creation code has been
split out into functions.
cc #132713
cc #133267
remove support for the (unstable) #[start] attribute
As explained by `@Noratrieb:`
`#[start]` should be deleted. It's nothing but an accidentally leaked implementation detail that's a not very useful mix between "portable" entrypoint logic and bad abstraction.
I think the way the stable user-facing entrypoint should work (and works today on stable) is pretty simple:
- `std`-using cross-platform programs should use `fn main()`. the compiler, together with `std`, will then ensure that code ends up at `main` (by having a platform-specific entrypoint that gets directed through `lang_start` in `std` to `main` - but that's just an implementation detail)
- `no_std` platform-specific programs should use `#![no_main]` and define their own platform-specific entrypoint symbol with `#[no_mangle]`, like `main`, `_start`, `WinMain` or `my_embedded_platform_wants_to_start_here`. most of them only support a single platform anyways, and need cfg for the different platform's ways of passing arguments or other things *anyways*
`#[start]` is in a super weird position of being neither of those two. It tries to pretend that it's cross-platform, but its signature is a total lie. Those arguments are just stubbed out to zero on ~~Windows~~ wasm, for example. It also only handles the platform-specific entrypoints for a few platforms that are supported by `std`, like Windows or Unix-likes. `my_embedded_platform_wants_to_start_here` can't use it, and neither could a libc-less Linux program.
So we have an attribute that only works in some cases anyways, that has a signature that's a total lie (and a signature that, as I might want to add, has changed recently, and that I definitely would not be comfortable giving *any* stability guarantees on), and where there's a pretty easy way to get things working without it in the first place.
Note that this feature has **not** been RFCed in the first place.
*This comment was posted [in May](https://github.com/rust-lang/rust/issues/29633#issuecomment-2088596042) and so far nobody spoke up in that issue with a usecase that would require keeping the attribute.*
Closes https://github.com/rust-lang/rust/issues/29633
try-job: x86_64-gnu-nopt
try-job: x86_64-msvc-1
try-job: x86_64-msvc-2
try-job: test-various
Rework dyn trait lowering to stop being so intertwined with trait alias expansion
This PR reworks the trait object lowering code to stop handling trait aliases so funky, and removes the `TraitAliasExpander` in favor of a much simpler design. This refactoring is important for making the code that I'm writing in https://github.com/rust-lang/rust/pull/133397 understandable and easy to maintain, so the diagnostics regressions are IMO inevitable.
In the old trait object lowering code, we used to be a bit sloppy with the lists of traits in their unexpanded and expanded forms. This PR largely rewrites this logic to expand the trait aliases *once* and handle them more responsibly throughout afterwards.
Please review this with whitespace disabled.
r? lcnr
Use trait definition cycle detection for trait alias definitions, too
fixes#133901
In general doing this for `All` is not right, but this code path is specifically for traits and trait aliases, and there we only ever use `All` for trait aliases.
Treat safe target_feature functions as unsafe by default [less invasive variant]
This unblocks
* #134090
As I stated in https://github.com/rust-lang/rust/pull/134090#issuecomment-2541332415 I think the previous impl was too easy to get wrong, as by default it treated safe target feature functions as safe and had to add additional checks for when they weren't. Now the logic is inverted. By default they are unsafe and you have to explicitly handle safe target feature functions.
This is the less (imo) invasive variant of #134317, as it doesn't require changing the Safety enum, so it only affects FnDefs and nothing else, as it should.
Improve `DispatchFromDyn` and `CoerceUnsized` impl validation
* Disallow arbitrary 1-ZST fields in `DispatchFromDyn` -- only `PhantomData`, and 1-ZSTs that mention no params (which is needed to support, e.g., the `Global` alloctor in `Box<T, U = Global>`).
* Don't allow coercing between non-ZSTs to ZSTs (since the previous check wasn't actually checking the field tys were the same before checking the layout...)
* Normalize the field before checking it's `PhantomData`.
Fixes#135215Fixes#135214Fixes#135220
r? ```@BoxyUwU``` or reassign
Exclude dependencies of `std` for diagnostics
Currently crates in the sysroot can show up in diagnostic suggestions, such as in https://github.com/rust-lang/rust/issues/135232. To prevent this, duplicate `all_traits` into `visible_traits` which only shows traits in non-private crates.
Setting `#![feature(rustc_private)]` overrides this and makes items in private crates visible as well, since `rustc_private` enables use of `std`'s private dependencies.
This may be reviewed per-commit.
Fixes: https://github.com/rust-lang/rust/issues/135232
Add an alternative to `tcx.all_traits()` that only shows traits that the
user might be able to use, for diagnostic purposes. With this available,
make use of it for diagnostics including associated type errors, which
is part of the problem with [1].
Includes a few comment updates for related API.
[1]: https://github.com/rust-lang/rust/issues/135232
Remove a bunch of diagnostic stashing that doesn't do anything
#121669 removed a bunch of conditional diagnostic stashing/canceling, but left around the `steal` calls which just emitted the error eagerly instead of canceling the diagnostic. I think that these no-op `steal` calls don't do much and are confusing to encounter, so let's remove them.
The net effect is:
1. We emit more duplicated errors, since stashing has the side effect of duplicating diagnostics. This is not a big deal, since outside of `-Zdeduplicate-diagnostics=no`, the errors are already being deduplicated by the compiler.
2. It changes the order of diagnostics, since we're no longer stashing and then later stealing the errors. I don't think this matters much for the changes that the UI test suite manifests, and it makes these errors less order dependent.
Suggest typo fix when trait path expression is typo'ed
When users write something like `Default::defualt()` (notice the typo), failure to resolve the erroneous `defualt` item will cause resolution + lowering to interpret this as a type-dependent path whose self type is `Default` which is a trait object without `dyn`, rather than a trait function like `<_ as Default>::default()`.
Try to provide a bit of guidance in this situation when we can detect the typo.
Fixes https://github.com/rust-lang/rust/issues/135349
Make `lit_to_mir_constant` and `lit_to_const` infallible
My motivation for this change is just that it's annoying to check everywhere, especially since all but one call site was just ICEing on errors anyway right there.
They can still fail, but now just return an error constant instead of having the caller handle the error.
fixes#114317fixes#126182