Skip to content

Derive GenericTypeVisitable for RegionConstraint _correctly_ - #160914

Open
ada4a wants to merge 5 commits into
rust-lang:mainfrom
ada4a:GenericTypeVisitable-bounds
Open

Derive GenericTypeVisitable for RegionConstraint _correctly_#160914
ada4a wants to merge 5 commits into
rust-lang:mainfrom
ada4a:GenericTypeVisitable-bounds

Conversation

@ada4a

@ada4a ada4a commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

View all comments

The derive added in #160164 was incorrect -- it resulted in an overflow during trait solving. This is because #[derive(GenericTypeVisitable)] automatically adds a : GenericTypeVisitable bound to every field of a type -- in this case, Box<[RegionConstraint<I>]>: GenericTypeVisitable<V>.

To fix this, I added a #[generic_type_visitable(bounds(..))] attribute to the derive macro, which allows overriding the added bounds.

I also made the derive macro no longer a no-op in rustc, so that errors like this can be caught on r-l/r CI in the future.

Best reviewed commit-by-commit.

cc @ChayimFriedman2

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

rustbot commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

r? @JonathanBrouwer

rustbot has assigned @JonathanBrouwer.
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 75 candidates
  • Random selection from 18 candidates

@rust-log-analyzer

This comment has been minimized.

@ChayimFriedman2

Copy link
Copy Markdown
Contributor

It doesn't need to be unsafe. If the bounds are wrong it won't compile (at least in r-a).

@ada4a

ada4a commented Aug 11, 2026

Copy link
Copy Markdown
Contributor Author

What about a case like this?

#[derive(GenericTypeVisitable)]
struct Foo {
    #[generic_type_visitable(unsafe(bounds()))]
    contains_self: (Box<Self>, Bar),
}

struct Bar;

AFAICT bounds are incorrectly missing Bar: GenericTypeVisitable, which leads to unsoundness.

@ada4a
ada4a force-pushed the GenericTypeVisitable-bounds branch from 87bfdc9 to fc37746 Compare August 11, 2026 14:52
@ChayimFriedman2

Copy link
Copy Markdown
Contributor

No, because then calling GenericTypeVisitable::visit(&self.contains_self) will fail compilation.

@ada4a
ada4a force-pushed the GenericTypeVisitable-bounds branch 2 times, most recently from 64616ec to ec68072 Compare August 11, 2026 15:25
@ada4a

ada4a commented Aug 11, 2026

Copy link
Copy Markdown
Contributor Author

The newly added complexity of the derive macro makes me wonder if it deserves some ui tests now.. Not sure where they would go though

@ChayimFriedman2

Copy link
Copy Markdown
Contributor

Note that only making the derive not-no-op won't make forgetting to derive it a CI failure, since rustc does not use it for anything.

@ada4a

ada4a commented Aug 11, 2026

Copy link
Copy Markdown
Contributor Author

Yes, that will be covered by a future PR. I thought I'd get this one merged now, so that the fixed derive already gets into the source code -- otherwise the list of ra-ap crate versions I need to catch up on will only continue to rise over time 😅

@rust-log-analyzer

This comment has been minimized.

@ada4a
ada4a force-pushed the GenericTypeVisitable-bounds branch from ec68072 to 958b222 Compare August 11, 2026 16:25
@ada4a

ada4a commented Aug 11, 2026

Copy link
Copy Markdown
Contributor Author

Apparently, a backtick in an ignore description breaks everything... How silly

@JonathanBrouwer

Copy link
Copy Markdown
Member

The newly added complexity of the derive macro makes me wonder if it deserves some ui tests now.. Not sure where they would go though

I think this does deserve some tests.
You can write tests that depend on rustc crates in tests/ui-fulldeps, I think these make sense.

Comment thread compiler/rustc_type_ir/src/generic_visit.rs
/// ```ignore (would need to import GenericTypeVisitable to get this to compile)
/// #[derive(GenericTypeVisitable)]
/// struct Foo {
/// #[generic_type_visitable(bounds())]

@JonathanBrouwer JonathanBrouwer Aug 14, 2026

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.

How hard would it be to automatically detect bounds that would overflow the trait solver in the proc macro and remove them, rather than having to manually specify the bounds?

