Port rustc_abi to the attribute parser
Tracking issue: https://github.com/rust-lang/rust/issues/131229
This attribute either dumps the abi info for functions (debug arg)
or if you put it on a pair of fn ptr's it checks they match (assert_eq arg)
r? @JonathanBrouwer
Provide more context on trait bounds being unmet due to imperfect derive
When encountering a value that has a borrow checker error where the type was previously moved, when suggesting cloning verify that it is not already being derived. If it is, explain why the `derive(Clone)` doesn't apply:
```
note: if `TypedAddress<T>` implemented `Clone`, you could clone the value
--> $DIR/derive-clone-implicit-bound.rs:6:1
|
LL | #[derive(Clone, Copy)]
| ----- derived `Clone` adds implicit bounds on type parameters
LL | pub struct TypedAddress<T>{
| ^^^^^^^^^^^^^^^^^^^^^^^^-^
| | |
| | introduces an implicit `T: Clone` bound
| consider manually implementing `Clone` for this type
...
LL | let old = self.return_value(offset);
| ------ you could clone this value
```
When encountering a bound coming from a derive macro, suggest manual impl of the trait.
Use the span for the specific param when adding bounds in builtin derive macros, so the diagnostic will point at them as well as the derive macro itself.
```
note: required for `Id<SomeNode>` to implement `PartialEq`
--> $DIR/derive-implicit-bound.rs:5:10
|
LL | #[derive(PartialEq, Eq)]
| ^^^^^^^^^
LL | pub struct Id<T>(PhantomData<T>);
| - unsatisfied trait bound introduced in this `derive` macro
= help: consider manually implementing `PartialEq` to avoid undesired bounds
```
Mention that the trait could be manually implemented in E0599.
Fixrust-lang/rust#108894. Address rust-lang/rust#143714. Address #rust-lang/rust#146515 (but ideally would also suggest constraining the fn bound correctly as well).
It has a single impl, which does nothing, as you'd expect when hashing a
type called `HashIgnoredAttrId`!
So this commit just removes it, and `HashIgnoredAttrId::hash_stable`
ends up doing nothing (with a comment) instead of calling the trait
method to do nothing.
Port reexport_test_harness_main to attr parser
Tracking issue: https://github.com/rust-lang/rust/issues/131229
I don't think I can use the parsed form in compiler/rustc_builtin_macros/src/test_harness.rs since that has to use the AST attrs?
r? @JonathanBrouwer
When encountering a bound coming from a derive macro, suggest manual impl of the trait.
Use the span for the specific param when adding bounds in builtin derive macros, so the diagnostic will point at them as well as the derive macro itself.
```
error[E0277]: can't compare `SomeNode` with `SomeNode`
--> f29.rs:24:15
|
24 | accept_eq(&node);
| --------- ^^^^^ no implementation for `SomeNode == SomeNode`
| |
| required by a bound introduced by this call
|
= note: -Ztrack-diagnostics: created at compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs:279:39
= help: the trait `PartialEq` is not implemented for `SomeNode`
note: required for `Id<SomeNode>` to implement `PartialEq`
--> f29.rs:3:10
|
3 | #[derive(PartialEq, Eq)]
| ^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro
4 | pub struct Id<T>(PhantomData<T>);
| -
= help: consider manually implementing `PartialEq` to avoid undesired bounds
note: required by a bound in `accept_eq`
--> f29.rs:15:23
|
15 | fn accept_eq(_: &impl PartialEq) { }
| ^^^^^^^^^ required by this bound in `accept_eq`
help: consider annotating `SomeNode` with `#[derive(PartialEq)]`
|
13 + #[derive(PartialEq)]
14 | struct SomeNode();
|
```
`const` blocks as a `mod` item
Tracking issue: rust-lang/rust#149226
This adds support for writing `const { ... }` as an item in a module. In the current implementation, this is a unique AST item that gets lowered to `const _: () = const { ... };` in HIR.
rustfmt support included.
TODO:
- `pub const { ... }` does not make sense (see rust-lang/rust#147136). Reject it. Should this be rejected by the parser or smth?
- Improve diagnostics (preferably they should not mention the fake `_` ident).
Replace `#[rustc_do_not_implement_via_object]` with `#[rustc_dyn_incompatible_trait]`
Background: `#[rustc_do_not_implement_via_object]` on a trait currently still allows `dyn Trait` to exist (if the trait is otherwise dyn-compatible), it just means that `dyn Trait` does not automatically implement `Trait` via the normal object candidate. For some traits, this means that `dyn Trait` does not implement `Trait` at all (e.g. `Unsize` and `Tuple`). For some traits, this means that `dyn Trait` implements `Trait`, but with different associated types (e.g. `Pointee`, `DiscriminantKind`). Both of these cases can can cause issues with codegen , as seen in https://github.com/rust-lang/rust/issues/148089 (and https://github.com/rust-lang/rust/issues/148089#issuecomment-3447803823 ), because codegen assumes that if `dyn Trait` does not implement `Trait` (including if `dyn Trait<Assoc = T>` does not implement `Trait` with `Assoc == T`), then `dyn Trait` cannot be constructed, so vtable accesses on `dyn Trait` are unreachable, but this is not the case if `dyn Trait` has multiple supertraits: one which is `#[rustc_do_not_implement_via_object]`, and one which we are doing the vtable access to call a method from.
This PR replaces `#[rustc_do_not_implement_via_object]` with `#[rustc_dyn_incompatible_trait]`, which makes the marked trait dyn-incompatible, making `dyn Trait` not well-formed, instead of it being well-formed but not implementing `Trait`. This resolvesrust-lang/rust#148089 by making it not compile.
May fixrust-lang/rust#148615
The traits that are currently marked `#[rustc_do_not_implement_via_object]` are: `Sized`, `MetaSized`, `PointeeSized`, `TransmuteFrom`, `Unsize`, `BikeshedGuaranteedNoDrop`, `DiscriminantKind`, `Destruct`, `Tuple`, `FnPtr`, `Pointee`. Of these:
* `Sized` and `FnPtr` are already not dyn-compatible (`FnPtr: Copy`, which implies `Sized`)
* `MetaSized`
* Removed `#[rustc_do_not_implement_via_object]`. Still dyn-compatible after this change. (Has a special-case in the trait solvers to ignore the object candidate for `dyn MetaSized`, since it `dyn MetaSized: MetSized` comes from the sized candidate that all `dyn Trait` get.)
* `PointeeSized`
* Removed `#[rustc_do_not_implement_via_object]`. It doesn't seem to have been doing anything anyway ([playground](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2024&gist=a395626c8bef791b87a2d371777b7841)), since `PointeeSized` is removed before trait solving(?).
* `Pointee`, `DiscriminantKind`, `Unsize`, and `Tuple` being dyn-compatible without having `dyn Trait: Trait` (with same assoc tys) can be observed to cause codegen issues (https://github.com/rust-lang/rust/issues/148089) so should be made dyn-incompatible
* `Destruct`, `TransmuteFrom`, and `BikeshedGuaranteedNoDrop` I'm not sure if would be useful as object types, but they can be relaxed to being dyn-compatible later if it is determined they should be.
-----
<details> <summary> resolved </summary>
Questions before merge:
1. `dyn MetaSized: MetaSized` having both `SizedCandidate` and `ObjectCandidate`
1. I'm not sure if the checks in compiler/rustc_trait_selection/src/traits/project.rs and compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs were "load-bearing" for `MetaSized` (which is the only trait that was previously `#[rustc_do_not_implement_via_object]` that is still dyn-compatible after this change). Is it fine to just remove them? Removing them (as I did in the second commit) doesn't change any UI test results.
3. IIUC, `dyn MetaSized` could get its `MetaSized` implementation in two ways: the object candidate (the normal `dyn Trait: Trait`) that was supressed by `#[rustc_do_not_implement_via_object]`, and the `SizedCandidate` (that all `dyn Trait` get for `dyn Trait: MetaSized`). Given that `MetaSized` has no associated types or methods, is it fine that these both exist now? Or is it better to only have the `SizedCandidate` and leave these checks in (i.e. drop the second commit, and remove the FIXMEs)?
4. Resolved: the trait solvers special-case `dyn MetaSized` to ignore the object candidate in preference to the sizedness candidate (technically the check is for any `is_sizedness_trait`, but only `MetaSized` gets this far (`Sized` is inherently dyn-incompatible, and `dyn PointeeSized` is ill-formed for other reasons)
4. Diagnostics improvements?
1. The diagnostics are kinda bad. If you have a `trait Foo: Pointee {}`, you now get a note that reads like *Foo* "opted out of dyn-compatbility", when really `Pointee` did that.
2. Resolved: can be improved later
<details> <summary>diagnostic example</summary>
```rs
#![feature(ptr_metadata)]
trait C: std::ptr::Pointee {}
fn main() {
let y: &dyn C;
}
```
```rs
error[E0038]: the trait `C` is not dyn compatible
--> c.rs:6:17
|
6 | let y: &dyn C;
| ^ `C` is not dyn compatible
|
note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
--> /home/zachary/opt_mount/zachary/Programming/rust-compiler-2/library/core/src/ptr/metadata.rs:57:1
|
57 | #[rustc_dyn_incompatible_trait]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...because it opted out of dyn-compatbility
|
::: c.rs:3:7
|
3 | trait C: std::ptr::Pointee {}
| - this trait is not dyn compatible...
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0038`.
```
</details> </details>
Still investigating "3. `compiler/rustc_hir/src/attrs/encode_cross_crate.rs`: Should `DynIncompatibleTrait` attribute be encoded cross crate?"
Removes the attribute from `MetaSized` and `PointeeSized`, with a special case in the trait solvers for `MetaSized`.
`dyn MetaSized` is a perfectly cromulent type, and seems to only have had #[rustc_do_not_implement_via_object] so the builtin object
candidate does not overlap with the builtin MetaSized impl that all `dyn` types get.
Resolves this with a special case by checking `is_sizedness_trait` where the trait solvers previously checked `implement_via_object`.
`dyn PointeeSized` alone is rejected for other reasons (since `dyn PointeeSized` is considered to have no principal trait because `PointeeSized`
is removed at an earlier stage of the compiler), but `(dyn PointeeSized + Send)` is valid and equivalent to `dyn Send`.
Add suggestions from code review
Update compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs and tests
Co-authored-by: lcnr <rust@lcnr.de>
FCW Lint when using an ambiguously glob imported trait
Related to rust-lang/rust#147992.
Report a lint when using an ambiguously glob import trait, this is a FCW because this should not be allowed.
r? @petrochenkov