Open
Description
I am trying to implement something very generic, and in the course of doing so, am using trait associated types. That, in turn, apparently doesn't allow the unsizing rules to kick in.
The following compiles fine:
#![crate_type="lib"]
use std::cell::UnsafeCell;
struct Foo<T: ?Sized>(UnsafeCell<T>);
impl<T> Foo<T> {
fn new(t: T) -> Foo<T> {
Foo(UnsafeCell::new(t))
}
}
pub fn foo() {
let foo: &Foo<[i32]> = &Foo::new([1,2,3]);
}
Now, adding some nesting in the above fails:
#![crate_type="lib"]
use std::cell::UnsafeCell;
trait Wrapper {
type Type: ?Sized;
}
struct Wrap<T: ?Sized>(T);
impl<T: ?Sized> Wrapper for Wrap<T> {
type Type = T;
}
struct Foo<T: Wrapper + ?Sized>(UnsafeCell<T::Type>);
impl<T> Foo<Wrap<T>> {
fn new(t: T) -> Self {
Foo(UnsafeCell::new(t))
}
}
pub fn foo() {
let foo: &Foo<Wrap<[i32]>> = &Foo::new([1,2,3]);
}
That fails with:
error[E0308]: mismatched types
--> src/lib.rs:23:34
|
23 | let foo: &Foo<Wrap<[i32]>> = &Foo::new([1,2,3]);
| ^^^^^^^^^^^^^^^^^^ expected slice, found array of 3 elements
|
= note: expected type `&Foo<Wrap<[i32]>>`
found type `&Foo<Wrap<[i32; 3]>>`
In fact, it fails similarly with a simplified version that differs even less with the original:
#![crate_type="lib"]
use std::cell::UnsafeCell;
trait Wrapper {
type Type: ?Sized;
}
impl<T: ?Sized> Wrapper for T {
type Type = T;
}
struct Foo<T: Wrapper + ?Sized>(UnsafeCell<T::Type>);
impl<T> Foo<T> {
fn new(t: T) -> Self {
Foo(UnsafeCell::new(t))
}
}
pub fn foo() {
let foo: &Foo<[i32]> = &Foo::new([1,2,3]);
}
error[E0308]: mismatched types
--> src/lib.rs:21:28
|
21 | let foo: &Foo<[i32]> = &Foo::new([1,2,3]);
| ^^^^^^^^^^^^^^^^^^ expected slice, found array of 3 elements
|
= note: expected type `&Foo<[i32]>`
found type `&Foo<[i32; 3]>`
(In fact, the UnsafeCell
is irrelevant, and can be removed too)
#![crate_type="lib"]
trait Wrapper {
type Type: ?Sized;
}
impl<T: ?Sized> Wrapper for T {
type Type = T;
}
struct Foo<T: Wrapper + ?Sized>(T::Type);
impl<T> Foo<T> {
fn new(t: T) -> Self {
Foo(t)
}
}
pub fn foo() {
let foo: &Foo<[i32]> = &Foo::new([1,2,3]);
}
error[E0308]: mismatched types
--> src/lib.rs:19:28
|
19 | let foo: &Foo<[i32]> = &Foo::new([1,2,3]);
| ^^^^^^^^^^^^^^^^^^ expected slice, found array of 3 elements
|
= note: expected type `&Foo<[i32]>`
found type `&Foo<[i32; 3]>`