From 8a4d9bb80a484193dc24c474af30d0d0e091963b Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 16 Jun 2021 10:48:07 +0300 Subject: [PATCH] internal: add fn to minicore --- crates/hir_ty/src/tests/patterns.rs | 76 +++-- crates/hir_ty/src/tests/regression.rs | 64 ++--- crates/hir_ty/src/tests/traits.rs | 392 +++++++++++--------------- crates/ide/src/hover.rs | 4 +- crates/test_utils/src/fixture.rs | 4 +- crates/test_utils/src/minicore.rs | 28 +- 6 files changed, 258 insertions(+), 310 deletions(-) diff --git a/crates/hir_ty/src/tests/patterns.rs b/crates/hir_ty/src/tests/patterns.rs index aa513c56d5c..5adbe9c45e5 100644 --- a/crates/hir_ty/src/tests/patterns.rs +++ b/crates/hir_ty/src/tests/patterns.rs @@ -571,48 +571,44 @@ fn main() { fn match_ergonomics_in_closure_params() { check_infer( r#" - #[lang = "fn_once"] - trait FnOnce { - type Output; - } +//- minicore: fn +fn foo U>(t: T, f: F) -> U { loop {} } - fn foo U>(t: T, f: F) -> U { loop {} } - - fn test() { - foo(&(1, "a"), |&(x, y)| x); // normal, no match ergonomics - foo(&(1, "a"), |(x, y)| x); - } - "#, +fn test() { + foo(&(1, "a"), |&(x, y)| x); // normal, no match ergonomics + foo(&(1, "a"), |(x, y)| x); +} +"#, expect![[r#" - 93..94 't': T - 99..100 'f': F - 110..121 '{ loop {} }': U - 112..119 'loop {}': ! - 117..119 '{}': () - 133..232 '{ ... x); }': () - 139..142 'foo': fn foo<&(i32, &str), i32, |&(i32, &str)| -> i32>(&(i32, &str), |&(i32, &str)| -> i32) -> i32 - 139..166 'foo(&(...y)| x)': i32 - 143..152 '&(1, "a")': &(i32, &str) - 144..152 '(1, "a")': (i32, &str) - 145..146 '1': i32 - 148..151 '"a"': &str - 154..165 '|&(x, y)| x': |&(i32, &str)| -> i32 - 155..162 '&(x, y)': &(i32, &str) - 156..162 '(x, y)': (i32, &str) - 157..158 'x': i32 - 160..161 'y': &str - 164..165 'x': i32 - 203..206 'foo': fn foo<&(i32, &str), &i32, |&(i32, &str)| -> &i32>(&(i32, &str), |&(i32, &str)| -> &i32) -> &i32 - 203..229 'foo(&(...y)| x)': &i32 - 207..216 '&(1, "a")': &(i32, &str) - 208..216 '(1, "a")': (i32, &str) - 209..210 '1': i32 - 212..215 '"a"': &str - 218..228 '|(x, y)| x': |&(i32, &str)| -> &i32 - 219..225 '(x, y)': (i32, &str) - 220..221 'x': &i32 - 223..224 'y': &&str - 227..228 'x': &i32 + 32..33 't': T + 38..39 'f': F + 49..60 '{ loop {} }': U + 51..58 'loop {}': ! + 56..58 '{}': () + 72..171 '{ ... x); }': () + 78..81 'foo': fn foo<&(i32, &str), i32, |&(i32, &str)| -> i32>(&(i32, &str), |&(i32, &str)| -> i32) -> i32 + 78..105 'foo(&(...y)| x)': i32 + 82..91 '&(1, "a")': &(i32, &str) + 83..91 '(1, "a")': (i32, &str) + 84..85 '1': i32 + 87..90 '"a"': &str + 93..104 '|&(x, y)| x': |&(i32, &str)| -> i32 + 94..101 '&(x, y)': &(i32, &str) + 95..101 '(x, y)': (i32, &str) + 96..97 'x': i32 + 99..100 'y': &str + 103..104 'x': i32 + 142..145 'foo': fn foo<&(i32, &str), &i32, |&(i32, &str)| -> &i32>(&(i32, &str), |&(i32, &str)| -> &i32) -> &i32 + 142..168 'foo(&(...y)| x)': &i32 + 146..155 '&(1, "a")': &(i32, &str) + 147..155 '(1, "a")': (i32, &str) + 148..149 '1': i32 + 151..154 '"a"': &str + 157..167 '|(x, y)| x': |&(i32, &str)| -> &i32 + 158..164 '(x, y)': (i32, &str) + 159..160 'x': &i32 + 162..163 'y': &&str + 166..167 'x': &i32 "#]], ); } diff --git a/crates/hir_ty/src/tests/regression.rs b/crates/hir_ty/src/tests/regression.rs index abd9c385aee..1edec1615fd 100644 --- a/crates/hir_ty/src/tests/regression.rs +++ b/crates/hir_ty/src/tests/regression.rs @@ -884,41 +884,37 @@ fn issue_4966() { fn issue_6628() { check_infer( r#" - #[lang = "fn_once"] - pub trait FnOnce { - type Output; - } - - struct S(); - impl S { - fn f(&self, _t: T) {} - fn g(&self, _f: F) {} - } - fn main() { - let s = S(); - s.g(|_x| {}); - s.f(10); - } - "#, +//- minicore: fn +struct S(); +impl S { + fn f(&self, _t: T) {} + fn g(&self, _f: F) {} +} +fn main() { + let s = S(); + s.g(|_x| {}); + s.f(10); +} +"#, expect![[r#" - 105..109 'self': &S - 111..113 '_t': T - 118..120 '{}': () - 146..150 'self': &S - 152..154 '_f': F - 159..161 '{}': () - 174..225 '{ ...10); }': () - 184..185 's': S - 188..189 'S': S() -> S - 188..191 'S()': S - 197..198 's': S - 197..209 's.g(|_x| {})': () - 201..208 '|_x| {}': |&i32| -> () - 202..204 '_x': &i32 - 206..208 '{}': () - 215..216 's': S - 215..222 's.f(10)': () - 219..221 '10': i32 + 40..44 'self': &S + 46..48 '_t': T + 53..55 '{}': () + 81..85 'self': &S + 87..89 '_f': F + 94..96 '{}': () + 109..160 '{ ...10); }': () + 119..120 's': S + 123..124 'S': S() -> S + 123..126 'S()': S + 132..133 's': S + 132..144 's.g(|_x| {})': () + 136..143 '|_x| {}': |&i32| -> () + 137..139 '_x': &i32 + 141..143 '{}': () + 150..151 's': S + 150..157 's.f(10)': () + 154..156 '10': i32 "#]], ); } diff --git a/crates/hir_ty/src/tests/traits.rs b/crates/hir_ty/src/tests/traits.rs index 65fed02d24f..065cca74f7e 100644 --- a/crates/hir_ty/src/tests/traits.rs +++ b/crates/hir_ty/src/tests/traits.rs @@ -1846,11 +1846,7 @@ fn test() { fn closure_1() { check_infer_with_mismatches( r#" -#[lang = "fn_once"] -trait FnOnce { - type Output; -} - +//- minicore: fn enum Option { Some(T), None } impl Option { fn map U>(self, f: F) -> Option { loop {} } @@ -1863,34 +1859,34 @@ fn test() { let y: Option = x.map(|_v| 1); }"#, expect![[r#" - 147..151 'self': Option - 153..154 'f': F - 172..183 '{ loop {} }': Option - 174..181 'loop {}': ! - 179..181 '{}': () - 197..316 '{ ... 1); }': () - 207..208 'x': Option - 211..223 'Option::Some': Some(u32) -> Option - 211..229 'Option...(1u32)': Option - 224..228 '1u32': u32 - 235..236 'x': Option - 235..251 'x.map(...v + 1)': Option - 241..250 '|v| v + 1': |u32| -> u32 - 242..243 'v': u32 - 245..246 'v': u32 - 245..250 'v + 1': u32 - 249..250 '1': u32 - 257..258 'x': Option - 257..273 'x.map(... 1u64)': Option - 263..272 '|_v| 1u64': |u32| -> u64 - 264..266 '_v': u32 - 268..272 '1u64': u64 - 283..284 'y': Option - 300..301 'x': Option - 300..313 'x.map(|_v| 1)': Option - 306..312 '|_v| 1': |u32| -> i64 - 307..309 '_v': u32 - 311..312 '1': i64 + 86..90 'self': Option + 92..93 'f': F + 111..122 '{ loop {} }': Option + 113..120 'loop {}': ! + 118..120 '{}': () + 136..255 '{ ... 1); }': () + 146..147 'x': Option + 150..162 'Option::Some': Some(u32) -> Option + 150..168 'Option...(1u32)': Option + 163..167 '1u32': u32 + 174..175 'x': Option + 174..190 'x.map(...v + 1)': Option + 180..189 '|v| v + 1': |u32| -> u32 + 181..182 'v': u32 + 184..185 'v': u32 + 184..189 'v + 1': u32 + 188..189 '1': u32 + 196..197 'x': Option + 196..212 'x.map(... 1u64)': Option + 202..211 '|_v| 1u64': |u32| -> u64 + 203..205 '_v': u32 + 207..211 '1u64': u64 + 222..223 'y': Option + 239..240 'x': Option + 239..252 'x.map(|_v| 1)': Option + 245..251 '|_v| 1': |u32| -> i64 + 246..248 '_v': u32 + 250..251 '1': i64 "#]], ); } @@ -1964,11 +1960,7 @@ fn test u64>(f: F) { fn closure_as_argument_inference_order() { check_infer_with_mismatches( r#" -#[lang = "fn_once"] -trait FnOnce { - type Output; -} - +//- minicore: fn fn foo1 U>(x: T, f: F) -> U { loop {} } fn foo2 U>(f: F, x: T) -> U { loop {} } @@ -1987,62 +1979,62 @@ fn test() { let x4 = S.foo2(|s| s.method(), S); }"#, expect![[r#" - 94..95 'x': T - 100..101 'f': F - 111..122 '{ loop {} }': U - 113..120 'loop {}': ! - 118..120 '{}': () - 156..157 'f': F - 162..163 'x': T - 173..184 '{ loop {} }': U - 175..182 'loop {}': ! - 180..182 '{}': () - 219..223 'self': S - 271..275 'self': S - 277..278 'x': T - 283..284 'f': F - 294..305 '{ loop {} }': U - 296..303 'loop {}': ! - 301..303 '{}': () - 343..347 'self': S - 349..350 'f': F - 355..356 'x': T - 366..377 '{ loop {} }': U - 368..375 'loop {}': ! - 373..375 '{}': () - 391..550 '{ ... S); }': () - 401..403 'x1': u64 - 406..410 'foo1': fn foo1 u64>(S, |S| -> u64) -> u64 - 406..429 'foo1(S...hod())': u64 - 411..412 'S': S - 414..428 '|s| s.method()': |S| -> u64 - 415..416 's': S - 418..419 's': S - 418..428 's.method()': u64 - 439..441 'x2': u64 - 444..448 'foo2': fn foo2 u64>(|S| -> u64, S) -> u64 - 444..467 'foo2(|...(), S)': u64 - 449..463 '|s| s.method()': |S| -> u64 - 450..451 's': S - 453..454 's': S - 453..463 's.method()': u64 - 465..466 'S': S - 477..479 'x3': u64 - 482..483 'S': S - 482..507 'S.foo1...hod())': u64 - 489..490 'S': S - 492..506 '|s| s.method()': |S| -> u64 - 493..494 's': S - 496..497 's': S - 496..506 's.method()': u64 - 517..519 'x4': u64 - 522..523 'S': S - 522..547 'S.foo2...(), S)': u64 - 529..543 '|s| s.method()': |S| -> u64 - 530..531 's': S - 533..534 's': S - 533..543 's.method()': u64 - 545..546 'S': S + 33..34 'x': T + 39..40 'f': F + 50..61 '{ loop {} }': U + 52..59 'loop {}': ! + 57..59 '{}': () + 95..96 'f': F + 101..102 'x': T + 112..123 '{ loop {} }': U + 114..121 'loop {}': ! + 119..121 '{}': () + 158..162 'self': S + 210..214 'self': S + 216..217 'x': T + 222..223 'f': F + 233..244 '{ loop {} }': U + 235..242 'loop {}': ! + 240..242 '{}': () + 282..286 'self': S + 288..289 'f': F + 294..295 'x': T + 305..316 '{ loop {} }': U + 307..314 'loop {}': ! + 312..314 '{}': () + 330..489 '{ ... S); }': () + 340..342 'x1': u64 + 345..349 'foo1': fn foo1 u64>(S, |S| -> u64) -> u64 + 345..368 'foo1(S...hod())': u64 + 350..351 'S': S + 353..367 '|s| s.method()': |S| -> u64 + 354..355 's': S + 357..358 's': S + 357..367 's.method()': u64 + 378..380 'x2': u64 + 383..387 'foo2': fn foo2 u64>(|S| -> u64, S) -> u64 + 383..406 'foo2(|...(), S)': u64 + 388..402 '|s| s.method()': |S| -> u64 + 389..390 's': S + 392..393 's': S + 392..402 's.method()': u64 + 404..405 'S': S + 416..418 'x3': u64 + 421..422 'S': S + 421..446 'S.foo1...hod())': u64 + 428..429 'S': S + 431..445 '|s| s.method()': |S| -> u64 + 432..433 's': S + 435..436 's': S + 435..445 's.method()': u64 + 456..458 'x4': u64 + 461..462 'S': S + 461..486 'S.foo2...(), S)': u64 + 468..482 '|s| s.method()': |S| -> u64 + 469..470 's': S + 472..473 's': S + 472..482 's.method()': u64 + 484..485 'S': S "#]], ); } @@ -2051,11 +2043,7 @@ fn test() { fn fn_item_fn_trait() { check_types( r#" -#[lang = "fn_once"] -trait FnOnce { - type Output; -} - +//- minicore: fn struct S; fn foo() -> S {} @@ -2494,12 +2482,7 @@ fn test() -> impl Trait { fn assoc_types_from_bounds() { check_infer( r#" -//- /main.rs -#[lang = "fn_once"] -trait FnOnce { - type Output; -} - +//- minicore: fn trait T { type O; } @@ -2518,15 +2501,15 @@ fn main() { f::<(), _>(|z| { z; }); }"#, expect![[r#" - 133..135 '_v': F - 178..181 '{ }': () - 193..224 '{ ... }); }': () - 199..209 'f::<(), _>': fn f<(), |&()| -> ()>(|&()| -> ()) - 199..221 'f::<()... z; })': () - 210..220 '|z| { z; }': |&()| -> () - 211..212 'z': &() - 214..220 '{ z; }': () - 216..217 'z': &() + 72..74 '_v': F + 117..120 '{ }': () + 132..163 '{ ... }); }': () + 138..148 'f::<(), _>': fn f<(), |&()| -> ()>(|&()| -> ()) + 138..160 'f::<()... z; })': () + 149..159 '|z| { z; }': |&()| -> () + 150..151 'z': &() + 153..159 '{ z; }': () + 155..156 'z': &() "#]], ); } @@ -2599,17 +2582,7 @@ fn test() { fn iterator_chain() { check_infer_with_mismatches( r#" -//- /main.rs -#[lang = "fn_once"] -trait FnOnce { - type Output; -} -#[lang = "fn_mut"] -trait FnMut: FnOnce { } - -enum Option { Some(T), None } -use Option::*; - +//- minicore: fn, option pub trait Iterator { type Item; @@ -2669,46 +2642,46 @@ fn main() { .for_each(|y| { y; }); }"#, expect![[r#" - 226..230 'self': Self - 232..233 'f': F - 317..328 '{ loop {} }': FilterMap - 319..326 'loop {}': ! - 324..326 '{}': () - 349..353 'self': Self - 355..356 'f': F - 405..416 '{ loop {} }': () - 407..414 'loop {}': ! - 412..414 '{}': () - 525..529 'self': Self - 854..858 'self': I - 865..885 '{ ... }': I - 875..879 'self': I - 944..955 '{ loop {} }': Vec - 946..953 'loop {}': ! - 951..953 '{}': () - 1142..1269 '{ ... }); }': () - 1148..1163 'Vec::::new': fn new() -> Vec - 1148..1165 'Vec::<...:new()': Vec - 1148..1177 'Vec::<...iter()': IntoIter - 1148..1240 'Vec::<...one })': FilterMap, |i32| -> Option> - 1148..1266 'Vec::<... y; })': () - 1194..1239 '|x| if...None }': |i32| -> Option - 1195..1196 'x': i32 - 1198..1239 'if x >...None }': Option - 1201..1202 'x': i32 - 1201..1206 'x > 0': bool - 1205..1206 '0': i32 - 1207..1225 '{ Some...u32) }': Option - 1209..1213 'Some': Some(u32) -> Option - 1209..1223 'Some(x as u32)': Option - 1214..1215 'x': i32 - 1214..1222 'x as u32': u32 - 1231..1239 '{ None }': Option - 1233..1237 'None': Option - 1255..1265 '|y| { y; }': |u32| -> () - 1256..1257 'y': u32 - 1259..1265 '{ y; }': () - 1261..1262 'y': u32 + 61..65 'self': Self + 67..68 'f': F + 152..163 '{ loop {} }': FilterMap + 154..161 'loop {}': ! + 159..161 '{}': () + 184..188 'self': Self + 190..191 'f': F + 240..251 '{ loop {} }': () + 242..249 'loop {}': ! + 247..249 '{}': () + 360..364 'self': Self + 689..693 'self': I + 700..720 '{ ... }': I + 710..714 'self': I + 779..790 '{ loop {} }': Vec + 781..788 'loop {}': ! + 786..788 '{}': () + 977..1104 '{ ... }); }': () + 983..998 'Vec::::new': fn new() -> Vec + 983..1000 'Vec::<...:new()': Vec + 983..1012 'Vec::<...iter()': IntoIter + 983..1075 'Vec::<...one })': FilterMap, |i32| -> Option> + 983..1101 'Vec::<... y; })': () + 1029..1074 '|x| if...None }': |i32| -> Option + 1030..1031 'x': i32 + 1033..1074 'if x >...None }': Option + 1036..1037 'x': i32 + 1036..1041 'x > 0': bool + 1040..1041 '0': i32 + 1042..1060 '{ Some...u32) }': Option + 1044..1048 'Some': Some(u32) -> Option + 1044..1058 'Some(x as u32)': Option + 1049..1050 'x': i32 + 1049..1057 'x as u32': u32 + 1066..1074 '{ None }': Option + 1068..1072 'None': Option + 1090..1100 '|y| { y; }': |u32| -> () + 1091..1092 'y': u32 + 1094..1100 '{ y; }': () + 1096..1097 'y': u32 "#]], ); } @@ -2995,45 +2968,23 @@ fn foo() { fn infer_fn_trait_arg() { check_infer_with_mismatches( r#" - //- /lib.rs deps:std - - #[lang = "fn_once"] - pub trait FnOnce { - type Output; - - extern "rust-call" fn call_once(&self, args: Args) -> Self::Output; - } - - #[lang = "fn"] - pub trait Fn:FnOnce { - extern "rust-call" fn call(&self, args: Args) -> Self::Output; - } - - enum Option { - None, - Some(T) - } - - fn foo(f: F) -> T - where - F: Fn(Option) -> T, - { - let s = None; - f(s) - } - "#, +//- minicore: fn, option +fn foo(f: F) -> T +where + F: Fn(Option) -> T, +{ + let s = None; + f(s) +} +"#, expect![[r#" - 101..105 'self': &Self - 107..111 'args': Args - 220..224 'self': &Self - 226..230 'args': Args - 313..314 'f': F - 359..389 '{ ...f(s) }': T - 369..370 's': Option - 373..377 'None': Option - 383..384 'f': F - 383..387 'f(s)': T - 385..386 's': Option + 13..14 'f': F + 59..89 '{ ...f(s) }': T + 69..70 's': Option + 73..77 'None': Option + 83..84 'f': F + 83..87 'f(s)': T + 85..86 's': Option "#]], ); } @@ -3112,17 +3063,7 @@ fn foo() { fn infer_dyn_fn_output() { check_types( r#" -#[lang = "fn_once"] -pub trait FnOnce { - type Output; - extern "rust-call" fn call_once(self, args: Args) -> Self::Output; -} - -#[lang = "fn"] -pub trait Fn: FnOnce { - extern "rust-call" fn call(&self, args: Args) -> Self::Output; -} - +//- minicore: fn fn foo() { let f: &dyn Fn() -> i32; f(); @@ -3135,12 +3076,7 @@ fn foo() { fn infer_dyn_fn_once_output() { check_types( r#" -#[lang = "fn_once"] -pub trait FnOnce { - type Output; - extern "rust-call" fn call_once(self, args: Args) -> Self::Output; -} - +//- minicore: fn fn foo() { let f: dyn FnOnce() -> i32; f(); @@ -3575,20 +3511,16 @@ fn main() { fn fn_returning_unit() { check_infer_with_mismatches( r#" -#[lang = "fn_once"] -trait FnOnce { - type Output; -} - +//- minicore: fn fn test(f: F) { let _: () = f(); }"#, expect![[r#" - 82..83 'f': F - 88..112 '{ ...f(); }': () - 98..99 '_': () - 106..107 'f': F - 106..109 'f()': () + 21..22 'f': F + 27..51 '{ ...f(); }': () + 37..38 '_': () + 45..46 'f': F + 45..48 'f()': () "#]], ); } diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs index 14cf94d6077..529cf5f3305 100644 --- a/crates/ide/src/hover.rs +++ b/crates/ide/src/hover.rs @@ -3016,8 +3016,8 @@ fn foo() { file_id: FileId( 1, ), - full_range: 244..426, - focus_range: 283..289, + full_range: 245..427, + focus_range: 284..290, name: "Future", kind: Trait, description: "pub trait Future", diff --git a/crates/test_utils/src/fixture.rs b/crates/test_utils/src/fixture.rs index 313088c3766..005a5c092ae 100644 --- a/crates/test_utils/src/fixture.rs +++ b/crates/test_utils/src/fixture.rs @@ -164,7 +164,9 @@ impl Fixture { let mut env = FxHashMap::default(); let mut introduce_new_source_root = false; 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 { "crate" => krate = Some(value.to_string()), "deps" => deps = value.split(',').map(|it| it.to_string()).collect(), diff --git a/crates/test_utils/src/minicore.rs b/crates/test_utils/src/minicore.rs index 8555ff935ad..e04ca58d285 100644 --- a/crates/test_utils/src/minicore.rs +++ b/crates/test_utils/src/minicore.rs @@ -9,12 +9,13 @@ //! //! Available flags: //! sized: +//! unsize: sized +//! coerce_unsized: unsize //! slice: //! range: -//! unsize: sized //! deref: sized //! deref_mut: deref -//! coerce_unsized: unsize +//! fn: //! pin: //! future: pin //! option: @@ -74,7 +75,7 @@ pub mod ops { } pub use self::deref::Deref; pub use self::deref::DerefMut; //:deref_mut - // endregion:deref + // endregion:deref // region:range mod range { @@ -112,6 +113,26 @@ pub mod ops { pub use self::range::{Range, RangeFrom, RangeFull, RangeTo}; pub use self::range::{RangeInclusive, RangeToInclusive}; // endregion:range + + // region:fn + mod function { + #[lang = "fn"] + #[fundamental] + pub trait Fn: FnMut {} + + #[lang = "fn_mut"] + #[fundamental] + pub trait FnMut: FnOnce {} + + #[lang = "fn_once"] + #[fundamental] + pub trait FnOnce { + #[lang = "fn_once_output"] + type Output; + } + } + pub use self::function::{Fn, FnMut, FnOnce}; + // endregion:fn } // region:slice @@ -189,6 +210,7 @@ pub mod prelude { pub mod v1 { pub use crate::{ marker::Sized, // :sized + ops::{Fn, FnMut, FnOnce}, // :fn option::Option::{self, None, Some}, // :option result::Result::{self, Err, Ok}, // :result };