Skip to content

New Attribute Syntax (#2569) #12538

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

Closed

Conversation

thehydroimpulse
Copy link
Contributor

This implements the currently leading (inner) attribute syntax (#2569) while keeping backwards compatibility. Everything compiles and passes (including two new tests).

New Syntax:

inner: #![foo(bar)] (without a semicolon)
outer: stays the same.

The new syntax also supports semicolons for backward compability.

@thehydroimpulse
Copy link
Contributor Author

Oops, forgot to remove debug print statements.

@brson
Copy link
Contributor

brson commented Feb 26, 2014

I feel good about this solution, and commend you @thehydroimpulse for taking the initiative to push it through.

@pnkfelix Can you deal without the semis?

@brson
Copy link
Contributor

brson commented Feb 26, 2014

@pcwalton You may have an opinion too.

@thehydroimpulse
Copy link
Contributor Author

@brson Added two warning statements when using the old syntax. (One for the missing ! and the other for a useless ;)

@huonw
Copy link
Member

huonw commented Feb 26, 2014

I think the warnings should be commented out until a snapshot and the main codebase has been migrated to the new syntax, or every build will be really noisy.

@thehydroimpulse
Copy link
Contributor Author

@huonw The builds were definitely way too noisy, so I commented the warnings.

@pnkfelix
Copy link
Member

@brson if the brackets stay, i can live without the semis. (it's not worth further belaboring at that point.)

If there is any chance of the square brackets going away, then I will want the semis back. But right now we continue to have a clear end-delimiter, So it's okay.

@brson
Copy link
Contributor

brson commented Feb 26, 2014

This needs a test that a #![foo] on the first line of a file is interpreted as an attribute and not a shebang. That test will need an // ignore-license.

@thehydroimpulse
Copy link
Contributor Author

@brson Added the shebang test. Not sure if it's correct or not, but everything passes.

inner_attr_bang = true;
if !permit_inner {
self.fatal("An inner attribute was not permitted in this context.");
}
Copy link
Member

Choose a reason for hiding this comment

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

There should be a test for this case (inner attribute when you're not expecting it)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ahh, yes.

Is there a prime case for when it's not expecting one? For example, not at the top of some file/module.

fn main() {}

#![lang(foo)]
fn foo() {}

Something like that?

Copy link
Member

Choose a reason for hiding this comment

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

Looks like a good test to me.

Copy link
Member

Choose a reason for hiding this comment

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

BTW, error messages should start with lower case (i.e. "an inner ...")

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@huonw Good to know, thanks.

@alexcrichton
Copy link
Member

I think @brson was thinking of a test that looks like:

#![some_outer_attribute]
// ignore-license

fn main() {}

Also, I don't think this should change the pretty printer right now (because we're just accepting the #![ syntax, not changing to it), but it would be nice for this to identify the relevant location in the pretty printer to get modified when this merges and gets a snapshot. Not required, but would be nice to have!

@thehydroimpulse
Copy link
Contributor Author

@alexcrichton Ahh, ok. I'll fix that.

@brson
Copy link
Contributor

brson commented Feb 27, 2014

I think this is the ideal test case:

#![main]
// ignore-license
fn foo() {}

Makeing the attribute something real will prevent a false-negative that just parses the attribute as a shebang and throws it away.

@huonw
Copy link
Member

huonw commented Feb 27, 2014

Preferably the other tests would do the same:

mod foo {}
mod foo {
     #![cfg(this_will_never_occur)]
}
fn main() {}

then if the cfg isn't parsed correctly there will be two mod foo's and the compiler will throw an error.

@thehydroimpulse
Copy link
Contributor Author

@brson @alexcrichton Added a new commit addressing all of the comments. I'll squash my commits once everything is good.

@bstrie
Copy link
Contributor

bstrie commented Feb 27, 2014

If we're going to make further changes to the attribute syntax by removing brackets, I think it would make more sense to do it all at once.

I also disagree with pnkfelix, in that I don't think that bracket-less attributes need semicolons to delimit them. They're perfectly readable without the trailing delimeter, and using semicolons there just leads people into thinking that they're statements.

@liigo
Copy link
Contributor

liigo commented Feb 27, 2014

2014年2月27日 下午10:49于 "Ben Striegel" notifications@github.com写道:

If we're going to make further changes to the attribute syntax by
removing brackets, I think it would make more sense to do it all at once.

I also disagree with pnkfelix, in that I don't think that bracket-less
attributes need semicolons to delimit them. They're perfectly readable
without the trailing delimeter, and using semicolons there just leads
people into thinking that they're statements.

+1

Reply to this email directly or view it on GitHub.

@pnkfelix
Copy link
Member

@bstrie I guess we will just have to agree to disagree on this point. I've already posted my reasoning behind why using semicolons as a terminator is not inconsistent (in a comment on #2569), and you and I have already posted our disagreement on this point there. At this point I'm sorry I even brought it up again.

@liigo
Copy link
Contributor

liigo commented Feb 27, 2014

Even without the brackets and semicolon, we can still parse attributes
syntax properly. I don't know why need them. Please remove them all, which
are useless at all.
2014年2月27日 下午11:44于 "Felix S Klock II" notifications@github.com写道:

@bstrie https://github.com/bstrie I guess we will just have to agree to
disagree on this point. I've already posted my reasoning behind why using
semicolons as a terminator is not inconsistent (in a comment on #2569http://../2569#issuecomment-21098112).
At this point I'm sorry I even brought it up again.


Reply to this email directly or view it on GitHubhttps://github.com//pull/12538#issuecomment-36255215
.

@pnkfelix
Copy link
Member

@liigo Until #11886 lands, one needs a terminator to tell whether an attribute is #!foo = bar or if it is just #!foo. Now, that terminator could be the end-of-line, which may be what you were thinking. But as noted in previous comments we do not currently treat end-of-line as significant except for // comments.

(The above note is just about parser-ambiguities; a separate topic from the question of user-experience, which I am also concerned about, but is more subjective and/or requires user testing for which we do not have resources currently.)

(Also, for outer attributes, the item itself acts as a the terminator, which I believe is why the previous bracket-less suggestion terminated by semi-colons would have "worked." But at this point I have said I am fine with the approach outlined on this ticket.)

@brson
Copy link
Contributor

brson commented Feb 28, 2014

@thehydroimpulse I've told you wrong on the attr-shebang test. What we're trying to test for is that rust doesn't interpret an inner attribute on the first line as a shebang (Rust ignores shebangs), but the test case I gave you uses an outer attr instead of inner.

Something like this might be more appropriate:

#![allow(unknown_features)]
#![feature(bogus)]
fn main() { }

The code for parsing shebangs is here.

From reading it, it will interpret the the first two bytes of a file being '#!' as a shebang. I think the rule should be more like: if the first two characters are '#!' and the first three characters not counting whitespace are not '#![', then discard the first line as a shebang.

Note that unfortunately there's a second shebang parser here that is just used for pretty printing. That also needs to be changed to follow the same rule.

self.fatal("an inner attribute was not permitted in this context.");
}
} else {
warned = true;
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 think warned is necessary. The message here is different from the warn below. Although the refer to the same new syntax, they are warning about different things.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@flaper87 There was two warning calls for using the old syntax. The second warn is just about the extra semicolon though, so I see your point. But, any old syntax will now print one warning instead of two.

@alexcrichton
Copy link
Member

@thehydroimpulse, it looks like @brson's comment about shebangs still needs to get addressed. If you're running low on time, though, I can take over if you want!

@thehydroimpulse
Copy link
Contributor Author

Yup. I just need to push my changes which I'll do that today.
On Mar 10, 2014 2:13 PM, "Alex Crichton" notifications@github.com wrote:

@thehydroimpulse https://github.com/TheHydroImpulse, it looks like
@brson https://github.com/brson's comment about shebangs still needs to
get addressed. If you're running low on time, though, I can take over if
you want!

Reply to this email directly or view it on GitHubhttps://github.com//pull/12538#issuecomment-37228418
.

@thehydroimpulse
Copy link
Contributor Author

@alexcrichton I've been getting the same error from Travis locally, too. Not sure what's going on. Rebase, re-configuring, and cleaning doesn't fix it.

/home/travis/build/mozilla/rust/src/libstd/lib.rs:72:14: 72:34 error: can't find crate for `rustuv`
/home/travis/build/mozilla/rust/src/libstd/lib.rs:72 #[cfg(test)] extern crate rustuv;


// EFFECT: Peek 'n' characters ahead.
pub fn peek(rdr: &StringReader, n: uint) -> Option<char> {
let offset = byte_offset(rdr, rdr.pos.get()).to_uint() + (n - 1);
Copy link
Member

Choose a reason for hiding this comment

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

This seems to be a dubious method, because this isn't looking n characters ahead, but rather n bytes ahead.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ahh, makes sense. I basically followed what nextch had, but also having the ability to specify more than one to be peeked. This was the simpler option to forget/rollback.

@alexcrichton
Copy link
Member

That test failure looks like the attributes aren't getting parsed correctly. Looking at the code, I'm not entirely sure why, but I would recommend dumping the AST of some small programs to take a look at what's happening with the attributes.


let style = if permit_inner {

if self.eat(&token::SEMI) {
Copy link
Member

Choose a reason for hiding this comment

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

Judging by the previous if statement, it looks like this should be structured as if permit_inner && self.eat(&token::SEMI) rather than permit_inner always parsing an inner attribute.

Copy link
Member

Choose a reason for hiding this comment

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

This logic should also change, the semicolon no longer dictates whether it's an inner attribute, something will need to get done when the ! is parsed.

@alexcrichton
Copy link
Member

@thehydroimpulse it'd be awesome to get this in for the 0.10 release (coming up soon-ish), would you like me to rebase and take over?

@thehydroimpulse
Copy link
Contributor Author

Yeah, I botched my setup on this branch and can't seem to rebuild it. So
go ahead and take it over if you wish.
On Mar 20, 2014 11:40 AM, "Alex Crichton" notifications@github.com wrote:

@thehydroimpulse https://github.com/TheHydroImpulse it'd be awesome to
get this in for the 0.10 release (coming up soon-ish), would you like me to
rebase and take over?

Reply to this email directly or view it on GitHubhttps://github.com//pull/12538#issuecomment-38197949
.

@alexcrichton
Copy link
Member

Ok, thanks for your work!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants