Skip to content

external macros don't evaluate panicking consts when crate-local ones do. #61058

Closed
@rodrimati1992

Description

@rodrimati1992

I have a proc macro crate which produces a panicking constant in its generate code.

For some reason the constant outputed by the proc-macro doesn't get evaluated in cargo check,even though it gets evaluated when the macro is manually expanded.

This is the conversation that motivated me to write this issue:dtolnay/case-studies#6

I've put all the code in this repository.

All of these were tried using the current stable.

Commands to run:

git clone https://github.com/rodrimati1992/const_panic_issue.git
cd ./const_panic_issue/using_const_panic/
cargo check --bin with_proc_macro
cargo check --bin manually_expanded
cargo check --bin with_internal_macro_rules
cargo check --bin with_external_macro_rules

With a proc macro

const_panic_proc_macro crate:

use proc_macro::TokenStream;
use quote::quote;

#[proc_macro]
pub fn const_panicking(_input: TokenStream) -> TokenStream {
    TokenStream::from(quote! {
        const E0: usize = [0][3];
    })
}

using_proc_macro crate:

const_panic_proc_macro::const_panicking!{}

The compiler detects no const errors,even though there is an out of bounds error in the constant.

Output:

cargo check --bin with_proc_macro
    Checking using_const_panic v0.1.0 (/home/matias/Documents/eclipse_workspace/tmp/panic_in_const/using_const_panic)
    Finished dev [unoptimized + debuginfo] target(s) in 0.19s

Manually expanded version

Here is the manually expanded version of the macro (in the manually_expanded binary in using_const_panic):

const E0: usize = [0][3];

When compiled with cargo check outputs the out of bounds error.

Output:

cargo check --bin manually_expanded
   Compiling const_panic_proc_macro v0.1.0 (/home/matias/Documents/eclipse_workspace/tmp/panic_in_const/const_panic_proc_macro)
    Checking using_const_panic v0.1.0 (/home/matias/Documents/eclipse_workspace/tmp/panic_in_const/using_const_panic)
warning: constant item is never used: `E0`
 --> src/bin/manually_expanded/main.rs:1:1
  |
1 | const E0: usize = [0][3];
  | ^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: #[warn(dead_code)] on by default

error: any use of this value will cause an error
 --> src/bin/manually_expanded/main.rs:1:1
  |
1 | const E0: usize = [0][3];
  | ^^^^^^^^^^^^^^^^^^------^
  |                   |
  |                   index out of bounds: the len is 1 but the index is 3
  |
  = note: #[deny(const_err)] on by default

error: aborting due to previous error

With macro_rules in the same crate

With a macro_rule declared in the with_internal_macro_rules binary in using_const_panic:

mod local_panic{
    #[macro_export]
    macro_rules! local_panic_const_panicking{
        ()=>{
            const E0: usize = [0][3];
        }
    }
}
local_panic_const_panicking!{}

When compiled with cargo check it produces the intended const error.

Output:

cargo check --bin with_internal_macro_rules
    Checking using_const_panic v0.1.0 (/home/matias/Documents/eclipse_workspace/tmp/panic_in_const/using_const_panic)
warning: constant item is never used: `E0`
 --> src/bin/with_internal_macro_rules/main.rs:5:13
  |
5 |             const E0: usize = [0][3];
  |             ^^^^^^^^^^^^^^^^^^^^^^^^^
...
9 | local_panic_const_panicking!{}
  | ------------------------------ in this macro invocation
  |
  = note: #[warn(dead_code)] on by default

error: any use of this value will cause an error
 --> src/bin/with_internal_macro_rules/main.rs:5:13
  |
5 |             const E0: usize = [0][3];
  |             ^^^^^^^^^^^^^^^^^^------^
  |                               |
  |                               index out of bounds: the len is 1 but the index is 3
...
9 | local_panic_const_panicking!{}
  | ------------------------------ in this macro invocation
  |
  = note: #[deny(const_err)] on by default

error: aborting due to previous error

error: Could not compile `using_const_panic`.

With macro_rules from another crate

With a macro_rule declared in another crate:

macro_rules_panic crate:

#[macro_export]
macro_rules! const_panicking{
    ()=>{
        const E0: usize = [0][3];
    }
}

with_external_macro_rules binary in using_const_panic:

macro_rules_panic::const_panicking!{}

This code cargo checks without errors,even though it has an out of bounds error in the constant.

Output:

cargo check --bin with_external_macro_rules
    Checking using_const_panic v0.1.0 (/home/matias/Documents/eclipse_workspace/tmp/panic_in_const/using_const_panic)
    Finished dev [unoptimized + debuginfo] target(s) in 0.17s

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-const-evalArea: Constant evaluation, covers all const contexts (static, const fn, ...)A-diagnosticsArea: Messages for errors, warnings, and lintsA-macrosArea: All kinds of macros (custom derive, macro_rules!, proc macros, ..)C-bugCategory: This is a bug.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

    No branches or pull requests

    Issue actions