4 lines
9.7 KiB
Plaintext
4 lines
9.7 KiB
Plaintext
{"$message_type":"diagnostic","message":"temporary value dropped while borrowed","code":{"code":"E0716","explanation":"A temporary value is being dropped while a borrow is still in active use.\n\nErroneous code example:\n\n```compile_fail,E0716\nfn foo() -> i32 { 22 }\nfn bar(x: &i32) -> &i32 { x }\nlet p = bar(&foo());\n // ------ creates a temporary\nlet q = *p;\n```\n\nHere, the expression `&foo()` is borrowing the expression `foo()`. As `foo()` is\na call to a function, and not the name of a variable, this creates a\n**temporary** -- that temporary stores the return value from `foo()` so that it\ncan be borrowed. You could imagine that `let p = bar(&foo());` is equivalent to\nthe following, which uses an explicit temporary variable.\n\nErroneous code example:\n\n```compile_fail,E0597\n# fn foo() -> i32 { 22 }\n# fn bar(x: &i32) -> &i32 { x }\nlet p = {\n let tmp = foo(); // the temporary\n bar(&tmp) // error: `tmp` does not live long enough\n}; // <-- tmp is freed as we exit this block\nlet q = p;\n```\n\nWhenever a temporary is created, it is automatically dropped (freed) according\nto fixed rules. Ordinarily, the temporary is dropped at the end of the enclosing\nstatement -- in this case, after the `let`. This is illustrated in the example\nabove by showing that `tmp` would be freed as we exit the block.\n\nTo fix this problem, you need to create a local variable to store the value in\nrather than relying on a temporary. For example, you might change the original\nprogram to the following:\n\n```\nfn foo() -> i32 { 22 }\nfn bar(x: &i32) -> &i32 { x }\nlet value = foo(); // dropped at the end of the enclosing block\nlet p = bar(&value);\nlet q = *p;\n```\n\nBy introducing the explicit `let value`, we allocate storage that will last\nuntil the end of the enclosing block (when `value` goes out of scope). When we\nborrow `&value`, we are borrowing a local variable that already exists, and\nhence no temporary is created.\n\nTemporaries are not always dropped at the end of the enclosing statement. In\nsimple cases where the `&` expression is immediately stored into a variable, the\ncompiler will automatically extend the lifetime of the temporary until the end\nof the enclosing block. Therefore, an alternative way to fix the original\nprogram is to write `let tmp = &foo()` and not `let tmp = foo()`:\n\n```\nfn foo() -> i32 { 22 }\nfn bar(x: &i32) -> &i32 { x }\nlet value = &foo();\nlet p = bar(value);\nlet q = *p;\n```\n\nHere, we are still borrowing `foo()`, but as the borrow is assigned directly\ninto a variable, the temporary will not be dropped until the end of the\nenclosing block. Similar rules apply when temporaries are stored into aggregate\nstructures like a tuple or struct:\n\n```\n// Here, two temporaries are created, but\n// as they are stored directly into `value`,\n// they are not dropped until the end of the\n// enclosing block.\nfn foo() -> i32 { 22 }\nlet value = (&foo(), &foo());\n```\n"},"level":"error","spans":[{"file_name":"src/main.rs","byte_start":492,"byte_end":511,"line_start":15,"line_end":15,"column_start":39,"column_end":58,"is_primary":true,"text":[{"text":" let graph_dot = Dot::with_config(&graph.to_petgraph(), &[Config::EdgeNoLabel]);","highlight_start":39,"highlight_end":58}],"label":"creates a temporary value which is freed while still in use","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"src/main.rs","byte_start":536,"byte_end":537,"line_start":15,"line_end":15,"column_start":83,"column_end":84,"is_primary":false,"text":[{"text":" let graph_dot = Dot::with_config(&graph.to_petgraph(), &[Config::EdgeNoLabel]);","highlight_start":83,"highlight_end":84}],"label":"temporary value is freed at the end of this statement","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"src/main.rs","byte_start":557,"byte_end":566,"line_start":16,"line_end":16,"column_start":20,"column_end":29,"is_primary":false,"text":[{"text":" println!(\"{}\", graph_dot);","highlight_start":20,"highlight_end":29}],"label":"borrow later used here","suggested_replacement":null,"suggestion_applicability":null,"expansion":{"span":{"file_name":"/Users/arlo/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/macros.rs","byte_start":4429,"byte_end":4462,"line_start":143,"line_end":143,"column_start":28,"column_end":61,"is_primary":false,"text":[{"text":" $crate::io::_print($crate::format_args_nl!($($arg)*));","highlight_start":28,"highlight_end":61}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":{"span":{"file_name":"src/main.rs","byte_start":542,"byte_end":567,"line_start":16,"line_end":16,"column_start":5,"column_end":30,"is_primary":false,"text":[{"text":" println!(\"{}\", graph_dot);","highlight_start":5,"highlight_end":30}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},"macro_decl_name":"println!","def_site_span":{"file_name":"/Users/arlo/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/macros.rs","byte_start":4307,"byte_end":4327,"line_start":138,"line_end":138,"column_start":1,"column_end":21,"is_primary":false,"text":[{"text":"macro_rules! println {","highlight_start":1,"highlight_end":21}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}}},"macro_decl_name":"$crate::format_args_nl!","def_site_span":{"file_name":"/Users/arlo/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/macros/mod.rs","byte_start":34557,"byte_end":34584,"line_start":1007,"line_end":1007,"column_start":5,"column_end":32,"is_primary":false,"text":[{"text":" macro_rules! format_args_nl {","highlight_start":5,"highlight_end":32}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}}}],"children":[{"message":"consider using a `let` binding to create a longer lived value","code":null,"level":"help","spans":[{"file_name":"src/main.rs","byte_start":458,"byte_end":458,"line_start":15,"line_end":15,"column_start":5,"column_end":5,"is_primary":true,"text":[{"text":" let graph_dot = Dot::with_config(&graph.to_petgraph(), &[Config::EdgeNoLabel]);","highlight_start":5,"highlight_end":5}],"label":null,"suggested_replacement":"let binding = graph.to_petgraph();\n ","suggestion_applicability":"MaybeIncorrect","expansion":null},{"file_name":"src/main.rs","byte_start":492,"byte_end":511,"line_start":15,"line_end":15,"column_start":39,"column_end":58,"is_primary":true,"text":[{"text":" let graph_dot = Dot::with_config(&graph.to_petgraph(), &[Config::EdgeNoLabel]);","highlight_start":39,"highlight_end":58}],"label":null,"suggested_replacement":"binding","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"\u001b[0m\u001b[1m\u001b[38;5;9merror[E0716]\u001b[0m\u001b[0m\u001b[1m: temporary value dropped while borrowed\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m--> \u001b[0m\u001b[0msrc/main.rs:15:39\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\n\u001b[0m\u001b[1m\u001b[38;5;12m15\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0m let graph_dot = Dot::with_config(&graph.to_petgraph(), &[Config::EdgeNoLabel]);\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m| \u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;9m^^^^^^^^^^^^^^^^^^^\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m-\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12mtemporary value is freed at the end of this statement\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m| \u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;9m|\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m| \u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;9mcreates a temporary value which is freed while still in use\u001b[0m\n\u001b[0m\u001b[1m\u001b[38;5;12m16\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0m println!(\"{}\", graph_dot);\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m| \u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m---------\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12mborrow later used here\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\n\u001b[0m\u001b[1m\u001b[38;5;14mhelp\u001b[0m\u001b[0m: consider using a `let` binding to create a longer lived value\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\n\u001b[0m\u001b[1m\u001b[38;5;12m15\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[38;5;10m~ \u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[38;5;10mlet binding = graph.to_petgraph();\u001b[0m\n\u001b[0m\u001b[1m\u001b[38;5;12m16\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[38;5;10m~ \u001b[0m\u001b[0mlet graph_dot = Dot::with_config(&\u001b[0m\u001b[0m\u001b[38;5;10mbinding\u001b[0m\u001b[0m, &[Config::EdgeNoLabel]);\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\n\n"}
|
|
{"$message_type":"diagnostic","message":"aborting due to 1 previous error","code":null,"level":"error","spans":[],"children":[],"rendered":"\u001b[0m\u001b[1m\u001b[38;5;9merror\u001b[0m\u001b[0m\u001b[1m: aborting due to 1 previous error\u001b[0m\n\n"}
|
|
{"$message_type":"diagnostic","message":"For more information about this error, try `rustc --explain E0716`.","code":null,"level":"failure-note","spans":[],"children":[],"rendered":"\u001b[0m\u001b[1mFor more information about this error, try `rustc --explain E0716`.\u001b[0m\n"}
|