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

include!() code inside of a decl macro cannot access identifiers declared within the macro #118475

Open
wangziling opened this issue Nov 30, 2023 · 3 comments
Labels
A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) C-bug Category: This is a bug.

Comments

@wangziling
Copy link

wangziling commented Nov 30, 2023

Related issue: rust-sailfish/sailfish#59 (comment)

Please test with the crate source code.
Test once with the original code, it works well.

And then modify the file examples/simple.rs as:

use sailfish::TemplateOnce;

macro_rules! template {
    ($name:ident, $path:literal, { $($field:ident: $type:ty),* } ) => {
        #[derive(TemplateOnce)]
        #[template(path=$path)]
        struct $name {
            $($field: $type,)*
        }
    }
}

template!(Simple, "simple.stpl", { messages: Vec<String> });

fn main() {
    let messages = vec![String::from("Message 1"), String::from("<Message 2>")];
    println!("{}", Simple { messages }.render_once().unwrap();
}

It will throw errors. The built codes between these two operations are TOTTALY the SAME.
So I guess it maybe is caused by the rustc compiler.

Meta

rustc --version --verbose:

rustc 1.74.0 (79e9716c9 2023-11-13)
Backtrace

Running `cargo +nightly run -p sailfish-examples --bin simple --message-format=json`...
   Compiling sailfish-compiler v0.8.3 (E:\Codes\Source\sailfish\sailfish-compiler)
   Compiling sailfish-macros v0.8.3 (E:\Codes\Source\sailfish\sailfish-macros)
   Compiling sailfish v0.8.3 (E:\Codes\Source\sailfish\sailfish)
   Compiling sailfish-examples v0.8.3 (E:\Codes\Source\sailfish\examples)
error[E0425]: cannot find value `__sf_buf` in this scope
 --> e:\Codes\Source\sailfish\target\debug\build\sailfish-compiler-6296a0e0a31320dd\out\templates\ac48a56bd5e90428-4d1386660dfbab60:2:29
  |
2 | { __sf_rt :: render_text ! (__sf_buf , "<!DOCTYPE html>\n<html>\n  <body>\n    \n    ") ; for (i , msg) in messages . iter () . enumerate...
  |                             ^^^^^^^^ not found in this scope

error[E0425]: cannot find value `__sf_buf` in this scope
 --> e:\Codes\Source\sailfish\target\debug\build\sailfish-compiler-6296a0e0a31320dd\out\templates\ac48a56bd5e90428-4d1386660dfbab60:2:170
  |
2 | ...iter () . enumerate () { __sf_rt :: render_text ! (__sf_buf , "\n      ") ; if i == 0 { __sf_rt :: render_text ! (__sf_buf , "\n      ...
  |                                                       ^^^^^^^^ not found in this scope

error[E0425]: cannot find value `__sf_buf` in this scope
 --> e:\Codes\Source\sailfish\target\debug\build\sailfish-compiler-6296a0e0a31320dd\out\templates\ac48a56bd5e90428-4d1386660dfbab60:2:233
  |
2 | ...\n      ") ; if i == 0 { __sf_rt :: render_text ! (__sf_buf , "\n        <h1>Hello, world!</h1>\n      ") ; } __sf_rt :: render_text !...
  |                                                       ^^^^^^^^ not found in this scope

error[E0425]: cannot find value `__sf_buf` in this scope
 --> e:\Codes\Source\sailfish\target\debug\build\sailfish-compiler-6296a0e0a31320dd\out\templates\ac48a56bd5e90428-4d1386660dfbab60:2:318
  |
2 | ...orld!</h1>\n      ") ; } __sf_rt :: render_text ! (__sf_buf , "\n      <div>") ; __sf_rt :: render_escaped ! (__sf_buf , * msg) ; __sf...
  |                                                       ^^^^^^^^ not found in this scope

error[E0425]: cannot find value `__sf_buf` in this scope
 --> e:\Codes\Source\sailfish\target\debug\build\sailfish-compiler-6296a0e0a31320dd\out\templates\ac48a56bd5e90428-4d1386660dfbab60:2:377
  |
2 | ... , "\n      <div>") ; __sf_rt :: render_escaped ! (__sf_buf , * msg) ; __sf_rt :: render_text ! (__sf_buf , "</div>\n    ") ; } __sf_r...
  |                                                       ^^^^^^^^ not found in this scope

error[E0425]: cannot find value `__sf_buf` in this scope
 --> e:\Codes\Source\sailfish\target\debug\build\sailfish-compiler-6296a0e0a31320dd\out\templates\ac48a56bd5e90428-4d1386660dfbab60:2:423
  |
2 | ...d ! (__sf_buf , * msg) ; __sf_rt :: render_text ! (__sf_buf , "</div>\n    ") ; } __sf_rt :: render_text ! (__sf_buf , "\n  </body>\n<...
  |                                                       ^^^^^^^^ not found in this scope

error[E0425]: cannot find value `__sf_buf` in this scope
 --> e:\Codes\Source\sailfish\target\debug\build\sailfish-compiler-6296a0e0a31320dd\out\templates\ac48a56bd5e90428-4d1386660dfbab60:2:480
  |
2 | ...uf , "</div>\n    ") ; } __sf_rt :: render_text ! (__sf_buf , "\n  </body>\n</html>") ; }
  |                                                       ^^^^^^^^ not found in this scope

