Skip to content

Fix dyn suggestion for bare trait objects starting with :: - #163679

Open
simonether wants to merge 1 commit into
rust-lang:mainfrom
simonether:bare-trait-object-global-path
Open

simonether wants to merge 1 commit into
rust-lang:mainfrom
simonether:bare-trait-object-global-path

Conversation

@simonether

Copy link
Copy Markdown
Contributor

Fixes #63330

The dyn suggestion for a bare trait object whose trait path starts with :: wraps all bounds in parentheses. For Box<::std::any::Any + 'static> it suggests Box<dyn (::std::any::Any + 'static)>, which fails to compile in every edition with "incorrect parentheses around trait bounds". The suggestion is machine-applicable, so cargo fix --edition hits it too (rust-lang/cargo#7349). In edition 2018 and later it also adds parentheses after dyn, which is a keyword there, and unused_parens then asks to remove them.

The parentheses are only needed in edition 2015, where dyn ::a::B parses as the path dyn::a::B. This change adds them only in 2015, and only around the first bound when the text right after the inserted dyn starts with ::. unused_parens already treats parentheses around a leading :: path as necessary in 2015 (dyn2015_exception in compiler/rustc_lint/src/unused.rs), so the suggestion and the lint now agree. The E0782 error in edition 2021 uses the same suggestion and is fixed by the same change.

Bare trait object 2015 2018 and later
Box<::std::any::Any + 'static> dyn (::std::any::Any) + 'static dyn ::std::any::Any + 'static
Box<::std::any::Any> dyn (::std::any::Any) (unchanged) dyn ::std::any::Any
Box<'static + ::std::any::Any> dyn 'static + ::std::any::Any same

When the trait is the only bound and the type also needs angle brackets (::Dyn::func() becomes <dyn (::Dyn)>::func()), ) and > stay in a single insertion so their order is fixed. tests/ui/lint/bare-trait-objects-path.stderr is unchanged.

The new test tests/ui/dyn-keyword/bare-trait-object-global-path-sugg.rs has 2015, 2018 and 2021 revisions with run-rustfix and #![deny(unused_parens)], so the fixed code has to compile and can't contain parentheses it doesn't need. On main, all three revisions fail, and the code suggested there doesn't compile in any of the three editions . The existing UI tests in dyn-keyword, lint, parser, traits/object, cast and typeck pass with no snapshot changes, and tidy passes.

In edition 2015, `dyn ::a::B` parses as the path `dyn::a::B`, so the
suggestion to add `dyn` wraps a global trait path in parentheses. It
wrapped all bounds, though, and `dyn (::std::any::Any + 'static)` is
rejected in every edition. It also added the parentheses in later
editions, where `unused_parens` warns about them.

Add them only in edition 2015, and only around the first bound when it
is a path starting with `::`.
@rustbot

rustbot commented Oct 2, 2026

Copy link
Copy Markdown
Collaborator

HIR ty lowering was modified

cc @fmease

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Oct 2, 2026
@rustbot

rustbot commented Oct 2, 2026

Copy link
Copy Markdown
Collaborator

r? @mu001999

rustbot has assigned @mu001999.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: compiler
  • compiler expanded to 77 candidates
  • Random selection from 19 candidates

@mu001999 mu001999 left a comment •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

//[e2015,e2018]~^^ ERROR trait objects without an explicit `dyn` are deprecated
//[e2015,e2018]~| WARN this is accepted in the current edition

pub type LifetimeFirst = Box<'static + ::std::any::Any>;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you also add tests for Send + ::std::any::Any and ::std::marker::Send + ::std::any::Any?

And for the latter, I think the suggestion should be dyn (::std::marker::Send) + ::std::any::Any.

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Oct 12, 2026
@rustbot

rustbot commented Oct 12, 2026

Copy link
Copy Markdown
Collaborator

Reminder, once the PR becomes ready for a review, use @rustbot ready.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bare_trait_objects help is incorrect with Box<Trait + 'lifetime> in 2015 edition

3 participants