Skip to content

Implement tool_attributes feature (RFC 2103) #47773

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
wants to merge 7 commits into from

Conversation

topecongiro
Copy link
Contributor

This PR implements a tool_attributes feature. If this implementaion is acceptable, I am going to create a similar PR that implements tool_lints.

This PR only adds rustfmt and clippy to known tool name list. The list resides in libsyntax/attr.rs.

cc #44690.

r? @nrc

@petrochenkov petrochenkov self-assigned this Jan 26, 2018
@petrochenkov petrochenkov added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jan 26, 2018
@topecongiro
Copy link
Contributor Author

Hmm. Should I add the section to the unstable book after this PR is merged, or am I missing something? I followed the instruction in https://forge.rust-lang.org/feature-guide.html.

@kennytm
Copy link
Member

kennytm commented Jan 26, 2018

@topecongiro The problem is that unstable book file should be written in hyphenated lower case. Try to rename it as tool-attributes.md.

@topecongiro
Copy link
Contributor Author

@kennytm Thank you!

#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct MetaItem {
pub name: Name,
pub name: MetaItemName,
pub node: MetaItemKind,
pub span: Span,
Copy link
Contributor

@petrochenkov petrochenkov Jan 27, 2018

Choose a reason for hiding this comment

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

Contents of ast::Attribute and ast::MetaItem are the same thing by definition, but in the compiler they diverged significantly in recent months.
An attribute is a "macro invocation" that consists of a Path and a TokenStream, MetaItem should have the same structure and they should share code, ideally.
I'd rather do this refactoring instead of adding temporary hacks like Vec<Name>, preferably in a separate PR.

(The attribute/meta-item Path goes through usual path resolution procedure, and that's where resolution of the "tool module" rustfmt or clippy should be added as well, ideally.)

Copy link
Member

@nrc nrc left a comment

Choose a reason for hiding this comment

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

This looks fine to me, but I think someone more active in compiler work should sign off too.

/// Unscoped name, e.g. `name` in `#[name(..)]`.
Single(Name),
/// Scoped name, e.g. `rustfmt::skip` in `#[rustfmt::skip]`.
Scoped(Vec<Name>),
Copy link
Member

Choose a reason for hiding this comment

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

Could we use a Path here, rather than Vec<Name>?

Copy link
Member

Choose a reason for hiding this comment

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

In fact I wonder if we could use Path instead of MetaItemName and always treat attributes as paths rather than names (we have to do this for macro attributes anyway)

@nrc
Copy link
Member

nrc commented Jan 29, 2018

r? @petrochenkov

@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-review Status: Awaiting review from the assignee but also interested parties. labels Jan 29, 2018
@topecongiro
Copy link
Contributor Author

topecongiro commented Jan 29, 2018

@petrochenkov @nrc Thank you for you reviews!

So I am going to replace MetaItemName with Path, and move the tool name checking from feature_gate.rs to somewhere in parser code.

EDIT: I actually kept the tool name checking in feature_gate.rs.

@topecongiro topecongiro force-pushed the rfc2103 branch 2 times, most recently from 54f59e1 to b6a9355 Compare January 30, 2018 10:31
@@ -708,6 +708,22 @@ pub trait PrintState<'a> {
Ok(())
}

