Skip to content

Commit ddc1d58

Browse files
committed
Add a note about scoping differences between *x and *x.deref()
1 parent e122eef commit ddc1d58

File tree

1 file changed

+24
-0
lines changed

1 file changed

+24
-0
lines changed

src/expressions/operator-expr.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,30 @@ let y = &mut 9;
189189
assert_eq!(*y, 11);
190190
```
191191

192+
> [!NOTE]
193+
> The [temporary scopes][temporary scope] of `x` in `*x` and `*std::ops::Deref::deref(&x)` are not always the same in all immutable place expression contexts.
194+
> Likewise, the temporary scopes of `x` in `*x` and `*std::ops::DerefMut::deref_mut(&mut x)` are not always the same in all mutable place expression contexts.
195+
>
196+
> If `*x` has an [extended][temporary lifetime extension] temporary scope, then `x` does as well ([destructors.scope.lifetime-extension.sub-expressions]).
197+
> However, the same does not apply to `*std::ops::Deref::deref(&x)` or `*std::ops::DerefMut::deref_mut(&mut x)`.
198+
>
199+
> For example:
200+
>
201+
> ```rust
202+
> // The temporary holding the result of `String::new()` is extended
203+
> // to live to the end of the block, so `x` may be used in subsequent
204+
> // statements.
205+
> let x = &*String::new();
206+
> # x;
207+
> ```
208+
>
209+
> ```rust,compile_fail,E0716
210+
> // The temporary holding the result of `String::new()` is dropped at
211+
> // the end of the statement, so it's an error to use `y` after.
212+
> let y = &*std::ops::Deref::deref(&String::new()); // ERROR
213+
> # y;
214+
> ```
215+
192216
r[expr.try]
193217
## The try propagation expression
194218

0 commit comments

Comments
 (0)