Skip to content

When enableExperimental true, rust-analyzer incorrectly reports type mismatch for async-trait implementations: Pin<Box<dyn Future>> vs Pin<Box<impl Future>> #19957

Open
@henryverlin

Description

@henryverlin

I encountered a persistent type mismatch error when using async-trait that only appeared in rust-analyzer but not during compilation. After several hours of troubleshooting, I discovered that the issue was caused by having rust-analyzer.diagnostics.enableExperimental set to true in my workspace settings.

Setting enableExperimental to false completely resolves the issue, while cargo check and cargo build work correctly regardless of this setting.

Impact:

This appears to be a bug in rust-analyzer's experimental diagnostics when processing async-trait macro expansions. The experimental feature incorrectly reports type mismatches between Pin<Box> and Pin<Box> for async trait implementations.

Reproduction:

The issue can be reproduced by:

Setting "rust-analyzer.diagnostics.enableExperimental": true in VS Code settings
Using #[async_trait] with async methods in trait definitions and implementations
Observing the false positive type mismatch errors in the IDE
Workaround:

Setting "rust-analyzer.diagnostics.enableExperimental": false eliminates the issue entirely.

I'm reporting this to help improve the experimental diagnostics feature and assist other developers who may encounter the same issue.

Description:
rust-analyzer shows a type mismatch error for async trait implementations using the async-trait crate when vscode has "rust-analyzer.diagnostics.enableExperimental": true:

error[E0308]: mismatched types
expected Pin<Box<dyn Future<Output = Result<SimpleResult, Box<dyn Error + Send + Sync + 'static, Global>>> + Send + 'async_trait, Global>>
found    Pin<Box<impl Future<Output = Result<SimpleResult, Box<dyn Error + Send + Sync + 'static, Global>>>, Global>>

code snippet to reproduce:

use async_trait::async_trait;
use std::error::Error;

#[derive(Debug, PartialEq)]
pub enum SimpleResult {
    Ok,
    Error,
}

pub struct ExampleData {
    pub id: i32,
    pub name: String,
}

#[async_trait]
pub trait SimpleModel {
    async fn save(&self) -> Result<SimpleResult, Box<dyn Error + Send + Sync + 'static>>;
}

#[async_trait]
impl SimpleModel for ExampleData {
    async fn save(&self) -> Result<SimpleResult, Box<dyn Error + Send + Sync + 'static>> {
        if self.id > 0 {
            Ok(SimpleResult::Ok)
        } else {
            Ok(SimpleResult::Error)
        }
    }
}

vscode workspace file settings:

{
  "folders": [
    {
      "path": "."
    }
  ],
  "settings": {
    // Rust Configuration
    "rust-analyzer.showUnlinkedFileNotification": false,
    "rust-analyzer.check.command": "clippy",
    "rust-analyzer.check.allTargets": false,
    "rust-analyzer.diagnostics.enable": true,
    "rust-analyzer.diagnostics.enableExperimental": true,
    "rust-analyzer.completion.autoimport.enable": true,
    "rust-analyzer.imports.granularity.group": "module",
    "rust-analyzer.imports.prefix": "crate",
    "rust-analyzer.rustfmt.extraArgs": ["+stable"],
  },
}

Expected behavior:
No error should be shown, as the #[async_trait] macro should transform the async fn into the correct Pin<Box> type.

Actual behavior:
rust-analyzer shows a type mismatch between Pin<Box> and Pin<Box>, suggesting it's not correctly processing the async-trait macro expansion.

Additional context:

  • cargo check and cargo build complete successfully with no errors
  • The error only appears in the IDE, not during compilation
  • The error occurs specifically when combining #[async_trait] with async fn methods
  • Non-async trait methods work fine
  • Issue persists after cache clearing, rust-analyzer restarts, and ensuring single async-trait version

Dependencies:
[dependencies]
async-trait = "0.1.88"

This appears to be a rust-analyzer issue with macro expansion for the async-trait crate, where the IDE incorrectly analyzes the return type of async trait methods.

rust-analyzer version: 0.4.2488-standalone (6acff6c 2025-06-06) [/Users/henryverlin/.vscode/extensions/rust-lang.rust-analyzer-0.4.2488-darwin-arm64/server/rust-analyzer]

rustc version: rustc 1.87.0 (17067e9ac 2025-05-09)

editor or extension: VSCode with rust-analyzer extension version 0.4.2488

relevant settings: Default settings, workspace with Cargo.toml at root defining fetcher as member

repository link (if public, optional): N/A

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-tytype system / type inference / traits / method resolutionC-bugCategory: bugS-blocked-on-new-solverwill be fixed when we will switch to the new trait solver

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions