internal: add fn to minicore

This commit is contained in:
Aleksey Kladov 2021-06-16 10:48:07 +03:00
parent d2c9f3add1
commit 8a4d9bb80a
6 changed files with 258 additions and 310 deletions

View file

@ -571,48 +571,44 @@ fn main() {
fn match_ergonomics_in_closure_params() { fn match_ergonomics_in_closure_params() {
check_infer( check_infer(
r#" r#"
#[lang = "fn_once"] //- minicore: fn
trait FnOnce<Args> { fn foo<T, U, F: FnOnce(T) -> U>(t: T, f: F) -> U { loop {} }
type Output;
}
fn foo<T, U, F: FnOnce(T) -> U>(t: T, f: F) -> U { loop {} } fn test() {
fn test() {
foo(&(1, "a"), |&(x, y)| x); // normal, no match ergonomics foo(&(1, "a"), |&(x, y)| x); // normal, no match ergonomics
foo(&(1, "a"), |(x, y)| x); foo(&(1, "a"), |(x, y)| x);
} }
"#, "#,
expect![[r#" expect![[r#"
93..94 't': T 32..33 't': T
99..100 'f': F 38..39 'f': F
110..121 '{ loop {} }': U 49..60 '{ loop {} }': U
112..119 'loop {}': ! 51..58 'loop {}': !
117..119 '{}': () 56..58 '{}': ()
133..232 '{ ... x); }': () 72..171 '{ ... x); }': ()
139..142 'foo': fn foo<&(i32, &str), i32, |&(i32, &str)| -> i32>(&(i32, &str), |&(i32, &str)| -> i32) -> i32 78..81 'foo': fn foo<&(i32, &str), i32, |&(i32, &str)| -> i32>(&(i32, &str), |&(i32, &str)| -> i32) -> i32
139..166 'foo(&(...y)| x)': i32 78..105 'foo(&(...y)| x)': i32
143..152 '&(1, "a")': &(i32, &str) 82..91 '&(1, "a")': &(i32, &str)
144..152 '(1, "a")': (i32, &str) 83..91 '(1, "a")': (i32, &str)
145..146 '1': i32 84..85 '1': i32
148..151 '"a"': &str 87..90 '"a"': &str
154..165 '|&(x, y)| x': |&(i32, &str)| -> i32 93..104 '|&(x, y)| x': |&(i32, &str)| -> i32
155..162 '&(x, y)': &(i32, &str) 94..101 '&(x, y)': &(i32, &str)
156..162 '(x, y)': (i32, &str) 95..101 '(x, y)': (i32, &str)
157..158 'x': i32 96..97 'x': i32
160..161 'y': &str 99..100 'y': &str
164..165 'x': i32 103..104 'x': i32
203..206 'foo': fn foo<&(i32, &str), &i32, |&(i32, &str)| -> &i32>(&(i32, &str), |&(i32, &str)| -> &i32) -> &i32 142..145 'foo': fn foo<&(i32, &str), &i32, |&(i32, &str)| -> &i32>(&(i32, &str), |&(i32, &str)| -> &i32) -> &i32
203..229 'foo(&(...y)| x)': &i32 142..168 'foo(&(...y)| x)': &i32
207..216 '&(1, "a")': &(i32, &str) 146..155 '&(1, "a")': &(i32, &str)
208..216 '(1, "a")': (i32, &str) 147..155 '(1, "a")': (i32, &str)
209..210 '1': i32 148..149 '1': i32
212..215 '"a"': &str 151..154 '"a"': &str
218..228 '|(x, y)| x': |&(i32, &str)| -> &i32 157..167 '|(x, y)| x': |&(i32, &str)| -> &i32
219..225 '(x, y)': (i32, &str) 158..164 '(x, y)': (i32, &str)
220..221 'x': &i32 159..160 'x': &i32
223..224 'y': &&str 162..163 'y': &&str
227..228 'x': &i32 166..167 'x': &i32
"#]], "#]],
); );
} }

View file

@ -884,41 +884,37 @@ fn issue_4966() {
fn issue_6628() { fn issue_6628() {
check_infer( check_infer(
r#" r#"
#[lang = "fn_once"] //- minicore: fn
pub trait FnOnce<Args> { struct S<T>();
type Output; impl<T> S<T> {
}
struct S<T>();
impl<T> S<T> {
fn f(&self, _t: T) {} fn f(&self, _t: T) {}
fn g<F: FnOnce(&T)>(&self, _f: F) {} fn g<F: FnOnce(&T)>(&self, _f: F) {}
} }
fn main() { fn main() {
let s = S(); let s = S();
s.g(|_x| {}); s.g(|_x| {});
s.f(10); s.f(10);
} }
"#, "#,
expect![[r#" expect![[r#"
105..109 'self': &S<T> 40..44 'self': &S<T>
111..113 '_t': T 46..48 '_t': T
118..120 '{}': () 53..55 '{}': ()
146..150 'self': &S<T> 81..85 'self': &S<T>
152..154 '_f': F 87..89 '_f': F
159..161 '{}': () 94..96 '{}': ()
174..225 '{ ...10); }': () 109..160 '{ ...10); }': ()
184..185 's': S<i32> 119..120 's': S<i32>
188..189 'S': S<i32>() -> S<i32> 123..124 'S': S<i32>() -> S<i32>
188..191 'S()': S<i32> 123..126 'S()': S<i32>
197..198 's': S<i32> 132..133 's': S<i32>
197..209 's.g(|_x| {})': () 132..144 's.g(|_x| {})': ()
201..208 '|_x| {}': |&i32| -> () 136..143 '|_x| {}': |&i32| -> ()
202..204 '_x': &i32 137..139 '_x': &i32
206..208 '{}': () 141..143 '{}': ()
215..216 's': S<i32> 150..151 's': S<i32>
215..222 's.f(10)': () 150..157 's.f(10)': ()
219..221 '10': i32 154..156 '10': i32
"#]], "#]],
); );
} }

View file

@ -1846,11 +1846,7 @@ fn test() {
fn closure_1() { fn closure_1() {
check_infer_with_mismatches( check_infer_with_mismatches(
r#" r#"
#[lang = "fn_once"] //- minicore: fn
trait FnOnce<Args> {
type Output;
}
enum Option<T> { Some(T), None } enum Option<T> { Some(T), None }
impl<T> Option<T> { impl<T> Option<T> {
fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Option<U> { loop {} } fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Option<U> { loop {} }
@ -1863,34 +1859,34 @@ fn test() {
let y: Option<i64> = x.map(|_v| 1); let y: Option<i64> = x.map(|_v| 1);
}"#, }"#,
expect![[r#" expect![[r#"
147..151 'self': Option<T> 86..90 'self': Option<T>
153..154 'f': F 92..93 'f': F
172..183 '{ loop {} }': Option<U> 111..122 '{ loop {} }': Option<U>
174..181 'loop {}': ! 113..120 'loop {}': !
179..181 '{}': () 118..120 '{}': ()
197..316 '{ ... 1); }': () 136..255 '{ ... 1); }': ()
207..208 'x': Option<u32> 146..147 'x': Option<u32>
211..223 'Option::Some': Some<u32>(u32) -> Option<u32> 150..162 'Option::Some': Some<u32>(u32) -> Option<u32>
211..229 'Option...(1u32)': Option<u32> 150..168 'Option...(1u32)': Option<u32>
224..228 '1u32': u32 163..167 '1u32': u32
235..236 'x': Option<u32> 174..175 'x': Option<u32>
235..251 'x.map(...v + 1)': Option<u32> 174..190 'x.map(...v + 1)': Option<u32>
241..250 '|v| v + 1': |u32| -> u32 180..189 '|v| v + 1': |u32| -> u32
242..243 'v': u32 181..182 'v': u32
245..246 'v': u32 184..185 'v': u32
245..250 'v + 1': u32 184..189 'v + 1': u32
249..250 '1': u32 188..189 '1': u32
257..258 'x': Option<u32> 196..197 'x': Option<u32>
257..273 'x.map(... 1u64)': Option<u64> 196..212 'x.map(... 1u64)': Option<u64>
263..272 '|_v| 1u64': |u32| -> u64 202..211 '|_v| 1u64': |u32| -> u64
264..266 '_v': u32 203..205 '_v': u32
268..272 '1u64': u64 207..211 '1u64': u64
283..284 'y': Option<i64> 222..223 'y': Option<i64>
300..301 'x': Option<u32> 239..240 'x': Option<u32>
300..313 'x.map(|_v| 1)': Option<i64> 239..252 'x.map(|_v| 1)': Option<i64>
306..312 '|_v| 1': |u32| -> i64 245..251 '|_v| 1': |u32| -> i64
307..309 '_v': u32 246..248 '_v': u32
311..312 '1': i64 250..251 '1': i64
"#]], "#]],
); );
} }
@ -1964,11 +1960,7 @@ fn test<F: FnOnce(u32) -> u64>(f: F) {
fn closure_as_argument_inference_order() { fn closure_as_argument_inference_order() {
check_infer_with_mismatches( check_infer_with_mismatches(
r#" r#"
#[lang = "fn_once"] //- minicore: fn
trait FnOnce<Args> {
type Output;
}
fn foo1<T, U, F: FnOnce(T) -> U>(x: T, f: F) -> U { loop {} } fn foo1<T, U, F: FnOnce(T) -> U>(x: T, f: F) -> U { loop {} }
fn foo2<T, U, F: FnOnce(T) -> U>(f: F, x: T) -> U { loop {} } fn foo2<T, U, F: FnOnce(T) -> U>(f: F, x: T) -> U { loop {} }
@ -1987,62 +1979,62 @@ fn test() {
let x4 = S.foo2(|s| s.method(), S); let x4 = S.foo2(|s| s.method(), S);
}"#, }"#,
expect![[r#" expect![[r#"
94..95 'x': T 33..34 'x': T
100..101 'f': F 39..40 'f': F
111..122 '{ loop {} }': U 50..61 '{ loop {} }': U
113..120 'loop {}': ! 52..59 'loop {}': !
118..120 '{}': () 57..59 '{}': ()
156..157 'f': F 95..96 'f': F
162..163 'x': T 101..102 'x': T
173..184 '{ loop {} }': U 112..123 '{ loop {} }': U
175..182 'loop {}': ! 114..121 'loop {}': !
180..182 '{}': () 119..121 '{}': ()
219..223 'self': S 158..162 'self': S
271..275 'self': S 210..214 'self': S
277..278 'x': T 216..217 'x': T
283..284 'f': F 222..223 'f': F
294..305 '{ loop {} }': U 233..244 '{ loop {} }': U
296..303 'loop {}': ! 235..242 'loop {}': !
301..303 '{}': () 240..242 '{}': ()
343..347 'self': S 282..286 'self': S
349..350 'f': F 288..289 'f': F
355..356 'x': T 294..295 'x': T
366..377 '{ loop {} }': U 305..316 '{ loop {} }': U
368..375 'loop {}': ! 307..314 'loop {}': !
373..375 '{}': () 312..314 '{}': ()
391..550 '{ ... S); }': () 330..489 '{ ... S); }': ()
401..403 'x1': u64 340..342 'x1': u64
406..410 'foo1': fn foo1<S, u64, |S| -> u64>(S, |S| -> u64) -> u64 345..349 'foo1': fn foo1<S, u64, |S| -> u64>(S, |S| -> u64) -> u64
406..429 'foo1(S...hod())': u64 345..368 'foo1(S...hod())': u64
411..412 'S': S 350..351 'S': S
414..428 '|s| s.method()': |S| -> u64 353..367 '|s| s.method()': |S| -> u64
415..416 's': S 354..355 's': S
418..419 's': S 357..358 's': S
418..428 's.method()': u64 357..367 's.method()': u64
439..441 'x2': u64 378..380 'x2': u64
444..448 'foo2': fn foo2<S, u64, |S| -> u64>(|S| -> u64, S) -> u64 383..387 'foo2': fn foo2<S, u64, |S| -> u64>(|S| -> u64, S) -> u64
444..467 'foo2(|...(), S)': u64 383..406 'foo2(|...(), S)': u64
449..463 '|s| s.method()': |S| -> u64 388..402 '|s| s.method()': |S| -> u64
450..451 's': S 389..390 's': S
453..454 's': S 392..393 's': S
453..463 's.method()': u64 392..402 's.method()': u64
465..466 'S': S 404..405 'S': S
477..479 'x3': u64 416..418 'x3': u64
482..483 'S': S 421..422 'S': S
482..507 'S.foo1...hod())': u64 421..446 'S.foo1...hod())': u64
489..490 'S': S 428..429 'S': S
492..506 '|s| s.method()': |S| -> u64 431..445 '|s| s.method()': |S| -> u64
493..494 's': S 432..433 's': S
496..497 's': S 435..436 's': S
496..506 's.method()': u64 435..445 's.method()': u64
517..519 'x4': u64 456..458 'x4': u64
522..523 'S': S 461..462 'S': S
522..547 'S.foo2...(), S)': u64 461..486 'S.foo2...(), S)': u64
529..543 '|s| s.method()': |S| -> u64 468..482 '|s| s.method()': |S| -> u64
530..531 's': S 469..470 's': S
533..534 's': S 472..473 's': S
533..543 's.method()': u64 472..482 's.method()': u64
545..546 'S': S 484..485 'S': S
"#]], "#]],
); );
} }
@ -2051,11 +2043,7 @@ fn test() {
fn fn_item_fn_trait() { fn fn_item_fn_trait() {
check_types( check_types(
r#" r#"
#[lang = "fn_once"] //- minicore: fn
trait FnOnce<Args> {
type Output;
}
struct S; struct S;
fn foo() -> S {} fn foo() -> S {}
@ -2494,12 +2482,7 @@ fn test() -> impl Trait<i32> {
fn assoc_types_from_bounds() { fn assoc_types_from_bounds() {
check_infer( check_infer(
r#" r#"
//- /main.rs //- minicore: fn
#[lang = "fn_once"]
trait FnOnce<Args> {
type Output;
}
trait T { trait T {
type O; type O;
} }
@ -2518,15 +2501,15 @@ fn main() {
f::<(), _>(|z| { z; }); f::<(), _>(|z| { z; });
}"#, }"#,
expect![[r#" expect![[r#"
133..135 '_v': F 72..74 '_v': F
178..181 '{ }': () 117..120 '{ }': ()
193..224 '{ ... }); }': () 132..163 '{ ... }); }': ()
199..209 'f::<(), _>': fn f<(), |&()| -> ()>(|&()| -> ()) 138..148 'f::<(), _>': fn f<(), |&()| -> ()>(|&()| -> ())
199..221 'f::<()... z; })': () 138..160 'f::<()... z; })': ()
210..220 '|z| { z; }': |&()| -> () 149..159 '|z| { z; }': |&()| -> ()
211..212 'z': &() 150..151 'z': &()
214..220 '{ z; }': () 153..159 '{ z; }': ()
216..217 'z': &() 155..156 'z': &()
"#]], "#]],
); );
} }
@ -2599,17 +2582,7 @@ fn test() {
fn iterator_chain() { fn iterator_chain() {
check_infer_with_mismatches( check_infer_with_mismatches(
r#" r#"
//- /main.rs //- minicore: fn, option
#[lang = "fn_once"]
trait FnOnce<Args> {
type Output;
}
#[lang = "fn_mut"]
trait FnMut<Args>: FnOnce<Args> { }
enum Option<T> { Some(T), None }
use Option::*;
pub trait Iterator { pub trait Iterator {
type Item; type Item;
@ -2669,46 +2642,46 @@ fn main() {
.for_each(|y| { y; }); .for_each(|y| { y; });
}"#, }"#,
expect![[r#" expect![[r#"
226..230 'self': Self 61..65 'self': Self
232..233 'f': F 67..68 'f': F
317..328 '{ loop {} }': FilterMap<Self, F> 152..163 '{ loop {} }': FilterMap<Self, F>
319..326 'loop {}': ! 154..161 'loop {}': !
324..326 '{}': () 159..161 '{}': ()
349..353 'self': Self 184..188 'self': Self
355..356 'f': F 190..191 'f': F
405..416 '{ loop {} }': () 240..251 '{ loop {} }': ()
407..414 'loop {}': ! 242..249 'loop {}': !
412..414 '{}': () 247..249 '{}': ()
525..529 'self': Self 360..364 'self': Self
854..858 'self': I 689..693 'self': I
865..885 '{ ... }': I 700..720 '{ ... }': I
875..879 'self': I 710..714 'self': I
944..955 '{ loop {} }': Vec<T> 779..790 '{ loop {} }': Vec<T>
946..953 'loop {}': ! 781..788 'loop {}': !
951..953 '{}': () 786..788 '{}': ()
1142..1269 '{ ... }); }': () 977..1104 '{ ... }); }': ()
1148..1163 'Vec::<i32>::new': fn new<i32>() -> Vec<i32> 983..998 'Vec::<i32>::new': fn new<i32>() -> Vec<i32>
1148..1165 'Vec::<...:new()': Vec<i32> 983..1000 'Vec::<...:new()': Vec<i32>
1148..1177 'Vec::<...iter()': IntoIter<i32> 983..1012 'Vec::<...iter()': IntoIter<i32>
1148..1240 'Vec::<...one })': FilterMap<IntoIter<i32>, |i32| -> Option<u32>> 983..1075 'Vec::<...one })': FilterMap<IntoIter<i32>, |i32| -> Option<u32>>
1148..1266 'Vec::<... y; })': () 983..1101 'Vec::<... y; })': ()
1194..1239 '|x| if...None }': |i32| -> Option<u32> 1029..1074 '|x| if...None }': |i32| -> Option<u32>
1195..1196 'x': i32 1030..1031 'x': i32
1198..1239 'if x >...None }': Option<u32> 1033..1074 'if x >...None }': Option<u32>
1201..1202 'x': i32 1036..1037 'x': i32
1201..1206 'x > 0': bool 1036..1041 'x > 0': bool
1205..1206 '0': i32 1040..1041 '0': i32
1207..1225 '{ Some...u32) }': Option<u32> 1042..1060 '{ Some...u32) }': Option<u32>
1209..1213 'Some': Some<u32>(u32) -> Option<u32> 1044..1048 'Some': Some<u32>(u32) -> Option<u32>
1209..1223 'Some(x as u32)': Option<u32> 1044..1058 'Some(x as u32)': Option<u32>
1214..1215 'x': i32 1049..1050 'x': i32
1214..1222 'x as u32': u32 1049..1057 'x as u32': u32
1231..1239 '{ None }': Option<u32> 1066..1074 '{ None }': Option<u32>
1233..1237 'None': Option<u32> 1068..1072 'None': Option<u32>
1255..1265 '|y| { y; }': |u32| -> () 1090..1100 '|y| { y; }': |u32| -> ()
1256..1257 'y': u32 1091..1092 'y': u32
1259..1265 '{ y; }': () 1094..1100 '{ y; }': ()
1261..1262 'y': u32 1096..1097 'y': u32
"#]], "#]],
); );
} }
@ -2995,45 +2968,23 @@ fn foo() {
fn infer_fn_trait_arg() { fn infer_fn_trait_arg() {
check_infer_with_mismatches( check_infer_with_mismatches(
r#" r#"
//- /lib.rs deps:std //- minicore: fn, option
fn foo<F, T>(f: F) -> T
#[lang = "fn_once"] where
pub trait FnOnce<Args> {
type Output;
extern "rust-call" fn call_once(&self, args: Args) -> Self::Output;
}
#[lang = "fn"]
pub trait Fn<Args>:FnOnce<Args> {
extern "rust-call" fn call(&self, args: Args) -> Self::Output;
}
enum Option<T> {
None,
Some(T)
}
fn foo<F, T>(f: F) -> T
where
F: Fn(Option<i32>) -> T, F: Fn(Option<i32>) -> T,
{ {
let s = None; let s = None;
f(s) f(s)
} }
"#, "#,
expect![[r#" expect![[r#"
101..105 'self': &Self 13..14 'f': F
107..111 'args': Args 59..89 '{ ...f(s) }': T
220..224 'self': &Self 69..70 's': Option<i32>
226..230 'args': Args 73..77 'None': Option<i32>
313..314 'f': F 83..84 'f': F
359..389 '{ ...f(s) }': T 83..87 'f(s)': T
369..370 's': Option<i32> 85..86 's': Option<i32>
373..377 'None': Option<i32>
383..384 'f': F
383..387 'f(s)': T
385..386 's': Option<i32>
"#]], "#]],
); );
} }
@ -3112,17 +3063,7 @@ fn foo() {
fn infer_dyn_fn_output() { fn infer_dyn_fn_output() {
check_types( check_types(
r#" r#"
#[lang = "fn_once"] //- minicore: fn
pub trait FnOnce<Args> {
type Output;
extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
}
#[lang = "fn"]
pub trait Fn<Args>: FnOnce<Args> {
extern "rust-call" fn call(&self, args: Args) -> Self::Output;
}
fn foo() { fn foo() {
let f: &dyn Fn() -> i32; let f: &dyn Fn() -> i32;
f(); f();
@ -3135,12 +3076,7 @@ fn foo() {
fn infer_dyn_fn_once_output() { fn infer_dyn_fn_once_output() {
check_types( check_types(
r#" r#"
#[lang = "fn_once"] //- minicore: fn
pub trait FnOnce<Args> {
type Output;
extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
}
fn foo() { fn foo() {
let f: dyn FnOnce() -> i32; let f: dyn FnOnce() -> i32;
f(); f();
@ -3575,20 +3511,16 @@ fn main() {
fn fn_returning_unit() { fn fn_returning_unit() {
check_infer_with_mismatches( check_infer_with_mismatches(
r#" r#"
#[lang = "fn_once"] //- minicore: fn
trait FnOnce<Args> {
type Output;
}
fn test<F: FnOnce()>(f: F) { fn test<F: FnOnce()>(f: F) {
let _: () = f(); let _: () = f();
}"#, }"#,
expect![[r#" expect![[r#"
82..83 'f': F 21..22 'f': F
88..112 '{ ...f(); }': () 27..51 '{ ...f(); }': ()
98..99 '_': () 37..38 '_': ()
106..107 'f': F 45..46 'f': F
106..109 'f()': () 45..48 'f()': ()
"#]], "#]],
); );
} }

View file

@ -3016,8 +3016,8 @@ fn foo() {
file_id: FileId( file_id: FileId(
1, 1,
), ),
full_range: 244..426, full_range: 245..427,
focus_range: 283..289, focus_range: 284..290,
name: "Future", name: "Future",
kind: Trait, kind: Trait,
description: "pub trait Future", description: "pub trait Future",

View file

@ -164,7 +164,9 @@ impl Fixture {
let mut env = FxHashMap::default(); let mut env = FxHashMap::default();
let mut introduce_new_source_root = false; let mut introduce_new_source_root = false;
for component in components[1..].iter() { for component in components[1..].iter() {
let (key, value) = component.split_once(':').unwrap(); let (key, value) = component
.split_once(':')
.unwrap_or_else(|| panic!("invalid meta line: {:?}", meta));
match key { match key {
"crate" => krate = Some(value.to_string()), "crate" => krate = Some(value.to_string()),
"deps" => deps = value.split(',').map(|it| it.to_string()).collect(), "deps" => deps = value.split(',').map(|it| it.to_string()).collect(),

View file

@ -9,12 +9,13 @@
//! //!
//! Available flags: //! Available flags:
//! sized: //! sized:
//! unsize: sized
//! coerce_unsized: unsize
//! slice: //! slice:
//! range: //! range:
//! unsize: sized
//! deref: sized //! deref: sized
//! deref_mut: deref //! deref_mut: deref
//! coerce_unsized: unsize //! fn:
//! pin: //! pin:
//! future: pin //! future: pin
//! option: //! option:
@ -112,6 +113,26 @@ pub mod ops {
pub use self::range::{Range, RangeFrom, RangeFull, RangeTo}; pub use self::range::{Range, RangeFrom, RangeFull, RangeTo};
pub use self::range::{RangeInclusive, RangeToInclusive}; pub use self::range::{RangeInclusive, RangeToInclusive};
// endregion:range // endregion:range
// region:fn
mod function {
#[lang = "fn"]
#[fundamental]
pub trait Fn<Args>: FnMut<Args> {}
#[lang = "fn_mut"]
#[fundamental]
pub trait FnMut<Args>: FnOnce<Args> {}
#[lang = "fn_once"]
#[fundamental]
pub trait FnOnce<Args> {
#[lang = "fn_once_output"]
type Output;
}
}
pub use self::function::{Fn, FnMut, FnOnce};
// endregion:fn
} }
// region:slice // region:slice
@ -189,6 +210,7 @@ pub mod prelude {
pub mod v1 { pub mod v1 {
pub use crate::{ pub use crate::{
marker::Sized, // :sized marker::Sized, // :sized
ops::{Fn, FnMut, FnOnce}, // :fn
option::Option::{self, None, Some}, // :option option::Option::{self, None, Some}, // :option
result::Result::{self, Err, Ok}, // :result result::Result::{self, Err, Ok}, // :result
}; };