Skip to content

overflow => generics that produce trans errors depending on type parameters #32498

Closed
@comex

Description

@comex

In which we sneakily define a type that contains itself:

(EDIT: Actually, this one didn't depend on specialization. There was previously a default impl of Tr2 not depending on Tr, but it wasn't necessary. The second one does seem to depend on it.)

trait Tr {
    type X;
}
trait Tr2 {
    type Y;
}

struct S<T: ?Sized + Tr> {
    x: <<T as Tr>::X as Tr2>::Y,
}

impl<T: Tr> Tr2 for T {
    type Y = S<T>;
}

impl<T> Tr for T { type X = T; }

fn func<T>() {
    let _: S<T> = panic!();
}

fn main() {
    func::<u32>();
}

produces:

error: overflow representing the type S<u32>

This error comes from trans, and it goes away if either the call to func or func's usage of S<T> is commented out. In other words, func claims to allow instantiation with any type but actually supports no types. (By adding more specializations it could be made to support only certain types.)

A similar issue is when overflow occurs while determining whether a given specialization applies:

#![feature(specialization)]

trait Tr {
    type Other;
}
struct S<T>(T);
impl<T> Tr for T {
    default type Other = <S<T> as Tr>::Other;
}
impl Tr for S<S<S<S<u32>>>> {
    type Other = u32;
}
fn func<T>() {
    let _: <T as Tr>::Other = panic!();
}

fn main() {
    func::<u32>();
}

This happens to compile, but if the u32 in main is changed to u64, I get:

error: overflow evaluating the requirement <S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<u64>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> as Tr>::Other

Is this a known consequence of specialization? I haven't seen it discussed. It seems to violate Rust's normal policy of type-safe generics, and I'm not sure what a rule to prevent it upfront would look like (especially considering that the patterns can in some cases be split across multiple crates).

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-specializationArea: Trait impl specializationC-bugCategory: This is a bug.P-lowLow priorityT-langRelevant to the language 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