rust-lang / rust-lang/rust

Type inference fails with multiple impl blocks despite explicit type annotation

Open
#151,698 4 comments 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-inference A-method-lookup C-bug T-types
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

Im encountering a situation where the Rust compiler cannot infer which new method to call, even when an explicit type annotation is provided for the variable receiving the result. This leads to the E0034 error, "multiple applicable items in scope." requiring the use of turbofish syntax to avoid.

This is a pretty large example showcasing the issue and my use cases for it but for reproduction sake i have also created an minimal example using rust's playground:

pub trait IndexFormat: Pod + Zeroable  {
    fn format() -> wgpu::IndexFormat;
    fn size() -> usize {size_of::<Self>()}
}

pub struct IndexBuffer<T> {
    pub count: usize,
    pub device: Device,
    pub capacity: usize,
    phantom: PhantomData<T>,
    pub buffer: wgpu::Buffer,
    pub format: wgpu::IndexFormat,
}

impl<T: IndexFormat> IndexBuffer<T> {
    pub fn new(device: &Device, label: Option<String>, data: impl AsRef<[T]>) -> Self {
        todo!()
    }
}

impl IndexBuffer<Dynamic> {
    pub fn new(device: &Device, label: Option<String>, index_size: usize, data: &[u8]) -> Self {
        todo!()
    }
}

impl<T: IndexFormat, const N: usize> IndexBuffer<[T; N]> {
    pub fn new(device: &Device, label: Option<String>, data: &[T]) -> Self {
        todo!()
    }
}

impl IndexFormat for u16 {
    fn format() -> wgpu::IndexFormat {
        return wgpu::IndexFormat::Uint16;
    }
}

impl IndexFormat for u32 {
    fn format() -> wgpu::IndexFormat {
        return wgpu::IndexFormat::Uint32;
    }
}

fn test(device: Device) {
    // These will compile with or without type explicit annotations
    let _c1 = IndexBuffer::<u16>::new(device, None, &[0u16, 1, 2, 3]);
    let _c2 = IndexBuffer::<[u32; 128]>::new(device, None, &[0u32; 128]);
    let _c3 = IndexBuffer::<Dynamic>::new(device, None, 4, &[0u8, 1, 2, 3]);

    // These will fails with E0034: multiple applicable items in scope
    // Despite explicit type annotations being provided which should disambiguate
    let _c4: IndexBuffer<u16> = IndexBuffer::new(device, None, &[0u16, 1, 2, 3]);
    let _c5: IndexBuffer<[u32; 128]> = IndexBuffer::new(device, None, &[0u32; 128]);
    let _c6: IndexBuffer<Dynamic> = IndexBuffer::new(device, None, 2, &[0u8, 1, 2, 3]);
}
Expected Behavior:

I expect the Rust compiler to use the explicit type annotation of the variable (IndexBuffer<u16>) to disambiguate which impl block's new function should be called. The type of the variable should provide enough information for the compiler to select the correct function.

Current Behavior:

The compiler fails to compile the code, citing error E0034, "multiple applicable items in scope." This forces the developer to use the turbofish syntax (IndexBuffer::<u16>::new(...)) to manually specify the type at the call site.

Meta

rustc --version --verbose:

rustc 1.92.0 (ded5c06cf 2025-12-08)
binary: rustc
commit-hash: ded5c06cf21d2b93bffd5d884aa6e96934ee4234
commit-date: 2025-12-08
host: x86_64-unknown-linux-gnu
release: 1.92.0
LLVM version: 21.1.3

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the minimal Rust Playground reproduction linked in the issue and compare method resolution for the turbofish calls with the explicitly annotated assignments that produce E0034. Trace the compiler's type inference and associated function lookup behavior, then validate that a regression case allows the assignment type to disambiguate the impl without turbofish syntax.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.