Skip to content

Confusing diagnostic for attributes on types #144132

@purplesyringa

Description

@purplesyringa

Code

fn f() {
    let _generic: Box<#[attr] i32> = Box::new(1);
    let _assignment: #[attr] i32 = Box::new(1);
}

Current output

error: invalid const generic expression
 --> src/lib.rs:2:31
  |
2 |     let _generic: Box<#[attr] i32> = Box::new(1);
  |                               ^^^
  |
help: expressions must be enclosed in braces to be used as const generic arguments
  |
2 |     let _generic: Box<#[attr] { i32 }> = Box::new(1);
  |                               +     +

error: expected type, found `#`
 --> src/lib.rs:3:22
  |
3 |     let _assignment: #[attr] i32 = Box::new(1);
  |                    - ^ expected type
  |                    |
  |                    while parsing the type for `_assignment`
  |                    help: use `=` if you meant to assign

error[E0658]: attributes on expressions are experimental
 --> src/lib.rs:3:22
  |
3 |     let _assignment: #[attr] i32 = Box::new(1);
  |                      ^^^^^^^
  |
  = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information

error: cannot find attribute `attr` in this scope
 --> src/lib.rs:3:24
  |
3 |     let _assignment: #[attr] i32 = Box::new(1);
  |                        ^^^^
  |
help: consider importing this attribute macro
  |
1 + use rustversion::attr;
  |

error[E0423]: expected value, found builtin type `i32`
 --> src/lib.rs:3:30
  |
3 |     let _assignment: #[attr] i32 = Box::new(1);
  |                              ^^^ not a value
  |
help: consider importing one of these functions instead
  |
1 + use fastrand::i32;
  |
1 + use nom::character::complete::i32;
  |
1 + use nom::character::streaming::i32;
  |
1 + use nom::number::complete::i32;
  |
    and 2 other candidates

error[E0747]: constant provided when a type was expected
 --> src/lib.rs:2:31
  |
2 |     let _generic: Box<#[attr] i32> = Box::new(1);
  |                               ^^^

Desired output

error: attributes cannot be applied to a type
 --> src/lib.rs:2:31
  |
2 |     let _generic: Box<#[attr] i32> = Box::new(1);
  |                       ^^^^^^^ attributes are not allowed here

error: attributes cannot be applied to a type
 --> src/lib.rs:3:22
  |
3 |     let _assignment: #[attr] i32 = Box::new(1);
  |                      ^^^^^^^ attributes are not allowed here

Rationale and extra context

Since function-like macros are allowed in type position, I thought attributes might work in type position as well, but apparently not. The diagnostic is pretty confusing, though. We already emit a good one when the attribute is in parameter position, e.g.

fn f(_param: #[attr] i32) {}
error: attributes cannot be applied to a function parameter's type
 --> src/lib.rs:1:14
  |
1 | fn f(_param: #[attr] i32) {}
  |              ^^^^^^^ attributes are not allowed here

...but apparently not in other type positions.

Other cases

Rust Version

rustc 1.90.0-nightly (a00149764 2025-07-14)
binary: rustc
commit-hash: a001497644bc229f1abcc5b2528733386591647f
commit-date: 2025-07-14
host: x86_64-unknown-linux-gnu
release: 1.90.0-nightly
LLVM version: 20.1.8

Anything else?

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-attributesArea: Attributes (`#[…]`, `#![…]`)A-diagnosticsArea: Messages for errors, warnings, and lintsA-parserArea: The lexing & parsing of Rust source code to an ASTT-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