Skip to content

Unexpected token: expected ;, found #. #106020

Closed
@Jerrody

Description

@Jerrody
Contributor
#[cfg(feature = "validation")]
[debug_utils_ext, (*surface_extensions).to_owned()].concat()

#[cfg(not(feature = "validation"))]
surface_extensions.to_owned()

Error code:

error: expected `;`, found `#`
  --> src\engine\renderer\context\instance.rs:44:73
   |
44 |             [debug_utils_ext, (*surface_extensions).to_owned()].concat()
   |                                                                         ^ help: add `;` here
45 |
46 |             #[cfg(not(feature = "validation"))]
   |             - unexpected token

Metadata:

rustc 1.67.0-nightly (e1d819583 2022-12-05)
binary: rustc
commit-hash: e1d819583f0bf13b016b119c1c2c43e6d3979450
commit-date: 2022-12-05
host: x86_64-pc-windows-msvc
release: 1.67.0-nightly
LLVM version: 15.0.4

Activity

changed the title [-]Unexpected token: `expected `;`, found `#`.[/-] [+]Unexpected token: expected `;`, found `#`.[/+] on Dec 21, 2022
compiler-errors

compiler-errors commented on Dec 21, 2022

@compiler-errors
Member

What is the issue you are reporting here @Jerrody ?

Jerrody

Jerrody commented on Dec 21, 2022

@Jerrody
ContributorAuthor

What is the issue you are reporting here @Jerrody ?

Well, I thought that compiler can understand that #[cfg()] is related to the block of code, but it fails.

Noratrieb

Noratrieb commented on Dec 22, 2022

@Noratrieb
Member

Can you post a minimal reproducible example that demonstrates your issue? Or at least mention exactly what you'd expect to happen and why.

Even code that is cfged out is still required to parse successfully.

Jerrody

Jerrody commented on Dec 22, 2022

@Jerrody
ContributorAuthor

Can you post a minimal reproducible example that demonstrates your issue? Or at least mention exactly what you'd expect to happen and why.

Even code that is cfged out is still required to parse successfully.

Let's show you what exactly problem I have.
Full code:

let instance_extensions = {
    let surface_extensions =
        ash_window::enumerate_required_extensions(window.raw_display_handle()).track()?;

    #[cfg(feature = "validation")]
    let debug_utils_ext = vec![ash::extensions::ext::DebugUtils::name().as_ptr()];

    #[cfg(feature = "validation")]
    [debug_utils_ext, (*surface_extensions).to_owned()].concat()

    #[cfg(not(feature = "validation"))]
    surface_extensions.to_owned()
};

And I get this error:

error: expected `;`, found `#`
  --> src\engine\renderer\context\instance.rs:44:73
   |
44 |             [debug_utils_ext, (*surface_extensions).to_owned()].concat()
   |                                                                         ^ help: add `;` here
45 |
46 |             #[cfg(not(feature = "validation"))]
   |             - unexpected token
SkiFire13

SkiFire13 commented on Dec 22, 2022

@SkiFire13
Contributor

You seem to already have posted this in this discussion in the internals forum a month ago. What you're asking seems a rather big change to me, I'm not that familiar with how the compiler parser works but I believe it currently requires your program syntax to be correct before #[cfg(...)] macros are expanded, which is not true for your example, so some fundamental changes would be needed.

Jerrody

Jerrody commented on Dec 22, 2022

@Jerrody
ContributorAuthor

You seem to already have posted this in this discussion in the internals forum a month ago. What you're asking seems a rather big change to me, I'm not that familiar with how the compiler parser works but I believe it currently requires your program syntax to be correct before #[cfg(...)] macros are expanded, which is not true for your example, so some fundamental changes would be needed.

Oh, damn, sorry. I totally forgot that I made a post.
Well, if it's not a bug and parser works like this it is bad, anyway, exists alternative way to write like this.
But for me my issue is a candidate to feature request or a bug. Anyway, I'm not a lang dev, so I don't know what scales of this defect (?).

lukas-code

lukas-code commented on Dec 22, 2022

@lukas-code
Member

The workaround for this is to wrap the expressions in a block:

let instance_extensions = {
    let surface_extensions =
        ash_window::enumerate_required_extensions(window.raw_display_handle()).track()?;

    #[cfg(feature = "validation")]
    let debug_utils_ext = vec![ash::extensions::ext::DebugUtils::name().as_ptr()];

    #[cfg(feature = "validation")]
    { [debug_utils_ext, (*surface_extensions).to_owned()].concat() }

    #[cfg(not(feature = "validation"))]
    { surface_extensions.to_owned() }
};
Jerrody

Jerrody commented on Dec 22, 2022

@Jerrody
ContributorAuthor

The workaround for this is to wrap the expressions in a block:

let instance_extensions = {
    let surface_extensions =
        ash_window::enumerate_required_extensions(window.raw_display_handle()).track()?;

    #[cfg(feature = "validation")]
    let debug_utils_ext = vec![ash::extensions::ext::DebugUtils::name().as_ptr()];

    #[cfg(feature = "validation")]
    { [debug_utils_ext, (*surface_extensions).to_owned()].concat() }

    #[cfg(not(feature = "validation"))]
    { surface_extensions.to_owned() }
};

I solved this issue exactly as you did.

albertlarsan68

albertlarsan68 commented on Dec 23, 2022

@albertlarsan68
Member

Another way to do this is using the cfg! macro and if ... else.
I personally thinks it is more clear, and should optimize the same.

let instance_extensions = {
    let surface_extensions =
        ash_window::enumerate_required_extensions(window.raw_display_handle()).track()?;

    #[cfg(feature = "validation")]
    let debug_utils_ext = vec![ash::extensions::ext::DebugUtils::name().as_ptr()];

    if cfg!(feature = "validation") {
        [debug_utils_ext, (*surface_extensions).to_owned()].concat()
    } else {
        surface_extensions.to_owned()
    }
};
Jerrody

Jerrody commented on Dec 24, 2022

@Jerrody
ContributorAuthor

Another way to do this is using the cfg! macro and if ... else. I personally thinks it is more clear, and should optimize the same.

let instance_extensions = {
    let surface_extensions =
        ash_window::enumerate_required_extensions(window.raw_display_handle()).track()?;

    #[cfg(feature = "validation")]
    let debug_utils_ext = vec![ash::extensions::ext::DebugUtils::name().as_ptr()];

    if cfg!(feature = "validation") {
        [debug_utils_ext, (*surface_extensions).to_owned()].concat()
    } else {
        surface_extensions.to_owned()
    }
};

Work is not the same, due to cfg! compile-time evaluating an expression that we pass in it and evaluates only it, but at the same time everything compiles what is inside of if else.

added
A-parserArea: The lexing & parsing of Rust source code to an AST
T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
and removed
C-bugCategory: This is a bug.
on Mar 14, 2023

6 remaining items

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-parserArea: The lexing & parsing of Rust source code to an ASTD-confusingDiagnostics: Confusing error or lint that should be reworked.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      Participants

      @estebank@compiler-errors@SkiFire13@lukas-code@Noratrieb

      Issue actions

        Unexpected token: expected `;`, found `#`. · Issue #106020 · rust-lang/rust