diff options
| author | bors <bors@rust-lang.org> | 2018-11-03 02:37:29 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2018-11-03 02:37:29 +0000 |
| commit | 3fc70e8d4686190891b575204326c9b9dcd2d3ed (patch) | |
| tree | 3780984da4d2269cfcf6a71ddc54abe478fde944 /src/test | |
| parent | 8b096314a6381e28834ddb1e662ce90e5b32736b (diff) | |
| parent | 192e7c4b51ab35f4cfbbacde9eeffa8e12dba873 (diff) | |
| download | rust-3fc70e8d4686190891b575204326c9b9dcd2d3ed.tar.gz rust-3fc70e8d4686190891b575204326c9b9dcd2d3ed.zip | |
Auto merge of #54383 - mikeyhew:custom-receivers-object-safety, r=nikomatsakis
Take 2: Implement object-safety and dynamic dispatch for arbitrary_self_types
This replaces #50173. Over the months that that PR was open, we made a lot of changes to the way this was going to be implemented, and the long, meandering comment thread and commit history would have been confusing to people reading it in the future. So I decided to package everything up with new, straighforward commits and open a new PR.
Here are the main points. Please read the commit messages for details.
- To simplify codegen, we only support receivers that have the ABI of a pointer. That means they are builtin pointer types, or newtypes thereof.
- We introduce a new trait: `DispatchFromDyn<T>`, similar to `CoerceUnsized<T>`. `DispatchFromDyn` has extra requirements that `CoerceUnsized` does not: when you implement `DispatchFromDyn` for a struct, there cannot be any extra fields besides the field being coerced and `PhantomData` fields. This ensures that the struct's ABI is the same as a pointer.
- For a method's receiver (e.g. `self: Rc<Self>`) to be object-safe, it needs to have the following property:
- let `DynReceiver` be the receiver when `Self = dyn Trait`
- let `ConcreteReceiver` be the receiver when `Self = T`, where `T` is some unknown `Sized` type that implements `Trait`, and is the erased type of the trait object.
- `ConcreteReceiver` must implement `DispatchFromDyn<DynReceiver>`
In the case of `Rc<Self>`, this requires `Rc<T>: DispatchFromDyn<Rc<dyn Trait>>`
These rules are explained more thoroughly in the doc comment on `receiver_is_dispatchable` in object_safety.rs.
r? @nikomatsakis and @eddyb
cc @arielb1 @cramertj @withoutboats
Special thanks to @nikomatsakis for getting me un-stuck when implementing the object-safety checks, and @eddyb for helping with the codegen parts.
EDIT 2018-11-01: updated because CoerceSized has been replaced with DispatchFromDyn
Diffstat (limited to 'src/test')
| -rw-r--r-- | src/test/run-pass/arbitrary_self_types_pointers_and_wrappers.rs | 76 | ||||
| -rw-r--r-- | src/test/run-pass/arbitrary_self_types_stdlib_pointers.rs | 56 | ||||
| -rw-r--r-- | src/test/ui/arbitrary-self-types-not-object-safe.rs | 20 | ||||
| -rw-r--r-- | src/test/ui/arbitrary-self-types-not-object-safe.stderr | 16 | ||||
| -rw-r--r-- | src/test/ui/error-codes/E0375.stderr | 2 | ||||
| -rw-r--r-- | src/test/ui/invalid_dispatch_from_dyn_impls.rs | 52 | ||||
| -rw-r--r-- | src/test/ui/invalid_dispatch_from_dyn_impls.stderr | 41 | ||||
| -rw-r--r-- | src/test/ui/issues/issue-26905.stderr | 2 | ||||
| -rw-r--r-- | src/test/ui/traits/trait-item-privacy.rs | 2 | ||||
| -rw-r--r-- | src/test/ui/traits/trait-item-privacy.stderr | 38 | ||||
| -rw-r--r-- | src/test/ui/traits/trait-test-2.rs | 1 | ||||
| -rw-r--r-- | src/test/ui/traits/trait-test-2.stderr | 10 |
12 files changed, 254 insertions, 62 deletions
diff --git a/src/test/run-pass/arbitrary_self_types_pointers_and_wrappers.rs b/src/test/run-pass/arbitrary_self_types_pointers_and_wrappers.rs new file mode 100644 index 00000000000..e1663563cec --- /dev/null +++ b/src/test/run-pass/arbitrary_self_types_pointers_and_wrappers.rs @@ -0,0 +1,76 @@ +// 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, dispatch_from_dyn)] +#![feature(rustc_attrs)] + +use std::{ + ops::{Deref, CoerceUnsized, DispatchFromDyn}, + marker::Unsize, +}; + +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> DispatchFromDyn<Ptr<U>> for Ptr<T> {} + +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: DispatchFromDyn<U>, U> DispatchFromDyn<Wrapper<U>> for Wrapper<T> {} + + +trait Trait { + // This method isn't object-safe yet. Unsized by-value `self` is object-safe (but not callable + // without unsized_locals), but wrappers arond `Self` currently are not. + // FIXME (mikeyhew) uncomment this when unsized rvalues object-safety is implemented + // 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 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); +} diff --git a/src/test/run-pass/arbitrary_self_types_stdlib_pointers.rs b/src/test/run-pass/arbitrary_self_types_stdlib_pointers.rs new file mode 100644 index 00000000000..80a7ce96911 --- /dev/null +++ b/src/test/run-pass/arbitrary_self_types_stdlib_pointers.rs @@ -0,0 +1,56 @@ +// 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()); +} diff --git a/src/test/ui/arbitrary-self-types-not-object-safe.rs b/src/test/ui/arbitrary-self-types-not-object-safe.rs index 48918b996ef..4dc481174a4 100644 --- a/src/test/ui/arbitrary-self-types-not-object-safe.rs +++ b/src/test/ui/arbitrary-self-types-not-object-safe.rs @@ -12,38 +12,38 @@ 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(); } diff --git a/src/test/ui/arbitrary-self-types-not-object-safe.stderr b/src/test/ui/arbitrary-self-types-not-object-safe.stderr index ec9e65fc4c6..77ca118471d 100644 --- a/src/test/ui/arbitrary-self-types-not-object-safe.stderr +++ b/src/test/ui/arbitrary-self-types-not-object-safe.stderr @@ -1,19 +1,19 @@ 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`'s receiver cannot be dispatched on 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`'s receiver cannot be dispatched on + = 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 diff --git a/src/test/ui/error-codes/E0375.stderr b/src/test/ui/error-codes/E0375.stderr index 3ffd25084b8..f3db697790c 100644 --- a/src/test/ui/error-codes/E0375.stderr +++ b/src/test/ui/error-codes/E0375.stderr @@ -5,7 +5,7 @@ LL | impl<T, U> CoerceUnsized<Foo<U, T>> for Foo<T, U> {} | ^^^^^^^^^^^^^^^^^^^^^^^^ requires multiple coercions | = note: `CoerceUnsized` may only be implemented for a coercion between structures with one field being coerced - = note: currently, 2 fields need coercions: b (T to U), c (U to T) + = note: currently, 2 fields need coercions: `b` (`T` to `U`), `c` (`U` to `T`) error: aborting due to previous error diff --git a/src/test/ui/invalid_dispatch_from_dyn_impls.rs b/src/test/ui/invalid_dispatch_from_dyn_impls.rs new file mode 100644 index 00000000000..1cf5c73ab13 --- /dev/null +++ b/src/test/ui/invalid_dispatch_from_dyn_impls.rs @@ -0,0 +1,52 @@ +// 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, dispatch_from_dyn)] + +use std::{ + ops::DispatchFromDyn, + marker::{Unsize, PhantomData}, +}; + +struct WrapperWithExtraField<T>(T, i32); + +impl<T, U> DispatchFromDyn<WrapperWithExtraField<U>> for WrapperWithExtraField<T> +where + T: DispatchFromDyn<U>, +{} //~^^^ ERROR [E0378] + + +struct MultiplePointers<T: ?Sized>{ + ptr1: *const T, + ptr2: *const T, +} + +impl<T: ?Sized, U: ?Sized> DispatchFromDyn<MultiplePointers<U>> for MultiplePointers<T> +where + T: Unsize<U>, +{} //~^^^ ERROR [E0378] + + +struct NothingToCoerce<T: ?Sized> { + data: PhantomData<T>, +} + +impl<T: ?Sized, U: ?Sized> DispatchFromDyn<NothingToCoerce<T>> for NothingToCoerce<U> {} +//~^ ERROR [E0378] + +#[repr(C)] +struct HasReprC<T: ?Sized>(Box<T>); + +impl<T: ?Sized, U: ?Sized> DispatchFromDyn<HasReprC<U>> for HasReprC<T> +where + T: Unsize<U>, +{} //~^^^ ERROR [E0378] + +fn main() {} diff --git a/src/test/ui/invalid_dispatch_from_dyn_impls.stderr b/src/test/ui/invalid_dispatch_from_dyn_impls.stderr new file mode 100644 index 00000000000..82186b67d97 --- /dev/null +++ b/src/test/ui/invalid_dispatch_from_dyn_impls.stderr @@ -0,0 +1,41 @@ +error[E0378]: the trait `DispatchFromDyn` may only be implemented for structs containing the field being coerced, `PhantomData` fields, and nothing else + --> $DIR/invalid_dispatch_from_dyn_impls.rs:20:1 + | +LL | / impl<T, U> DispatchFromDyn<WrapperWithExtraField<U>> for WrapperWithExtraField<T> +LL | | where +LL | | T: DispatchFromDyn<U>, +LL | | {} //~^^^ ERROR [E0378] + | |__^ + | + = note: extra field `1` of type `i32` is not allowed + +error[E0378]: implementing the `DispatchFromDyn` trait requires multiple coercions + --> $DIR/invalid_dispatch_from_dyn_impls.rs:31:1 + | +LL | / impl<T: ?Sized, U: ?Sized> DispatchFromDyn<MultiplePointers<U>> for MultiplePointers<T> +LL | | where +LL | | T: Unsize<U>, +LL | | {} //~^^^ ERROR [E0378] + | |__^ + | + = note: the trait `DispatchFromDyn` may only be implemented for a coercion between structures with a single field being coerced + = note: currently, 2 fields need coercions: `ptr1` (`*const T` to `*const U`), `ptr2` (`*const T` to `*const U`) + +error[E0378]: the trait `DispatchFromDyn` may only be implemented for a coercion between structures with a single field being coerced, none found + --> $DIR/invalid_dispatch_from_dyn_impls.rs:41:1 + | +LL | impl<T: ?Sized, U: ?Sized> DispatchFromDyn<NothingToCoerce<T>> for NothingToCoerce<U> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0378]: structs implementing `DispatchFromDyn` may not have `#[repr(packed)]` or `#[repr(C)]` + --> $DIR/invalid_dispatch_from_dyn_impls.rs:47:1 + | +LL | / impl<T: ?Sized, U: ?Sized> DispatchFromDyn<HasReprC<U>> for HasReprC<T> +LL | | where +LL | | T: Unsize<U>, +LL | | {} //~^^^ ERROR [E0378] + | |__^ + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0378`. diff --git a/src/test/ui/issues/issue-26905.stderr b/src/test/ui/issues/issue-26905.stderr index f18b58a8330..7feabef5660 100644 --- a/src/test/ui/issues/issue-26905.stderr +++ b/src/test/ui/issues/issue-26905.stderr @@ -5,7 +5,7 @@ LL | impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<MyRc<U>> for MyRc<T>{ | ^^^^^^^^^^^^^^^^^^^^^^ requires multiple coercions | = note: `CoerceUnsized` may only be implemented for a coercion between structures with one field being coerced - = note: currently, 2 fields need coercions: _ptr (*const T to *const U), _boo (NotPhantomData<T> to NotPhantomData<U>) + = note: currently, 2 fields need coercions: `_ptr` (`*const T` to `*const U`), `_boo` (`NotPhantomData<T>` to `NotPhantomData<U>`) error: aborting due to previous error diff --git a/src/test/ui/traits/trait-item-privacy.rs b/src/test/ui/traits/trait-item-privacy.rs index f8e4f0d596e..1db5ec09737 100644 --- a/src/test/ui/traits/trait-item-privacy.rs +++ b/src/test/ui/traits/trait-item-privacy.rs @@ -110,9 +110,7 @@ fn check_assoc_const() { // A, B, C are resolved as inherent items, their traits don't need to be in scope C::A; //~ ERROR associated constant `A` is private //~^ ERROR the trait `assoc_const::C` cannot be made into an object - //~| ERROR the trait bound `dyn assoc_const::C: assoc_const::A` is not satisfied C::B; // ERROR the trait `assoc_const::C` cannot be made into an object - //~^ ERROR the trait bound `dyn assoc_const::C: assoc_const::B` is not satisfied C::C; // OK } diff --git a/src/test/ui/traits/trait-item-privacy.stderr b/src/test/ui/traits/trait-item-privacy.stderr index fc14ae91d7b..4ede83d5d73 100644 --- a/src/test/ui/traits/trait-item-privacy.stderr +++ b/src/test/ui/traits/trait-item-privacy.stderr @@ -100,30 +100,6 @@ error[E0624]: associated constant `A` is private LL | C::A; //~ ERROR associated constant `A` is private | ^^^^ -error[E0277]: the trait bound `dyn assoc_const::C: assoc_const::A` is not satisfied - --> $DIR/trait-item-privacy.rs:111:5 - | -LL | C::A; //~ ERROR associated constant `A` is private - | ^^^^ the trait `assoc_const::A` is not implemented for `dyn assoc_const::C` - | -note: required by `assoc_const::A::A` - --> $DIR/trait-item-privacy.rs:35:9 - | -LL | const A: u8 = 0; - | ^^^^^^^^^^^^^^^^ - -error[E0277]: the trait bound `dyn assoc_const::C: assoc_const::B` is not satisfied - --> $DIR/trait-item-privacy.rs:114:5 - | -LL | C::B; // ERROR the trait `assoc_const::C` cannot be made into an object - | ^^^^ the trait `assoc_const::B` is not implemented for `dyn assoc_const::C` - | -note: required by `assoc_const::B::B` - --> $DIR/trait-item-privacy.rs:39:9 - | -LL | const B: u8 = 0; - | ^^^^^^^^^^^^^^^^ - error[E0038]: the trait `assoc_const::C` cannot be made into an object --> $DIR/trait-item-privacy.rs:111:5 | @@ -135,36 +111,36 @@ LL | C::A; //~ ERROR associated constant `A` is private = note: the trait cannot contain associated consts like `A` error[E0223]: ambiguous associated type - --> $DIR/trait-item-privacy.rs:127:12 + --> $DIR/trait-item-privacy.rs:125:12 | LL | let _: S::A; //~ ERROR ambiguous associated type | ^^^^ help: use fully-qualified syntax: `<S as Trait>::A` error[E0223]: ambiguous associated type - --> $DIR/trait-item-privacy.rs:128:12 + --> $DIR/trait-item-privacy.rs:126:12 | LL | let _: S::B; //~ ERROR ambiguous associated type | ^^^^ help: use fully-qualified syntax: `<S as Trait>::B` error[E0223]: ambiguous associated type - --> $DIR/trait-item-privacy.rs:129:12 + --> $DIR/trait-item-privacy.rs:127:12 | LL | let _: S::C; //~ ERROR ambiguous associated type | ^^^^ help: use fully-qualified syntax: `<S as Trait>::C` error: associated type `A` is private - --> $DIR/trait-item-privacy.rs:131:12 + --> $DIR/trait-item-privacy.rs:129:12 | LL | let _: T::A; //~ ERROR associated type `A` is private | ^^^^ error: associated type `A` is private - --> $DIR/trait-item-privacy.rs:140:9 + --> $DIR/trait-item-privacy.rs:138:9 | LL | A = u8, //~ ERROR associated type `A` is private | ^^^^^^ -error: aborting due to 17 previous errors +error: aborting due to 15 previous errors -Some errors occurred: E0038, E0223, E0277, E0599, E0624. +Some errors occurred: E0038, E0223, E0599, E0624. For more information about an error, try `rustc --explain E0038`. diff --git a/src/test/ui/traits/trait-test-2.rs b/src/test/ui/traits/trait-test-2.rs index dac76fb57fd..01d7e89847a 100644 --- a/src/test/ui/traits/trait-test-2.rs +++ b/src/test/ui/traits/trait-test-2.rs @@ -20,5 +20,4 @@ fn main() { (box 10 as Box<bar>).dup(); //~^ ERROR E0038 //~| ERROR E0038 - //~| ERROR E0277 } diff --git a/src/test/ui/traits/trait-test-2.stderr b/src/test/ui/traits/trait-test-2.stderr index 1e1fcbe340e..db0cd38cb6a 100644 --- a/src/test/ui/traits/trait-test-2.stderr +++ b/src/test/ui/traits/trait-test-2.stderr @@ -10,12 +10,6 @@ error[E0107]: wrong number of type arguments: expected 1, found 2 LL | 10.blah::<i32, i32>(); //~ ERROR wrong number of type arguments: expected 1, found 2 | ^^^ unexpected type argument -error[E0277]: the trait bound `dyn bar: bar` is not satisfied - --> $DIR/trait-test-2.rs:20:26 - | -LL | (box 10 as Box<bar>).dup(); - | ^^^ the trait `bar` is not implemented for `dyn bar` - error[E0038]: the trait `bar` cannot be made into an object --> $DIR/trait-test-2.rs:20:16 | @@ -35,7 +29,7 @@ LL | (box 10 as Box<bar>).dup(); = note: method `blah` has generic type parameters = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<std::boxed::Box<dyn bar>>` for `std::boxed::Box<{integer}>` -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors -Some errors occurred: E0038, E0107, E0277. +Some errors occurred: E0038, E0107. For more information about an error, try `rustc --explain E0038`. |
