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

Macro invocation with curly-braces as a statement #22

Closed
NalaGinrut opened this issue May 16, 2020 · 6 comments
Closed

Macro invocation with curly-braces as a statement #22

NalaGinrut opened this issue May 16, 2020 · 6 comments

Comments

@NalaGinrut
Copy link
Contributor

NalaGinrut commented May 16, 2020

This issue is related to 0378-expr-macros

  • Treat all macro invocations with parentheses, (), or square brackets, [], as expressions.
  • Curly braces or a semicolon following the invocation to invoke a macro as a statement

However, it seems that macro_invoce!{x} doesn't work for nightly rustc:

macro_rules! maybe_return { ($e:expr) => ($e); }

fn frob(x: i32) -> i32{
    maybe_return! {x}
    // should return -1 
    -1
}

The result is:

error[E0308]: mismatched types
 --> ma.rs:4:20
  |
4 |     maybe_return! {x}
  |                    ^- help: consider using a semicolon here
  |                    |
  |                    expected `()`, found `i32`

I may incorrectly understand the RFC description, anyway, I leave it here for a placeholder.

Our curent parser doesn't recogonize it too:

i32 frob(x : i32)
BlockExpr:
{
 outer attributes: none
 inner attributes: none
 statements: none
 final expression: 
ArithmeticOrLogicalExpr: MacroInvocation: maybe_return!{x} - 1
}
@SimplyTheOther
Copy link
Member

