Skip to content

delegation: Implement glob delegation - #124135

Merged
bors merged 1 commit into
rust-lang:masterfrom
petrochenkov:deleglob
Jun 19, 2024
Merged

delegation: Implement glob delegation#124135
bors merged 1 commit into
rust-lang:masterfrom
petrochenkov:deleglob

Conversation

@petrochenkov

@petrochenkovpetrochenkov commented Apr 18, 2024

Copy link
Copy Markdown
Contributor

Support delegating to all trait methods in one go.
Overriding globs with explicit definitions is also supported.

The implementation is generally based on the design from rust-lang/rfcs#3530 (comment), but unlike with list delegation in #123413 we cannot expand glob delegation eagerly.
We have to enqueue it into the queue of unexpanded macros (most other macros are processed this way too), and then a glob delegation waits in that queue until its trait path is resolved, and enough code expands to generate the identifier list produced from the glob.

Glob delegation is only allowed in impls, and can only point to traits.
Supporting it in other places gives very little practical benefit, but significantly raises the implementation complexity.

Part of #118212.

@rustbot

Copy link
Copy Markdown
Collaborator

r? @estebank

rustbot has assigned @estebank.
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

@rustbotrustbot 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 Apr 18, 2024
@petrochenkovpetrochenkov 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 Apr 18, 2024
@rustbot

Copy link
Copy Markdown
Collaborator

Some changes occurred in src/tools/rustfmt

cc @rust-lang/rustfmt

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@fmease

Copy link
Copy Markdown
Member

I guess it makes the most sense if I review this one, too.

r? fmease

@rustbotrustbot assigned fmease and unassigned estebankApr 23, 2024
@petrochenkov

Copy link
Copy Markdown
ContributorAuthor

This is basically blocked on #123413 now.
@rustbot blocked

