[{"data":1,"prerenderedAt":2410},["ShallowReactive",2],{"page-\u002Frust\u002F29-advanced-type-system":3},{"id":4,"title":5,"body":6,"description":16,"extension":2404,"meta":2405,"navigation":778,"path":2406,"seo":2407,"stem":2408,"__hash__":2409},"content\u002Frust\u002F29-advanced-type-system.md","29 — Advanced Type System (Variance, HRTBs, Subtyping)",{"type":7,"value":8,"toc":2367},"minimark",[9,13,17,22,39,61,162,166,169,208,213,361,365,373,499,509,513,519,523,591,608,612,691,695,703,707,822,836,843,857,867,874,898,909,913,916,956,959,975,979,991,1044,1054,1060,1070,1086,1095,1165,1172,1257,1262,1304,1310,1314,1399,1430,1434,1437,1627,1642,1646,1815,1819,1836,1843,1846,1960,1967,1971,1974,1991,2004,2008,2089,2092,2099,2190,2205,2209,2232,2242,2246,2347,2351,2360,2363],[10,11,5],"h1",{"id":12},"_29-advanced-type-system-variance-hrtbs-subtyping",[14,15,16],"p",{},"This chapter covers the parts of the type system that most Rust developers never need to write, but should understand to read errors and design libraries.",[18,19,21],"h2",{"id":20},"subtyping-in-rust","Subtyping in Rust",[14,23,24,25,29,30,33,34,38],{},"Most languages have subtyping via inheritance (Cat : Animal). Rust's subtyping is ",[26,27,28],"strong",{},"only"," through ",[26,31,32],{},"lifetimes",": a longer lifetime is a ",[35,36,37],"em",{},"subtype"," of a shorter one.",[14,40,41,45,46,49,50,52,53,56,57,60],{},[42,43,44],"code",{},"'static"," is a subtype of ",[42,47,48],{},"'a"," for any ",[42,51,48],{},": a ",[42,54,55],{},"&'static str"," can be used where ",[42,58,59],{},"&'a str"," is expected.",[62,63,65],"code-wrapper",{"language":64},"rust",[66,67,71],"pre",{"className":68,"code":69,"language":64,"meta":70,"style":70},"language-rust shiki shiki-themes github-light github-dark","fn takes_str\u003C'a>(s: &'a str) { \u002F* ... *\u002F }\nlet s: &'static str = \"hi\";\ntakes_str(s);    \u002F\u002F OK: 'static \u003C: 'a\n","",[42,72,73,120,150],{"__ignoreMap":70},[74,75,78,82,86,90,93,96,99,102,105,107,110,113,117],"span",{"class":76,"line":77},"line",1,[74,79,81],{"class":80},"svdQ7","fn",[74,83,85],{"class":84},"sIsaT"," takes_str",[74,87,89],{"class":88},"ssxIu","\u003C'",[74,91,92],{"class":84},"a",[74,94,95],{"class":88},">(s",[74,97,98],{"class":80},":",[74,100,101],{"class":80}," &",[74,103,104],{"class":88},"'",[74,106,92],{"class":84},[74,108,109],{"class":84}," str",[74,111,112],{"class":88},") { ",[74,114,116],{"class":115},"sdCPZ","\u002F* ... *\u002F",[74,118,119],{"class":88}," }\n",[74,121,123,126,129,131,133,135,138,140,143,147],{"class":76,"line":122},2,[74,124,125],{"class":80},"let",[74,127,128],{"class":88}," s",[74,130,98],{"class":80},[74,132,101],{"class":80},[74,134,104],{"class":88},[74,136,137],{"class":84},"static",[74,139,109],{"class":84},[74,141,142],{"class":80}," =",[74,144,146],{"class":145},"sJ6F3"," \"hi\"",[74,148,149],{"class":88},";\n",[74,151,153,156,159],{"class":76,"line":152},3,[74,154,155],{"class":84},"takes_str",[74,157,158],{"class":88},"(s);    ",[74,160,161],{"class":115},"\u002F\u002F OK: 'static \u003C: 'a\n",[18,163,165],{"id":164},"variance","Variance",[14,167,168],{},"Variance describes how subtyping of parameters affects subtyping of the constructed type:",[170,171,172,186,196,202],"ul",{},[173,174,175,178,179,182,183],"li",{},[26,176,177],{},"Covariant"," ",[42,180,181],{},"T \u003C: U"," → ",[42,184,185],{},"F\u003CT> \u003C: F\u003CU>",[173,187,188,178,191,182,193],{},[26,189,190],{},"Contravariant",[42,192,181],{},[42,194,195],{},"F\u003CU> \u003C: F\u003CT>",[173,197,198,201],{},[26,199,200],{},"Invariant"," no subtyping relationship",[173,203,204,207],{},[26,205,206],{},"Bivariant"," both directions (rare; only happens with unused params)",[209,210,212],"h3",{"id":211},"examples","Examples",[214,215,216,228],"table",{},[217,218,219],"thead",{},[220,221,222,226],"tr",{},[223,224,225],"th",{},"Type",[223,227,165],{},[229,230,231,248,266,277,289,305,322,339],"tbody",{},[220,232,233,239],{},[234,235,236],"td",{},[42,237,238],{},"&'a T",[234,240,241,242,244,245],{},"covariant in ",[42,243,48],{}," and ",[42,246,247],{},"T",[220,249,250,255],{},[234,251,252],{},[42,253,254],{},"&'a mut T",[234,256,241,257,259,260,263,264],{},[42,258,48],{},", ",[26,261,262],{},"invariant"," in ",[42,265,247],{},[220,267,268,273],{},[234,269,270],{},[42,271,272],{},"*const T",[234,274,241,275],{},[42,276,247],{},[220,278,279,284],{},[234,280,281],{},[42,282,283],{},"*mut T",[234,285,286,287],{},"invariant in ",[42,288,247],{},[220,290,291,296],{},[234,292,293],{},[42,294,295],{},"fn(T) -> U",[234,297,298,299,301,302],{},"contravariant in ",[42,300,247],{},", covariant in ",[42,303,304],{},"U",[220,306,307,318],{},[234,308,309,259,312,259,315],{},[42,310,311],{},"Box\u003CT>",[42,313,314],{},"Arc\u003CT>",[42,316,317],{},"Vec\u003CT>",[234,319,241,320],{},[42,321,247],{},[220,323,324,335],{},[234,325,326,259,329,259,332],{},[42,327,328],{},"Cell\u003CT>",[42,330,331],{},"RefCell\u003CT>",[42,333,334],{},"UnsafeCell\u003CT>",[234,336,286,337],{},[42,338,247],{},[220,340,341,346],{},[234,342,343],{},[42,344,345],{},"&'a mut &'b T",[234,347,241,348,350,351,354,355,244,358,360],{},[42,349,48],{},", invariant in ",[42,352,353],{},"&'b T"," (which is covariant in ",[42,356,357],{},"'b",[42,359,247],{},")",[209,362,364],{"id":363},"why-does-variance-matter","Why does variance matter?",[14,366,367,368,370,371,98],{},"If ",[42,369,254],{}," were covariant in ",[42,372,247],{},[62,374,375],{"language":64},[66,376,378],{"className":68,"code":377,"language":64,"meta":70,"style":70},"let mut s = String::from(\"hi\");\nlet r: &mut &'static str = &mut s;    \u002F\u002F would-be covariance\nlet short = String::from(\"bye\");\n*r = &short;                          \u002F\u002F writes &'short str into a &'static slot\nprintln!(\"{}\", s);                    \u002F\u002F s dangling!\n",[42,379,380,411,441,463,482],{"__ignoreMap":70},[74,381,382,384,387,390,393,396,399,402,405,408],{"class":76,"line":77},[74,383,125],{"class":80},[74,385,386],{"class":80}," mut",[74,388,389],{"class":88}," s ",[74,391,392],{"class":80},"=",[74,394,395],{"class":84}," String",[74,397,398],{"class":80},"::",[74,400,401],{"class":84},"from",[74,403,404],{"class":88},"(",[74,406,407],{"class":145},"\"hi\"",[74,409,410],{"class":88},");\n",[74,412,413,415,418,420,423,425,427,429,431,433,435,438],{"class":76,"line":122},[74,414,125],{"class":80},[74,416,417],{"class":88}," r",[74,419,98],{"class":80},[74,421,422],{"class":80}," &mut",[74,424,101],{"class":80},[74,426,104],{"class":88},[74,428,137],{"class":84},[74,430,109],{"class":84},[74,432,142],{"class":80},[74,434,422],{"class":80},[74,436,437],{"class":88}," s;    ",[74,439,440],{"class":115},"\u002F\u002F would-be covariance\n",[74,442,443,445,448,450,452,454,456,458,461],{"class":76,"line":152},[74,444,125],{"class":80},[74,446,447],{"class":88}," short ",[74,449,392],{"class":80},[74,451,395],{"class":84},[74,453,398],{"class":80},[74,455,401],{"class":84},[74,457,404],{"class":88},[74,459,460],{"class":145},"\"bye\"",[74,462,410],{"class":88},[74,464,466,469,472,474,476,479],{"class":76,"line":465},4,[74,467,468],{"class":80},"*",[74,470,471],{"class":88},"r ",[74,473,392],{"class":80},[74,475,101],{"class":80},[74,477,478],{"class":88},"short;                          ",[74,480,481],{"class":115},"\u002F\u002F writes &'short str into a &'static slot\n",[74,483,485,488,490,493,496],{"class":76,"line":484},5,[74,486,487],{"class":84},"println!",[74,489,404],{"class":88},[74,491,492],{"class":145},"\"{}\"",[74,494,495],{"class":88},", s);                    ",[74,497,498],{"class":115},"\u002F\u002F s dangling!\n",[14,500,501,502,504,505,508],{},"Invariance in ",[42,503,247],{}," for ",[42,506,507],{},"&mut T"," is what prevents this. The compiler rejects the first assignment.",[209,510,512],{"id":511},"practical-implication","Practical Implication",[14,514,515,516,518],{},"When you get a weird lifetime error, invariance is often the cause. The fix is usually to add an explicit lifetime tie or to introduce indirection (",[42,517,311],{}," makes some invariance problems tractable).",[18,520,522],{"id":521},"higher-rank-trait-bounds-hrtbs","Higher-Rank Trait Bounds (HRTBs)",[62,524,525],{"language":64},[66,526,528],{"className":68,"code":527,"language":64,"meta":70,"style":70},"fn foo\u003CF>(f: F) where F: for\u003C'a> Fn(&'a str) { \u002F* ... *\u002F }\n",[42,529,530],{"__ignoreMap":70},[74,531,532,534,537,540,543,546,548,551,554,557,559,561,564,566,568,571,574,576,579,581,583,585,587,589],{"class":76,"line":77},[74,533,81],{"class":80},[74,535,536],{"class":84}," foo",[74,538,539],{"class":88},"\u003C",[74,541,542],{"class":84},"F",[74,544,545],{"class":88},">(f",[74,547,98],{"class":80},[74,549,550],{"class":84}," F",[74,552,553],{"class":88},") ",[74,555,556],{"class":80},"where",[74,558,550],{"class":84},[74,560,98],{"class":80},[74,562,563],{"class":80}," for",[74,565,89],{"class":88},[74,567,92],{"class":84},[74,569,570],{"class":88},"> ",[74,572,573],{"class":84},"Fn",[74,575,404],{"class":88},[74,577,578],{"class":80},"&",[74,580,104],{"class":88},[74,582,92],{"class":84},[74,584,109],{"class":84},[74,586,112],{"class":88},[74,588,116],{"class":115},[74,590,119],{"class":88},[14,592,593,596,597,599,600,603,604,607],{},[42,594,595],{},"for\u003C'a>"," means \"for all possible lifetimes ",[42,598,48],{},"\". The function ",[42,601,602],{},"f"," must accept any borrowed ",[42,605,606],{},"&str",", not just one with a specific lifetime.",[209,609,611],{"id":610},"where-hrtbs-appear","Where HRTBs Appear",[170,613,614,679],{},[173,615,616,617],{},"Closures that take references without explicit lifetimes:\n",[62,618,619],{"language":64},[66,620,622],{"className":68,"code":621,"language":64,"meta":70,"style":70},"let f: impl for\u003C'a> Fn(&'a str) = |s| println!(\"{s}\");\n",[42,623,624],{"__ignoreMap":70},[74,625,626,628,631,633,636,638,640,642,644,646,648,650,652,654,656,658,660,663,666,669,672,674,677],{"class":76,"line":77},[74,627,125],{"class":80},[74,629,630],{"class":88}," f",[74,632,98],{"class":80},[74,634,635],{"class":80}," impl",[74,637,563],{"class":80},[74,639,89],{"class":88},[74,641,92],{"class":84},[74,643,570],{"class":88},[74,645,573],{"class":84},[74,647,404],{"class":88},[74,649,578],{"class":80},[74,651,104],{"class":88},[74,653,92],{"class":84},[74,655,109],{"class":84},[74,657,553],{"class":88},[74,659,392],{"class":80},[74,661,662],{"class":80}," |",[74,664,665],{"class":88},"s",[74,667,668],{"class":80},"|",[74,670,671],{"class":84}," println!",[74,673,404],{"class":88},[74,675,676],{"class":145},"\"{s}\"",[74,678,410],{"class":88},[173,680,681,683,684,683,687,690],{},[42,682,573],{},"\u002F",[42,685,686],{},"FnMut",[42,688,689],{},"FnOnce"," implicitly use HRTB on their arguments.",[209,692,694],{"id":693},"common-pattern","Common Pattern",[66,696,701],{"className":697,"code":699,"language":700},[698],"language-text","::rust\nfn apply_any(f: impl for\u003C'a> Fn(&'a [u8])) {\n    let buf = [0u8; 16];\n    f(&buf);\n}\n","text",[42,702,699],{"__ignoreMap":70},[18,704,706],{"id":705},"associated-types-vs-generics","Associated Types vs Generics",[62,708,709],{"language":64},[66,710,712],{"className":68,"code":711,"language":64,"meta":70,"style":70},"\u002F\u002F Associated type — impl picks:\ntrait Iterator { type Item; fn next(&mut self) -> Option\u003CSelf::Item>; }\n\n\u002F\u002F Generic — caller picks:\ntrait From\u003CT> { fn from(value: T) -> Self; }\n",[42,713,714,719,774,780,785],{"__ignoreMap":70},[74,715,716],{"class":76,"line":77},[74,717,718],{"class":115},"\u002F\u002F Associated type — impl picks:\n",[74,720,721,724,727,730,733,736,739,741,744,746,749,753,755,758,761,763,766,768,771],{"class":76,"line":122},[74,722,723],{"class":80},"trait",[74,725,726],{"class":84}," Iterator",[74,728,729],{"class":88}," { ",[74,731,732],{"class":80},"type",[74,734,735],{"class":84}," Item",[74,737,738],{"class":88},"; ",[74,740,81],{"class":80},[74,742,743],{"class":84}," next",[74,745,404],{"class":88},[74,747,748],{"class":80},"&mut",[74,750,752],{"class":751},"snvgF"," self",[74,754,553],{"class":88},[74,756,757],{"class":80},"->",[74,759,760],{"class":84}," Option",[74,762,539],{"class":88},[74,764,765],{"class":751},"Self",[74,767,398],{"class":80},[74,769,770],{"class":84},"Item",[74,772,773],{"class":88},">; }\n",[74,775,776],{"class":76,"line":152},[74,777,779],{"emptyLinePlaceholder":778},true,"\n",[74,781,782],{"class":76,"line":465},[74,783,784],{"class":115},"\u002F\u002F Generic — caller picks:\n",[74,786,787,789,792,794,796,799,801,804,807,809,812,814,816,819],{"class":76,"line":484},[74,788,723],{"class":80},[74,790,791],{"class":84}," From",[74,793,539],{"class":88},[74,795,247],{"class":84},[74,797,798],{"class":88},"> { ",[74,800,81],{"class":80},[74,802,803],{"class":84}," from",[74,805,806],{"class":88},"(value",[74,808,98],{"class":80},[74,810,811],{"class":84}," T",[74,813,553],{"class":88},[74,815,757],{"class":80},[74,817,818],{"class":751}," Self",[74,820,821],{"class":88},"; }\n",[14,823,824,825,828,829,259,832,835],{},"Use associated types when each impl has ",[35,826,827],{},"one"," natural type. Use generics when multiple impls can coexist (",[42,830,831],{},"From\u003C&str>",[42,833,834],{},"From\u003CString>",").",[18,837,839,842],{"id":838},"impl-trait-internals",[42,840,841],{},"impl Trait"," Internals",[14,844,845,848,849,852,853,856],{},[42,846,847],{},"fn f() -> impl Trait"," returns ",[35,850,851],{},"some"," concrete type that implements ",[42,854,855],{},"Trait",". The type is inferred per return path; if branches return different concrete types, you must box.",[14,858,859,862,863,866],{},[42,860,861],{},"fn f(x: impl Trait)"," is sugar for ",[42,864,865],{},"fn f\u003CT: Trait>(x: T)",". The caller picks the type.",[18,868,870,873],{"id":869},"dyn-trait-type-erasure",[42,871,872],{},"dyn Trait"," Type Erasure",[14,875,876,878,879,882,883,259,886,259,889,259,892,259,895,835],{},[42,877,872],{}," is a ",[26,880,881],{},"dynamic"," type — values are behind a pointer (",[42,884,885],{},"Box\u003Cdyn Trait>",[42,887,888],{},"&dyn Trait",[42,890,891],{},"Arc\u003Cdyn Trait>",[42,893,894],{},"Rc\u003Cdyn Trait>",[42,896,897],{},"Pin\u003CBox\u003Cdyn Trait>>",[14,899,900,901,904,905,908],{},"The pointer is ",[26,902,903],{},"wide"," (fat): ",[42,906,907],{},"(data_ptr, vtable_ptr)",".",[18,910,912],{"id":911},"object-safety-recap","Object Safety (Recap)",[14,914,915],{},"A trait is object-safe iff:",[170,917,918,924,927,938,943],{},[173,919,920,921,923],{},"No ",[42,922,765],{}," in argument positions or return by value.",[173,925,926],{},"No generics in methods.",[173,928,929,930,933,934,937],{},"All methods have ",[42,931,932],{},"where Self: Sized"," or take ",[42,935,936],{},"self"," by reference.",[173,939,940,941,908],{},"No associated constants without a default that depend on ",[42,942,765],{},[173,944,945,683,948,951,952,955],{},[42,946,947],{},"Send",[42,949,950],{},"Sync"," as supertraits are OK; ",[42,953,954],{},"Sized"," as a supertrait disqualifies.",[14,957,958],{},"Workarounds for non-object-safe traits:",[170,960,961,966,969],{},[173,962,963,964,908],{},"Use a wrapper trait that doesn't return ",[42,965,765],{},[173,967,968],{},"Use generic dispatch instead of trait objects.",[173,970,971,972,974],{},"Add ",[42,973,932],{}," to static methods.",[18,976,978],{"id":977},"auto-traits","Auto Traits",[14,980,981,259,983,259,985,259,988,990],{},[42,982,947],{},[42,984,950],{},[42,986,987],{},"Unpin",[42,989,954],{}," are auto traits — the compiler auto-implements them based on constituent types.",[62,992,993],{"language":64},[66,994,996],{"className":68,"code":995,"language":64,"meta":70,"style":70},"struct MyType(Rc\u003Cu8>);   \u002F\u002F not Send, not Sync because Rc isn't\nstruct MyType2(Arc\u003Cu8>); \u002F\u002F Send + Sync\n",[42,997,998,1022],{"__ignoreMap":70},[74,999,1000,1003,1006,1008,1011,1013,1016,1019],{"class":76,"line":77},[74,1001,1002],{"class":80},"struct",[74,1004,1005],{"class":84}," MyType",[74,1007,404],{"class":88},[74,1009,1010],{"class":84},"Rc",[74,1012,539],{"class":88},[74,1014,1015],{"class":84},"u8",[74,1017,1018],{"class":88},">);   ",[74,1020,1021],{"class":115},"\u002F\u002F not Send, not Sync because Rc isn't\n",[74,1023,1024,1026,1029,1031,1034,1036,1038,1041],{"class":76,"line":122},[74,1025,1002],{"class":80},[74,1027,1028],{"class":84}," MyType2",[74,1030,404],{"class":88},[74,1032,1033],{"class":84},"Arc",[74,1035,539],{"class":88},[74,1037,1015],{"class":84},[74,1039,1040],{"class":88},">); ",[74,1042,1043],{"class":115},"\u002F\u002F Send + Sync\n",[14,1045,1046,1047,683,1050,1053],{},"You can opt out or opt in via ",[42,1048,1049],{},"unsafe impl",[42,1051,1052],{},"impl !Send"," (negative impls are unstable).",[18,1055,1057,1059],{"id":1056},"sized-trait",[42,1058,954],{}," Trait",[14,1061,1062,1063,1065,1066,1069],{},"Most types are ",[42,1064,954],{}," (known size at compile time). Exceptions are ",[42,1067,1068],{},"?Sized"," types:",[170,1071,1072],{},[173,1073,1074,259,1077,259,1080,259,1082,1085],{},[42,1075,1076],{},"str",[42,1078,1079],{},"[T]",[42,1081,872],{},[42,1083,1084],{},"*const ()"," (in some contexts)",[14,1087,1088,1089,1091,1092,98],{},"Generic parameters default to ",[42,1090,954],{},"; relax with ",[42,1093,1094],{},"T: ?Sized",[62,1096,1097],{"language":64},[66,1098,1100],{"className":68,"code":1099,"language":64,"meta":70,"style":70},"fn first_byte(s: &str) -> u8 { \u002F* str is !Sized but you can take &str *\u002F }\nfn foo\u003CT: ?Sized>(x: &T) { \u002F* works for unsized T *\u002F }\n",[42,1101,1102,1132],{"__ignoreMap":70},[74,1103,1104,1106,1109,1112,1114,1116,1118,1120,1122,1125,1127,1130],{"class":76,"line":77},[74,1105,81],{"class":80},[74,1107,1108],{"class":84}," first_byte",[74,1110,1111],{"class":88},"(s",[74,1113,98],{"class":80},[74,1115,101],{"class":80},[74,1117,1076],{"class":84},[74,1119,553],{"class":88},[74,1121,757],{"class":80},[74,1123,1124],{"class":84}," u8",[74,1126,729],{"class":88},[74,1128,1129],{"class":115},"\u002F* str is !Sized but you can take &str *\u002F",[74,1131,119],{"class":88},[74,1133,1134,1136,1138,1140,1142,1144,1147,1149,1152,1154,1156,1158,1160,1163],{"class":76,"line":122},[74,1135,81],{"class":80},[74,1137,536],{"class":84},[74,1139,539],{"class":88},[74,1141,247],{"class":84},[74,1143,98],{"class":80},[74,1145,1146],{"class":80}," ?",[74,1148,954],{"class":84},[74,1150,1151],{"class":88},">(x",[74,1153,98],{"class":80},[74,1155,101],{"class":80},[74,1157,247],{"class":84},[74,1159,112],{"class":88},[74,1161,1162],{"class":115},"\u002F* works for unsized T *\u002F",[74,1164,119],{"class":88},[18,1166,1168,1171],{"id":1167},"phantomdatat-marker-for-unused-type-params",[42,1169,1170],{},"PhantomData\u003CT>"," — Marker for Unused Type Params",[62,1173,1174],{"language":64},[66,1175,1177],{"className":68,"code":1176,"language":64,"meta":70,"style":70},"use std::marker::PhantomData;\n\nstruct Tagged\u003CTag, T> {\n    data: T,\n    _tag: PhantomData\u003CTag>,\n}\n",[42,1178,1179,1199,1203,1222,1234,1251],{"__ignoreMap":70},[74,1180,1181,1184,1187,1189,1192,1194,1197],{"class":76,"line":77},[74,1182,1183],{"class":80},"use",[74,1185,1186],{"class":84}," std",[74,1188,398],{"class":80},[74,1190,1191],{"class":84},"marker",[74,1193,398],{"class":80},[74,1195,1196],{"class":84},"PhantomData",[74,1198,149],{"class":88},[74,1200,1201],{"class":76,"line":122},[74,1202,779],{"emptyLinePlaceholder":778},[74,1204,1205,1207,1210,1212,1215,1217,1219],{"class":76,"line":152},[74,1206,1002],{"class":80},[74,1208,1209],{"class":84}," Tagged",[74,1211,539],{"class":88},[74,1213,1214],{"class":84},"Tag",[74,1216,259],{"class":88},[74,1218,247],{"class":84},[74,1220,1221],{"class":88},"> {\n",[74,1223,1224,1227,1229,1231],{"class":76,"line":465},[74,1225,1226],{"class":88},"    data",[74,1228,98],{"class":80},[74,1230,811],{"class":84},[74,1232,1233],{"class":88},",\n",[74,1235,1236,1239,1241,1244,1246,1248],{"class":76,"line":484},[74,1237,1238],{"class":88},"    _tag",[74,1240,98],{"class":80},[74,1242,1243],{"class":84}," PhantomData",[74,1245,539],{"class":88},[74,1247,1214],{"class":84},[74,1249,1250],{"class":88},">,\n",[74,1252,1254],{"class":76,"line":1253},6,[74,1255,1256],{"class":88},"}\n",[14,1258,1259,1261],{},[42,1260,1196],{}," is zero-sized but tells the compiler about ownership\u002Fvariance:",[170,1263,1264,1272,1280,1292],{},[173,1265,1266,1268,1269,1271],{},[42,1267,1170],{}," makes your type behave like it owns a ",[42,1270,247],{}," for drop-checking and variance.",[173,1273,1274,1277,1278,908],{},[42,1275,1276],{},"PhantomData\u003C&'a T>"," makes it covariant in ",[42,1279,48],{},[173,1281,1282,1285,1286,683,1289,908],{},[42,1283,1284],{},"PhantomData\u003C*mut T>"," makes it invariant and ",[42,1287,1288],{},"!Send",[42,1290,1291],{},"!Sync",[173,1293,1294,1297,1298,244,1300,683,1302,908],{},[42,1295,1296],{},"PhantomData\u003Cfn(T) -> ()>"," makes it contravariant in ",[42,1299,247],{},[42,1301,1288],{},[42,1303,1291],{},[14,1305,1306,1307,1309],{},"Picking the right ",[42,1308,1196],{}," variant is critical for unsafe collections.",[18,1311,1313],{"id":1312},"newtype-pattern","Newtype Pattern",[62,1315,1316],{"language":64},[66,1317,1319],{"className":68,"code":1318,"language":64,"meta":70,"style":70},"struct Meters(f64);\nstruct Miles(f64);\n\nimpl Meters { fn to_miles(self) -> Miles { Miles(self.0 \u002F 1609.344) } }\n",[42,1320,1321,1335,1348,1352],{"__ignoreMap":70},[74,1322,1323,1325,1328,1330,1333],{"class":76,"line":77},[74,1324,1002],{"class":80},[74,1326,1327],{"class":84}," Meters",[74,1329,404],{"class":88},[74,1331,1332],{"class":84},"f64",[74,1334,410],{"class":88},[74,1336,1337,1339,1342,1344,1346],{"class":76,"line":122},[74,1338,1002],{"class":80},[74,1340,1341],{"class":84}," Miles",[74,1343,404],{"class":88},[74,1345,1332],{"class":84},[74,1347,410],{"class":88},[74,1349,1350],{"class":76,"line":152},[74,1351,779],{"emptyLinePlaceholder":778},[74,1353,1354,1357,1359,1361,1363,1366,1368,1370,1372,1374,1376,1378,1381,1383,1385,1387,1390,1393,1396],{"class":76,"line":465},[74,1355,1356],{"class":80},"impl",[74,1358,1327],{"class":84},[74,1360,729],{"class":88},[74,1362,81],{"class":80},[74,1364,1365],{"class":84}," to_miles",[74,1367,404],{"class":88},[74,1369,936],{"class":751},[74,1371,553],{"class":88},[74,1373,757],{"class":80},[74,1375,1341],{"class":84},[74,1377,729],{"class":88},[74,1379,1380],{"class":84},"Miles",[74,1382,404],{"class":88},[74,1384,936],{"class":751},[74,1386,908],{"class":80},[74,1388,1389],{"class":751},"0",[74,1391,1392],{"class":80}," \u002F",[74,1394,1395],{"class":751}," 1609.344",[74,1397,1398],{"class":88},") } }\n",[170,1400,1401,1404,1411],{},[173,1402,1403],{},"Zero-cost wrapper for type safety.",[173,1405,1406,1407,1410],{},"No accidental mixing: ",[42,1408,1409],{},"Meters(5.0) + Miles(1.0)"," is a type error.",[173,1412,1413,1414,683,1417,683,1420,683,1423,683,1426,1429],{},"Implement ",[42,1415,1416],{},"From",[42,1418,1419],{},"Into",[42,1421,1422],{},"Display",[42,1424,1425],{},"Deref",[42,1427,1428],{},"Add"," as needed.",[18,1431,1433],{"id":1432},"type-level-programming","Type-Level Programming",[14,1435,1436],{},"With traits and associated types:",[62,1438,1439],{"language":64},[66,1440,1442],{"className":68,"code":1441,"language":64,"meta":70,"style":70},"trait Peano { type Next; }\nstruct Zero;\nstruct Succ\u003CT>(T);\n\nimpl Peano for Zero { type Next = Succ\u003CZero>; }\nimpl\u003CT: Peano> Peano for Succ\u003CT> { type Next = Succ\u003CSucc\u003CT>>; }\n\ntype One = \u003CZero as Peano>::Next;\ntype Two = \u003COne as Peano>::Next;\n",[42,1443,1444,1460,1469,1487,1491,1518,1565,1570,1600],{"__ignoreMap":70},[74,1445,1446,1448,1451,1453,1455,1458],{"class":76,"line":77},[74,1447,723],{"class":80},[74,1449,1450],{"class":84}," Peano",[74,1452,729],{"class":88},[74,1454,732],{"class":80},[74,1456,1457],{"class":84}," Next",[74,1459,821],{"class":88},[74,1461,1462,1464,1467],{"class":76,"line":122},[74,1463,1002],{"class":80},[74,1465,1466],{"class":84}," Zero",[74,1468,149],{"class":88},[74,1470,1471,1473,1476,1478,1480,1483,1485],{"class":76,"line":152},[74,1472,1002],{"class":80},[74,1474,1475],{"class":84}," Succ",[74,1477,539],{"class":88},[74,1479,247],{"class":84},[74,1481,1482],{"class":88},">(",[74,1484,247],{"class":84},[74,1486,410],{"class":88},[74,1488,1489],{"class":76,"line":465},[74,1490,779],{"emptyLinePlaceholder":778},[74,1492,1493,1495,1497,1499,1501,1503,1505,1507,1509,1511,1513,1516],{"class":76,"line":484},[74,1494,1356],{"class":80},[74,1496,1450],{"class":84},[74,1498,563],{"class":80},[74,1500,1466],{"class":84},[74,1502,729],{"class":88},[74,1504,732],{"class":80},[74,1506,1457],{"class":84},[74,1508,142],{"class":80},[74,1510,1475],{"class":84},[74,1512,539],{"class":88},[74,1514,1515],{"class":84},"Zero",[74,1517,773],{"class":88},[74,1519,1520,1522,1524,1526,1528,1530,1532,1535,1537,1539,1541,1543,1545,1547,1549,1551,1553,1555,1558,1560,1562],{"class":76,"line":1253},[74,1521,1356],{"class":80},[74,1523,539],{"class":88},[74,1525,247],{"class":84},[74,1527,98],{"class":80},[74,1529,1450],{"class":84},[74,1531,570],{"class":88},[74,1533,1534],{"class":84},"Peano",[74,1536,563],{"class":80},[74,1538,1475],{"class":84},[74,1540,539],{"class":88},[74,1542,247],{"class":84},[74,1544,798],{"class":88},[74,1546,732],{"class":80},[74,1548,1457],{"class":84},[74,1550,142],{"class":80},[74,1552,1475],{"class":84},[74,1554,539],{"class":88},[74,1556,1557],{"class":84},"Succ",[74,1559,539],{"class":88},[74,1561,247],{"class":84},[74,1563,1564],{"class":88},">>; }\n",[74,1566,1568],{"class":76,"line":1567},7,[74,1569,779],{"emptyLinePlaceholder":778},[74,1571,1573,1575,1578,1580,1583,1585,1588,1590,1593,1595,1598],{"class":76,"line":1572},8,[74,1574,732],{"class":80},[74,1576,1577],{"class":84}," One",[74,1579,142],{"class":80},[74,1581,1582],{"class":88}," \u003C",[74,1584,1515],{"class":84},[74,1586,1587],{"class":80}," as",[74,1589,1450],{"class":84},[74,1591,1592],{"class":88},">",[74,1594,398],{"class":80},[74,1596,1597],{"class":84},"Next",[74,1599,149],{"class":88},[74,1601,1603,1605,1608,1610,1612,1615,1617,1619,1621,1623,1625],{"class":76,"line":1602},9,[74,1604,732],{"class":80},[74,1606,1607],{"class":84}," Two",[74,1609,142],{"class":80},[74,1611,1582],{"class":88},[74,1613,1614],{"class":84},"One",[74,1616,1587],{"class":80},[74,1618,1450],{"class":84},[74,1620,1592],{"class":88},[74,1622,398],{"class":80},[74,1624,1597],{"class":84},[74,1626,149],{"class":88},[14,1628,1629,1630,1633,1634,1637,1638,1641],{},"Practical for ",[42,1631,1632],{},"typenum"," (compile-time integers), dimension tracking (",[42,1635,1636],{},"uom","), and ",[42,1639,1640],{},"frunk","'s HList.",[18,1643,1645],{"id":1644},"const-generics-deep","Const Generics (Deep)",[62,1647,1648],{"language":64},[66,1649,1651],{"className":68,"code":1650,"language":64,"meta":70,"style":70},"struct Arr\u003Cconst N: usize> { data: [u8; N] }\n\nimpl\u003Cconst N: usize> Arr\u003CN> {\n    fn len(&self) -> usize { N }\n}\n\nfn sum\u003Cconst N: usize>(arr: &[i32; N]) -> i32 { arr.iter().sum() }\n",[42,1652,1653,1691,1695,1720,1746,1750,1754],{"__ignoreMap":70},[74,1654,1655,1657,1660,1662,1665,1668,1670,1673,1676,1678,1681,1683,1685,1688],{"class":76,"line":77},[74,1656,1002],{"class":80},[74,1658,1659],{"class":84}," Arr",[74,1661,539],{"class":88},[74,1663,1664],{"class":80},"const",[74,1666,1667],{"class":751}," N",[74,1669,98],{"class":80},[74,1671,1672],{"class":84}," usize",[74,1674,1675],{"class":88},"> { data",[74,1677,98],{"class":80},[74,1679,1680],{"class":88}," [",[74,1682,1015],{"class":84},[74,1684,738],{"class":88},[74,1686,1687],{"class":84},"N",[74,1689,1690],{"class":88},"] }\n",[74,1692,1693],{"class":76,"line":122},[74,1694,779],{"emptyLinePlaceholder":778},[74,1696,1697,1699,1701,1703,1705,1707,1709,1711,1714,1716,1718],{"class":76,"line":152},[74,1698,1356],{"class":80},[74,1700,539],{"class":88},[74,1702,1664],{"class":80},[74,1704,1667],{"class":751},[74,1706,98],{"class":80},[74,1708,1672],{"class":84},[74,1710,570],{"class":88},[74,1712,1713],{"class":84},"Arr",[74,1715,539],{"class":88},[74,1717,1687],{"class":84},[74,1719,1221],{"class":88},[74,1721,1722,1725,1728,1730,1732,1734,1736,1738,1740,1742,1744],{"class":76,"line":465},[74,1723,1724],{"class":80},"    fn",[74,1726,1727],{"class":84}," len",[74,1729,404],{"class":88},[74,1731,578],{"class":80},[74,1733,936],{"class":751},[74,1735,553],{"class":88},[74,1737,757],{"class":80},[74,1739,1672],{"class":84},[74,1741,729],{"class":88},[74,1743,1687],{"class":84},[74,1745,119],{"class":88},[74,1747,1748],{"class":76,"line":484},[74,1749,1256],{"class":88},[74,1751,1752],{"class":76,"line":1253},[74,1753,779],{"emptyLinePlaceholder":778},[74,1755,1756,1758,1761,1763,1765,1767,1769,1771,1774,1776,1778,1781,1784,1786,1788,1791,1793,1796,1799,1801,1804,1807,1809,1812],{"class":76,"line":1567},[74,1757,81],{"class":80},[74,1759,1760],{"class":84}," sum",[74,1762,539],{"class":88},[74,1764,1664],{"class":80},[74,1766,1667],{"class":84},[74,1768,98],{"class":80},[74,1770,1672],{"class":84},[74,1772,1773],{"class":88},">(arr",[74,1775,98],{"class":80},[74,1777,101],{"class":80},[74,1779,1780],{"class":88},"[",[74,1782,1783],{"class":84},"i32",[74,1785,738],{"class":88},[74,1787,1687],{"class":84},[74,1789,1790],{"class":88},"]) ",[74,1792,757],{"class":80},[74,1794,1795],{"class":84}," i32",[74,1797,1798],{"class":88}," { arr",[74,1800,908],{"class":80},[74,1802,1803],{"class":84},"iter",[74,1805,1806],{"class":88},"()",[74,1808,908],{"class":80},[74,1810,1811],{"class":84},"sum",[74,1813,1814],{"class":88},"() }\n",[209,1816,1818],{"id":1817},"limits","Limits",[170,1820,1821,1824,1830],{},[173,1822,1823],{},"Only integer\u002Fbool\u002Fchar const params on stable.",[173,1825,1826,1827,835],{},"Const expressions as params are unstable (",[42,1828,1829],{},"[T; N + 1]",[173,1831,1832,1833,1835],{},"Min const generics only — full generics (e.g., ",[42,1834,59],{}," const param) is unstable.",[18,1837,1839,1842],{"id":1838},"min_specialization-and-full-specialization",[42,1840,1841],{},"min_specialization"," and Full Specialization",[14,1844,1845],{},"Specialization lets you provide a more specific impl overriding a general one:",[62,1847,1848],{"language":64},[66,1849,1851],{"className":68,"code":1850,"language":64,"meta":70,"style":70},"#![feature(min_specialization)]\ntrait Pick { fn pick(&self); }\nimpl\u003CT> Pick for T { default fn pick(&self) { println!(\"default\"); } }\nimpl Pick for String { fn pick(&self) { println!(\"string\"); } }  \u002F\u002F specialized\n",[42,1852,1853,1858,1881,1923],{"__ignoreMap":70},[74,1854,1855],{"class":76,"line":77},[74,1856,1857],{"class":88},"#![feature(min_specialization)]\n",[74,1859,1860,1862,1865,1867,1869,1872,1874,1876,1878],{"class":76,"line":122},[74,1861,723],{"class":80},[74,1863,1864],{"class":84}," Pick",[74,1866,729],{"class":88},[74,1868,81],{"class":80},[74,1870,1871],{"class":84}," pick",[74,1873,404],{"class":88},[74,1875,578],{"class":80},[74,1877,936],{"class":751},[74,1879,1880],{"class":88},"); }\n",[74,1882,1883,1885,1887,1889,1891,1894,1896,1898,1901,1903,1905,1907,1909,1911,1913,1915,1917,1920],{"class":76,"line":152},[74,1884,1356],{"class":80},[74,1886,539],{"class":88},[74,1888,247],{"class":84},[74,1890,570],{"class":88},[74,1892,1893],{"class":84},"Pick",[74,1895,563],{"class":80},[74,1897,811],{"class":84},[74,1899,1900],{"class":88}," { default ",[74,1902,81],{"class":80},[74,1904,1871],{"class":84},[74,1906,404],{"class":88},[74,1908,578],{"class":80},[74,1910,936],{"class":751},[74,1912,112],{"class":88},[74,1914,487],{"class":84},[74,1916,404],{"class":88},[74,1918,1919],{"class":145},"\"default\"",[74,1921,1922],{"class":88},"); } }\n",[74,1924,1925,1927,1929,1931,1933,1935,1937,1939,1941,1943,1945,1947,1949,1951,1954,1957],{"class":76,"line":465},[74,1926,1356],{"class":80},[74,1928,1864],{"class":84},[74,1930,563],{"class":80},[74,1932,395],{"class":84},[74,1934,729],{"class":88},[74,1936,81],{"class":80},[74,1938,1871],{"class":84},[74,1940,404],{"class":88},[74,1942,578],{"class":80},[74,1944,936],{"class":751},[74,1946,112],{"class":88},[74,1948,487],{"class":84},[74,1950,404],{"class":88},[74,1952,1953],{"class":145},"\"string\"",[74,1955,1956],{"class":88},"); } }  ",[74,1958,1959],{"class":115},"\u002F\u002F specialized\n",[14,1961,1962,1963,1966],{},"Unstable. Avoid in production. Workarounds: macros, separate traits, or ",[42,1964,1965],{},"auto impl","-style delegation.",[18,1968,1970],{"id":1969},"higher-kinded-types-hkt","Higher-Kinded Types (HKT)",[14,1972,1973],{},"Rust doesn't have HKTs (types parameterized over type constructors). Workarounds:",[170,1975,1976,1982,1985],{},[173,1977,1978,1981],{},[42,1979,1980],{},"higher"," crate",[173,1983,1984],{},"Associated type families (unstable)",[173,1986,1987,1988,1990],{},"Manual \"Functor\" traits via ",[42,1989,1196],{}," (clunky)",[14,1992,1993,1994,259,1997,259,2000,2003],{},"The lack of HKTs limits abstracting over ",[42,1995,1996],{},"Option",[42,1998,1999],{},"Vec",[42,2001,2002],{},"Result"," uniformly. Most code doesn't need it.",[18,2005,2007],{"id":2006},"gats-generic-associated-types","GATs (Generic Associated Types)",[62,2009,2010],{"language":64},[66,2011,2013],{"className":68,"code":2012,"language":64,"meta":70,"style":70},"trait LendingIterator {\n    type Item\u003C'a> where Self: 'a;\n    fn next(&mut self) -> Option\u003CSelf::Item\u003C'_>>;\n}\n",[42,2014,2015,2025,2051,2085],{"__ignoreMap":70},[74,2016,2017,2019,2022],{"class":76,"line":77},[74,2018,723],{"class":80},[74,2020,2021],{"class":84}," LendingIterator",[74,2023,2024],{"class":88}," {\n",[74,2026,2027,2030,2032,2034,2036,2038,2040,2042,2044,2047,2049],{"class":76,"line":122},[74,2028,2029],{"class":80},"    type",[74,2031,735],{"class":84},[74,2033,89],{"class":88},[74,2035,92],{"class":84},[74,2037,570],{"class":88},[74,2039,556],{"class":80},[74,2041,818],{"class":751},[74,2043,98],{"class":80},[74,2045,2046],{"class":88}," '",[74,2048,92],{"class":84},[74,2050,149],{"class":88},[74,2052,2053,2055,2057,2059,2061,2063,2065,2067,2069,2071,2073,2075,2077,2079,2082],{"class":76,"line":152},[74,2054,1724],{"class":80},[74,2056,743],{"class":84},[74,2058,404],{"class":88},[74,2060,748],{"class":80},[74,2062,752],{"class":751},[74,2064,553],{"class":88},[74,2066,757],{"class":80},[74,2068,760],{"class":84},[74,2070,539],{"class":88},[74,2072,765],{"class":751},[74,2074,398],{"class":80},[74,2076,770],{"class":84},[74,2078,89],{"class":88},[74,2080,2081],{"class":84},"_",[74,2083,2084],{"class":88},">>;\n",[74,2086,2087],{"class":76,"line":465},[74,2088,1256],{"class":88},[14,2090,2091],{},"Associated types that themselves have generic params (lifetimes\u002Ftypes). Stable since 1.65. Lets you express borrowing iterators, async traits, etc.",[18,2093,2095,2096],{"id":2094},"subtyping-and-cow","Subtyping and ",[42,2097,2098],{},"Cow",[62,2100,2101],{"language":64},[66,2102,2104],{"className":68,"code":2103,"language":64,"meta":70,"style":70},"fn process\u003C'a>(s: Cow\u003C'a, str>) { \u002F* ... *\u002F }\nprocess(\"static\".into());      \u002F\u002F Cow::Borrowed(&'static str)\nprocess(String::from(\"x\").into());   \u002F\u002F Cow::Owned\n",[42,2105,2106,2139,2160],{"__ignoreMap":70},[74,2107,2108,2110,2113,2115,2117,2119,2121,2124,2126,2128,2130,2132,2135,2137],{"class":76,"line":77},[74,2109,81],{"class":80},[74,2111,2112],{"class":84}," process",[74,2114,89],{"class":88},[74,2116,92],{"class":84},[74,2118,95],{"class":88},[74,2120,98],{"class":80},[74,2122,2123],{"class":84}," Cow",[74,2125,89],{"class":88},[74,2127,92],{"class":84},[74,2129,259],{"class":88},[74,2131,1076],{"class":84},[74,2133,2134],{"class":88},">) { ",[74,2136,116],{"class":115},[74,2138,119],{"class":88},[74,2140,2141,2144,2146,2149,2151,2154,2157],{"class":76,"line":122},[74,2142,2143],{"class":84},"process",[74,2145,404],{"class":88},[74,2147,2148],{"class":145},"\"static\"",[74,2150,908],{"class":80},[74,2152,2153],{"class":84},"into",[74,2155,2156],{"class":88},"());      ",[74,2158,2159],{"class":115},"\u002F\u002F Cow::Borrowed(&'static str)\n",[74,2161,2162,2164,2166,2169,2171,2173,2175,2178,2180,2182,2184,2187],{"class":76,"line":152},[74,2163,2143],{"class":84},[74,2165,404],{"class":88},[74,2167,2168],{"class":84},"String",[74,2170,398],{"class":80},[74,2172,401],{"class":84},[74,2174,404],{"class":88},[74,2176,2177],{"class":145},"\"x\"",[74,2179,360],{"class":88},[74,2181,908],{"class":80},[74,2183,2153],{"class":84},[74,2185,2186],{"class":88},"());   ",[74,2188,2189],{"class":115},"\u002F\u002F Cow::Owned\n",[14,2191,2192,2195,2196,2198,2199,45,2202,908],{},[42,2193,2194],{},"Cow\u003C'a, B>"," is variant in ",[42,2197,48],{}," (covariant), so ",[42,2200,2201],{},"Cow\u003C'static, str>",[42,2203,2204],{},"Cow\u003C'a, str>",[18,2206,2208],{"id":2207},"negative-trait-impls","Negative Trait Impls",[62,2210,2211],{"language":64},[66,2212,2214],{"className":68,"code":2213,"language":64,"meta":70,"style":70},"impl !Send for MyType {}\n",[42,2215,2216],{"__ignoreMap":70},[74,2217,2218,2220,2223,2225,2227,2229],{"class":76,"line":77},[74,2219,1356],{"class":80},[74,2221,2222],{"class":80}," !",[74,2224,947],{"class":84},[74,2226,563],{"class":80},[74,2228,1005],{"class":84},[74,2230,2231],{"class":88}," {}\n",[14,2233,2234,2235,2238,2239,908],{},"Unstable; you can opt out of auto traits today via ",[42,2236,2237],{},"PhantomData\u003C*const ()>"," or ",[42,2240,2241],{},"Rc\u003C()>",[18,2243,2245],{"id":2244},"common-pitfalls","Common Pitfalls",[170,2247,2248,2261,2281,2295,2304,2316,2331],{},[173,2249,2250,2253,2254,2256,2257,2260],{},[26,2251,2252],{},"Forgetting variance",": writing ",[42,2255,1170],{}," when you needed ",[42,2258,2259],{},"PhantomData\u003Cfn() -> T>"," (covariant vs invariant).",[173,2262,2263,2266,2267,2270,2271,738,2274,878,2277,2280],{},[26,2264,2265],{},"HRTB vs named lifetime",": ",[42,2268,2269],{},"fn(&str)"," is ",[42,2272,2273],{},"for\u003C'a> fn(&'a str)",[42,2275,2276],{},"fn\u003C'a>(&'a str)",[35,2278,2279],{},"specific"," lifetime.",[173,2282,2283,2288,2289,2291,2292,908],{},[26,2284,2285],{},[42,2286,2287],{},"dyn Trait + 'static",": by default ",[42,2290,872],{}," borrows for some lifetime; you usually want ",[42,2293,2294],{},"Box\u003Cdyn Trait + 'static>",[173,2296,2297,2300,2301,2303],{},[26,2298,2299],{},"Object safety regression",": adding a generic method to a trait breaks all ",[42,2302,872],{}," users.",[173,2305,2306,2309,2310,2312,2313,908],{},[26,2307,2308],{},"Auto-trait inference",": a struct containing a ",[42,2311,1010],{}," makes the whole struct ",[42,2314,2315],{},"!Send + !Sync",[173,2317,2318,2266,2323,2326,2327,2330],{},[26,2319,2320,2322],{},[42,2321,954],{}," default",[42,2324,2325],{},"fn foo\u003CT>()"," requires ",[42,2328,2329],{},"T: Sized","; unsized locals and parameters are unstable.",[173,2332,2333,2266,2338,2340,2341,2343,2344,908],{},[26,2334,2335,2336],{},"Trait objects and ",[42,2337,947],{},[42,2339,885],{}," isn't ",[42,2342,947],{}," unless you write ",[42,2345,2346],{},"Box\u003Cdyn Trait + Send>",[18,2348,2350],{"id":2349},"summary","Summary",[14,2352,2353,2354,2356,2357,2359],{},"Variance governs subtype relationships and is mostly about lifetimes (and ",[42,2355,748],{},"'s invariance in ",[42,2358,247],{},"). HRTBs express \"for all lifetimes.\" Associated types vs generics: one natural type vs caller-supplied. Object safety limits trait objects. GATs (1.65+) enable borrowing in associated types. Const generics (1.51+) parameterize by integers\u002Fbools. PhantomData tunes variance and drop behavior. Newtype pattern is the idiomatic type-distinctness tool.",[14,2361,2362],{},"Next: Common design patterns and idiomatic Rust.",[2364,2365,2366],"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 .sdCPZ, html code.shiki .sdCPZ{--shiki-default:#6A737D;--shiki-github-dark:#6A737D}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":70,"searchDepth":122,"depth":122,"links":2368},[2369,2370,2375,2379,2380,2382,2384,2385,2386,2388,2390,2391,2392,2395,2397,2398,2399,2401,2402,2403],{"id":20,"depth":122,"text":21},{"id":164,"depth":122,"text":165,"children":2371},[2372,2373,2374],{"id":211,"depth":152,"text":212},{"id":363,"depth":152,"text":364},{"id":511,"depth":152,"text":512},{"id":521,"depth":122,"text":522,"children":2376},[2377,2378],{"id":610,"depth":152,"text":611},{"id":693,"depth":152,"text":694},{"id":705,"depth":122,"text":706},{"id":838,"depth":122,"text":2381},"impl Trait Internals",{"id":869,"depth":122,"text":2383},"dyn Trait Type Erasure",{"id":911,"depth":122,"text":912},{"id":977,"depth":122,"text":978},{"id":1056,"depth":122,"text":2387},"Sized Trait",{"id":1167,"depth":122,"text":2389},"PhantomData\u003CT> — Marker for Unused Type Params",{"id":1312,"depth":122,"text":1313},{"id":1432,"depth":122,"text":1433},{"id":1644,"depth":122,"text":1645,"children":2393},[2394],{"id":1817,"depth":152,"text":1818},{"id":1838,"depth":122,"text":2396},"min_specialization and Full Specialization",{"id":1969,"depth":122,"text":1970},{"id":2006,"depth":122,"text":2007},{"id":2094,"depth":122,"text":2400},"Subtyping and Cow",{"id":2207,"depth":122,"text":2208},{"id":2244,"depth":122,"text":2245},{"id":2349,"depth":122,"text":2350},"md",{},"\u002Frust\u002F29-advanced-type-system",{"title":5,"description":16},"rust\u002F29-advanced-type-system","y3p8WRN5Y5rGAjce9MbX26AsNFmgZWBN5bwvJaShZY8",1785944093277]