Skip to content

Take 2: Implement object-safety and dynamic dispatch for arbitrary_self_types #54383

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 19 commits into from
Nov 3, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
d14af13
Make all object-safety methods require a global TyCtxt
mikeyhew Jul 2, 2018
a920036
move some code around to avoid query cycles
mikeyhew Sep 20, 2018
be80a79
Add CoerceSized trait and lang item
mikeyhew Sep 20, 2018
d5c2c4a
Implement the object-safety checks for arbitrary_self_types: part 1
mikeyhew Sep 20, 2018
9f59da2
Implement object-safety for arbitrary_self_types: part 2
mikeyhew Sep 20, 2018
192900e
Add CoerceSized impls throughout libstd
mikeyhew Sep 20, 2018
a0f23f8
update tests that have changed output
mikeyhew Sep 20, 2018
82f1f9a
Add new tests and update existing for object-safe custom receivers
mikeyhew Sep 20, 2018
c29641e
fix docs on trait
mikeyhew Sep 21, 2018
f12c250
Replace CoerceSized trait with DispatchFromDyn
mikeyhew Oct 4, 2018
48d7f8d
update DispatchFromDyn doctest
mikeyhew Oct 5, 2018
3c56d8d
fix error-index test
mikeyhew Oct 5, 2018
74ef46c
Replace UncoeribleReceiver error message with UndispatchableReceiver
mikeyhew Oct 9, 2018
6f2a161
Add layout sanity checks in object safety
mikeyhew Oct 9, 2018
b5b25f8
Put backticks around field names, types and paths in error messages
mikeyhew Oct 9, 2018
eb997d7
add `U: Trait` to the param env during DispatchFromDyn check
mikeyhew Oct 12, 2018
3db2203
Remove this check for object-safety during selection of trait object …
mikeyhew Oct 17, 2018
a468da9
Add a check for reprs that could change the ABI
mikeyhew Oct 26, 2018
192e7c4
Add comments explaining how codegen works for `dyn Trait` methods
mikeyhew Nov 1, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add CoerceSized trait and lang item
This trait is more-or-less the reverse of CoerceUnsized, and will be
used for object-safety checks. Receiver types like `Rc` will have to
implement `CoerceSized` so that methods that use `Rc<Self>` as the
receiver will be considered object-safe.
  • Loading branch information
mikeyhew committed Nov 1, 2018
commit be80a79a1ea247a71e5ffa408356b9b72cddb644
3 changes: 3 additions & 0 deletions src/libcore/ops/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,3 +201,6 @@ pub use self::generator::{Generator, GeneratorState};

#[unstable(feature = "coerce_unsized", issue = "27732")]
pub use self::unsize::CoerceUnsized;

#[unstable(feature = "coerce_sized", issue = "0")]
pub use self::unsize::CoerceSized;
33 changes: 32 additions & 1 deletion src/libcore/ops/unsize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ use marker::Unsize;
/// [nomicon-coerce]: ../../nomicon/coercions.html
#[unstable(feature = "coerce_unsized", issue = "27732")]
#[lang = "coerce_unsized"]
pub trait CoerceUnsized<T> {
pub trait CoerceUnsized<T: ?Sized> {
// Empty.
}

Expand Down Expand Up @@ -77,3 +77,34 @@ impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *mut T {}
// *const T -> *const U
#[unstable(feature = "coerce_unsized", issue = "27732")]
impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *const T {}


/// Pointers to unsized types that can be coerced to a pointer to a sized type,
/// as long as pointee is actually a value of that sized type. This is used for
/// object safety, to check that a method's receiver type can be coerced from the version
/// where `Self = dyn Trait` to the version where `Self = T`, the erased, sized type
/// of the underlying object.
///
/// CoerceSized is implemented for:
/// - &[T] is CoerceSized<&[T; N]> for any N
/// - &Trait is CoerceSized<&T> for any T: Trait
/// - and similarly for &mut T, *const T, *mut T, Box<T>, Rc<T>, Arc<T>
#[unstable(feature = "coerce_sized", issue = "0")]
#[cfg_attr(not(stage0), lang = "coerce_sized")]
pub trait CoerceSized<T> where T: CoerceUnsized<Self> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, we need to rename this, per @eddyb's suggestion

// Empty.
}

// &U -> &T
#[unstable(feature = "coerce_sized", issue = "0")]
impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceSized<&'a T> for &'a U {}
// &mut U -> &mut T
#[unstable(feature = "coerce_sized", issue = "0")]
impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceSized<&'a mut T> for &'a mut U {}
// *const U -> *const T
#[unstable(feature = "coerce_sized", issue = "0")]
impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceSized<*const T> for *const U {}
// *mut U -> *mut T
#[unstable(feature = "coerce_sized", issue = "0")]
impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceSized<*mut T> for *mut U {}

1 change: 1 addition & 0 deletions src/librustc/middle/lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ language_item_table! {
DropTraitLangItem, "drop", drop_trait, Target::Trait;

CoerceUnsizedTraitLangItem, "coerce_unsized", coerce_unsized_trait, Target::Trait;
CoerceSizedTraitLangItem, "coerce_sized", coerce_sized_trait, Target::Trait;

AddTraitLangItem, "add", add_trait, Target::Trait;
SubTraitLangItem, "sub", sub_trait, Target::Trait;
Expand Down