View changes since the review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I mean.. that would require us to filter out the fields whose types contain Self, unless it's a type like (Self, Bar), in which case we'd need to filter out Self but not Bar, etc. etc. I'd argue that this is pretty difficult to do in general, as proc-macros don't have access to name resolution.

Given that this is also my literal first time writing proc macro code, I'd rather keep it simple (if a bit annoying for the user) than risk unsoundness 😅

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

One last argument is that this is the first time such a manual bound was even necessary, and that's with GenericTypeVisitable having existed for some while. So my hope is that cases like this will only come up relatively rarely.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

IMO that's just not worth it. Other proc macros in the ecosystem also just require specifying bounds.

@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 Aug 14, 2026
@rustbot

rustbot commented Aug 14, 2026

Copy link
Copy Markdown
Collaborator

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

@rust-bors

This comment has been minimized.

@JonathanBrouwer

Copy link
Copy Markdown
Member

@rustbot ready
I think this is ready for me to take a look at again?
This feel off my radar, oops, sorry :3. I'll take a look tonight or tomorrow

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Aug 22, 2026
ada4a added 2 commits August 22, 2026 18:43
This is motivated by rust-lang#160164,
which added the derive which wouldn't actually work, due to recusrive
trait bounds (more on this in a later commit). This change will make it
so that these errors are caught in rustc CI.
@ada4a
ada4a force-pushed the GenericTypeVisitable-bounds branch from 958b222 to d75b165 Compare August 22, 2026 16:48
@rustbot

rustbot commented Aug 22, 2026

Copy link
Copy Markdown
Collaborator

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@ada4a

ada4a commented Aug 22, 2026

Copy link
Copy Markdown
Contributor Author

I think this is ready for me to take a look at again?

Ah, sorry, forgot about the ready thing^^ Yes, it is:)

@ada4a

ada4a commented Aug 22, 2026

Copy link
Copy Markdown
Contributor Author

Oh, apparently rustc-dev-guide has a section on GenericTypeVisitable. I'd like to update it according to this PR's changes, but I should really not be working right now 😅 So I'd do that in a follow-up PR next week. (I'd like to avoid delaying the merge of this PR any further, so that it gets into the next ra-ap-rustc_* release)

@JonathanBrouwer JonathanBrouwer 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.

@bors r+ rollup
This looks reasonable, thanks! <3
As a follow up you:

  • Should make a rustc-dev-guide PR explaining the new bounds option (Feel free to assign me for review if you feel like the PR benefits from review)
  • Could add a ui-fulldeps test for this macro

View changes since this review

@rust-bors

rust-bors Bot commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

📌 Commit d75b165 has been approved by JonathanBrouwer

It is now in the queue for this repository.

@rust-bors rust-bors Bot added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 22, 2026
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Aug 22, 2026
… r=JonathanBrouwer

Derive `GenericTypeVisitable` for `RegionConstraint` _correctly_

The derive added in rust-lang#160164 was incorrect -- it resulted in an overflow during trait solving. This is because `#[derive(GenericTypeVisitable)]` automatically adds a `: GenericTypeVisitable` bound to every field of a type -- in this case, `Box<[RegionConstraint<I>]>: GenericTypeVisitable<V>`.

To fix this, I added a `#[generic_type_visitable(bounds(..))]` attribute to the derive macro, which allows overriding the added bounds.

I also made the derive macro no longer a no-op in rustc, so that errors like this can be caught on r-l/r CI in the future.

Best reviewed commit-by-commit.

cc @ChayimFriedman2
rust-bors Bot pushed a commit that referenced this pull request Aug 22, 2026
…uwer

Rollup of 7 pull requests

Successful merges:

 - #157513 (Reject non-constructor self types in const-arg tuple-call lowering)
 - #159887 (compiletest: forward disable-minification from bootstrap)
 - #160949 (Add floating point inline ASM support for SPARC)
 - #156160 (feat: add symmetric PartialEq impls for Vec, &[T], &mut [T] versus Cow<'_, [T]>)
 - #160302 (target_features: sse (or at least avx2) is incompatible with soft-float ABI)
 - #160914 (Derive `GenericTypeVisitable` for `RegionConstraint` _correctly_)
 - #161341 (be more permissive wrt overflow and and improve diagnostics)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. 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.

5 participants