-
Notifications
You must be signed in to change notification settings - Fork 488
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
Update for nested receivers. #724
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -95,6 +95,98 @@ Object safe traits can be the base trait of a [trait object]. A trait is | |
* It must not have any associated constants. | ||
* All supertraits must also be object safe. | ||
|
||
When there isn't a `Self: Sized` bound on a method, the type of a method | ||
receiver must be one of the following types: | ||
|
||
* `&Self` | ||
* `&mut Self` | ||
* [`Box<Self>`] | ||
* [`Rc<Self>`] | ||
* [`Arc<Self>`] | ||
* [`Pin<P>`] where `P` is one of the types above | ||
|
||
```rust | ||
# use std::rc::Rc; | ||
# use std::sync::Arc; | ||
# use std::pin::Pin; | ||
// Examples of object safe methods. | ||
trait TraitMethods { | ||
fn by_ref(self: &Self) {} | ||
fn by_ref_mut(self: &mut Self) {} | ||
fn by_box(self: Box<Self>) {} | ||
fn by_rc(self: Rc<Self>) {} | ||
fn by_arc(self: Arc<Self>) {} | ||
fn by_pin(self: Pin<&Self>) {} | ||
fn with_lifetime<'a>(self: &'a Self) {} | ||
fn nested_pin(self: Pin<Arc<Self>>) {} | ||
} | ||
# struct S; | ||
# impl TraitMethods for S {} | ||
# let t: Box<dyn TraitMethods> = Box::new(S); | ||
``` | ||
|
||
```rust,compile_fail | ||
// This trait is object-safe, but these methods cannot be dispatched on a trait object. | ||
trait NonDispatchable { | ||
// Non-methods cannot be dispatched. | ||
fn foo() where Self: Sized {} | ||
// Self type isn't known until runtime. | ||
fn returns(&self) -> Self where Self: Sized; | ||
// `other` may be a different concrete type of the receiver. | ||
fn param(&self, other: Self) where Self: Sized {} | ||
ehuss marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// Generics are not compatible with vtables. | ||
fn typed<T>(&self, x: T) where Self: Sized {} | ||
} | ||
|
||
struct S; | ||
impl NonDispatchable for S { | ||
fn returns(&self) -> Self where Self: Sized { S } | ||
} | ||
let obj: Box<dyn NonDispatchable> = Box::new(S); | ||
obj.returns(); // ERROR: cannot call with Self return | ||
obj.param(S); // ERROR: cannot call with Self parameter | ||
obj.typed(1); // ERROR: cannot call with generic type | ||
``` | ||
|
||
```rust,compile_fail | ||
# use std::rc::Rc; | ||
// Examples of non-object safe traits. | ||
trait NotObjectSafe { | ||
const CONST: i32 = 1; // ERROR: cannot have associated const | ||
|
||
fn foo() {} // ERROR: associated function without Sized | ||
fn returns(&self) -> Self; // ERROR: Self in return type | ||
fn typed<T>(&self, x: T) {} // ERROR: has generic type parameters | ||
fn nested(self: Rc<Box<Self>>) {} // ERROR: nested receiver not yet supported | ||
} | ||
|
||
struct S; | ||
impl NotObjectSafe for S { | ||
fn returns(&self) -> Self { S } | ||
} | ||
let obj: Box<dyn NotObjectSafe> = Box::new(S); // ERROR | ||
``` | ||
|
||
```rust,compile_fail | ||
// Self: Sized traits are not object-safe. | ||
trait TraitWithSize where Self: Sized {} | ||
|
||
struct S; | ||
impl TraitWithSize for S {} | ||
let obj: Box<dyn TraitWithSize> = Box::new(S); // ERROR | ||
``` | ||
|
||
```rust,compile_fail | ||
// Not object safe if `Self` is a type argument. | ||
trait Super<A> {} | ||
trait WithSelf: Super<Self> where Self: Sized {} | ||
|
||
struct S; | ||
impl<A> Super<A> for S {} | ||
impl WithSelf for S {} | ||
let obj: Box<dyn WithSelf> = Box::new(S); // ERROR: cannot use `Self` type parameter | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't see how this falls out of the rules listed above. Is this an extra rule, or some combination I am not understanding? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems like Niko hasn't had time to address this. Let's file an issue for now and then Niko can follow up on that one? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yea, I wasn't expecting to fix it in this PR, I was just a little confused. Filed #756. |
||
``` | ||
|
||
## Supertraits | ||
|
||
**Supertraits** are traits that are required to be implemented for a type to | ||
|
@@ -268,3 +360,7 @@ fn main() { | |
[trait implementation]: implementations.md#trait-implementations | ||
[`Send`]: ../special-types-and-traits.md#send | ||
[`Sync`]: ../special-types-and-traits.md#sync | ||
[`Arc<Self>`]: ../special-types-and-traits.md#arct | ||
[`Box<Self>`]: ../special-types-and-traits.md#boxt | ||
[`Pin<P>`]: ../special-types-and-traits.md#pinp | ||
[`Rc<Self>`]: ../special-types-and-traits.md#rct |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's a "semantic type"? In the PL research community this has a very specific meaning (which you can read about e.g. in this paper), but I doubt that is what you mean.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, it's not the "semantic type system" notion in PL research. Rather, this means to say that the
Self
here is not meant literally (as in those characters making upSelf
). So it could be a type alias to e.g.Rc<TheImplementingType>
. Ideas for a better wording?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"unfolded type"? "fully expanded type"? "resolved type"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"resolved type" seems good.