-
-
Notifications
You must be signed in to change notification settings - Fork 14.2k
Support syntax for one-line trait reuse #150130
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Support syntax for one-line trait reuse #150130
Conversation
43b3a47 to
829d1bf
Compare
| // no: `reuse ::path` for compatibility reasons with macro invocations | ||
| if self.look_ahead(LOOK_AHEAD_DIST, |t| t.is_path_start() && *t != token::PathSep) { | ||
| Some(ReuseKind::Path) | ||
| } else if self.look_ahead_check_impl_frontmatter(LOOK_AHEAD_DIST) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why disabling the diagnostics here instead of using the old check_impl_frontmatter?
| let deleg = DelegationMac { qself, prefix: path, suffixes, body: body(self)? }; | ||
| ItemKind::DelegationMac(Box::new(deleg)) | ||
|
|
||
| Ok(ItemKind::DelegationMac(Box::new(DelegationMac { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| Ok(ItemKind::DelegationMac(Box::new(DelegationMac { | |
| ItemKind::DelegationMac(Box::new(DelegationMac { |
Ok can be moved out of the condition.
| })); | ||
| }; | ||
|
|
||
| if matches!(of_trait.polarity, ImplPolarity::Negative(..)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a semantic error, not a parsing error.
I think we can just generate a negative trait impl here, it will be reported later.
| }, | ||
| kind: AssocItemKind::DelegationMac(Box::new(DelegationMac { | ||
| qself: None, | ||
| prefix: of_trait.trait_ref.path.clone(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, so you cannot do things like impl my_trait!() for Type {}.
This is good, it means the impl delegation desugaring won't result in duplicating macro calls, and the parsing-time treatment of the feature is not a very bad approximation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Items in the trait path will still get duplicated.
reuse impl Trait<{ struct S; 0 }> for Type {}
->
impl Trait<{ struct S; 0 }> for Type {
reuse Trait<{ struct S; 0 }>::*;
}, but that's probably ok because the glob delegation will duplicate the item too (?)
reuse Trait<{ struct S; 0 }>::foo;
reuse Trait<{ struct S; 0 }>::bar;
reuse Trait<{ struct S; 0 }>::baz;Could you maybe add an AST pretty-printing test for this case?
This PR adds support for reusing the whole trait with a one-line reuse syntax and is part of the delegation feature #118212:
The core idea is that we already have support for glob reuse, so in this scenario we want to transform one-line reuse into a trait impl block with a glob reuse in the following way:
It seems like this task can be solved during parsing stage, when we encountered a one-line trait reuse, we can expand into this impl block right away, and the code which was already written to expand glob delegations will take care about the rest. We will copy trait path into glob reuse path.
The implementation of the transformation reuses already existing methods for
implparsing, however, we do not parse innerimplitems, instead we parse "inner items" as delegation body. Thus, we do not have to deal with generics, consts, unsafe and otherimplrelated features.Other syntax possibility is trying to shorten one-line reuse by replacing
implkeyword withreusekeyword:In this case implementation may become more complicated, and the syntax more confusing, as keywords such as
constorunsafewill precedereuse, and there are also generics:In the first (currently implemented) version reuse is placed in the beginning of the item, and it is clear that we will reuse trait implementation, while in the second, shorter version, the
reusekeyword may be lost in generics and keywords that may precedeimpl.r? @petrochenkov