Implement RFC 3678: Final trait methods
Tracking: https://github.com/rust-lang/rust/issues/131179
This PR is based on rust-lang/rust#130802, with some minor changes and conflict resolution.
Futhermore, this PR excludes final methods from the vtable of a dyn Trait.
And some excerpt from the original PR description:
> Implements the surface part of https://github.com/rust-lang/rfcs/pull/3678.
>
> I'm using the word "method" in the title, but in the diagnostics and the feature gate I used "associated function", since that's more accurate.
cc @joshtriplett
Pass alignments through the shim as `Alignment` (not `usize`)
We're using `Layout` on both sides, so might as well skip the transmutes back and forth to `usize`.
The mir-opt test shows that doing so allows simplifying the boxed-slice drop slightly, for example.
We're using `Layout` on both sides, so might as well skip the transmutes back and forth to `usize`.
The mir-opt test shows that doing so allows simplifying the boxed-slice drop slightly, for example.
rustc_parse_format: improve diagnostics for unsupported debug = syntax
Detect Python-style f-string debug syntax in format strings and emit a
clear diagnostic explaining that it is not supported in Rust. When the
intended operation can be inferred, suggest the corresponding Rust
alternative (e.g. `dbg!` for `{x=}`).
Revert, but without type const.
Update symbol for feature err, then update suggestion output, and lastly update tests that change because of those.
Update these new tests with the correct syntax, and few existing tests with the new outputs the merge with main added.
Fix for tidyfmt and some errors when manually resolving a merge conflicts.
Update these tests to use update error messages and type const syntax.
Update comments and error message to use new syntax instead of old type_const attribute.
Remove the type_const attribute
update some more tests to use the new syntax.
Update these test cases.
update feature gate test
Change gate logic for `mgca_type_const_syntax` to work also if `min_generic_const_args` is enabled.
Create a new feature gate that checks for the feature before expansion.
Make rustfmt handle the `type const` syntax correctly.
Add a convience method to check if a RhsKind is type const.
Rename `Const` discriminant to `Body` for `ConstItemRhsKind`
Give the `TraitItemKind` flag an enum instead of a simple bool to better describe what the flag is for.
Update formatting for these match statements.
Update clippy test to use type const syntax.
Update test to use type const syntax.
update rustfmt to match ast items.
Update clippy to match ast and hir items.
Few more test cases that used old attribute, instead of 'type const'
Update to match the output from the feature gate checks.
tidyfmt adjustments.
Update the is_type_const, so I can constrain record!(..) in encoder.rs
Update conditional compilation test.
Move the feature gate to after expansion to allow for cfg(...) to work.
Update some more tests to use the new syntax.
Update type const tests in associated-const-bindings to use new syntax.
Don't check based off the attribute, but the item here.
Update some tests outside of the const_generics folder that were using #[type_const]
update the tests in associated consts that use #[type_const] to use type const
Update these mgca tests with the type const syntax.
Add a flag to TraitItemKind for detecting type const for now. Maybe later change ItemConstRhs to have optional consts but that touches a lot more lines of code.
Don't need into for these now that it's a query.
Add is_type_const query to handle foreign def ids.
update this test to use type const syntax.
Fix logic here, we only want to lower if there is expression in this case.
Update built-in macros to use ConstItemRhsKind
Update more instance of the old ConstItemRhs.
Rename ConstItemKind to ConstItemRhsKind, I noticed there is a typed called ConstantItemKind, so add the Rhs to the name to avoid confusion.
Update lower to use ConstItemKind
Add an other helper method to check if the rhs kinda has an expr.
Update item parse to use ConstItemKind enum.
Felt the field name could a be little clear when editing a few other things.
Change the ConstItem struct see know if we have a type const or regular const.
Make sure this syntax is properly feature gated.
Also duplicate `#[expect]` attribute in `#[derive]`-ed code
This PR updates our derive logic to also duplicate any `#[expect]` attribute in the `#[derive]`-ed code, as we already do for all the other lint attribute (`#[allow]`, `#[warn]`, `#[deny]`, ...).
The original and duplicated attribute share the same attribute id, which due to the way [`check_expectations`](56aaf58ec0/compiler/rustc_lint/src/expect.rs (L28-L46)) is implemented makes the expectation fulfilled if the lint is either trigger in the original code or the derived code.
This was discussed by T-lang in https://github.com/rust-lang/rust/issues/150553#issuecomment-3780810363.
cc @rust-lang/lang-ops (in case you want to do an FCP)
Fixesrust-lang/rust#150553
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).
Detect Python-style f-string debug syntax in format strings and emit a
clear diagnostic explaining that it is not supported in Rust. When the
intended operation can be inferred, suggest the corresponding Rust
alternative e.g from `println!("{=}", x)` to `dbg!({x})`.
Signed-off-by: Usman Akinyemi <usmanakinyemi202@gmail.com>
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();
|
```
checksum-freshness: Fix invalid checksum calculation for binary files
Admittedly this is not the cleanest way to achieve this, but SourceMap is quite intertwined with source files being represented as Strings.
Tracking issue: https://github.com/rust-lang/cargo/issues/14136Closes: rust-lang/rust#151090
`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).
Avoid `-> ()` in derived functions.
`hash` and `assert_receiver_is_total_eq` have no return type. This commit removes the `-> ()` that is currently printed for them.
r? @Kobzol
The problem is that when a macro expand to `compile_error!` because
its input is malformed, the actual error message from the
`compile_error!` might be hidden in a long list of other messages about
using items that should have otherwise been generated by the macro.
So suppress error about missing items in that module.
Fixes issue 68838
Clean up `rustc_attr_parsing`
Follow-up of rust-lang/rust#150934.
It removes the `Option<>` wrapping for `SharedContext::target` field and completely removed the `target_id` field. Considering this type contains a closure and never updates its `target_id` field, there is no need to keep it around, it can be used directly in the lint emitter.
r? @JonathanBrouwer
Disallow eii in statement position
With how v2 macros resolve, and the name resolution of `super` works, I realized with @WaffleLapkin that there's actually no way to consistently expand EIIs in statement position.
r? @WaffleLapkin
Currently all core and std macros are automatically added to the prelude
via #[macro_use]. However a situation arose where we want to add a new macro
`assert_matches` but don't want to pull it into the standard prelude for
compatibility reasons. By explicitly exporting the macros found in the core and
std crates we get to decide on a per macro basis and can later add them via
the rust_20xx preludes.
compiler: Forward attributes to eii-expanded macros
Since https://github.com/rust-lang/rust/pull/150592 is quite complicated to reason about I figured it would be good to split it up in smaller pieces that are easier to digest. Here is the attribute fix in isolation.
## The Problem
With this eii in **library/std/src/io/mod.rs**:
```rs
/// Foo
#[eii(on_broken_pipe)]
#[unstable(feature = "on_broken_pipe", issue = "150588")]
pub fn on_broken_pipe() -> OnBrokenPipe {
OnBrokenPipe::BackwardsCompatible
}
```
you currently get this compilation error:
```
error: attribute macro has missing stability attribute
--> library/std/src/io/mod.rs:2269:1
|
2269 | #[eii(on_broken_pipe)]
| ^^^^^^^^^^^^^^^^^^^^--
| |
| in this attribute macro expansion
|
::: library/core/src/macros/mod.rs:1899:5
|
1899 | pub macro eii($item:item) {
| ------------- in this expansion of `#[eii]`
```
because with ` MAGIC_EXTRA_RUSTFLAGS=-Zunpretty=expanded ./x build library/std` we can see that a pub item in the expanded code is indeed missing that attribute:
```rs
const _: () =
{
#[on_broken_pipe]
fn on_broken_pipe() -> OnBrokenPipe {
OnBrokenPipe::BackwardsCompatible
}
};
unsafe extern "Rust" {
/// Foo
#[unstable(feature = "on_broken_pipe", issue = "150588")]
#[rustc_eii_extern_item]
pub safe fn on_broken_pipe()
-> OnBrokenPipe;
}
#[rustc_builtin_macro(eii_shared_macro)]
#[eii_extern_target(on_broken_pipe)]
pub macro on_broken_pipe { () => {} }
```
## The Solution
With the fix, that error goes away because we get this expanded code instead:
```rs
const _: () =
{
#[on_broken_pipe]
fn on_broken_pipe() -> OnBrokenPipe {
OnBrokenPipe::BackwardsCompatible
}
};
unsafe extern "Rust" {
/// Foo
#[unstable(feature = "on_broken_pipe", issue = "150588")]
#[rustc_eii_extern_item]
pub safe fn on_broken_pipe()
-> OnBrokenPipe;
}
/// Foo
#[unstable(feature = "on_broken_pipe", issue = "150588")]
#[rustc_builtin_macro(eii_shared_macro)]
#[eii_extern_target(on_broken_pipe)]
pub macro on_broken_pipe { () => {} }
```
Note that we also need to forward the docs, otherwise get get (fatal) warnings like these:
```
warning: missing documentation for an attribute macro
--> library/std/src/io/mod.rs:2269:1
```
r? @jdonszelmann
Tracking issues:
- https://github.com/rust-lang/rust/issues/125418
- https://github.com/rust-lang/rust/issues/150588
### What about a test?
https://github.com/rust-lang/rust/pull/150591 will prevent regressions once it lands since it does not build without this fix. I think it is overkill to add a temporary eii to std before that.
Otherwise you get errors like these if you have an Externally
Implementable Item defined in std:
error: attribute macro has missing stability attribute
--> library/std/src/io/mod.rs:2269:1
|
2269 | #[eii(on_broken_pipe)]
| ^^^^^^^^^^^^^^^^^^^^--
| |
| in this attribute macro expansion
|
::: library/core/src/macros/mod.rs:1899:5
|
1899 | pub macro eii($item:item) {
| ------------- in this expansion of `#[eii]`
Or (fatal) warnings like these:
warning: missing documentation for an attribute macro
--> library/std/src/io/mod.rs:2269:1
rustc_parse_format: improve error for missing `:` before `?` in format args
Detect the `{ident?}` pattern where `?` is immediately followed by `}` and emit a clearer diagnostic explaining that `:` is required for Debug formatting. This avoids falling back to a generic “invalid format string” error and adds a targeted UI test for the case.