Skip to content

Commit 64239df

Browse files
authored
Merge pull request rust-lang#724 from ehuss/nested-receiver
Update for nested receivers.
2 parents c73c5a1 + f183df7 commit 64239df

File tree

2 files changed

+113
-11
lines changed

2 files changed

+113
-11
lines changed

src/items/associated-items.md

+17-11
Original file line numberDiff line numberDiff line change
@@ -98,24 +98,28 @@ Associated functions whose first parameter is named `self` are called *methods*
9898
and may be invoked using the [method call operator], for example, `x.foo()`, as
9999
well as the usual function call notation.
100100

101-
If the type of the `self` parameter is specified, it is limited to one of the
102-
following types:
101+
If the type of the `self` parameter is specified, it is limited to semantic
102+
types generated by the following grammar (where `'lt` denotes some arbitrary
103+
lifetime):
103104

104-
- `Self`
105-
- `&Self`
106-
- `&mut Self`
107-
- [`Box<Self>`]
108-
- [`Rc<Self>`]
109-
- [`Arc<Self>`]
110-
- [`Pin<P>`] where `P` is one of the above types except `Self`.
105+
```text
106+
P = &'lt S | &'lt mut S | Box<S> | Rc<S> | Arc<S> | Pin<P>
107+
S = Self | P
108+
```
111109

112-
The `Self` term can be replaced with the type being implemented.
110+
The `Self` terminal in this grammar is the semantic `Self` type and can be
111+
replaced with the type being implemented, including type aliases or associated
112+
type projections for the type.
113113

114114
```rust
115115
# use std::rc::Rc;
116116
# use std::sync::Arc;
117117
# use std::pin::Pin;
118+
// Examples of methods implemented on struct `Example`.
118119
struct Example;
120+
type Alias = Example;
121+
trait Trait { type Output; }
122+
impl Trait for Example { type Output = Example; }
119123
impl Example {
120124
fn by_value(self: Self) {}
121125
fn by_ref(self: &Self) {}
@@ -126,6 +130,8 @@ impl Example {
126130
fn by_pin(self: Pin<&Self>) {}
127131
fn explicit_type(self: Arc<Example>) {}
128132
fn with_lifetime<'a>(self: &'a Self) {}
133+
fn nested<'a>(self: &mut &'a Arc<Rc<Box<Alias>>>) {}
134+
fn via_projection(self: <Example as Trait>::Output) {}
129135
}
130136
```
131137

@@ -360,4 +366,4 @@ fn main() {
360366
[function item]: ../types/function-item.md
361367
[method call operator]: ../expressions/method-call-expr.md
362368
[path]: ../paths.md
363-
[regular function parameters]: functions.md#attributes-on-function-parameters
369+
[regular function parameters]: functions.md#attributes-on-function-parameters

src/items/traits.md

+96
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,98 @@ Object safe traits can be the base trait of a [trait object]. A trait is
9595
* It must not have any associated constants.
9696
* All supertraits must also be object safe.
9797

98+
When there isn't a `Self: Sized` bound on a method, the type of a method
99+
receiver must be one of the following types:
100+
101+
* `&Self`
102+
* `&mut Self`
103+
* [`Box<Self>`]
104+
* [`Rc<Self>`]
105+
* [`Arc<Self>`]
106+
* [`Pin<P>`] where `P` is one of the types above
107+
108+
```rust
109+
# use std::rc::Rc;
110+
# use std::sync::Arc;
111+
# use std::pin::Pin;
112+
// Examples of object safe methods.
113+
trait TraitMethods {
114+
fn by_ref(self: &Self) {}
115+
fn by_ref_mut(self: &mut Self) {}
116+
fn by_box(self: Box<Self>) {}
117+
fn by_rc(self: Rc<Self>) {}
118+
fn by_arc(self: Arc<Self>) {}
119+
fn by_pin(self: Pin<&Self>) {}
120+
fn with_lifetime<'a>(self: &'a Self) {}
121+
fn nested_pin(self: Pin<Arc<Self>>) {}
122+
}
123+
# struct S;
124+
# impl TraitMethods for S {}
125+
# let t: Box<dyn TraitMethods> = Box::new(S);
126+
```
127+
128+
```rust,compile_fail
129+
// This trait is object-safe, but these methods cannot be dispatched on a trait object.
130+
trait NonDispatchable {
131+
// Non-methods cannot be dispatched.
132+
fn foo() where Self: Sized {}
133+
// Self type isn't known until runtime.
134+
fn returns(&self) -> Self where Self: Sized;
135+
// `other` may be a different concrete type of the receiver.
136+
fn param(&self, other: Self) where Self: Sized {}
137+
// Generics are not compatible with vtables.
138+
fn typed<T>(&self, x: T) where Self: Sized {}
139+
}
140+
141+
struct S;
142+
impl NonDispatchable for S {
143+
fn returns(&self) -> Self where Self: Sized { S }
144+
}
145+
let obj: Box<dyn NonDispatchable> = Box::new(S);
146+
obj.returns(); // ERROR: cannot call with Self return
147+
obj.param(S); // ERROR: cannot call with Self parameter
148+
obj.typed(1); // ERROR: cannot call with generic type
149+
```
150+
151+
```rust,compile_fail
152+
# use std::rc::Rc;
153+
// Examples of non-object safe traits.
154+
trait NotObjectSafe {
155+
const CONST: i32 = 1; // ERROR: cannot have associated const
156+
157+
fn foo() {} // ERROR: associated function without Sized
158+
fn returns(&self) -> Self; // ERROR: Self in return type
159+
fn typed<T>(&self, x: T) {} // ERROR: has generic type parameters
160+
fn nested(self: Rc<Box<Self>>) {} // ERROR: nested receiver not yet supported
161+
}
162+
163+
struct S;
164+
impl NotObjectSafe for S {
165+
fn returns(&self) -> Self { S }
166+
}
167+
let obj: Box<dyn NotObjectSafe> = Box::new(S); // ERROR
168+
```
169+
170+
```rust,compile_fail
171+
// Self: Sized traits are not object-safe.
172+
trait TraitWithSize where Self: Sized {}
173+
174+
struct S;
175+
impl TraitWithSize for S {}
176+
let obj: Box<dyn TraitWithSize> = Box::new(S); // ERROR
177+
```
178+
179+
```rust,compile_fail
180+
// Not object safe if `Self` is a type argument.
181+
trait Super<A> {}
182+
trait WithSelf: Super<Self> where Self: Sized {}
183+
184+
struct S;
185+
impl<A> Super<A> for S {}
186+
impl WithSelf for S {}
187+
let obj: Box<dyn WithSelf> = Box::new(S); // ERROR: cannot use `Self` type parameter
188+
```
189+
98190
## Supertraits
99191

100192
**Supertraits** are traits that are required to be implemented for a type to
@@ -268,3 +360,7 @@ fn main() {
268360
[trait implementation]: implementations.md#trait-implementations
269361
[`Send`]: ../special-types-and-traits.md#send
270362
[`Sync`]: ../special-types-and-traits.md#sync
363+
[`Arc<Self>`]: ../special-types-and-traits.md#arct
364+
[`Box<Self>`]: ../special-types-and-traits.md#boxt
365+
[`Pin<P>`]: ../special-types-and-traits.md#pinp
366+
[`Rc<Self>`]: ../special-types-and-traits.md#rct

0 commit comments

Comments
 (0)