What is the scope of unnamed values?
When do unnamed values go out of scope, when is the value dropped?
I'm looking for an answer based on official docs, not based on experiments.
Example 1:
f(foo().bar());
Example 2:
match foo().bar() {
// ...
}
If bar
is fn bar(self) -> ...
it takes ownership of the passed value, and it is dropped as usual, but what happens if bar
borrows, i.e. fn bar(&self) -> ...
? Does it matter whether the result of bar
depends on the lifetime of &self
?
That is, foo
could be returning a MutexGuard
; it is essential to know when the guard is dropped (and the mutex is unlocked).
The experimental method shows that the unnamed value is dropped after the statement it is created in is "finished"; to force the "early" drop a let
statement is required.
Playground
#[derive(Debug)]
pub struct Foo;
pub fn foo() -> Foo {
println!("foo()");
Foo
}
impl Foo {
pub fn bar(&self) {
}
}
impl Drop for Foo {
fn drop(&mut self) {
println!("Foo::drop()");
}
}
fn main() {
println!("--- scope test start");
println!("value: {:?}", foo().bar());
println!("--- end");
println!("--- scope test start");
match foo().bar() {
v => println!("value: {:?}", v),
}
println!("--- end");
println!("--- scope test start");
let v = foo().bar();
println!("value: {:?}", v);
println!("--- end");
}
prints:
--- scope test start
foo()
value: ()
Foo::drop()
--- end
--- scope test start
foo()
value: ()
Foo::drop()
--- end
--- scope test start
foo()
Foo::drop()
value: ()
--- end
rust
add a comment |
When do unnamed values go out of scope, when is the value dropped?
I'm looking for an answer based on official docs, not based on experiments.
Example 1:
f(foo().bar());
Example 2:
match foo().bar() {
// ...
}
If bar
is fn bar(self) -> ...
it takes ownership of the passed value, and it is dropped as usual, but what happens if bar
borrows, i.e. fn bar(&self) -> ...
? Does it matter whether the result of bar
depends on the lifetime of &self
?
That is, foo
could be returning a MutexGuard
; it is essential to know when the guard is dropped (and the mutex is unlocked).
The experimental method shows that the unnamed value is dropped after the statement it is created in is "finished"; to force the "early" drop a let
statement is required.
Playground
#[derive(Debug)]
pub struct Foo;
pub fn foo() -> Foo {
println!("foo()");
Foo
}
impl Foo {
pub fn bar(&self) {
}
}
impl Drop for Foo {
fn drop(&mut self) {
println!("Foo::drop()");
}
}
fn main() {
println!("--- scope test start");
println!("value: {:?}", foo().bar());
println!("--- end");
println!("--- scope test start");
match foo().bar() {
v => println!("value: {:?}", v),
}
println!("--- end");
println!("--- scope test start");
let v = foo().bar();
println!("value: {:?}", v);
println!("--- end");
}
prints:
--- scope test start
foo()
value: ()
Foo::drop()
--- end
--- scope test start
foo()
value: ()
Foo::drop()
--- end
--- scope test start
foo()
Foo::drop()
value: ()
--- end
rust
Can you clarify what you mean by "to force the "early" drop"?
– Shepmaster
Oct 31 '17 at 21:03
@Shepmaster Well, withlet
the drop happens as expected, but compared to the other constructionsFoo
is dropped "early".
– Stefan
Oct 31 '17 at 21:13
add a comment |
When do unnamed values go out of scope, when is the value dropped?
I'm looking for an answer based on official docs, not based on experiments.
Example 1:
f(foo().bar());
Example 2:
match foo().bar() {
// ...
}
If bar
is fn bar(self) -> ...
it takes ownership of the passed value, and it is dropped as usual, but what happens if bar
borrows, i.e. fn bar(&self) -> ...
? Does it matter whether the result of bar
depends on the lifetime of &self
?
That is, foo
could be returning a MutexGuard
; it is essential to know when the guard is dropped (and the mutex is unlocked).
The experimental method shows that the unnamed value is dropped after the statement it is created in is "finished"; to force the "early" drop a let
statement is required.
Playground
#[derive(Debug)]
pub struct Foo;
pub fn foo() -> Foo {
println!("foo()");
Foo
}
impl Foo {
pub fn bar(&self) {
}
}
impl Drop for Foo {
fn drop(&mut self) {
println!("Foo::drop()");
}
}
fn main() {
println!("--- scope test start");
println!("value: {:?}", foo().bar());
println!("--- end");
println!("--- scope test start");
match foo().bar() {
v => println!("value: {:?}", v),
}
println!("--- end");
println!("--- scope test start");
let v = foo().bar();
println!("value: {:?}", v);
println!("--- end");
}
prints:
--- scope test start
foo()
value: ()
Foo::drop()
--- end
--- scope test start
foo()
value: ()
Foo::drop()
--- end
--- scope test start
foo()
Foo::drop()
value: ()
--- end
rust
When do unnamed values go out of scope, when is the value dropped?
I'm looking for an answer based on official docs, not based on experiments.
Example 1:
f(foo().bar());
Example 2:
match foo().bar() {
// ...
}
If bar
is fn bar(self) -> ...
it takes ownership of the passed value, and it is dropped as usual, but what happens if bar
borrows, i.e. fn bar(&self) -> ...
? Does it matter whether the result of bar
depends on the lifetime of &self
?
That is, foo
could be returning a MutexGuard
; it is essential to know when the guard is dropped (and the mutex is unlocked).
The experimental method shows that the unnamed value is dropped after the statement it is created in is "finished"; to force the "early" drop a let
statement is required.
Playground
#[derive(Debug)]
pub struct Foo;
pub fn foo() -> Foo {
println!("foo()");
Foo
}
impl Foo {
pub fn bar(&self) {
}
}
impl Drop for Foo {
fn drop(&mut self) {
println!("Foo::drop()");
}
}
fn main() {
println!("--- scope test start");
println!("value: {:?}", foo().bar());
println!("--- end");
println!("--- scope test start");
match foo().bar() {
v => println!("value: {:?}", v),
}
println!("--- end");
println!("--- scope test start");
let v = foo().bar();
println!("value: {:?}", v);
println!("--- end");
}
prints:
--- scope test start
foo()
value: ()
Foo::drop()
--- end
--- scope test start
foo()
value: ()
Foo::drop()
--- end
--- scope test start
foo()
Foo::drop()
value: ()
--- end
rust
rust
edited Oct 31 '17 at 21:03
Shepmaster
148k12283418
148k12283418
asked Oct 31 '17 at 20:58
Stefan
3,61911129
3,61911129
Can you clarify what you mean by "to force the "early" drop"?
– Shepmaster
Oct 31 '17 at 21:03
@Shepmaster Well, withlet
the drop happens as expected, but compared to the other constructionsFoo
is dropped "early".
– Stefan
Oct 31 '17 at 21:13
add a comment |
Can you clarify what you mean by "to force the "early" drop"?
– Shepmaster
Oct 31 '17 at 21:03
@Shepmaster Well, withlet
the drop happens as expected, but compared to the other constructionsFoo
is dropped "early".
– Stefan
Oct 31 '17 at 21:13
Can you clarify what you mean by "to force the "early" drop"?
– Shepmaster
Oct 31 '17 at 21:03
Can you clarify what you mean by "to force the "early" drop"?
– Shepmaster
Oct 31 '17 at 21:03
@Shepmaster Well, with
let
the drop happens as expected, but compared to the other constructions Foo
is dropped "early".– Stefan
Oct 31 '17 at 21:13
@Shepmaster Well, with
let
the drop happens as expected, but compared to the other constructions Foo
is dropped "early".– Stefan
Oct 31 '17 at 21:13
add a comment |
1 Answer
1
active
oldest
votes
From the reference:
When using an rvalue in most lvalue contexts, a temporary unnamed
lvalue is created and used instead, if not promoted to'static
.
Promotion of an rvalue expression to a'static
slot occurs when the
expression could be written in a constant, borrowed, and dereferencing
that borrow where the expression was the originally written, without
changing the runtime behavior. That is, the promoted expression can be
evaluated at compile-time and the resulting value does not contain
interior mutability or destructors (these properties are determined
based on the value where possible, e.g.&None
always has the type
&'static Option<_>
, as it contains nothing disallowed). Otherwise, the
lifetime of temporary values is typically
the innermost enclosing statement; the tail expression of a block is
considered part of the statement that encloses the block, or
the
condition expression or the loop conditional expression if the
temporary is created in the condition expression of an if or an
if
/else
or in the loop conditional expression of awhile
expression.
When a temporary rvalue is being created that is assigned into a
let
declaration, however, the temporary is created with the lifetime of
the enclosing block instead, as using the enclosing statement (thelet
declaration) would be a guaranteed error (since a pointer to the
temporary would be stored into a variable, but the temporary would be
freed before the variable could be used). The compiler uses simple
syntactic rules to decide which values are being assigned into a let
binding, and therefore deserve a longer temporary lifetime.
The reference then has examples of these rules.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f47044453%2fwhat-is-the-scope-of-unnamed-values%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
From the reference:
When using an rvalue in most lvalue contexts, a temporary unnamed
lvalue is created and used instead, if not promoted to'static
.
Promotion of an rvalue expression to a'static
slot occurs when the
expression could be written in a constant, borrowed, and dereferencing
that borrow where the expression was the originally written, without
changing the runtime behavior. That is, the promoted expression can be
evaluated at compile-time and the resulting value does not contain
interior mutability or destructors (these properties are determined
based on the value where possible, e.g.&None
always has the type
&'static Option<_>
, as it contains nothing disallowed). Otherwise, the
lifetime of temporary values is typically
the innermost enclosing statement; the tail expression of a block is
considered part of the statement that encloses the block, or
the
condition expression or the loop conditional expression if the
temporary is created in the condition expression of an if or an
if
/else
or in the loop conditional expression of awhile
expression.
When a temporary rvalue is being created that is assigned into a
let
declaration, however, the temporary is created with the lifetime of
the enclosing block instead, as using the enclosing statement (thelet
declaration) would be a guaranteed error (since a pointer to the
temporary would be stored into a variable, but the temporary would be
freed before the variable could be used). The compiler uses simple
syntactic rules to decide which values are being assigned into a let
binding, and therefore deserve a longer temporary lifetime.
The reference then has examples of these rules.
add a comment |
From the reference:
When using an rvalue in most lvalue contexts, a temporary unnamed
lvalue is created and used instead, if not promoted to'static
.
Promotion of an rvalue expression to a'static
slot occurs when the
expression could be written in a constant, borrowed, and dereferencing
that borrow where the expression was the originally written, without
changing the runtime behavior. That is, the promoted expression can be
evaluated at compile-time and the resulting value does not contain
interior mutability or destructors (these properties are determined
based on the value where possible, e.g.&None
always has the type
&'static Option<_>
, as it contains nothing disallowed). Otherwise, the
lifetime of temporary values is typically
the innermost enclosing statement; the tail expression of a block is
considered part of the statement that encloses the block, or
the
condition expression or the loop conditional expression if the
temporary is created in the condition expression of an if or an
if
/else
or in the loop conditional expression of awhile
expression.
When a temporary rvalue is being created that is assigned into a
let
declaration, however, the temporary is created with the lifetime of
the enclosing block instead, as using the enclosing statement (thelet
declaration) would be a guaranteed error (since a pointer to the
temporary would be stored into a variable, but the temporary would be
freed before the variable could be used). The compiler uses simple
syntactic rules to decide which values are being assigned into a let
binding, and therefore deserve a longer temporary lifetime.
The reference then has examples of these rules.
add a comment |
From the reference:
When using an rvalue in most lvalue contexts, a temporary unnamed
lvalue is created and used instead, if not promoted to'static
.
Promotion of an rvalue expression to a'static
slot occurs when the
expression could be written in a constant, borrowed, and dereferencing
that borrow where the expression was the originally written, without
changing the runtime behavior. That is, the promoted expression can be
evaluated at compile-time and the resulting value does not contain
interior mutability or destructors (these properties are determined
based on the value where possible, e.g.&None
always has the type
&'static Option<_>
, as it contains nothing disallowed). Otherwise, the
lifetime of temporary values is typically
the innermost enclosing statement; the tail expression of a block is
considered part of the statement that encloses the block, or
the
condition expression or the loop conditional expression if the
temporary is created in the condition expression of an if or an
if
/else
or in the loop conditional expression of awhile
expression.
When a temporary rvalue is being created that is assigned into a
let
declaration, however, the temporary is created with the lifetime of
the enclosing block instead, as using the enclosing statement (thelet
declaration) would be a guaranteed error (since a pointer to the
temporary would be stored into a variable, but the temporary would be
freed before the variable could be used). The compiler uses simple
syntactic rules to decide which values are being assigned into a let
binding, and therefore deserve a longer temporary lifetime.
The reference then has examples of these rules.
From the reference:
When using an rvalue in most lvalue contexts, a temporary unnamed
lvalue is created and used instead, if not promoted to'static
.
Promotion of an rvalue expression to a'static
slot occurs when the
expression could be written in a constant, borrowed, and dereferencing
that borrow where the expression was the originally written, without
changing the runtime behavior. That is, the promoted expression can be
evaluated at compile-time and the resulting value does not contain
interior mutability or destructors (these properties are determined
based on the value where possible, e.g.&None
always has the type
&'static Option<_>
, as it contains nothing disallowed). Otherwise, the
lifetime of temporary values is typically
the innermost enclosing statement; the tail expression of a block is
considered part of the statement that encloses the block, or
the
condition expression or the loop conditional expression if the
temporary is created in the condition expression of an if or an
if
/else
or in the loop conditional expression of awhile
expression.
When a temporary rvalue is being created that is assigned into a
let
declaration, however, the temporary is created with the lifetime of
the enclosing block instead, as using the enclosing statement (thelet
declaration) would be a guaranteed error (since a pointer to the
temporary would be stored into a variable, but the temporary would be
freed before the variable could be used). The compiler uses simple
syntactic rules to decide which values are being assigned into a let
binding, and therefore deserve a longer temporary lifetime.
The reference then has examples of these rules.
edited Oct 31 '17 at 21:38
answered Oct 31 '17 at 21:08
Shepmaster
148k12283418
148k12283418
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f47044453%2fwhat-is-the-scope-of-unnamed-values%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Can you clarify what you mean by "to force the "early" drop"?
– Shepmaster
Oct 31 '17 at 21:03
@Shepmaster Well, with
let
the drop happens as expected, but compared to the other constructionsFoo
is dropped "early".– Stefan
Oct 31 '17 at 21:13