The RFC actually seems to be a bit ambiguous on what it really means, but the name of the RFC (expr-macros) and the name of the issue for the RFC ("Implement parse macro!()/macro![] as expr) implies to me that the primary point of the RFC is to force parsing macro invocations with parentheses or square brackets as an expression. As such, macro invocations with curly brackets can be parsed as an expression, but do not have to be.

That's just my interpretation of it, but it seems like it probably works with how rustc implements it.

TL;DR:

  • Treat all macro invocations with parentheses, (), or square brackets, [], as expressions.
  • If the macro invocation has curly brackets, {}, it may be parsed as a statement depending on the context.
  • If the macro invocation has a semicolon at the end, it must be parsed as a statement (either via ExpressionStatement or MacroInvocationWithSemi)

@NalaGinrut
Copy link
Contributor Author

@SimplyTheOther Yes, I realized that something in the RFC doesn't actually hold in the implementation, I'll try to point them out if I found them. At least for now, I think we should do what rustc does, and enhance them according to the ideas in RFC when the time is proper. After all, following the RFC could be one of our selling points.

cc @philberty

@philberty
Copy link
Member

Nice detective work on that i didn't know the RFC had forward name resolution on macros that's pretty neat. I've found the documentation of macros kind of lacking in rust so in my own programs I've always avoided them

@philberty philberty added this to To do in Control Flow 3 Macros via automation Jan 4, 2022
@philberty philberty added this to the Macro Expansion milestone Jan 4, 2022
@philberty philberty moved this from To do to In progress in Control Flow 3 Macros Feb 16, 2022
philberty added a commit that referenced this issue Feb 16, 2022
This is the first pass at implementing macros more testcases are needed.

This does not support repetition matchers but it supports simple
declarative macros and transcribes them. The approach taken here is that
we reuse our existing parser to call the apropriate functions as specified
as part of the MacroFragmentType enum if the parser does not have errors
parsing that item then it must be a match.

Then once we match a rule we have a map of the token begin/end offsets
for each fragment match, this is then used to adjust and create a new token
stream for the macro rule definition so that when we feed it to the parser
the tokens are already substituted. The resulting expression or item is
then attached to the respective macro invocation and this is then name
resolved and used for hir lowering.

Fixes #17 #22
Addresses #573
philberty added a commit that referenced this issue Feb 17, 2022
This is the first pass at implementing macros more testcases are needed.

This does not support repetition matchers but it supports simple
declarative macros and transcribes them. The approach taken here is that
we reuse our existing parser to call the apropriate functions as specified
as part of the MacroFragmentType enum if the parser does not have errors
parsing that item then it must be a match.

Then once we match a rule we have a map of the token begin/end offsets
for each fragment match, this is then used to adjust and create a new token
stream for the macro rule definition so that when we feed it to the parser
the tokens are already substituted. The resulting expression or item is
then attached to the respective macro invocation and this is then name
resolved and used for hir lowering.

Fixes #17 #22
Addresses #573
philberty added a commit that referenced this issue Feb 17, 2022
This is the first pass at implementing macros more testcases are needed.

This does not support repetition matchers but it supports simple
declarative macros and transcribes them. The approach taken here is that
we reuse our existing parser to call the apropriate functions as specified
as part of the MacroFragmentType enum if the parser does not have errors
parsing that item then it must be a match.

Then once we match a rule we have a map of the token begin/end offsets
for each fragment match, this is then used to adjust and create a new token
stream for the macro rule definition so that when we feed it to the parser
the tokens are already substituted. The resulting expression or item is
then attached to the respective macro invocation and this is then name
resolved and used for hir lowering.

Fixes #17 #22
Addresses #573
philberty added a commit that referenced this issue Feb 17, 2022
This is the first pass at implementing macros more testcases are needed.

This does not support repetition matchers but it supports simple
declarative macros and transcribes them. The approach taken here is that
we reuse our existing parser to call the apropriate functions as specified
as part of the MacroFragmentType enum if the parser does not have errors
parsing that item then it must be a match.

Then once we match a rule we have a map of the token begin/end offsets
for each fragment match, this is then used to adjust and create a new token
stream for the macro rule definition so that when we feed it to the parser
the tokens are already substituted. The resulting expression or item is
then attached to the respective macro invocation and this is then name
resolved and used for hir lowering.

Fixes #17 #22
Addresses #573
philberty added a commit that referenced this issue Feb 17, 2022
This is the first pass at implementing macros more testcases are needed.

This does not support repetition matchers but it supports simple
declarative macros and transcribes them. The approach taken here is that
we reuse our existing parser to call the apropriate functions as specified
as part of the MacroFragmentType enum if the parser does not have errors
parsing that item then it must be a match.

Then once we match a rule we have a map of the token begin/end offsets
for each fragment match, this is then used to adjust and create a new token
stream for the macro rule definition so that when we feed it to the parser
the tokens are already substituted. The resulting expression or item is
then attached to the respective macro invocation and this is then name
resolved and used for hir lowering.

Fixes #17 #22
Addresses #573
bors bot added a commit that referenced this issue Feb 17, 2022
938: First pass at declarative macro expansion  r=philberty a=philberty

This does not support repetition matchers but it supports simple
declarative macros and transcribes them. The approach taken here is that
we reuse our existing parser to call the apropriate functions as specified
as part of the MacroFragmentType enum if the parser does not have errors
parsing that item then it must be a match.
    
Then once we match a rule we have a map of the token begin/end offsets
for each fragment match, this is then used to adjust and create a new token
stream for the macro rule definition so that when we feed it to the parser
the tokens are already substituted. The resulting expression or item is
then attached to the respective macro invocation and this is then name
resolved and used for hir lowering.
    
Fixes #17 #22
Addresses #573

Co-authored-by: Philip Herron <philip.herron@embecosm.com>
@philberty philberty moved this from In progress to Review in progress in Control Flow 3 Macros Feb 17, 2022
@philberty philberty moved this from Review in progress to Reviewer approved in Control Flow 3 Macros Feb 18, 2022
@bjorn3
Copy link

bjorn3 commented Mar 21, 2022

macro_rules! maybe_return { ($e:expr) => ($e); }

fn frob(x: i32) -> i32{
    maybe_return! {x}
    // should return -1 
    -1
}

results in an ice with the version of gccrs on compiler explorer (1bb9a29).

rust1: internal compiler error: in take_expression_fragment, at rust/ast/rust-ast.h:1855
0x2042789 internal_error(char const*, ...)
	???:0
0x80023f fancy_abort(char const*, int, char const*)
	???:0
0x92a158 Rust::AST::ASTFragment::take_expression_fragment()
	???:0
0x9271f4 Rust::AttrVisitor::visit(Rust::AST::ArithmeticOrLogicalExpr&)
	???:0
0x9283a5 Rust::AttrVisitor::visit(Rust::AST::BlockExpr&)
	???:0
0x9268be Rust::AttrVisitor::visit(Rust::AST::Function&)
	???:0
0x8d27fe Rust::MacroExpander::expand_crate()
	???:0
0x8bec2e Rust::Session::expansion(Rust::AST::Crate&)
	???:0
0x8c1de4 Rust::Session::parse_file(char const*)
	???:0
0x8c29c0 Rust::Session::parse_files(int, char const**)
	???:0
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <https://gcc.gnu.org/bugs/> for instructions.
Compiler returned: 1

@philberty
Copy link
Member

can you raise this in a separate issue @bjorn3? i would like to track it as a ticket for our kanban board :)

@philberty
Copy link
Member

Closing this as the final issue is tracked under #1048

Control Flow 3 Macros automation moved this from Reviewer approved to Done Mar 28, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
No open projects
Development

No branches or pull requests

4 participants