Skip to content
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

Implement PartialEq for proc_macro::Ident == strings #78634

Closed
wants to merge 2 commits into from

Conversation

dtolnay
Copy link
Member

@dtolnay dtolnay commented Nov 1, 2020

impl PartialEq<str> for Ident
impl PartialEq<String> for Ident
impl<'a, T> PartialEq<&'a T> for Ident
where
    T: ?Sized,
    Ident: PartialEq<T>

Closes #51074.

We avoid implementing PartialEq<Ident> because "comparison in vacuum doesn't generally make sense in presence of hygiene and it became a source of bugs" --- see #51074 (comment). However, comparing an Ident to a string is "probably explicit enough" --- see #51074 (comment).

The use case is to support attribute parsing, among other things. For example parsing #[serde(rename = "...")] might involve if ident == "serde" and if ident == "rename".

@rust-highfive
Copy link
Collaborator

r? @petrochenkov

(rust_highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Nov 1, 2020
@jyn514 jyn514 added A-proc-macros Area: Procedural macros T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. labels Nov 1, 2020
@est31
Copy link
Member

est31 commented Nov 1, 2020

👍 Recently I've looked for an allocation free method for comparing idents with str's and couldn't find one. Had to use to_string which allocates.

@petrochenkov petrochenkov added I-nominated S-waiting-on-team Status: Awaiting decision from the relevant subteam (see the T-<team> label). and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Nov 1, 2020
@petrochenkov
Copy link
Contributor

I've nominated both this PR and the char PR for the libs team since they are instant stabilizations.
Both look reasonable to me.

@dtolnay
Copy link
Member Author

dtolnay commented Nov 1, 2020

@rfcbot fcp merge

@rfcbot
Copy link

rfcbot commented Nov 1, 2020

Team member @dtolnay has proposed to merge this. The next step is review by the rest of the tagged team members:

No concerns currently listed.

Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

See this document for info about what commands tagged team members can give me.

@rfcbot rfcbot added proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. labels Nov 1, 2020
@c410-f3r
Copy link
Contributor

c410-f3r commented Nov 2, 2020

cc #59070

@est31
Copy link
Member

est31 commented Nov 2, 2020

I thought about this a little. I wonder about raw vs non-raw idents and whether there should be something to accommodate for it. As in, should an Ident r#hello compare equal with "hello" or not.

If you are checking for keywords, then you don't want them to compare equal to each other. If you are checking for variable/function names etc, then usually you want r#hello be equivalent to "hello". So the problem is not solved by changing defaults (making r#hello compare equal with "hello").

In my puny little proc macro that I'm writing, I'm mainly comparing with keywords, so having them be not equal is good for me, but maybe some folks want to compare to function/variable names and they'll have to do if id == "hello" || id == "r#hello".

Maybe there could be a function like fn ignore_rawness(&self) -> IdentRawnessIgnored<'a> which impl's eq with strings as well, but ignores the rawness? There might also be "raw keywords" in the future which always eval to keywords, making it easier to use new keywords. Then maybe a different name would be nicer. I think both can be added backwards compatibly, and I think id == "hello" is a good shorthand for id.to_string() == "hello", so this PR is a step into the right direction. But important to keep this in mind.

@dtolnay
Copy link
Member Author

dtolnay commented Nov 2, 2020

We do pretty much that in Syn. There is a function unraw (https://docs.rs/syn/1.0.48/syn/ext/trait.IdentExt.html#tymethod.unraw) with signature &Ident -> Ident, so e.g. you'd write ident.unraw() == "value".

@rfcbot rfcbot added the final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. label Nov 12, 2020
@rfcbot
Copy link

rfcbot commented Nov 12, 2020

🔔 This is now entering its final comment period, as per the review above. 🔔

@rfcbot rfcbot removed the proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. label Nov 12, 2020
@petrochenkov
Copy link
Contributor

I've just checked and looks like the standard library doesn't currently any have any PartialEq impls recursively unwrapping references like #78634 (comment) does.

@dtolnay
Copy link
Member Author

dtolnay commented Nov 12, 2020

I am not dead set on that exact impl signature, but I have found some level of reference unwrapping quite key in practice specifically for Ident. proc_macro2 accomplishes the reference unwrapping by having:

impl<T> PartialEq<T> for Ident
where
    T: ?Sized + AsRef<str>;

where String and str obviously implement AsRef<str>, and then &U implements AsRef<str> whenever U does, unwrapping any number of layers of references via this impl:

impl<U, V> AsRef<V> for &'_ U
where
    U: ?Sized + AsRef<V>,
    V: ?Sized;

However I felt AsRef<str> was maybe too vague of a bound to use for proc_macro::Ident and preferred requiring the rhs to provide a PartialEq explicitly instead in order to compare with Ident.

@rfcbot rfcbot added finished-final-comment-period The final comment period is finished for this PR / Issue. and removed final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. labels Nov 22, 2020
@rfcbot
Copy link

rfcbot commented Nov 22, 2020

The final comment period, with a disposition to merge, as per the review above, is now complete.

As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed.

The RFC will be merged soon.

@rfcbot rfcbot added the to-announce Announce this issue on triage meeting label Nov 22, 2020
let _ = ident == "serde";
let _ = *ident == "serde";
let _ = *ident == string;
let _ = *ident == &&&string;
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you add some tests for raw identifiers?

@petrochenkov petrochenkov 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-team Status: Awaiting decision from the relevant subteam (see the T-<team> label). labels Nov 23, 2020
@bors
Copy link
Contributor

bors commented Nov 24, 2020

☔ The latest upstream changes (presumably #78636) made this pull request unmergeable. Please resolve the merge conflicts.

Note that reviewers usually do not review pull requests until merge conflicts are resolved! Once you resolve the conflicts, you should change the labels applied by bors to indicate that your PR is ready for review. Post this as a comment to change the labels:

@rustbot modify labels: +S-waiting-on-review -S-waiting-on-author

@spastorino spastorino removed the to-announce Announce this issue on triage meeting label Dec 3, 2020
@m-ou-se
Copy link
Member

m-ou-se commented Dec 8, 2020

I've just checked and looks like the standard library doesn't currently any have any PartialEq impls recursively unwrapping references like #78634 (comment) does.

This concern was discussed in the libs team meeting of 2020-11-18. Although this hasn't been done before in std, the consensus was that this is fine in this proc_macro addition.

(Thanks for pointing it out!)

@crlf0710 crlf0710 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-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jan 15, 2021
@JohnCSimon JohnCSimon 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-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Feb 8, 2021
@petrochenkov
Copy link
Contributor

Closing due to inactivity.

@dtolnay dtolnay deleted the identeq branch March 30, 2021 00:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-proc-macros Area: Procedural macros disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. finished-final-comment-period The final comment period is finished for this PR / Issue. S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implement PartialEq for Ident, PartialEq for TokenStream