@rustbotrustbot added S-blocked Status: Blocked on something else such as an RFC or other implementation work. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Apr 23, 2024
bors added a commit to rust-lang-ci/rust that referenced this pull request May 15, 2024
delegation: Implement list delegation
```rust
reuse prefix::{a, b, c};
```
Using design described in rust-lang/rfcs#3530 (comment) (the lists are desugared at macro expansion time).
List delegations are expanded eagerly when encountered, similarly to `#[cfg]`s, and not enqueued for later resolution/expansion like regular macros or glob delegation (rust-lang#124135).
Part of rust-lang#118212.
@petrochenkovpetrochenkov added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-blocked Status: Blocked on something else such as an RFC or other implementation work. labels May 15, 2024
@petrochenkov
petrochenkovforce-pushed the deleglob branch 2 times, most recently from d4b3384 to c2af71aCompareMay 31, 2024 16:42
@petrochenkov

Copy link
Copy Markdown
ContributorAuthor

@rustbot ready

@rustbotrustbot 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 May 31, 2024

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

(partial review)

pub rename: Option<Ident>,
pub body: Option<P<Block>>,
/// The item was expanded from a glob delegation item.
pub from_glob: bool,

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.

(not blocking) maybe even with enum FromGlob { Yes, No }

pub prefix: Path,
pub suffixes: ThinVec<(Ident, Option<Ident>)>,
// Some for list delegation, and None for glob delegation.
pub suffixes: Option<ThinVec<(Ident, Option<Ident>)>>,

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.

(not blocking) maybe even enum DelegationMacKind { List(/*...*/), Glob }

Comment threadcompiler/rustc_expand/src/base.rs
Comment threadcompiler/rustc_expand/src/expand.rs
Comment threadcompiler/rustc_resolve/src/macros.rs
Comment threadcompiler/rustc_expand/src/expand.rs Outdated

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.

Overriding globs with explicit definitions is also supported.

With that, I thought you meant sth. like reuse prefix::{*, src as dest}; which is obviously not the case. Do you plan on supporting that eventually?

@petrochenkovpetrochenkovJun 7, 2024

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Overriding typically means the function body is different, or at least the "target expression" is different.

reuse prefix::*{self.field}
fn override1(){overridden_body()}
reuse prefix::override2{ self.other_field }

In your example the body and the target expr are the same, only the name is different, which doesn't seem too useful.
But it can be supported, I guess, it should be pretty simple to do it as a part of list delegation expansion.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Nested lists could also be supported, but that's a significant complication for very little gain.
I sort of regret supporting them in use items.

Comment threadcompiler/rustc_expand/src/expand.rs

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

23/28 viewed (continuing in a sec)


struct S;
impl S {
reuse Trait::*; //~ ERROR empty glob delegation is not supported

@fmeasefmeaseJun 13, 2024

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.

(non-blocking) we probably want to permit that at some point. might be useful for macro authors generating reuse (similar how we permit struct S<T:>(T);, struct S where String:,;, fn f<T: Copy +>(){} and the like for flexibility)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

In this case it's annoying to support because Trait (and possible generic arguments in it), still needs to be checked for stability, privacy, etc.
So we'll have to keep an otherwise unnecessary dummy item after expansion, and even in HIR, to perform these checks.

Comment threadtests/ui/delegation/glob-glob-conflict.rs

struct Bad(u8);
impl Trait for Bad { //~ ERROR not all trait items implemented, missing: `CONST`, `Type`, `method`
reuse Trait::* { &self.0 }

@fmeasefmeaseJun 13, 2024

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.

(non-blocking) What do you think about skipping any non-fns? Not sure if that'd be less or more confusing for users. The diagnostics right now are certainly not helping the uninitiated ^^

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

The plan is to eventually support delegating non-function associated items too.
For now they are just supposed to report some kind of error (which they do).
I agree that the current error is suboptimal, but that's not very critical.

Comment threadtests/ui/delegation/glob-non-impl.stderr Outdated
macro_rules! u8 { () => { u8 } }
macro_rules! self_0 { () => { &self.0 } }
impl Trait for S {
reuse <u8!() as Trait>::* { self_0!() }

@fmeasefmeaseJun 13, 2024

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.

I'm surprised to see self_0 having access to the local binding self. Isn't this breaking hygiene rules? For comparison with normal functions, see this playground.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Yeah, looks like a hygiene bug.
We'll need to decide what the "expected" context for self should be inherited from (since there's no explicit definition for it, like in regular methods).
Perhaps from *, but we don't keep the *'s precise span right now.

@petrochenkovpetrochenkovJun 14, 2024

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

This is a pre-existing issue with the way in which the self binding is created, not related to glob delegation, I'll fix this separately.
(Upd: I've pushed the fix into this PR, but I'll move it to a new PR with a test.)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

PR - #126497

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Jun 15, 2024
…rrors
delegation: Fix hygiene for `self`
And fix diagnostics for `self` from a macro.
The missing rib caused `self` to be treated as a generic parameter and ignore `macro_rules` hygiene.
Addresses this comment rust-lang#124135 (comment).
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Jun 15, 2024
Rollup merge of rust-lang#126497 - petrochenkov:delehyg, r=compiler-errors
delegation: Fix hygiene for `self`
And fix diagnostics for `self` from a macro.
The missing rib caused `self` to be treated as a generic parameter and ignore `macro_rules` hygiene.
Addresses this comment rust-lang#124135 (comment).

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

Thanks a lot! Sorry for the long review times

) -> impl Iterator<Item = ast::Item<Node::ItemKind>> + 'a {
if suffixes.is_empty() {
// Report an error for now, to avoid keeping stem for resolution and
// stability checks.

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.

👍

@fmease

Copy link
Copy Markdown
Member

I guess this doesn't require a rebase (despite #126497) 🤔
@bors r+

@bors

bors commented Jun 18, 2024

Copy link
Copy Markdown
Collaborator

📌 Commit 22d0b1e has been approved by fmease

It is now in the queue for this repository.

@borsbors 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 Jun 18, 2024
jieyouxu added a commit to jieyouxu/rust that referenced this pull request Jun 19, 2024
delegation: Implement glob delegation
Support delegating to all trait methods in one go.
Overriding globs with explicit definitions is also supported.
The implementation is generally based on the design from rust-lang/rfcs#3530 (comment), but unlike with list delegation in rust-lang#123413 we cannot expand glob delegation eagerly.
We have to enqueue it into the queue of unexpanded macros (most other macros are processed this way too), and then a glob delegation waits in that queue until its trait path is resolved, and enough code expands to generate the identifier list produced from the glob.
Glob delegation is only allowed in impls, and can only point to traits.
Supporting it in other places gives very little practical benefit, but significantly raises the implementation complexity.
Part of rust-lang#118212.
This was referenced Jun 19, 2024
bors added a commit to rust-lang-ci/rust that referenced this pull request Jun 19, 2024
Rollup of 10 pull requests
Successful merges:
- rust-lang#124135 (delegation: Implement glob delegation)
- rust-lang#125078 (fix: break inside async closure has incorrect span for enclosing closure)
- rust-lang#125293 (Place tail expression behind terminating scope)
- rust-lang#126422 (Suggest using a standalone doctest for non-local impl defs)
- rust-lang#126493 (safe transmute: support non-ZST, variantful, uninhabited enums)
- rust-lang#126504 (Sync fuchsia test runner with clang test runner)
- rust-lang#126558 (hir_typeck: be more conservative in making "note caller chooses ty param" note)
- rust-lang#126586 (Add `@badboy` and `@BlackHoleFox` as Mac Catalyst maintainers)
- rust-lang#126615 (Add `rustc-ice*` to `.gitignore`)
- rust-lang#126632 (Replace `move||` with `move ||`)
r? `@ghost`
`@rustbot` modify labels: rollup
@bors
bors merged commit f8ce1cf into rust-lang:masterJun 19, 2024
@rustbotrustbot added this to the 1.81.0 milestone Jun 19, 2024
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Jun 19, 2024
Rollup merge of rust-lang#124135 - petrochenkov:deleglob, r=fmease
delegation: Implement glob delegation
Support delegating to all trait methods in one go.
Overriding globs with explicit definitions is also supported.
The implementation is generally based on the design from rust-lang/rfcs#3530 (comment), but unlike with list delegation in rust-lang#123413 we cannot expand glob delegation eagerly.
We have to enqueue it into the queue of unexpanded macros (most other macros are processed this way too), and then a glob delegation waits in that queue until its trait path is resolved, and enough code expands to generate the identifier list produced from the glob.
Glob delegation is only allowed in impls, and can only point to traits.
Supporting it in other places gives very little practical benefit, but significantly raises the implementation complexity.
Part of rust-lang#118212.
@petrochenkovpetrochenkov added the F-fn_delegation `#![feature(fn_delegation)]` label Jun 24, 2024
@petrochenkov
petrochenkov deleted the deleglob branch February 22, 2025 18:38
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

F-fn_delegation`#![feature(fn_delegation)]`S-waiting-on-borsStatus: Waiting on bors to run and complete tests. Bors will change the label on completion.T-compilerRelevant 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.

6 participants

@petrochenkov@rustbot@rust-log-analyzer@fmease@bors@estebank