--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+#![feature(arbitrary_self_types, unsize, coerce_unsized, coerce_sized)]
+#![feature(rustc_attrs)]
+
+use std::{
+ ops::{Deref, CoerceUnsized, CoerceSized},
+ marker::Unsize,
+ fmt::Debug,
+};
+
+struct Ptr<T: ?Sized>(Box<T>);
+
+impl<T: ?Sized> Deref for Ptr<T> {
+ type Target = T;
+
+ fn deref(&self) -> &T {
+ &*self.0
+ }
+}
+
+impl<T: Unsize<U> + ?Sized, U: ?Sized> CoerceUnsized<Ptr<U>> for Ptr<T> {}
+impl<T: Unsize<U> + ?Sized, U: ?Sized> CoerceSized<Ptr<T>> for Ptr<U> {}
+
+struct Wrapper<T: ?Sized>(T);
+
+impl<T: ?Sized> Deref for Wrapper<T> {
+ type Target = T;
+
+ fn deref(&self) -> &T {
+ &self.0
+ }
+}
+
+impl<T: CoerceUnsized<U>, U> CoerceUnsized<Wrapper<U>> for Wrapper<T> {}
+impl<T: CoerceUnsized<U>, U: CoerceSized<T>> CoerceSized<Wrapper<T>> for Wrapper<U> {}
+
+
+trait Trait {
+ // This method can't be called on trait objects, since the receiver would be unsized,
+ // but should not cause an object safety error
+ // fn wrapper(self: Wrapper<Self>) -> i32;
+ fn ptr_wrapper(self: Ptr<Wrapper<Self>>) -> i32;
+ fn wrapper_ptr(self: Wrapper<Ptr<Self>>) -> i32;
+ fn wrapper_ptr_wrapper(self: Wrapper<Ptr<Wrapper<Self>>>) -> i32;
+}
+
+impl Trait for i32 {
+ // fn wrapper(self: Wrapper<Self>) -> i32 {
+ // *self
+ // }
+ fn ptr_wrapper(self: Ptr<Wrapper<Self>>) -> i32 {
+ **self
+ }
+ fn wrapper_ptr(self: Wrapper<Ptr<Self>>) -> i32 {
+ **self
+ }
+ fn wrapper_ptr_wrapper(self: Wrapper<Ptr<Wrapper<Self>>>) -> i32 {
+ ***self
+ }
+}
+
+fn main() {
+ let pw = Ptr(Box::new(Wrapper(5))) as Ptr<Wrapper<dyn Trait>>;
+ assert_eq!(pw.ptr_wrapper(), 5);
+
+ let wp = Wrapper(Ptr(Box::new(6))) as Wrapper<Ptr<dyn Trait>>;
+ assert_eq!(wp.wrapper_ptr(), 6);
+
+ let wpw = Wrapper(Ptr(Box::new(Wrapper(7)))) as Wrapper<Ptr<Wrapper<dyn Trait>>>;
+ assert_eq!(wpw.wrapper_ptr_wrapper(), 7);
+}
--- /dev/null
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(arbitrary_self_types)]
+#![feature(pin)]
+#![feature(rustc_attrs)]
+
+use std::{
+ rc::Rc,
+ sync::Arc,
+ pin::Pin,
+};
+
+trait Trait {
+ fn by_rc(self: Rc<Self>) -> i64;
+ fn by_arc(self: Arc<Self>) -> i64;
+ fn by_pin_mut(self: Pin<&mut Self>) -> i64;
+ fn by_pin_box(self: Pin<Box<Self>>) -> i64;
+}
+
+impl Trait for i64 {
+ fn by_rc(self: Rc<Self>) -> i64 {
+ *self
+ }
+ fn by_arc(self: Arc<Self>) -> i64 {
+ *self
+ }
+ fn by_pin_mut(self: Pin<&mut Self>) -> i64 {
+ *self
+ }
+ fn by_pin_box(self: Pin<Box<Self>>) -> i64 {
+ *self
+ }
+}
+
+fn main() {
+ let rc = Rc::new(1i64) as Rc<dyn Trait>;
+ assert_eq!(1, rc.by_rc());
+
+ let arc = Arc::new(2i64) as Arc<dyn Trait>;
+ assert_eq!(2, arc.by_arc());
+
+ let mut value = 3i64;
+ let pin_mut = Pin::new(&mut value) as Pin<&mut dyn Trait>;
+ assert_eq!(3, pin_mut.by_pin_mut());
+
+ let pin_box = Into::<Pin<Box<i64>>>::into(Box::new(4i64)) as Pin<Box<dyn Trait>>;
+ assert_eq!(4, pin_box.by_pin_box());
+}
use std::rc::Rc;
trait Foo {
- fn foo(self: Rc<Self>) -> usize;
+ fn foo(self: &Rc<Self>) -> usize;
}
trait Bar {
- fn foo(self: Rc<Self>) -> usize where Self: Sized;
- fn bar(self: Box<Self>) -> usize;
+ fn foo(self: &Rc<Self>) -> usize where Self: Sized;
+ fn bar(self: Rc<Self>) -> usize;
}
impl Foo for usize {
- fn foo(self: Rc<Self>) -> usize {
- *self
+ fn foo(self: &Rc<Self>) -> usize {
+ **self
}
}
impl Bar for usize {
- fn foo(self: Rc<Self>) -> usize {
- *self
+ fn foo(self: &Rc<Self>) -> usize {
+ **self
}
- fn bar(self: Box<Self>) -> usize {
+ fn bar(self: Rc<Self>) -> usize {
*self
}
}
fn make_foo() {
- let x = Box::new(5usize) as Box<Foo>;
+ let x = Rc::new(5usize) as Rc<Foo>;
//~^ ERROR E0038
//~| ERROR E0038
}
fn make_bar() {
- let x = Box::new(5usize) as Box<Bar>;
+ let x = Rc::new(5usize) as Rc<Bar>;
x.bar();
}
error[E0038]: the trait `Foo` cannot be made into an object
- --> $DIR/arbitrary-self-types-not-object-safe.rs:40:33
+ --> $DIR/arbitrary-self-types-not-object-safe.rs:40:32
|
-LL | let x = Box::new(5usize) as Box<Foo>;
- | ^^^^^^^^ the trait `Foo` cannot be made into an object
+LL | let x = Rc::new(5usize) as Rc<Foo>;
+ | ^^^^^^^ the trait `Foo` cannot be made into an object
|
- = note: method `foo` has a non-standard `self` type
+ = note: method `foo` has an uncoercible receiver type
error[E0038]: the trait `Foo` cannot be made into an object
--> $DIR/arbitrary-self-types-not-object-safe.rs:40:13
|
-LL | let x = Box::new(5usize) as Box<Foo>;
- | ^^^^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object
+LL | let x = Rc::new(5usize) as Rc<Foo>;
+ | ^^^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object
|
- = note: method `foo` has a non-standard `self` type
- = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<std::boxed::Box<dyn Foo>>` for `std::boxed::Box<usize>`
+ = note: method `foo` has an uncoercible receiver type
+ = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<std::rc::Rc<dyn Foo>>` for `std::rc::Rc<usize>`
error: aborting due to 2 previous errors
--- /dev/null
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(unsize, coerce_sized, coerce_unsized)]
+
+use std::{
+ ops::{CoerceSized, CoerceUnsized},
+ marker::{Unsize, PhantomData},
+};
+
+struct WrapperWithExtraField<T>(T, i32);
+
+impl<T, U> CoerceUnsized<WrapperWithExtraField<U>> for WrapperWithExtraField<T>
+where
+ T: CoerceUnsized<U>,
+{}
+
+impl<T, U> CoerceSized<WrapperWithExtraField<T>> for WrapperWithExtraField<U>
+where
+ T: CoerceUnsized<U>,
+ U: CoerceSized<T>,
+{} //~^^^^ ERROR [E0378]
+
+
+struct MultiplePointers<T: ?Sized>{
+ ptr1: *const T,
+ ptr2: *const T,
+}
+
+// No CoerceUnsized impl
+
+impl<T: ?Sized, U: ?Sized> CoerceSized<MultiplePointers<T>> for MultiplePointers<U>
+where
+ T: Unsize<U>,
+{} //~^^^ ERROR [E0378]
+
+
+struct NothingToCoerce<T: ?Sized> {
+ data: PhantomData<T>,
+}
+
+// No CoerceUnsized impl
+
+impl<T: ?Sized, U: ?Sized> CoerceSized<NothingToCoerce<U>> for NothingToCoerce<T> {}
+//~^ ERROR [E0378]
+
+fn main() {}
--- /dev/null
+error[E0378]: the trait `CoerceSized` may only be implemented for structs containing the field being coerced, `PhantomData` fields, and nothing else
+ --> $DIR/invalid_coerce_sized_impls.rs:25:1
+ |
+LL | / impl<T, U> CoerceSized<WrapperWithExtraField<T>> for WrapperWithExtraField<U>
+LL | | where
+LL | | T: CoerceUnsized<U>,
+LL | | U: CoerceSized<T>,
+LL | | {} //~^^^^ ERROR [E0378]
+ | |__^
+ |
+ = note: extra field `1` of type `i32` is not allowed
+
+error[E0378]: implementing the `CoerceSized` trait requires multiple coercions
+ --> $DIR/invalid_coerce_sized_impls.rs:39:1
+ |
+LL | / impl<T: ?Sized, U: ?Sized> CoerceSized<MultiplePointers<T>> for MultiplePointers<U>
+LL | | where
+LL | | T: Unsize<U>,
+LL | | {} //~^^^ ERROR [E0378]
+ | |__^
+ |
+ = note: the trait `CoerceSized` may only be implemented for a coercion between structures with a single field being coerced
+ = note: currently, 2 fields need coercions: ptr1 (*const U to *const T), ptr2 (*const U to *const T)
+
+error[E0378]: the trait `CoerceSized` may only be implemented for a coercion between structures with a single field being coerced, none found
+ --> $DIR/invalid_coerce_sized_impls.rs:51:1
+ |
+LL | impl<T: ?Sized, U: ?Sized> CoerceSized<NothingToCoerce<U>> for NothingToCoerce<T> {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0378`.