error: aborting due to 7 previous errors

For more information about this error, try `rustc --explain E0425`.
error: could not compile `sailfish-examples` (bin "simple") due to 8 previous errors
Error: Cargo invocation failed.
        at t.Cargo.getCargoArtifacts (c:\Users\Sling\.vscode\extensions\vadimcn.vscode-lldb-1.10.0\extension.js:1:14943)
        at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
        at async Object.open (c:\Users\Sling\.vscode\extensions\vadimcn.vscode-lldb-1.10.0\extension.js:1:13253)
Caused by: Error: exit code: 101.
        at ChildProcess.<anonymous> (c:\Users\Sling\.vscode\extensions\vadimcn.vscode-lldb-1.10.0\extension.js:1:16610)
        at ChildProcess.emit (node:events:513:28)
        at ChildProcess.emit (node:domain:489:12)
        at maybeClose (node:internal/child_process:1091:16)
        at ChildProcess._handle.onexit (node:internal/child_process:302:5)
 *  The terminal process terminated with exit code: 1. 
 *  Terminal will be reused by tasks, press any key to close it. 

Seems after using macro_rules, the include!(); cannot get the current scope variable "__sf_buf".
The root code is here: https://github.com/rust-sailfish/sailfish/blob/2e392994830084874b2695bf7953f245752d7d44/sailfish-compiler/src/procmacro.rs#L374

@wangziling wangziling added the C-bug Category: This is a bug. label Nov 30, 2023
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Nov 30, 2023
@clubby789
Copy link
Contributor

clubby789 commented Nov 30, 2023

Given a template file containing something like "test", sailfish will generate a file like this

{
    __sf_rt::render_text!(__sf_buf, "test");
}

The derive macro will then use this like so:

quote! {
  /* ... */
    fn render_once_to(self, __sf_buf: &mut sailfish::runtime::Buffer) -> std::result::Result<(), sailfish::runtime::RenderError> {
      // This line is required for cargo to track child templates
      #include_bytes_seq;
      use sailfish::runtime as __sf_rt;
      let #name { #field_names } = self;
      include!(#output_file_string);
      Ok(())
    }
   /* ... */
}

Given that include is unhygienic, I'm not sure why the derive macro being inside a decl macro would break this

We can also access global identifers

@clubby789
Copy link
Contributor

clubby789 commented Nov 30, 2023

Actually, this also seems to happen with

macro_rules! generate {
    () => {
        fn render(buf: &mut ()) {
            include!("../body");
        }
    }
}

generate!();
fn main() {}

Where ../body is

{
    buf;
}

Renaming the issue accordingly - is this expected behaviour?

(Possibly related: #32379, #11390)

@clubby789 clubby789 changed the title Cannot refer to the scope variable after using macro_rules include!'d code inside of a decl macro cannot access identifiers declared within the macro Nov 30, 2023
@clubby789 clubby789 added A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Nov 30, 2023
@wangziling wangziling changed the title include!'d code inside of a decl macro cannot access identifiers declared within the macro included!() code inside of a decl macro cannot access identifiers declared within the macro Nov 30, 2023
@wangziling wangziling changed the title included!() code inside of a decl macro cannot access identifiers declared within the macro include!() code inside of a decl macro cannot access identifiers declared within the macro Nov 30, 2023
@wangziling
Copy link
Author

wangziling commented Nov 30, 2023

@clubby789 Sure, thanks for your assistance. 😉

The code bellow throws the error as well.

macro_rules! generate {
    () => {
        fn log() {
            let num = 2;
            include!("./file.txt");
        }
    };
}

generate!();

fn main() {
    log();
}

file.txt content:

{
  num
}

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) C-bug Category: This is a bug.
Projects
None yet
Development

No branches or pull requests

3 participants