Skip to content

Specialized Associated Type Cannot be Assigned to Value of Concrete Type (Despite type_name Working as Expected) #106700

Open
@NathanielB123

Description

@NathanielB123

I tried this code:

#![feature(specialization)]
#![allow(incomplete_features)]

use core::marker::PhantomData;

struct HCons<T, R>(PhantomData<(T, R)>);
struct Nil {}

struct True {}
struct False {}

trait Contains<T> {
    type Result;
}

impl<H, R: Contains<T>, T> Contains<T> for HCons<H, R> {
    default type Result = R::Result;
}

impl<T, R: Contains<T>> Contains<T> for HCons<T, R> {
    type Result = True;
}

impl<T> Contains<T> for Nil {
    type Result = False;
}

type F = <HCons<i32, HCons<String, Nil>> as Contains<String>>::Result;

fn main() {
    // Prints std::any::type_name::<F>() = "playground::True"
    dbg!(std::any::type_name::<F>());
    // Error here
    let x: F = True {};
}

Rust Playground: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=650a25b3c35c5626361afb0c61af2aa5

I expected to see this happen:
No compile error, program runs and prints [src/main.rs:31] std::any::type_name::<F>() = "playground::True"

Instead, this happened:
Compile Error:

error[[E0308]](https://doc.rust-lang.org/nightly/error-index.html#E0308): mismatched types
  --> src/main.rs:34:16
   |
34 |     let x: F = True {};
   |            -   ^^^^^^^ expected associated type, found struct `True`
   |            |
   |            expected due to this
   |
   = note: expected associated type `<HCons<i32, HCons<String, Nil>> as Contains<String>>::Result`
                       found struct `True`
   = help: consider constraining the associated type `<HCons<i32, HCons<String, Nil>> as Contains<String>>::Result` to `True` or calling a method that returns `<HCons<i32, HCons<String, Nil>> as Contains<String>>::Result`
   = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html

Interestingly, when removing the offending line, the code runs and prints that the type is playground::True as desired, so the compiler clearly knows that the type of F is True.

Playground with offending line removed: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=e511b1ca810826d8e20abb3316a46ba1

Playground Version:

Build using the Nightly version: 1.68.0-nightly
(2023-01-09 3020239de947ec52677e)

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-specializationArea: Trait impl specializationC-bugCategory: This is a bug.F-specialization`#![feature(specialization)]`

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions