Skip to content

Nested but non-conflicting projection predicates emerging from supertrait bounds leads to ambiguity #140217

Open
@dingxiangfei2009

Description

@dingxiangfei2009

Zulip Chat thread for discussion

I tried this code:

Original test case

use std::marker::PhantomData;

pub trait Receiver {
    type Target: ?Sized;
}

pub trait Deref: Receiver<Target = <Self as Deref>::Target> {
    type Target: ?Sized;
    fn deref(&self) -> &<Self as Deref>::Target;
}

impl<T: Deref> Receiver for T {
    type Target = <T as Deref>::Target;
}

// ===
pub struct Type<Id, T>(PhantomData<(Id, T)>);
pub struct AliasRef<Id, T: TypePtr<Id = Id>>(PhantomData<(Id, T)>);

pub trait TypePtr: Deref<Target = Type<<Self as TypePtr>::Id, Self>> + Sized {
    // ^ the impl head here provides the first candidate
    // <T as Deref>::Target := Type<<T as TypePtr>::Id>
    type Id;
}

pub struct Alias<Id, T>(PhantomData<(Id, T)>);

impl<Id, T> Deref for Alias<Id, T>
where
    T: TypePtr<Id = Id> + Deref<Target = Type<Id, T>>,
    // ^ the impl head here provides the second candidate
    // <T as Deref>::Target := Type<Id, T>
    // and additionally a normalisation is mandatory due to
    // the following supertrait relation trait
    // Deref: Receiver<Target = <Self as Deref>::Target>
{
    type Target = AliasRef<Id, T>;

    fn deref(&self) -> &<Self as Deref>::Target {
        todo!()
    }
}

I expected to see this happen: rustc compiles

Instead, this happened:

error[E0284]: type annotations needed
  --> src/lib.rs:28:1
   |
28 | / impl<Id, T> Deref for Alias<Id, T>
29 | | where
30 | |     T: TypePtr<Id = Id> + Deref<Target = Type<Id, T>>,
   | |______________________________________________________^ cannot infer type
   |
   = note: cannot satisfy `<T as Deref>::Target == _`

Meta

Rust version is at 1.88.0-nightly @ 2025-04-07 e643f59f6da3a84f43e7.

Backtrace

<backtrace>

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.F-arbitrary_self_types`#![feature(arbitrary_self_types)]`T-typesRelevant to the types 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