fn print_attribute_path(&mut self, path: &ast::Path) -> io::Result<()> {
Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like existing print_path can be used instead of introducing this new function.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

print_path is not a method of PrintState trait, so I am not sure how to exploit it. Should I write like self.writer().word(&path_to_string(path))?

@petrochenkov
Copy link
Contributor

The Travis CI build failed

rustdoc build fails

let (span, name) = match tokens.next() {
Some(TokenTree::Token(span, Token::Ident(ident))) => (span, ident.name),
let name = match tokens.next() {
Some(TokenTree::Token(span, Token::Ident(ident))) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

This looks like an imitation of parse_path, but I don't know how make the normal version and tokenstream version reuse the same code.
Could you leave a FIXME comment here?

@@ -1972,26 +1972,6 @@ impl<'a> Parser<'a> {
Ok(ast::Path { segments, span: lo.to(self.prev_span) })
}

/// Like `parse_path`, but also supports parsing `Word` meta items into paths for back-compat.
Copy link
Contributor

Choose a reason for hiding this comment

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

Where does this special back-compat support of Word meta items happen now?

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh, wait parse_path_allowing_meta is reintroduced in the next commit.

@@ -205,6 +211,10 @@ impl NestedMetaItem {
}
}

fn name_from_path(path: &ast::Path) -> Name {
path.segments.iter().next().unwrap().identifier.name
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 use the last segment instead?
In #[a::b::c] a and b are modules (possibly "tool modules") in which the attribute c is defined, and the last segment c is the attribute itself.

added to it in the future",
attr.path));
if attr.is_scoped() {
gate_feature!(self, tool_attributes, attr.span,
Copy link
Contributor

Choose a reason for hiding this comment

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

This solution is 100% technical debt, but I guess it can work while everything is unstable, and we go into this branch only if previous ways to resolve the attribute failed.

I described the proper solution in rust-lang/rfcs#2103 (comment).
TLDR: a::b::c in #[a::b::c(...)] should be resolved as a usual path in macro namespace and therefore rustfmt and clippy should be added into the language prelude as special modules (primitive types u8, u16, etc work in very similar way).
I don't suggest to implement this now though.

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't suggest to implement this now though.

But I suggest to implement this eventually, if you plan to continue working on macros/attributes and name resolution in rustc.

self.parse_sess.span_diagnostic,
attr.span,
E0693,
"An unkown tool name found in scoped attributes: `{}`.",
Copy link
Contributor

Choose a reason for hiding this comment

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

Typo "unkown" -> "unknown"

@topecongiro
Copy link
Contributor Author

@petrochenkov Thank you for your reviews and I am sorry for the late reply. I hope that I can update this PR today...

@petrochenkov
Copy link
Contributor

@bors r+

@bors
Copy link
Collaborator

bors commented Feb 4, 2018

📌 Commit 30214c9 has been approved by petrochenkov

@kennytm kennytm 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-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Feb 4, 2018
@bors
Copy link
Collaborator

bors commented Feb 4, 2018

⌛ Testing commit 30214c90d560ddc3b6e83992f34afb340dd43d5e with merge cac046403a27dd42eb53ef8b9c94801592a12b5d...

@bors
Copy link
Collaborator

bors commented Feb 4, 2018

💔 Test failed - status-travis

@topecongiro
Copy link
Contributor Author

Rebased against master.

I have a problem reproducing the above failures locally... running ./x.py test src/test/run-pass-fulldeps/ does succeed without any failure.

@kennytm kennytm 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 Feb 12, 2018
@petrochenkov
Copy link
Contributor

@topecongiro
This is actually a pretty-printing test, not run-pass-fulldeps test itself.
This should be reproducible with ./x.py test src/test/run-pass-fulldeps/pretty.

It is possible that this is an expected pretty-printer failure, then you can disable the test with // ignore-pretty if you are sure this is not this PR's fault.

@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-review Status: Awaiting review from the assignee but also interested parties. labels Feb 12, 2018
@topecongiro
Copy link
Contributor Author

@petrochenkov Thank you for your advice, I could reproduce this locally.

I cannot tell whether this is an expected pretty-printer failure or not. I looked at the original PR that added this test (#40346). It looks like now arbitrary tokens could appear as arguments to procedural macros. So I guess that this PR is trying to parse random tokens inside procedural macros as some valid paths when it shouldn't? Again, I am not sure, though.

self.parse_sess.span_diagnostic,
attr.span,
E0693,
"An unknown tool name found in scoped attributes: `{}`.",
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: error messages conventionally start with a lower-case letter.
(Same in the feature gate message below.)

@petrochenkov
Copy link
Contributor

@topecongiro
Pretty-printed code from run-pass-fulldeps/proc-macro/derive-b is identical before and after this PR, so the only difference is how name resolution treats B in #[cfg_attr(all(), B arbitrary tokens)].

I don't quite see where is the difference in name resolution comes from. Please make sure the logic for single-segment attribute paths is identical to what it was before. For example, fn name previously returned None for multi-segment attribute paths and now it's always successful, maybe it unintendedly makes difference somewhere.

@pietroalbini
Copy link
Member

@topecongiro can you fix that failing test so the PR can be merged?

@bors
Copy link
Collaborator

bors commented Feb 25, 2018

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

@shepmaster
Copy link
Member

Thank you for your hard work, @topecongiro ! However, we haven't heard from you in a few weeks, so I'm going to close this PR for now to keep the queue tidy. Please feel free to reopen this when you have a chance to fix the merge conflicts and the failing test.

@shepmaster shepmaster closed this Mar 2, 2018
@shepmaster shepmaster added S-inactive Status: Inactive and waiting on the author. This is often applied to closed PRs. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Mar 2, 2018
bors added a commit that referenced this pull request May 3, 2018
Implement tool_attributes feature (RFC 2103)

cc #44690

This is currently just a rebased and compiling (hopefully) version of #47773.

Let's see if travis likes this. I will add the implementation for `tool_lints` this week.
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
S-inactive Status: Inactive and waiting on the author. This is often applied to closed PRs.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants