Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upFix bugs in macro-expanded statement parsing #34660
Conversation
rust-highfive
assigned
eddyb
Jul 5, 2016
This comment has been minimized.
This comment has been minimized.
|
Starting a crater run. |
This comment has been minimized.
This comment has been minimized.
|
@eddyb Thanks! |
jseyfried
referenced this pull request
Jul 5, 2016
Closed
Semicolons are not required on some statements in macros #34543
This comment has been minimized.
This comment has been minimized.
|
cc @nrc |
This comment has been minimized.
This comment has been minimized.
|
Crater report claims 42 root regressions (87 total). @jseyfried Apparently this change causes type-checking to find a mismatch between some type and |
jseyfried
force-pushed the
jseyfried:fix_parse_stmt
branch
from
9dbe21b
to
e94e014
Jul 5, 2016
This comment has been minimized.
This comment has been minimized.
|
@eddyb macro_rules! m { () => { 2; } }
fn f() -> i32 {
let _: i32 = m!(); // The semicolon after `2` is ignored, so this is typechecks.
m!() // Before f639fc3, this invocation is considered to be in an expression position,
// so the semicolon after the `2` is ignored and this typechecks.
//
// After f639fc3, the invocation is considered to be in a statement position, so
// the semicolon is not ignored and it expands into a `StmtKind::Semi` statement,
// which doesn't typecheck.
}I removed f639fc3, which fixed the breakage. However, removing f639fc3 also means that macro_rules! n { () => {
let _ = ();
m!() // this is no longer considered to be in a statement position like it was
// before this PR, which could potentially lead to more breakage.
}
fn main() { n!(); }If this causes breakage in practice, I could treat only macro-expanded macros in trailing expression positions as statements. |
This comment has been minimized.
This comment has been minimized.
|
@jseyfried Sheesh, that's awful. I'll start a second crater run. |
This comment has been minimized.
This comment has been minimized.
|
Hmm, this seems like a bug fix and therefore something we should land even if it does break code. Would it be possible to turn this into a warning for a cycle? (Doesn't seem easy to me). Otherwise we should submit a PR to nom and fix that bustage (if possible) before landing this. |
This comment has been minimized.
This comment has been minimized.
I think the only change we can't phase in with a warning cycle is making macros in trailing expression statement positions expand into statements, not expressions (i.e. f639fc3). While I prefer this change, it's not super important and I had only included it here to reduce breakage (which backfired). I'd like to land as much as we can in this PR without causing breakage in practice. After that, we can do a PR that adds a warning cycle for the rest. If @eddyb's crater run comes back clean, all that will remain is to forbid trailing macro-expanded macro_rules m! { () => {
let x = 0 //< This PR will not affect trailing let statements, i.e. this will still be allowed.
}}
fn main() { m!(); }If we want to, it would be easy to start a warning cycle for this (we haven't cratered it yet, but based on the fallout in |
This comment has been minimized.
This comment has been minimized.
|
Crater report has 7 confirmed root regressions (13 total), most of which are: expected expression, found `` |
jseyfried
force-pushed the
jseyfried:fix_parse_stmt
branch
from
30ea84e
to
b2b4dac
Jul 5, 2016
This comment has been minimized.
This comment has been minimized.
|
The above commit should fix the remaining breakage. |
This comment has been minimized.
This comment has been minimized.
|
even if crater comes back clean, there might still be breakage out there in projects or platforms not covered by crater. It might be worth having a warning cycle for any errors one might reasonably expect to occur. |
This comment has been minimized.
This comment has been minimized.
|
@nrc macro_rules! m { () => { let x = 0 } }
fn main() {
m!(); // Is this OK? I think not, but it might be too common in the wild
// to include in the warning cycle -- we haven't cratered it yet.
}The rest of the potential breakage comes from non-braced macro invocation expression statements requiring trailing semicolons (except at the end of a block). Warning for this would be significantly more involved, but is doable. |
This comment has been minimized.
This comment has been minimized.
|
@nrc Actually, not all remaining potential breakage is warnable. macro_rules! m { () => { () } }
macro_rules! n {
() => { m!() - 1 } // This is treated like "m!(); -1" today
}
fn main() { n!(); }and this doesn't compile today but does compile after this PR: macro_rules! m { () => { 2 } } //< The only difference is that the `()` is changed to a `2`
macro_rules! n {
() => { m!() - 1 }
}
fn main() { n!(); }Since we can't distinguish these cases until type-checking, a complete warning cycle is infeasible. |
This comment has been minimized.
This comment has been minimized.
|
@nrc @eddyb All the breakage so far has been due to macros that expand into one statement / expression. |
This comment has been minimized.
This comment has been minimized.
|
So, regarding what to warn on, I think we should do the right thing and warn wherever possible. We shouldn't preserve incorrect behaviour for the sake of preventing breakage, unless there is an overwhelming number of uses. So, for example, the @jseyfried I'm not sure I understand the second more complex examples - could you explain the rules that the macro system will be using with this PR? |
nrc
added
I-nominated
T-lang
T-compiler
labels
Jul 7, 2016
This comment has been minimized.
This comment has been minimized.
|
Nominating for discussion due to potential breakage. |
nrc
removed
I-nominated
T-compiler
T-lang
labels
Jul 7, 2016
This comment has been minimized.
This comment has been minimized.
|
un-nominating since this PR is turning into more of a bug fix and will avoid breakage after all. |
This comment has been minimized.
This comment has been minimized.
|
@eddyb: could you do a Crater run with this version of the PR please? |
nrc
reviewed
Jul 7, 2016
| @@ -117,12 +117,18 @@ impl<'a> MacResult for ParserAnyMacro<'a> { | |||
|
|
|||
| fn make_stmts(self: Box<ParserAnyMacro<'a>>) | |||
| -> Option<SmallVector<ast::Stmt>> { | |||
| let parse_stmt = |parser: &mut Parser<'a>| -> ::parse::PResult<'a, _> { | |||
This comment has been minimized.
This comment has been minimized.
nrc
Jul 7, 2016
Member
Could you comment on what this closure does (i.e., why you don't just use parser.parse_stmt)?
Could it be a function rather than a closure?
This comment has been minimized.
This comment has been minimized.
jseyfried
Jul 7, 2016
•
Author
Contributor
Good point, I'll replace the method finish_parsing_statement with something like parse_full_stmt and use that here instead of defining a closure.
This comment has been minimized.
This comment has been minimized.
nrc
reviewed
Jul 7, 2016
| span: span | ||
| }); | ||
| } | ||
| /// Finish parsing expressions that start with macros and handle trailing semicolons |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
jseyfried
Jul 7, 2016
Author
Contributor
Could be either, I'll change it to "expression statements" to be most precise.
jseyfried
referenced this pull request
Jul 7, 2016
Open
macros: Trailing expression statement macros expand inconsistently #34707
This comment has been minimized.
This comment has been minimized.
|
Discussed at the compiler meeting, if it is possible, we would like to do a warning cycle here. During which time, we could also submit PRs to the broken crates. @jseyfried how hard would it be to do a warning cycle for the current PR? cc @Manishearth - Clippy is one of the crates with breakage here, I expect it is an easy fix, it should just need adding a semicolon or two to a macro somewhere. |
This comment has been minimized.
This comment has been minimized.
|
@nrc The The |
This comment has been minimized.
This comment has been minimized.
|
|
jseyfried
added some commits
Jul 2, 2016
jseyfried
force-pushed the
jseyfried:fix_parse_stmt
branch
from
1ed1085
to
bf3cb4b
Jul 12, 2016
This comment has been minimized.
This comment has been minimized.
|
@nrc I rebased and started a best-effort warning cycle. |
jseyfried
force-pushed the
jseyfried:fix_parse_stmt
branch
from
bf3cb4b
to
f789bc0
Jul 12, 2016
jseyfried
added some commits
Jul 5, 2016
jseyfried
force-pushed the
jseyfried:fix_parse_stmt
branch
from
f789bc0
to
57fac56
Jul 13, 2016
This comment has been minimized.
This comment has been minimized.
|
@bors: r+ |
This comment has been minimized.
This comment has been minimized.
|
|
jseyfried commentedJul 5, 2016
•
edited
Fixes #34543.
This is a [breaking-change].
The following would
breakbe a warning (c.f. #34660 (comment)):r? @eddyb