[{"data":1,"prerenderedAt":2397},["ShallowReactive",2],{"page-\u002Frust\u002F10-lifetimes":3},{"id":4,"title":5,"body":6,"description":346,"extension":2391,"meta":2392,"navigation":39,"path":2393,"seo":2394,"stem":2395,"__hash__":2396},"content\u002Frust\u002F10-lifetimes.md","10 — Lifetimes",{"type":7,"value":8,"toc":2354},"minimark",[9,13,114,189,257,331,509,574,682,806,1027,1364,1596,1672,1768,1865,1938,1987,2071,2173,2252,2350],[10,11,5],"h1",{"id":12},"_10-lifetimes",[14,15,16,26,76],"question-wrapper",{},[17,18,20,21,25],"h3",{"id":19},"q1-what-does-the-signature-fn-longestax-a-str-y-a-str-a-str-actually-promise-to-the-caller","Q1. What does the signature ",[22,23,24],"code",{},"fn longest\u003C'a>(x: &'a str, y: &'a str) -> &'a str"," actually promise to the caller?",[27,28,31,50,56,66],"ul",{"className":29},[30],"contains-task-list",[32,33,36,41,42,45,46,49],"li",{"className":34},[35],"task-list-item",[37,38],"input",{"disabled":39,"type":40},true,"checkbox"," That ",[22,43,44],{},"x"," and ",[22,47,48],{},"y"," live exactly as long as each other",[32,51,53,55],{"className":52},[35],[37,54],{"disabled":39,"type":40}," That the returned reference is valid for at least as long as the shorter of the two input borrows overlap",[32,57,59,61,62,65],{"className":58},[35],[37,60],{"disabled":39,"type":40}," That the function allocates a new string with a ",[22,63,64],{},"'static"," lifetime",[32,67,69,41,71,45,73,75],{"className":68},[35],[37,70],{"disabled":39,"type":40},[22,72,44],{},[22,74,48],{}," must be declared in the same scope",[77,78,79,83,91],"details",{},[80,81,82],"summary",{},"Show Answer",[84,85,86,90],"p",{},[87,88,89],"strong",{},"Answer:"," B — That the returned reference is valid for at least as long as the shorter of the two input borrows overlap",[84,92,93,96,97,100,101,45,103,105,106,45,108,110,111,113],{},[87,94,95],{},"Explanation:"," ",[22,98,99],{},"'a"," is not a concrete duration; it's a constraint the compiler solves for at each call site — it becomes the intersection (overlap) of however long ",[22,102,44],{},[22,104,48],{}," are actually borrowed for. The returned reference is only guaranteed valid within that overlap. A is wrong because ",[22,107,44],{},[22,109,48],{}," can have different concrete lifetimes; the annotation just forces the compiler to pick the smaller one for ",[22,112,99],{},". C is wrong because lifetime parameters describe borrows of existing data, not allocation. D is wrong — lifetimes are about how long borrows are valid, not lexical co-location.",[14,115,116,124,162],{},[17,117,119,120,123],{"id":118},"q2-given-fn-first_words-str-str-why-does-this-compile-without-any-explicit-lifetime-annotations","Q2. Given ",[22,121,122],{},"fn first_word(s: &str) -> &str",", why does this compile without any explicit lifetime annotations?",[27,125,127,133,139,152],{"className":126},[30],[32,128,130,132],{"className":129},[35],[37,131],{"disabled":39,"type":40}," The function doesn't return a reference, so no lifetime is needed",[32,134,136,138],{"className":135},[35],[37,137],{"disabled":39,"type":40}," Lifetime elision rule: a single input reference's lifetime is automatically assigned to all elided output lifetimes",[32,140,142,144,145,148,149],{"className":141},[35],[37,143],{"disabled":39,"type":40}," The Rust compiler infers lifetimes only for ",[22,146,147],{},"&str",", never for ",[22,150,151],{},"&T",[32,153,155,157,158,161],{"className":154},[35],[37,156],{"disabled":39,"type":40}," Because ",[22,159,160],{},"s"," is immutable, lifetimes are not checked",[77,163,164,166,171],{},[80,165,82],{},[84,167,168,170],{},[87,169,89],{}," B — Lifetime elision rule: a single input reference's lifetime is automatically assigned to all elided output lifetimes",[84,172,173,175,176,179,180,182,183,185,186,188],{},[87,174,95],{}," This is desugared by the compiler to ",[22,177,178],{},"fn first_word\u003C'a>(s: &'a str) -> &'a str",". The elision rules exist so common patterns don't require boilerplate. A is false — the return type is clearly ",[22,181,147],{},", a reference. C is false — elision applies uniformly to any ",[22,184,151],{},", not just ",[22,187,147],{},". D is false — mutability is irrelevant to lifetime elision; the rule is purely about counting input reference parameters.",[14,190,191,199,234],{},[17,192,194,195,198],{"id":193},"q3-why-does-fn-combinex-str-y-str-str-fail-to-compile-as-written","Q3. Why does ",[22,196,197],{},"fn combine(x: &str, y: &str) -> &str"," fail to compile as written?",[27,200,202,208,218,228],{"className":201},[30],[32,203,205,207],{"className":204},[35],[37,206],{"disabled":39,"type":40}," It doesn't — this compiles fine using elision",[32,209,211,213,214,217],{"className":210},[35],[37,212],{"disabled":39,"type":40}," There are two input lifetimes and no ",[22,215,216],{},"&self",", so elision cannot determine which one the output should borrow from",[32,219,221,96,223,225,226],{"className":220},[35],[37,222],{"disabled":39,"type":40},[22,224,147],{}," return types always require ",[22,227,64],{},[32,229,231,233],{"className":230},[35],[37,232],{"disabled":39,"type":40}," Rust forbids functions with two reference parameters",[77,235,236,238,245],{},[80,237,82],{},[84,239,240,242,243,217],{},[87,241,89],{}," B — There are two input lifetimes and no ",[22,244,216],{},[84,246,247,249,250,252,253,256],{},[87,248,95],{}," Elision rule 2 (single input lifetime applied to output) only fires when there is exactly one input reference. Rule 3 (use ",[22,251,216],{},"'s lifetime) only fires for methods. With two unrelated reference parameters and neither rule applicable, the compiler refuses to guess and demands an explicit ",[22,254,255],{},"fn combine\u003C'a>(x: &'a str, y: &'a str) -> &'a str"," (or distinct lifetimes if only one feeds the output). A is wrong — this genuinely fails with \"missing lifetime specifier.\" C and D are fabricated restrictions that don't exist in Rust.",[14,258,259,270,301],{},[17,260,262,263,266,267,269],{"id":261},"q4-in-impla-parsera-fn-peekself-other-str-str-which-lifetime-does-the-returned-str-borrow-from-per-elision-rule-3","Q4. In ",[22,264,265],{},"impl\u003C'a> Parser\u003C'a> { fn peek(&self, other: &str) -> &str { ... } }",", which lifetime does the returned ",[22,268,147],{}," borrow from, per elision rule 3?",[27,271,273,282,289,295],{"className":272},[30],[32,274,276,96,278,281],{"className":275},[35],[37,277],{"disabled":39,"type":40},[22,279,280],{},"other","'s lifetime",[32,283,285,96,287,281],{"className":284},[35],[37,286],{"disabled":39,"type":40},[22,288,216],{},[32,290,292,294],{"className":291},[35],[37,293],{"disabled":39,"type":40}," A fresh anonymous lifetime unrelated to either parameter",[32,296,298,300],{"className":297},[35],[37,299],{"disabled":39,"type":40}," This is ambiguous and fails to compile",[77,302,303,305,312],{},[80,304,82],{},[84,306,307,309,310,281],{},[87,308,89],{}," B — ",[22,311,216],{},[84,313,314,316,317,319,320,323,324,327,328,330],{},[87,315,95],{}," Elision rule 3 states that when a method has multiple input lifetimes but one of them is ",[22,318,216],{}," or ",[22,321,322],{},"&mut self",", the lifetime of ",[22,325,326],{},"self"," is assigned to all elided output lifetimes — this matches the common case where a method returns a borrow of its own fields. A is the tempting-but-wrong guess many make when reading ",[22,329,280],{}," as \"the last parameter, so it must apply.\" C and D ignore that rule 3 exists specifically to resolve this case without an error.",[14,332,334,338,430,471],{"language":333},"rust",[17,335,337],{"id":336},"q5-why-does-the-following-fail-to-compile","Q5. Why does the following fail to compile?",[339,340,341],"code-wrapper",{"language":333},[342,343,347],"pre",{"className":344,"code":345,"language":333,"meta":346,"style":346},"language-rust shiki shiki-themes github-light github-dark","fn make_owner() -> &str {\n    let s = String::from(\"temp\");\n    &s[..]\n}\n","",[22,348,349,378,409,424],{"__ignoreMap":346},[350,351,354,358,362,366,369,372,375],"span",{"class":352,"line":353},"line",1,[350,355,357],{"class":356},"svdQ7","fn",[350,359,361],{"class":360},"sIsaT"," make_owner",[350,363,365],{"class":364},"ssxIu","() ",[350,367,368],{"class":356},"->",[350,370,371],{"class":356}," &",[350,373,374],{"class":360},"str",[350,376,377],{"class":364}," {\n",[350,379,381,384,387,390,393,396,399,402,406],{"class":352,"line":380},2,[350,382,383],{"class":356},"    let",[350,385,386],{"class":364}," s ",[350,388,389],{"class":356},"=",[350,391,392],{"class":360}," String",[350,394,395],{"class":356},"::",[350,397,398],{"class":360},"from",[350,400,401],{"class":364},"(",[350,403,405],{"class":404},"sJ6F3","\"temp\"",[350,407,408],{"class":364},");\n",[350,410,412,415,418,421],{"class":352,"line":411},3,[350,413,414],{"class":356},"    &",[350,416,417],{"class":364},"s[",[350,419,420],{"class":356},"..",[350,422,423],{"class":364},"]\n",[350,425,427],{"class":352,"line":426},4,[350,428,429],{"class":364},"}\n",[27,431,433,442,450,460],{"className":432},[30],[32,434,436,96,438,441],{"className":435},[35],[37,437],{"disabled":39,"type":40},[22,439,440],{},"String::from"," cannot be indexed with a range",[32,443,445,96,447,449],{"className":444},[35],[37,446],{"disabled":39,"type":40},[22,448,160],{}," is dropped at the end of the function, so the returned reference would dangle",[32,451,453,455,456,459],{"className":452},[35],[37,454],{"disabled":39,"type":40}," The function is missing a ",[22,457,458],{},"mut"," keyword",[32,461,463,96,465,467,468],{"className":462},[35],[37,464],{"disabled":39,"type":40},[22,466,147],{}," cannot be constructed from a ",[22,469,470],{},"String",[77,472,473,475,481],{},[80,474,82],{},[84,476,477,309,479,449],{},[87,478,89],{},[22,480,160],{},[84,482,483,96,485,487,488,490,491,493,494,497,498,501,502,504,505,508],{},[87,484,95],{},[22,486,160],{}," is a local ",[22,489,470],{}," owned by the function's stack frame; once the function returns, ",[22,492,160],{}," is deallocated. Returning ",[22,495,496],{},"&s[..]"," would produce a reference to freed memory, so the borrow checker rejects it with \"cannot return reference to local variable.\" ",[87,499,500],{},"Safety:"," this is exactly the class of bug lifetimes exist to prevent at compile time instead of at runtime as a use-after-free. The fix is to return an owned ",[22,503,470],{}," (",[22,506,507],{},"fn make_owner() -> String","). A and D are false — both operations are valid Rust; C is irrelevant, mutability doesn't affect ownership\u002Fdrop timing.",[14,510,511,522,549],{},[17,512,514,515,517,518,521],{"id":513},"q6-what-does-the-static-lifetime-bound-on-a-reference-as-in-x-static-str-guarantee","Q6. What does the ",[22,516,64],{}," lifetime bound on a reference, as in ",[22,519,520],{},"x: &'static str",", guarantee?",[27,523,525,531,537,543],{"className":524},[30],[32,526,528,530],{"className":527},[35],[37,529],{"disabled":39,"type":40}," The value is heap-allocated",[32,532,534,536],{"className":533},[35],[37,535],{"disabled":39,"type":40}," The reference's data is valid for the entire remainder of the program's execution",[32,538,540,542],{"className":539},[35],[37,541],{"disabled":39,"type":40}," The value cannot be a string literal",[32,544,546,548],{"className":545},[35],[37,547],{"disabled":39,"type":40}," The variable is thread-local",[77,550,551,553,558],{},[80,552,82],{},[84,554,555,557],{},[87,556,89],{}," B — The reference's data is valid for the entire remainder of the program's execution",[84,559,560,96,562,564,565,567,568,570,571,573],{},[87,561,95],{},[22,563,64],{}," means the borrow does not need to be dropped before the program ends — the referenced data outlives everything else. String literals are the canonical example because they're baked into the binary's read-only data section. A is wrong — ",[22,566,64],{}," says nothing about heap vs. stack vs. static memory, only about duration. C is backwards — literals are the most common source of ",[22,569,64],{}," references. D is unrelated — ",[22,572,64],{}," has nothing to do with threading.",[14,575,576,580,629,658],{"language":333},[17,577,579],{"id":578},"q7-why-must-this-struct-definition-include-an-explicit-lifetime-parameter","Q7. Why must this struct definition include an explicit lifetime parameter?",[339,581,582],{"language":333},[342,583,585],{"className":344,"code":584,"language":333,"meta":346,"style":346},"struct Excerpt\u003C'a> {\n    part: &'a str,\n}\n",[22,586,587,604,625],{"__ignoreMap":346},[350,588,589,592,595,598,601],{"class":352,"line":353},[350,590,591],{"class":356},"struct",[350,593,594],{"class":360}," Excerpt",[350,596,597],{"class":364},"\u003C'",[350,599,600],{"class":360},"a",[350,602,603],{"class":364},"> {\n",[350,605,606,609,612,614,617,619,622],{"class":352,"line":380},[350,607,608],{"class":364},"    part",[350,610,611],{"class":356},":",[350,613,371],{"class":356},[350,615,616],{"class":364},"'",[350,618,600],{"class":360},[350,620,621],{"class":360}," str",[350,623,624],{"class":364},",\n",[350,626,627],{"class":352,"line":411},[350,628,429],{"class":364},[27,630,632,638,644,652],{"className":631},[30],[32,633,635,637],{"className":634},[35],[37,636],{"disabled":39,"type":40}," All structs in Rust require at least one generic parameter",[32,639,641,643],{"className":640},[35],[37,642],{"disabled":39,"type":40}," A struct that holds a reference must declare how long that reference is valid for, tied to the struct's own lifetime",[32,645,647,96,649,651],{"className":646},[35],[37,648],{"disabled":39,"type":40},[22,650,147],{}," fields are only allowed in enums, not structs",[32,653,655,657],{"className":654},[35],[37,656],{"disabled":39,"type":40}," It's optional style, not a compiler requirement",[77,659,660,662,667],{},[80,661,82],{},[84,663,664,666],{},[87,665,89],{}," B — A struct that holds a reference must declare how long that reference is valid for, tied to the struct's own lifetime",[84,668,669,671,672,675,676,678,679,681],{},[87,670,95],{}," Whenever a struct stores a borrowed reference instead of owned data, the compiler needs to know the reference can't outlive the data it points to, and that no instance of ",[22,673,674],{},"Excerpt"," can outlive ",[22,677,99],{},". Omitting the annotation is a hard compile error (\"missing lifetime specifier\"), not a style choice — D is wrong. A is a fabricated rule; plenty of structs have zero generic parameters. C is false — the restriction applies to any reference field, not specifically ",[22,680,147],{}," in enums.",[14,683,684,696,750],{},[17,685,687,688,691,692,695],{"id":686},"q8-a-junior-developer-claims-if-i-add-a-t-static-bound-to-a-generic-function-every-value-passed-in-must-be-created-before-main-starts-like-a-string-literal-is-this-accurate","Q8. A junior developer claims: \"If I add a ",[22,689,690],{},"T: 'static"," bound to a generic function, every value passed in must be created before ",[22,693,694],{},"main()"," starts, like a string literal.\" Is this accurate?",[27,697,699,708,727,738],{"className":698},[30],[32,700,702,704,705,707],{"className":701},[35],[37,703],{"disabled":39,"type":40}," Yes, ",[22,706,64],{}," bounds always require compile-time-constant data",[32,709,711,713,714,716,717,720,721,723,724,726],{"className":710},[35],[37,712],{"disabled":39,"type":40}," No — ",[22,715,690],{}," just means ",[22,718,719],{},"T"," contains no borrowed references shorter than ",[22,722,64],{},"; an owned, heap-allocated ",[22,725,470],{}," created at runtime satisfies it fine",[32,728,730,713,732,734,735],{"className":729},[35],[37,731],{"disabled":39,"type":40},[22,733,690],{}," means the value must be ",[22,736,737],{},"Copy",[32,739,741,743,744,45,746,749],{"className":740},[35],[37,742],{"disabled":39,"type":40}," Yes, but only for ",[22,745,470],{},[22,747,748],{},"Vec"," types specifically",[77,751,752,754,767],{},[80,753,82],{},[84,755,756,758,759,716,761,720,763,723,765,726],{},[87,757,89],{}," B — No — ",[22,760,690],{},[22,762,719],{},[22,764,64],{},[22,766,470],{},[84,768,769,771,772,774,775,777,778,780,781,783,784,787,788,791,792,794,795,798,799,45,802,805],{},[87,770,95],{}," This is one of the most common Rust misconceptions. ",[22,773,690],{}," does not mean \"lives forever\" or \"known at compile time\" — it means \"if ",[22,776,719],{}," contains any references, those references must be ",[22,779,64],{},".\" Owned types like ",[22,782,470],{},", ",[22,785,786],{},"Vec\u003Cu8>",", or ",[22,789,790],{},"i32"," trivially satisfy ",[22,793,690],{}," because they own their data outright and contain no borrows at all, regardless of when they're created. ",[87,796,797],{},"Idiom:"," this bound shows up constantly on ",[22,800,801],{},"thread::spawn",[22,803,804],{},"Box\u003Cdyn Trait>"," precisely to rule out dangling borrows across thread\u002Fheap boundaries, not to force compile-time construction. A, C, and D invent restrictions that don't exist.",[14,807,808,812,919,979],{"language":333},[17,809,811],{"id":810},"q9-consider-this-function-under-non-lexical-lifetimes-nll-why-does-it-compile","Q9. Consider this function under Non-Lexical Lifetimes (NLL). Why does it compile?",[339,813,814],{"language":333},[342,815,817],{"className":344,"code":816,"language":333,"meta":346,"style":346},"fn main() {\n    let mut v = vec![1, 2, 3];\n    let first = &v[0];\n    println!(\"{first}\");\n    v.push(4);\n}\n",[22,818,819,829,864,883,895,914],{"__ignoreMap":346},[350,820,821,823,826],{"class":352,"line":353},[350,822,357],{"class":356},[350,824,825],{"class":360}," main",[350,827,828],{"class":364},"() {\n",[350,830,831,833,836,839,841,844,847,851,853,856,858,861],{"class":352,"line":380},[350,832,383],{"class":356},[350,834,835],{"class":356}," mut",[350,837,838],{"class":364}," v ",[350,840,389],{"class":356},[350,842,843],{"class":360}," vec!",[350,845,846],{"class":364},"[",[350,848,850],{"class":849},"snvgF","1",[350,852,783],{"class":364},[350,854,855],{"class":849},"2",[350,857,783],{"class":364},[350,859,860],{"class":849},"3",[350,862,863],{"class":364},"];\n",[350,865,866,868,871,873,875,878,881],{"class":352,"line":411},[350,867,383],{"class":356},[350,869,870],{"class":364}," first ",[350,872,389],{"class":356},[350,874,371],{"class":356},[350,876,877],{"class":364},"v[",[350,879,880],{"class":849},"0",[350,882,863],{"class":364},[350,884,885,888,890,893],{"class":352,"line":426},[350,886,887],{"class":360},"    println!",[350,889,401],{"class":364},[350,891,892],{"class":404},"\"{first}\"",[350,894,408],{"class":364},[350,896,898,901,904,907,909,912],{"class":352,"line":897},5,[350,899,900],{"class":364},"    v",[350,902,903],{"class":356},".",[350,905,906],{"class":360},"push",[350,908,401],{"class":364},[350,910,911],{"class":849},"4",[350,913,408],{"class":364},[350,915,917],{"class":352,"line":916},6,[350,918,429],{"class":364},[27,920,922,939,955,969],{"className":921},[30],[32,923,925,927,928,931,932,935,936,938],{"className":924},[35],[37,926],{"disabled":39,"type":40}," It doesn't compile — ",[22,929,930],{},"first"," still borrows ",[22,933,934],{},"v"," when ",[22,937,906],{}," is called",[32,940,942,944,945,947,948,951,952,954],{"className":941},[35],[37,943],{"disabled":39,"type":40}," NLL ends ",[22,946,930],{},"'s borrow at its last use (the ",[22,949,950],{},"println!","), so the mutable borrow in ",[22,953,906],{}," doesn't conflict",[32,956,958,96,960,963,964,966,967],{"className":957},[35],[37,959],{"disabled":39,"type":40},[22,961,962],{},"v[0]"," copies the value instead of borrowing, since ",[22,965,790],{}," is ",[22,968,737],{},[32,970,972,96,974,976,977],{"className":971},[35],[37,973],{"disabled":39,"type":40},[22,975,906],{}," doesn't require a mutable borrow of ",[22,978,934],{},[77,980,981,983,994],{},[80,982,82],{},[84,984,985,987,988,947,990,951,992,954],{},[87,986,89],{}," B — NLL ends ",[22,989,930],{},[22,991,950],{},[22,993,906],{},[84,995,996,998,999,1003,1004,1006,1007,1010,1011,1013,1014,1016,1017,1020,1021,1024,1025,903],{},[87,997,95],{}," Before NLL (pre-2018 borrow checker), a reference's lifetime extended to the end of its lexical scope, so this would have failed. NLL changed the analysis to end a borrow's ",[1000,1001,1002],"em",{},"lifetime"," at its last actual use, which can be well before the closing brace — lifetime and scope are related but not identical. ",[87,1005,797],{}," this is exactly why \"lifetime\" and \"scope\" are distinct concepts; scope is lexical, lifetime is usage-based. A is the pre-NLL answer and a common outdated assumption. C is a red herring — indexing does borrow, ",[22,1008,1009],{},"i32: Copy"," doesn't change that ",[22,1012,962],{}," on a ",[22,1015,748],{}," desugars through ",[22,1018,1019],{},"Index",", though the copy happens right after the borrow, which is exactly why the borrow can end immediately. D is false — ",[22,1022,1023],{},"Vec::push"," requires ",[22,1026,322],{},[14,1028,1029,1033,1257,1301],{"language":333},[17,1030,1032],{"id":1031},"q10-whats-wrong-with-this-attempt-at-an-early-return-function","Q10. What's wrong with this attempt at an early-return function?",[339,1034,1035],{"language":333},[342,1036,1038],{"className":344,"code":1037,"language":333,"meta":346,"style":346},"fn shortest\u003C'a>(x: &'a str, y: &'a str) -> &'a str {\n    if x.len() \u003C y.len() { x } else { y }\n}\n\nfn caller() -> &'static str {\n    let long_lived = String::from(\"hello world\");\n    let result;\n    {\n        let short_lived = String::from(\"hi\");\n        result = shortest(long_lived.as_str(), short_lived.as_str());\n    }\n    result\n}\n",[22,1039,1040,1092,1121,1125,1130,1152,1174,1182,1188,1212,1240,1246,1252],{"__ignoreMap":346},[350,1041,1042,1044,1047,1049,1051,1054,1056,1058,1060,1062,1064,1067,1069,1071,1073,1075,1077,1080,1082,1084,1086,1088,1090],{"class":352,"line":353},[350,1043,357],{"class":356},[350,1045,1046],{"class":360}," shortest",[350,1048,597],{"class":364},[350,1050,600],{"class":360},[350,1052,1053],{"class":364},">(x",[350,1055,611],{"class":356},[350,1057,371],{"class":356},[350,1059,616],{"class":364},[350,1061,600],{"class":360},[350,1063,621],{"class":360},[350,1065,1066],{"class":364},", y",[350,1068,611],{"class":356},[350,1070,371],{"class":356},[350,1072,616],{"class":364},[350,1074,600],{"class":360},[350,1076,621],{"class":360},[350,1078,1079],{"class":364},") ",[350,1081,368],{"class":356},[350,1083,371],{"class":356},[350,1085,616],{"class":364},[350,1087,600],{"class":360},[350,1089,621],{"class":360},[350,1091,377],{"class":364},[350,1093,1094,1097,1100,1102,1105,1108,1110,1112,1115,1118],{"class":352,"line":380},[350,1095,1096],{"class":356},"    if",[350,1098,1099],{"class":364}," x",[350,1101,903],{"class":356},[350,1103,1104],{"class":360},"len",[350,1106,1107],{"class":364},"() \u003C y",[350,1109,903],{"class":356},[350,1111,1104],{"class":360},[350,1113,1114],{"class":364},"() { x } ",[350,1116,1117],{"class":356},"else",[350,1119,1120],{"class":364}," { y }\n",[350,1122,1123],{"class":352,"line":411},[350,1124,429],{"class":364},[350,1126,1127],{"class":352,"line":426},[350,1128,1129],{"emptyLinePlaceholder":39},"\n",[350,1131,1132,1134,1137,1139,1141,1143,1145,1148,1150],{"class":352,"line":897},[350,1133,357],{"class":356},[350,1135,1136],{"class":360}," caller",[350,1138,365],{"class":364},[350,1140,368],{"class":356},[350,1142,371],{"class":356},[350,1144,616],{"class":364},[350,1146,1147],{"class":360},"static",[350,1149,621],{"class":360},[350,1151,377],{"class":364},[350,1153,1154,1156,1159,1161,1163,1165,1167,1169,1172],{"class":352,"line":916},[350,1155,383],{"class":356},[350,1157,1158],{"class":364}," long_lived ",[350,1160,389],{"class":356},[350,1162,392],{"class":360},[350,1164,395],{"class":356},[350,1166,398],{"class":360},[350,1168,401],{"class":364},[350,1170,1171],{"class":404},"\"hello world\"",[350,1173,408],{"class":364},[350,1175,1177,1179],{"class":352,"line":1176},7,[350,1178,383],{"class":356},[350,1180,1181],{"class":364}," result;\n",[350,1183,1185],{"class":352,"line":1184},8,[350,1186,1187],{"class":364},"    {\n",[350,1189,1191,1194,1197,1199,1201,1203,1205,1207,1210],{"class":352,"line":1190},9,[350,1192,1193],{"class":356},"        let",[350,1195,1196],{"class":364}," short_lived ",[350,1198,389],{"class":356},[350,1200,392],{"class":360},[350,1202,395],{"class":356},[350,1204,398],{"class":360},[350,1206,401],{"class":364},[350,1208,1209],{"class":404},"\"hi\"",[350,1211,408],{"class":364},[350,1213,1215,1218,1220,1222,1225,1227,1230,1233,1235,1237],{"class":352,"line":1214},10,[350,1216,1217],{"class":364},"        result ",[350,1219,389],{"class":356},[350,1221,1046],{"class":360},[350,1223,1224],{"class":364},"(long_lived",[350,1226,903],{"class":356},[350,1228,1229],{"class":360},"as_str",[350,1231,1232],{"class":364},"(), short_lived",[350,1234,903],{"class":356},[350,1236,1229],{"class":360},[350,1238,1239],{"class":364},"());\n",[350,1241,1243],{"class":352,"line":1242},11,[350,1244,1245],{"class":364},"    }\n",[350,1247,1249],{"class":352,"line":1248},12,[350,1250,1251],{"class":364},"    result\n",[350,1253,1255],{"class":352,"line":1254},13,[350,1256,429],{"class":364},[27,1258,1260,1266,1282,1291],{"className":1259},[30],[32,1261,1263,1265],{"className":1262},[35],[37,1264],{"disabled":39,"type":40}," Nothing — this compiles and runs fine",[32,1267,1269,96,1271,1274,1275,1278,1279,1281],{"className":1268},[35],[37,1270],{"disabled":39,"type":40},[22,1272,1273],{},"result"," may borrow ",[22,1276,1277],{},"short_lived",", which is dropped at the end of the inner block, so using ",[22,1280,1273],{}," afterward is a dangling-reference error",[32,1283,1285,96,1287,1290],{"className":1284},[35],[37,1286],{"disabled":39,"type":40},[22,1288,1289],{},"shortest"," needs two separate lifetime parameters, one per argument",[32,1292,1294,96,1296,1298,1299],{"className":1293},[35],[37,1295],{"disabled":39,"type":40},[22,1297,440],{}," cannot be passed to a function expecting ",[22,1300,147],{},[77,1302,1303,1305,1315],{},[80,1304,82],{},[84,1306,1307,309,1309,1274,1311,1278,1313,1281],{},[87,1308,89],{},[22,1310,1273],{},[22,1312,1277],{},[22,1314,1273],{},[84,1316,1317,157,1319,1321,1322,1325,1326,1328,1329,1331,1332,1334,1335,1337,1338,1340,1341,1343,1344,1347,1348,1350,1351,1353,1354,1356,1357,1360,1361,1363],{},[87,1318,95],{},[22,1320,1289],{}," ties both inputs to the ",[1000,1323,1324],{},"same"," lifetime ",[22,1327,99],{},", the compiler must conservatively assume the returned reference could point into either argument. Since ",[22,1330,1277],{}," doesn't outlive the inner block, ",[22,1333,99],{}," is constrained to that shorter scope, and using ",[22,1336,1273],{}," after the block ends is rejected as \"",[22,1339,1277],{}," does not live long enough.\" ",[87,1342,500],{}," the compiler can't know at compile time which branch of the ",[22,1345,1346],{},"if"," will run, so it must assume the worst case. The fix is to shrink the scope of ",[22,1349,1273],{},"'s use to inside the block, or to have ",[22,1352,1289],{}," return an owned ",[22,1355,470],{},". C would actually make it worse — separate lifetimes would still require a return type tied to one of them, and the compiler still can't know statically which. D is false — ",[22,1358,1359],{},"&String"," coerces to ",[22,1362,147],{}," via deref coercion.",[14,1365,1366,1374,1486,1545],{"language":333},[17,1367,1369,1370,1373],{"id":1368},"q11-why-does-this-match-based-function-fail-to-compile","Q11. Why does this ",[22,1371,1372],{},"match","-based function fail to compile?",[339,1375,1376],{"language":333},[342,1377,1379],{"className":344,"code":1378,"language":333,"meta":346,"style":346},"fn pick\u003C'a>(flag: bool, a: &'a str) -> &'a str {\n    if flag {\n        a\n    } else {\n        let local = String::from(\"fallback\");\n        &local\n    }\n}\n",[22,1380,1381,1427,1434,1439,1448,1470,1478,1482],{"__ignoreMap":346},[350,1382,1383,1385,1388,1390,1392,1395,1397,1400,1403,1405,1407,1409,1411,1413,1415,1417,1419,1421,1423,1425],{"class":352,"line":353},[350,1384,357],{"class":356},[350,1386,1387],{"class":360}," pick",[350,1389,597],{"class":364},[350,1391,600],{"class":360},[350,1393,1394],{"class":364},">(flag",[350,1396,611],{"class":356},[350,1398,1399],{"class":360}," bool",[350,1401,1402],{"class":364},", a",[350,1404,611],{"class":356},[350,1406,371],{"class":356},[350,1408,616],{"class":364},[350,1410,600],{"class":360},[350,1412,621],{"class":360},[350,1414,1079],{"class":364},[350,1416,368],{"class":356},[350,1418,371],{"class":356},[350,1420,616],{"class":364},[350,1422,600],{"class":360},[350,1424,621],{"class":360},[350,1426,377],{"class":364},[350,1428,1429,1431],{"class":352,"line":380},[350,1430,1096],{"class":356},[350,1432,1433],{"class":364}," flag {\n",[350,1435,1436],{"class":352,"line":411},[350,1437,1438],{"class":364},"        a\n",[350,1440,1441,1444,1446],{"class":352,"line":426},[350,1442,1443],{"class":364},"    } ",[350,1445,1117],{"class":356},[350,1447,377],{"class":364},[350,1449,1450,1452,1455,1457,1459,1461,1463,1465,1468],{"class":352,"line":897},[350,1451,1193],{"class":356},[350,1453,1454],{"class":364}," local ",[350,1456,389],{"class":356},[350,1458,392],{"class":360},[350,1460,395],{"class":356},[350,1462,398],{"class":360},[350,1464,401],{"class":364},[350,1466,1467],{"class":404},"\"fallback\"",[350,1469,408],{"class":364},[350,1471,1472,1475],{"class":352,"line":916},[350,1473,1474],{"class":356},"        &",[350,1476,1477],{"class":364},"local\n",[350,1479,1480],{"class":352,"line":1176},[350,1481,1245],{"class":364},[350,1483,1484],{"class":352,"line":1184},[350,1485,429],{"class":364},[27,1487,1489,1500,1518,1534],{"className":1488},[30],[32,1490,1492,96,1494,1496,1497,1499],{"className":1491},[35],[37,1493],{"disabled":39,"type":40},[22,1495,1346],{},"\u002F",[22,1498,1117],{}," branches must return the same literal value",[32,1501,1503,1505,1506,1508,1509,1512,1513,1515,1516],{"className":1502},[35],[37,1504],{"disabled":39,"type":40}," The ",[22,1507,1117],{}," branch returns a reference to ",[22,1510,1511],{},"local",", which is dropped when the branch scope ends — it cannot satisfy the ",[22,1514,99],{}," bound tied to ",[22,1517,600],{},[32,1519,1521,96,1523,1526,1527,1530,1531],{"className":1520},[35],[37,1522],{"disabled":39,"type":40},[22,1524,1525],{},"flag"," must be ",[22,1528,1529],{},"&bool",", not ",[22,1532,1533],{},"bool",[32,1535,1537,96,1539,1541,1542],{"className":1536},[35],[37,1538],{"disabled":39,"type":40},[22,1540,470],{}," cannot be shadowed with ",[22,1543,1544],{},"let",[77,1546,1547,1549,1562],{},[80,1548,82],{},[84,1550,1551,1553,1554,1508,1556,1512,1558,1515,1560],{},[87,1552,89],{}," B — The ",[22,1555,1117],{},[22,1557,1511],{},[22,1559,99],{},[22,1561,600],{},[84,1563,1564,1566,1567,1569,1570,1572,1573,1576,1577,1579,1580,1582,1583,1585,1586,1589,1590,1592,1593,1595],{},[87,1565,95],{}," The function signature promises a return value valid for ",[22,1568,99],{}," (the lifetime of ",[22,1571,600],{},"), but ",[22,1574,1575],{},"&local"," is only valid for the tiny scope of the ",[22,1578,1117],{}," block. The compiler flags \"",[22,1581,1511],{}," does not live long enough\" because no lifetime annotation can make a truly local value outlive its own creation. The correct fix is to return an owned ",[22,1584,470],{}," from both branches (changing the signature to ",[22,1587,1588],{},"-> String",", cloning ",[22,1591,600],{}," in the ",[22,1594,1346],{}," branch) rather than trying to force a shared borrow. A, C, and D describe non-existent restrictions.",[14,1597,1598,1613,1649],{},[17,1599,1601,1602,1605,1606,1609,1610,1612],{"id":1600},"q12-which-scenario-genuinely-requires-a-struct-with-two-independent-lifetime-parameters-eg-struct-paira-b-instead-of-one-shared-a","Q12. Which scenario genuinely requires a struct with ",[87,1603,1604],{},"two independent"," lifetime parameters, e.g. ",[22,1607,1608],{},"struct Pair\u003C'a, 'b>",", instead of one shared ",[22,1611,99],{},"?",[27,1614,1616,1622,1628,1640],{"className":1615},[30],[32,1617,1619,1621],{"className":1618},[35],[37,1620],{"disabled":39,"type":40}," Never — using a single shared lifetime is always equivalent and preferred",[32,1623,1625,1627],{"className":1624},[35],[37,1626],{"disabled":39,"type":40}," When the two borrowed fields come from sources with different, unrelated lifetimes, and a method needs to return a reference tied to only one of them",[32,1629,1631,1633,1634,1636,1637],{"className":1630},[35],[37,1632],{"disabled":39,"type":40}," When one field is ",[22,1635,147],{}," and the other is ",[22,1638,1639],{},"&[u8]",[32,1641,1643,1645,1646],{"className":1642},[35],[37,1644],{"disabled":39,"type":40}," When the struct also derives ",[22,1647,1648],{},"Clone",[77,1650,1651,1653,1658],{},[80,1652,82],{},[84,1654,1655,1657],{},[87,1656,89],{}," B — When the two borrowed fields come from sources with different, unrelated lifetimes, and a method needs to return a reference tied to only one of them",[84,1659,1660,1662,1663,1665,1666,1668,1669,1671],{},[87,1661,95],{}," Collapsing both fields to a single ",[22,1664,99],{}," forces the compiler to use the shorter of the two lifetimes everywhere, which needlessly restricts callers when the fields are genuinely independent (e.g., one long-lived config string and one short-lived per-request buffer). Separate parameters let each field's borrow be tracked precisely. A is the tempting simplification that works until a caller hits an over-restrictive borrow error. C is false — the underlying type (",[22,1667,147],{}," vs ",[22,1670,1639],{},") has nothing to do with how many lifetime parameters are needed. D is unrelated to lifetimes at all.",[14,1673,1674,1684,1729],{},[17,1675,1677,1678,1681,1682,1612],{"id":1676},"q13-what-does-the-bound-fn-processt-debug-aitem-t-communicate-about-t","Q13. What does the bound ",[22,1679,1680],{},"fn process\u003CT: Debug + 'a>(item: T)"," communicate about ",[22,1683,719],{},[27,1685,1687,1695,1706,1718],{"className":1686},[30],[32,1688,1690,96,1692,1694],{"className":1689},[35],[37,1691],{"disabled":39,"type":40},[22,1693,719],{}," must be a reference type",[32,1696,1698,1700,1701,1703,1704],{"className":1697},[35],[37,1699],{"disabled":39,"type":40}," Any references contained within ",[22,1702,719],{}," must live at least as long as ",[22,1705,99],{},[32,1707,1709,96,1711,1713,1714,1717],{"className":1708},[35],[37,1710],{"disabled":39,"type":40},[22,1712,719],{}," must implement the ",[22,1715,1716],{},"Lifetime"," trait",[32,1719,1721,96,1723,1725,1726,1728],{"className":1720},[35],[37,1722],{"disabled":39,"type":40},[22,1724,99],{}," is ignored because ",[22,1727,719],{}," is passed by value",[77,1730,1731,1733,1742],{},[80,1732,82],{},[84,1734,1735,1737,1738,1703,1740],{},[87,1736,89],{}," B — Any references contained within ",[22,1739,719],{},[22,1741,99],{},[84,1743,1744,1746,1747,1750,1751,1753,1754,1756,1757,1760,1761,1764,1765,1767],{},[87,1745,95],{}," A lifetime bound on a generic type parameter (",[22,1748,1749],{},"T: 'a",") constrains any borrows nested inside ",[22,1752,719],{}," — whether ",[22,1755,719],{}," itself is a reference or an owned type that happens to hold one (like ",[22,1758,1759],{},"struct Wrapper\u003C'a>(&'a i32)","). It does ",[87,1762,1763],{},"not"," require ",[22,1766,719],{}," itself to be a reference type, so A is wrong. C invents a nonexistent trait — lifetimes are not traits. D is wrong — even owned generic types can embed references, so the bound still matters regardless of pass-by-value.",[14,1769,1770,1778,1832],{},[17,1771,1773,1774,1777],{"id":1772},"q14-what-is-the-lifetime-of-the-string-literal-in-let-s-static-str-hello-and-why","Q14. What is the lifetime of the string literal in ",[22,1775,1776],{},"let s: &'static str = \"hello\";",", and why?",[27,1779,1781,1796,1804,1816],{"className":1780},[30],[32,1782,1784,1786,1787,1789,1790,1792,1793,1795],{"className":1783},[35],[37,1785],{"disabled":39,"type":40}," It's ",[22,1788,64],{}," because all ",[22,1791,147],{}," variables default to ",[22,1794,64],{}," unless annotated otherwise",[32,1797,1799,1786,1801,1803],{"className":1798},[35],[37,1800],{"disabled":39,"type":40},[22,1802,64],{}," because the literal's bytes are embedded directly in the compiled binary's read-only memory, which exists for the whole program run",[32,1805,1807,1809,1810,1812,1813,1815],{"className":1806},[35],[37,1808],{"disabled":39,"type":40}," It's tied to the scope of ",[22,1811,160],{}," only, and ",[22,1814,64],{}," here is just an alias with no special meaning",[32,1817,1819,1786,1821,1823,1824,1827,1828,1831],{"className":1818},[35],[37,1820],{"disabled":39,"type":40},[22,1822,64],{}," only in ",[22,1825,1826],{},"release"," builds; in ",[22,1829,1830],{},"debug"," builds it's dropped at end of scope",[77,1833,1834,1836,1843],{},[80,1835,82],{},[84,1837,1838,1840,1841,1803],{},[87,1839,89],{}," B — It's ",[22,1842,64],{},[84,1844,1845,1847,1848,1850,1851,1853,1854,1856,1857,96,1859,1861,1862,1864],{},[87,1846,95],{}," String literals are stored in the binary itself, not on the heap or stack, so a ",[22,1849,147],{}," pointing at one is trivially valid for the program's entire lifetime — this is why literals are the textbook example of ",[22,1852,64],{}," data. A is false — general ",[22,1855,147],{}," variables are ",[1000,1858,1763],{},[22,1860,64],{}," by default; only specific sources like literals are. C understates what ",[22,1863,64],{}," means; it's a real, checked guarantee, not cosmetic. D is fabricated — build profile has no bearing on this.",[14,1866,1867,1875,1912],{},[17,1868,1870,1871,1874],{"id":1869},"q15-a-public-api-function-currently-returns-a-str-borrowed-from-an-input-forcing-every-caller-to-keep-the-input-alive-as-long-as-the-result-whats-the-idiomatic-best-practice-when-the-borrow-relationship-isnt-essential-to-the-apis-purpose","Q15. A public API function currently returns ",[22,1872,1873],{},"&'a str"," borrowed from an input, forcing every caller to keep the input alive as long as the result. What's the idiomatic best practice when the borrow relationship isn't essential to the API's purpose?",[27,1876,1878,1884,1893,1902],{"className":1877},[30],[32,1879,1881,1883],{"className":1880},[35],[37,1882],{"disabled":39,"type":40}," Always keep borrowing return types — allocating is un-idiomatic in Rust",[32,1885,1887,1889,1890,1892],{"className":1886},[35],[37,1888],{"disabled":39,"type":40}," Return an owned ",[22,1891,470],{}," instead, accepting the extra allocation, so callers aren't forced into awkward lifetime juggling",[32,1894,1896,1898,1899,1901],{"className":1895},[35],[37,1897],{"disabled":39,"type":40}," Add ",[22,1900,64],{}," to force the caller to leak the input",[32,1903,1905,1907,1908,1911],{"className":1904},[35],[37,1906],{"disabled":39,"type":40}," Wrap the return type in ",[22,1909,1910],{},"Rc\u003Cstr>"," regardless of whether sharing is needed",[77,1913,1914,1916,1923],{},[80,1915,82],{},[84,1917,1918,1920,1921,1892],{},[87,1919,89],{}," B — Return an owned ",[22,1922,470],{},[84,1924,1925,96,1927,1929,1930,1496,1932,1934,1935,1937],{},[87,1926,95],{},[87,1928,797],{}," Rust does favor borrowing when it's cheap and natural, but API ergonomics matter — if borrowing propagates a lifetime parameter through public structs and function signatures just to save one allocation, it's usually not worth the complexity for callers. A overstates the \"avoid allocation at all costs\" mentality; even the standard library returns owned ",[22,1931,470],{},[22,1933,748],{}," constantly. C is nonsensical — ",[22,1936,64],{}," cannot be conjured onto arbitrary borrowed data without genuinely leaking or owning it. D adds unnecessary reference-counting overhead and API surface when sharing isn't actually required.",[14,1939,1940,1944,1971],{},[17,1941,1943],{"id":1942},"q16-when-should-you-reach-for-an-explicit-lifetime-annotation-instead-of-relying-on-elision","Q16. When should you reach for an explicit lifetime annotation instead of relying on elision?",[27,1945,1947,1953,1959,1965],{"className":1946},[30],[32,1948,1950,1952],{"className":1949},[35],[37,1951],{"disabled":39,"type":40}," Whenever a function takes more than zero parameters",[32,1954,1956,1958],{"className":1955},[35],[37,1957],{"disabled":39,"type":40}," Only when the elision rules cannot uniquely determine the output lifetime, or when a struct\u002Fimpl block needs to tie multiple borrows together explicitly",[32,1960,1962,1964],{"className":1961},[35],[37,1963],{"disabled":39,"type":40}," Every function that returns any value at all",[32,1966,1968,1970],{"className":1967},[35],[37,1969],{"disabled":39,"type":40}," Never — explicit lifetimes are a deprecated Rust 2015 feature",[77,1972,1973,1975,1980],{},[80,1974,82],{},[84,1976,1977,1979],{},[87,1978,89],{}," B — Only when the elision rules cannot uniquely determine the output lifetime, or when a struct\u002Fimpl block needs to tie multiple borrows together explicitly",[84,1981,1982,96,1984,1986],{},[87,1983,95],{},[87,1985,797],{}," the elision rules exist precisely so idiomatic Rust rarely needs visible lifetime syntax; reaching for it should be a deliberate signal that the compiler genuinely needs disambiguation (two-plus input references feeding one output, or a struct storing borrowed fields). A and C wildly over-apply the rule and would make trivial functions unnecessarily verbose. D is false — explicit lifetimes are a core, actively used part of the language, not deprecated.",[14,1988,1989,1997,2036],{},[17,1990,1992,1993,1996],{"id":1991},"q17-why-is-casually-adding-dyn-trait-static-or-its-implicit-default-to-every-trait-object-in-a-long-lived-cache-considered-a-code-smell-when-the-objects-actually-hold-short-lived-borrowed-data","Q17. Why is casually adding ",[22,1994,1995],{},"dyn Trait + 'static"," (or its implicit default) to every trait object in a long-lived cache considered a code smell when the objects actually hold short-lived borrowed data?",[27,1998,2000,2009,2015,2024],{"className":1999},[30],[32,2001,2003,2005,2006,2008],{"className":2002},[35],[37,2004],{"disabled":39,"type":40}," It isn't a smell — ",[22,2007,64],{}," should always be the default for trait objects",[32,2010,2012,2014],{"className":2011},[35],[37,2013],{"disabled":39,"type":40}," It forces every value stored in the cache to be owned (or leaked), which can silently balloon memory or force unnecessary cloning just to satisfy the bound",[32,2016,2018,96,2020,2023],{"className":2017},[35],[37,2019],{"disabled":39,"type":40},[22,2021,2022],{},"dyn Trait"," objects cannot have lifetime bounds at all",[32,2025,2027,96,2029,2031,2032,2035],{"className":2026},[35],[37,2028],{"disabled":39,"type":40},[22,2030,64],{}," on trait objects only affects ",[22,2033,2034],{},"Debug"," formatting",[77,2037,2038,2040,2045],{},[80,2039,82],{},[84,2041,2042,2044],{},[87,2043,89],{}," B — It forces every value stored in the cache to be owned (or leaked), which can silently balloon memory or force unnecessary cloning just to satisfy the bound",[84,2046,2047,96,2049,2051,2052,2055,2056,2059,2060,2063,2064,2066,2067,2070],{},[87,2048,95],{},[22,2050,804],{}," defaults to ",[22,2053,2054],{},"Box\u003Cdyn Trait + 'static>"," unless you write a shorter bound like ",[22,2057,2058],{},"Box\u003Cdyn Trait + 'a>",". Reaching for the default without thinking means anything with a borrowed lifetime can no longer be boxed as that trait object without first cloning into an owned form — a common surprise when refactoring borrowing code into a trait-object-based design. ",[87,2061,2062],{},"Performance:"," unnecessary clones to satisfy an overly broad ",[22,2065,64],{}," bound are a frequent, easy-to-miss cost. A is the naive default that causes exactly this problem. C is false — ",[22,2068,2069],{},"dyn Trait + 'a"," is valid syntax. D is fabricated.",[14,2072,2073,2086,2124],{},[17,2074,2076,2077,2079,2080,2082,2083,2085],{"id":2075},"q18-a-method-takes-self-and-an-unrelated-str-parameter-and-needs-to-return-a-reference-borrowed-from-the-parameter-not-from-self-why-cant-you-rely-on-elision-here","Q18. A method takes ",[22,2078,216],{}," and an unrelated ",[22,2081,147],{}," parameter, and needs to return a reference borrowed from the parameter, not from ",[22,2084,326],{},". Why can't you rely on elision here?",[27,2087,2089,2101,2107,2115],{"className":2088},[30],[32,2090,2092,2094,2095,2097,2098,2100],{"className":2091},[35],[37,2093],{"disabled":39,"type":40}," Elision rule 3 always binds the output to ",[22,2096,216],{},"'s lifetime when ",[22,2099,326],{}," is present, regardless of what you actually want to return — so you must write explicit lifetimes to override it",[32,2102,2104,2106],{"className":2103},[35],[37,2105],{"disabled":39,"type":40}," Methods never support lifetime elision",[32,2108,2110,96,2112,2114],{"className":2109},[35],[37,2111],{"disabled":39,"type":40},[22,2113,147],{}," parameters are exempt from elision",[32,2116,2118,2120,2121,2123],{"className":2117},[35],[37,2119],{"disabled":39,"type":40}," This works fine with elision as long as the method has a ",[22,2122,322],{}," receiver instead",[77,2125,2126,2128,2137],{},[80,2127,82],{},[84,2129,2130,2132,2133,2097,2135,2100],{},[87,2131,89],{}," A — Elision rule 3 always binds the output to ",[22,2134,216],{},[22,2136,326],{},[84,2138,2139,2141,2142,1496,2144,1496,2146,2148,2149,2151,2152,2154,2155,2158,2159,2161,2162,2164,2165,2167,2168,2170,2171,903],{},[87,2140,95],{}," Rule 3 is a fixed heuristic, not a smart inference — it fires whenever a method has a ",[22,2143,326],{},[22,2145,216],{},[22,2147,322],{}," receiver plus other reference parameters, and unconditionally assigns ",[22,2150,326],{},"'s lifetime to the elided output. If you actually intend to return something borrowed from the ",[1000,2153,280],{}," parameter, you must write ",[22,2156,2157],{},"fn f\u003C'a, 'b>(&'a self, s: &'b str) -> &'b str"," explicitly, or the code either fails to compile (if ",[22,2160,326],{},"'s and the intended lifetime genuinely diverge) or silently over-constrains callers to keep ",[22,2163,326],{}," alive longer than necessary. B, C, and D are fabricated — elision works on methods too, applies to any ",[22,2166,151],{},", and ",[22,2169,322],{}," follows the identical rule 3 as ",[22,2172,216],{},[14,2174,2175,2185,2222],{},[17,2176,2178,2179,2181,2182,2184],{"id":2177},"q19-in-a-builder-pattern-struct-why-is-it-usually-better-to-store-owned-string-fields-rather-than-a-str-fields-tied-to-the-builders-lifetime","Q19. In a builder-pattern struct, why is it usually better to store owned ",[22,2180,470],{}," fields rather than ",[22,2183,1873],{}," fields tied to the builder's lifetime?",[27,2186,2188,2196,2202,2212],{"className":2187},[30],[32,2189,2191,96,2193,2195],{"className":2190},[35],[37,2192],{"disabled":39,"type":40},[22,2194,1873],{}," fields are always a compile error inside structs",[32,2197,2199,2201],{"className":2198},[35],[37,2200],{"disabled":39,"type":40}," Owned fields let the built value (and the builder itself) be returned from functions, stored in collections, or moved across threads without dragging a lifetime parameter through every type that uses the builder",[32,2203,2205,96,2207,2209,2210],{"className":2204},[35],[37,2206],{"disabled":39,"type":40},[22,2208,470],{}," is faster to compare than ",[22,2211,147],{},[32,2213,2215,2217,2218,2221],{"className":2214},[35],[37,2216],{"disabled":39,"type":40}," Borrowed fields make ",[22,2219,2220],{},"derive(Clone)"," impossible",[77,2223,2224,2226,2231],{},[80,2225,82],{},[84,2227,2228,2230],{},[87,2229,89],{}," B — Owned fields let the built value (and the builder itself) be returned from functions, stored in collections, or moved across threads without dragging a lifetime parameter through every type that uses the builder",[84,2232,2233,96,2235,2237,2238,2241,2242,2245,2246,2248,2249,2251],{},[87,2234,95],{},[87,2236,797],{}," this is a widely recommended Rust API-design tradeoff — a ",[22,2239,2240],{},"Config\u003C'a>"," builder that borrows its strings infects every function signature and struct that holds a ",[22,2243,2244],{},"Config"," with the same ",[22,2247,99],{},", which is rarely worth the saved allocations for something constructed once and used broadly. A is false — borrowed fields compile fine, they're just viral. C is an unrelated, generally false claim (comparison cost is similar). D is false — ",[22,2250,1648],{}," works on borrowed fields too, it just clones the reference (a pointer copy), not the data.",[14,2253,2254,2262,2308],{},[17,2255,2257,2258,2261],{"id":2256},"q20-code-review-flags-this-function-fn-cache_keyaa-self-id-u32-a-str-used-to-look-up-and-return-a-formatted-key-the-reviewer-says-this-design-is-a-lifetime-trap-waiting-to-bite-the-next-person-who-calls-it-in-a-loop-whats-the-most-likely-underlying-issue","Q20. Code review flags this function: ",[22,2259,2260],{},"fn cache_key\u003C'a>(&'a self, id: u32) -> &'a str",", used to look up and return a formatted key. The reviewer says \"this design is a lifetime trap waiting to bite the next person who calls it in a loop.\" What's the most likely underlying issue?",[27,2263,2265,2283,2292,2302],{"className":2264},[30],[32,2266,2268,2270,2271,2273,2274,2276,2277,2279,2280,2282],{"className":2267},[35],[37,2269],{"disabled":39,"type":40}," Returning ",[22,2272,1873],{}," tied to ",[22,2275,216],{}," means the borrow of ",[22,2278,326],{}," must stay alive as long as the returned key is used, which can prevent later mutable access to ",[22,2281,326],{}," (e.g., inserting into the same cache) within that same scope",[32,2284,2286,96,2288,2291],{"className":2285},[35],[37,2287],{"disabled":39,"type":40},[22,2289,2290],{},"u32"," parameters cannot be used inside lifetime-annotated functions",[32,2293,2295,2297,2298,2301],{"className":2294},[35],[37,2296],{"disabled":39,"type":40}," The function should return ",[22,2299,2300],{},"Result\u003C&str, Error>"," instead",[32,2303,2305,2307],{"className":2304},[35],[37,2306],{"disabled":39,"type":40}," There is no real issue — the reviewer is being overly cautious",[77,2309,2310,2312,2325],{},[80,2311,82],{},[84,2313,2314,2316,2317,2273,2319,2276,2321,2279,2323,2282],{},[87,2315,89],{}," A — Returning ",[22,2318,1873],{},[22,2320,216],{},[22,2322,326],{},[22,2324,326],{},[84,2326,2327,2329,2330,2333,2334,2336,2337,2340,2341,2343,2344,2346,2347,2349],{},[87,2328,95],{}," This is the classic \"read borrow blocks a later write borrow\" trap: if ",[22,2331,2332],{},"cache_key"," returns a reference borrowed from ",[22,2335,326],{},", and the caller then tries ",[22,2338,2339],{},"self.insert(...)"," (which needs ",[22,2342,322],{},") while still holding that returned key, the borrow checker rejects it — even though the two operations don't actually alias the same memory at runtime. ",[87,2345,797],{}," the fix is usually to return an owned ",[22,2348,470],{}," (or clone before mutating), trading a small allocation for an API that doesn't force awkward borrow-scope gymnastics on every caller. B is a fabricated restriction — primitive parameters don't interact with lifetime annotations. C addresses error handling, not the lifetime coupling being described. D dismisses a real, common production footgun.",[2351,2352,2353],"style",{},"html pre.shiki code .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}html pre.shiki code .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}html pre.shiki code .ssxIu, html code.shiki .ssxIu{--shiki-default:#24292E;--shiki-github-dark:#E1E4E8}html pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html.github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html pre.shiki code .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}",{"title":346,"searchDepth":380,"depth":380,"links":2355},[2356,2358,2360,2362,2364,2365,2367,2368,2370,2371,2372,2374,2376,2378,2380,2382,2383,2385,2387,2389],{"id":19,"depth":411,"text":2357},"Q1. What does the signature fn longest\u003C'a>(x: &'a str, y: &'a str) -> &'a str actually promise to the caller?",{"id":118,"depth":411,"text":2359},"Q2. Given fn first_word(s: &str) -> &str, why does this compile without any explicit lifetime annotations?",{"id":193,"depth":411,"text":2361},"Q3. Why does fn combine(x: &str, y: &str) -> &str fail to compile as written?",{"id":261,"depth":411,"text":2363},"Q4. In impl\u003C'a> Parser\u003C'a> { fn peek(&self, other: &str) -> &str { ... } }, which lifetime does the returned &str borrow from, per elision rule 3?",{"id":336,"depth":411,"text":337},{"id":513,"depth":411,"text":2366},"Q6. What does the 'static lifetime bound on a reference, as in x: &'static str, guarantee?",{"id":578,"depth":411,"text":579},{"id":686,"depth":411,"text":2369},"Q8. A junior developer claims: \"If I add a T: 'static bound to a generic function, every value passed in must be created before main() starts, like a string literal.\" Is this accurate?",{"id":810,"depth":411,"text":811},{"id":1031,"depth":411,"text":1032},{"id":1368,"depth":411,"text":2373},"Q11. Why does this match-based function fail to compile?",{"id":1600,"depth":411,"text":2375},"Q12. Which scenario genuinely requires a struct with two independent lifetime parameters, e.g. struct Pair\u003C'a, 'b>, instead of one shared 'a?",{"id":1676,"depth":411,"text":2377},"Q13. What does the bound fn process\u003CT: Debug + 'a>(item: T) communicate about T?",{"id":1772,"depth":411,"text":2379},"Q14. What is the lifetime of the string literal in let s: &'static str = \"hello\";, and why?",{"id":1869,"depth":411,"text":2381},"Q15. A public API function currently returns &'a str borrowed from an input, forcing every caller to keep the input alive as long as the result. What's the idiomatic best practice when the borrow relationship isn't essential to the API's purpose?",{"id":1942,"depth":411,"text":1943},{"id":1991,"depth":411,"text":2384},"Q17. Why is casually adding dyn Trait + 'static (or its implicit default) to every trait object in a long-lived cache considered a code smell when the objects actually hold short-lived borrowed data?",{"id":2075,"depth":411,"text":2386},"Q18. A method takes &self and an unrelated &str parameter, and needs to return a reference borrowed from the parameter, not from self. Why can't you rely on elision here?",{"id":2177,"depth":411,"text":2388},"Q19. In a builder-pattern struct, why is it usually better to store owned String fields rather than &'a str fields tied to the builder's lifetime?",{"id":2256,"depth":411,"text":2390},"Q20. Code review flags this function: fn cache_key\u003C'a>(&'a self, id: u32) -> &'a str, used to look up and return a formatted key. The reviewer says \"this design is a lifetime trap waiting to bite the next person who calls it in a loop.\" What's the most likely underlying issue?","md",{},"\u002Frust\u002F10-lifetimes",{"title":5,"description":346},"rust\u002F10-lifetimes","DYwCiSkjpVSAW2PyUof6H10m_t2OT5BB6DikxO4FDKg",1787335398377]