Skip to content

Fails to parse nested impl trait #21102

@mandar1jn

Description

@mandar1jn

I encountered this issue while working on a project. The type of asset in main() gets resolved to &{unknown} where I would expect it to resolve as &impl AssetID. This is a somewhat minimum reproduction from my stripped down code.

rust-analyzer version: 0.3.2683-standalone

rustc version: rustc 1.88.0 (6b00bc388 2025-06-23)

editor or extension: vscode (extension version 0.3.2683)

code snippet to reproduce:

use std::{error::Error, io, path::PathBuf};

trait Game {
    fn load(&mut self, path: PathBuf) -> std::result::Result<(), impl std::error::Error>;

    fn get_archives(&self) -> Vec<Box<&dyn Archive<impl AssetID, impl Asset>>>;
}

trait AssetID {
    fn full_name(&self) -> String;
}

trait Asset {}

trait Archive<I: AssetID, A: Asset> {
    fn name(&self) -> &String;

    fn get_identifiers(&self) -> &Vec<I>;

    fn get(&self, id: I) -> Option<A>;
}

struct NorthlightAssetID {}

impl AssetID for NorthlightAssetID {
    fn full_name(&self) -> String {
        String::new()
    }
}

struct NorthlightAsset {}

impl Asset for NorthlightAsset {}

struct NorthlightArchive {}

impl Archive<NorthlightAssetID, NorthlightAsset> for NorthlightArchive {
    fn name(&self) -> &String {
        todo!()
    }

    fn get_identifiers(&self) -> &Vec<NorthlightAssetID> {
        todo!()
    }

    fn get(&self, id: NorthlightAssetID) -> Option<NorthlightAsset> {
        todo!()
    }
}

struct NorthlightGame {}

impl NorthlightGame {
    fn new() -> Self {
        NorthlightGame {  }
    }
}

impl Game for NorthlightGame {
    fn load(&mut self, path: PathBuf) -> std::result::Result<(), impl std::error::Error> {
        if !path.exists() {
            return Err(io::Error::new(io::ErrorKind::NotFound, "file not exist"));
        }

        Ok(())
    }

    fn get_archives(&self) -> Vec<Box<&dyn Archive<NorthlightAssetID, NorthlightAsset>>> {
        let mut res = vec![];
        res
    }
}

enum Games {
    Northlight(NorthlightGame),
}

impl Game for Games {
    fn load(&mut self, path: PathBuf) -> std::result::Result<(), impl std::error::Error> {
        match self {
            Self::Northlight(game) => game.load(path),
        }
    }

    fn get_archives(&self) -> Vec<Box<&dyn Archive<impl AssetID, impl Asset>>> {
        match self {
            Self::Northlight(game) => game.get_archives(),
        }
    }
}

fn main() -> Result<(), Box<dyn Error>> {
    let mut game = Games::Northlight(NorthlightGame::new());

    let _ = game.load(PathBuf::from(
        "/home/marijn/.local/share/Steam/steamapps/common/Alan Wake/AlanWake.exe",
    ));

    for archive in game.get_archives() {
        println!("{}:", archive.name());
        for asset in archive.get_identifiers() {
            println!("\t{}", asset.full_name());
        }
    }

    Ok(())
}
Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions