Skip to content

Type inequality constraints in where clauses #1834

Open
@spinda

Description

@spinda

The idea of a != constraint form in where clauses has come up multiple times, in discussions of the where clause itself, in rust-lang/rust#20041 as a counterpart to the == constraint form, and in various proposals for negative trait reasoning (!Trait). I'd like to extract this idea into its own RFC.

Say we want to write a From instance for ! reflecting its ability to implicitly cast to any type.

#![feature(never_type)]

trait From<T> {
    fn from(T) -> Self;
}

impl<T> From<T> for T {
    fn from(t: T) -> Self { t }
}

impl<T> From<!> for T {
    fn from(t: !) -> Self { t }
}

This produces an overlapping error because both impls cover !: From<!>. Specialization can't help here, as the first impl does not fully contain the second. What's necessary is a way to limit the scope of the second impl to exclude T == !, avoiding the overlap altogether. I'd like to propose the following syntax:

#![feature(inequality_constraints)]
#![feature(never_type)]

trait From<T> {
    fn from(T) -> Self;
}

impl<T> From<T> for T {
    fn from(t: T) -> Self { t }
}

impl<T> From<!> for T where T != ! {
    fn from(t: !) -> Self { t }
}

Negative reasoning for traits has been held up in the past due to concerns over implementing a trait for a new type becoming a breaking change. The == constraint has been held up due to an expectation that it would affect normalization (see rust-lang/rust#22074 (comment)). The != constraint doesn't suffer from either of these issues and can be very useful on its own, so I think it makes sense to split it off.

Metadata

Metadata

Assignees

No one assigned

    Labels

    T-langRelevant to the language team, which will review and decide on the RFC.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions