Skip to content

min_specialization on local types should take impls into account to determine whether a trait can be specialized on #113452

Open
@the8472

Description

@the8472
#![feature(min_specialization)]

trait Read {}

struct BufReader<I> {
    inner: I 
}

impl<I: Read> Read for BufReader<I> {}

trait SpecUsingRead {
    fn use_it(self);
}

impl<T> SpecUsingRead for T where Self: Read {
    default fn use_it(self) {}
}

// impl<I> SpecUsingRead for BufReader<I> where Self: Read {   // <- works
impl<I> SpecUsingRead for BufReader<I> where Self: Read, I: Read { // <- doesn't
    fn use_it(self) {}
}

Playground link

error: cannot specialize on trait `Read`
  --> src/lib.rs:20:61
   |
20 | impl<I> SpecUsingRead for BufReader<I> where Self: Read, I: Read { // <- doesn't
   |                                                             ^^^^

Since all types are owned by the same crate it should be possible for the compiler to see that BufReader<I> where Self: Read can only be true if I: Read because there exists no other impl Read for BufReader that could satisfy the Self clause without satisfying the I one.

This is useful when combining a public trait that isn't #[rustc_specialization_trait] and wrapper structs for those traits. The wrappers often place the bounds on the impls but not on the struct itself. Having that extra bound in the specialization can unlock additional methods.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-specializationArea: Trait impl specializationC-enhancementCategory: An issue proposing an enhancement or a PR with one.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.requires-nightlyThis issue requires a nightly compiler in some way.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions