aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-06-16 10:21:29 +0100
committerGitHub <[email protected]>2021-06-16 10:21:29 +0100
commit8022e6ad6f951d86ce8f24335053fcaaeb7b296b (patch)
tree88eefd90d8cca113dfe2758def3fb3266ce56a68
parent2980fd430dbe30d5d8fd28091a8c47b3ffd4008f (diff)
parent8a4d9bb80a484193dc24c474af30d0d0e091963b (diff)
Merge #9297
9297: internal: add fn to minicore r=matklad a=matklad bors r+ 🤖 Co-authored-by: Aleksey Kladov <[email protected]>
-rw-r--r--crates/hir_ty/src/tests/patterns.rs76
-rw-r--r--crates/hir_ty/src/tests/regression.rs64
-rw-r--r--crates/hir_ty/src/tests/traits.rs392
-rw-r--r--crates/ide/src/hover.rs4
-rw-r--r--crates/ide_completion/src/render.rs22
-rw-r--r--crates/test_utils/src/fixture.rs58
-rw-r--r--crates/test_utils/src/minicore.rs36
7 files changed, 307 insertions, 345 deletions
diff --git a/crates/hir_ty/src/tests/patterns.rs b/crates/hir_ty/src/tests/patterns.rs
index aa513c56d..5adbe9c45 100644
--- a/crates/hir_ty/src/tests/patterns.rs
+++ b/crates/hir_ty/src/tests/patterns.rs
@@ -571,48 +571,44 @@ fn main() {
571fn match_ergonomics_in_closure_params() { 571fn match_ergonomics_in_closure_params() {
572 check_infer( 572 check_infer(
573 r#" 573 r#"
574 #[lang = "fn_once"] 574//- minicore: fn
575 trait FnOnce<Args> { 575fn foo<T, U, F: FnOnce(T) -> U>(t: T, f: F) -> U { loop {} }
576 type Output;
577 }
578
579 fn foo<T, U, F: FnOnce(T) -> U>(t: T, f: F) -> U { loop {} }
580 576
581 fn test() { 577fn test() {
582 foo(&(1, "a"), |&(x, y)| x); // normal, no match ergonomics 578 foo(&(1, "a"), |&(x, y)| x); // normal, no match ergonomics
583 foo(&(1, "a"), |(x, y)| x); 579 foo(&(1, "a"), |(x, y)| x);
584 } 580}
585 "#, 581"#,
586 expect![[r#" 582 expect![[r#"
587 93..94 't': T 583 32..33 't': T
588 99..100 'f': F 584 38..39 'f': F
589 110..121 '{ loop {} }': U 585 49..60 '{ loop {} }': U
590 112..119 'loop {}': ! 586 51..58 'loop {}': !
591 117..119 '{}': () 587 56..58 '{}': ()
592 133..232 '{ ... x); }': () 588 72..171 '{ ... x); }': ()
593 139..142 'foo': fn foo<&(i32, &str), i32, |&(i32, &str)| -> i32>(&(i32, &str), |&(i32, &str)| -> i32) -> i32 589 78..81 'foo': fn foo<&(i32, &str), i32, |&(i32, &str)| -> i32>(&(i32, &str), |&(i32, &str)| -> i32) -> i32
594 139..166 'foo(&(...y)| x)': i32 590 78..105 'foo(&(...y)| x)': i32
595 143..152 '&(1, "a")': &(i32, &str) 591 82..91 '&(1, "a")': &(i32, &str)
596 144..152 '(1, "a")': (i32, &str) 592 83..91 '(1, "a")': (i32, &str)
597 145..146 '1': i32 593 84..85 '1': i32
598 148..151 '"a"': &str 594 87..90 '"a"': &str
599 154..165 '|&(x, y)| x': |&(i32, &str)| -> i32 595 93..104 '|&(x, y)| x': |&(i32, &str)| -> i32
600 155..162 '&(x, y)': &(i32, &str) 596 94..101 '&(x, y)': &(i32, &str)
601 156..162 '(x, y)': (i32, &str) 597 95..101 '(x, y)': (i32, &str)
602 157..158 'x': i32 598 96..97 'x': i32
603 160..161 'y': &str 599 99..100 'y': &str
604 164..165 'x': i32 600 103..104 'x': i32
605 203..206 'foo': fn foo<&(i32, &str), &i32, |&(i32, &str)| -> &i32>(&(i32, &str), |&(i32, &str)| -> &i32) -> &i32 601 142..145 'foo': fn foo<&(i32, &str), &i32, |&(i32, &str)| -> &i32>(&(i32, &str), |&(i32, &str)| -> &i32) -> &i32
606 203..229 'foo(&(...y)| x)': &i32 602 142..168 'foo(&(...y)| x)': &i32
607 207..216 '&(1, "a")': &(i32, &str) 603 146..155 '&(1, "a")': &(i32, &str)
608 208..216 '(1, "a")': (i32, &str) 604 147..155 '(1, "a")': (i32, &str)
609 209..210 '1': i32 605 148..149 '1': i32
610 212..215 '"a"': &str 606 151..154 '"a"': &str
611 218..228 '|(x, y)| x': |&(i32, &str)| -> &i32 607 157..167 '|(x, y)| x': |&(i32, &str)| -> &i32
612 219..225 '(x, y)': (i32, &str) 608 158..164 '(x, y)': (i32, &str)
613 220..221 'x': &i32 609 159..160 'x': &i32
614 223..224 'y': &&str 610 162..163 'y': &&str
615 227..228 'x': &i32 611 166..167 'x': &i32
616 "#]], 612 "#]],
617 ); 613 );
618} 614}
diff --git a/crates/hir_ty/src/tests/regression.rs b/crates/hir_ty/src/tests/regression.rs
index abd9c385a..1edec1615 100644
--- a/crates/hir_ty/src/tests/regression.rs
+++ b/crates/hir_ty/src/tests/regression.rs
@@ -884,41 +884,37 @@ fn issue_4966() {
884fn issue_6628() { 884fn issue_6628() {
885 check_infer( 885 check_infer(
886 r#" 886 r#"
887 #[lang = "fn_once"] 887//- minicore: fn
888 pub trait FnOnce<Args> { 888struct S<T>();
889 type Output; 889impl<T> S<T> {
890 } 890 fn f(&self, _t: T) {}
891 891 fn g<F: FnOnce(&T)>(&self, _f: F) {}
892 struct S<T>(); 892}
893 impl<T> S<T> { 893fn main() {
894 fn f(&self, _t: T) {} 894 let s = S();
895 fn g<F: FnOnce(&T)>(&self, _f: F) {} 895 s.g(|_x| {});
896 } 896 s.f(10);
897 fn main() { 897}
898 let s = S(); 898"#,
899 s.g(|_x| {});
900 s.f(10);
901 }
902 "#,
903 expect![[r#" 899 expect![[r#"
904 105..109 'self': &S<T> 900 40..44 'self': &S<T>
905 111..113 '_t': T 901 46..48 '_t': T
906 118..120 '{}': () 902 53..55 '{}': ()
907 146..150 'self': &S<T> 903 81..85 'self': &S<T>
908 152..154 '_f': F 904 87..89 '_f': F
909 159..161 '{}': () 905 94..96 '{}': ()
910 174..225 '{ ...10); }': () 906 109..160 '{ ...10); }': ()
911 184..185 's': S<i32> 907 119..120 's': S<i32>
912 188..189 'S': S<i32>() -> S<i32> 908 123..124 'S': S<i32>() -> S<i32>
913 188..191 'S()': S<i32> 909 123..126 'S()': S<i32>
914 197..198 's': S<i32> 910 132..133 's': S<i32>
915 197..209 's.g(|_x| {})': () 911 132..144 's.g(|_x| {})': ()
916 201..208 '|_x| {}': |&i32| -> () 912 136..143 '|_x| {}': |&i32| -> ()
917 202..204 '_x': &i32 913 137..139 '_x': &i32
918 206..208 '{}': () 914 141..143 '{}': ()
919 215..216 's': S<i32> 915 150..151 's': S<i32>
920 215..222 's.f(10)': () 916 150..157 's.f(10)': ()
921 219..221 '10': i32 917 154..156 '10': i32
922 "#]], 918 "#]],
923 ); 919 );
924} 920}
diff --git a/crates/hir_ty/src/tests/traits.rs b/crates/hir_ty/src/tests/traits.rs
index 65fed02d2..065cca74f 100644
--- a/crates/hir_ty/src/tests/traits.rs
+++ b/crates/hir_ty/src/tests/traits.rs
@@ -1846,11 +1846,7 @@ fn test() {
1846fn closure_1() { 1846fn closure_1() {
1847 check_infer_with_mismatches( 1847 check_infer_with_mismatches(
1848 r#" 1848 r#"
1849#[lang = "fn_once"] 1849//- minicore: fn
1850trait FnOnce<Args> {
1851 type Output;
1852}
1853
1854enum Option<T> { Some(T), None } 1850enum Option<T> { Some(T), None }
1855impl<T> Option<T> { 1851impl<T> Option<T> {
1856 fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Option<U> { loop {} } 1852 fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Option<U> { loop {} }
@@ -1863,34 +1859,34 @@ fn test() {
1863 let y: Option<i64> = x.map(|_v| 1); 1859 let y: Option<i64> = x.map(|_v| 1);
1864}"#, 1860}"#,
1865 expect![[r#" 1861 expect![[r#"
1866 147..151 'self': Option<T> 1862 86..90 'self': Option<T>
1867 153..154 'f': F 1863 92..93 'f': F
1868 172..183 '{ loop {} }': Option<U> 1864 111..122 '{ loop {} }': Option<U>
1869 174..181 'loop {}': ! 1865 113..120 'loop {}': !
1870 179..181 '{}': () 1866 118..120 '{}': ()
1871 197..316 '{ ... 1); }': () 1867 136..255 '{ ... 1); }': ()
1872 207..208 'x': Option<u32> 1868 146..147 'x': Option<u32>
1873 211..223 'Option::Some': Some<u32>(u32) -> Option<u32> 1869 150..162 'Option::Some': Some<u32>(u32) -> Option<u32>
1874 211..229 'Option...(1u32)': Option<u32> 1870 150..168 'Option...(1u32)': Option<u32>
1875 224..228 '1u32': u32 1871 163..167 '1u32': u32
1876 235..236 'x': Option<u32> 1872 174..175 'x': Option<u32>
1877 235..251 'x.map(...v + 1)': Option<u32> 1873 174..190 'x.map(...v + 1)': Option<u32>
1878 241..250 '|v| v + 1': |u32| -> u32 1874 180..189 '|v| v + 1': |u32| -> u32
1879 242..243 'v': u32 1875 181..182 'v': u32
1880 245..246 'v': u32 1876 184..185 'v': u32
1881 245..250 'v + 1': u32 1877 184..189 'v + 1': u32
1882 249..250 '1': u32 1878 188..189 '1': u32
1883 257..258 'x': Option<u32> 1879 196..197 'x': Option<u32>
1884 257..273 'x.map(... 1u64)': Option<u64> 1880 196..212 'x.map(... 1u64)': Option<u64>
1885 263..272 '|_v| 1u64': |u32| -> u64 1881 202..211 '|_v| 1u64': |u32| -> u64
1886 264..266 '_v': u32 1882 203..205 '_v': u32
1887 268..272 '1u64': u64 1883 207..211 '1u64': u64
1888 283..284 'y': Option<i64> 1884 222..223 'y': Option<i64>
1889 300..301 'x': Option<u32> 1885 239..240 'x': Option<u32>
1890 300..313 'x.map(|_v| 1)': Option<i64> 1886 239..252 'x.map(|_v| 1)': Option<i64>
1891 306..312 '|_v| 1': |u32| -> i64 1887 245..251 '|_v| 1': |u32| -> i64
1892 307..309 '_v': u32 1888 246..248 '_v': u32
1893 311..312 '1': i64 1889 250..251 '1': i64
1894 "#]], 1890 "#]],
1895 ); 1891 );
1896} 1892}
@@ -1964,11 +1960,7 @@ fn test<F: FnOnce(u32) -> u64>(f: F) {
1964fn closure_as_argument_inference_order() { 1960fn closure_as_argument_inference_order() {
1965 check_infer_with_mismatches( 1961 check_infer_with_mismatches(
1966 r#" 1962 r#"
1967#[lang = "fn_once"] 1963//- minicore: fn
1968trait FnOnce<Args> {
1969 type Output;
1970}
1971
1972fn foo1<T, U, F: FnOnce(T) -> U>(x: T, f: F) -> U { loop {} } 1964fn foo1<T, U, F: FnOnce(T) -> U>(x: T, f: F) -> U { loop {} }
1973fn foo2<T, U, F: FnOnce(T) -> U>(f: F, x: T) -> U { loop {} } 1965fn foo2<T, U, F: FnOnce(T) -> U>(f: F, x: T) -> U { loop {} }
1974 1966
@@ -1987,62 +1979,62 @@ fn test() {
1987 let x4 = S.foo2(|s| s.method(), S); 1979 let x4 = S.foo2(|s| s.method(), S);
1988}"#, 1980}"#,
1989 expect![[r#" 1981 expect![[r#"
1990 94..95 'x': T 1982 33..34 'x': T
1991 100..101 'f': F 1983 39..40 'f': F
1992 111..122 '{ loop {} }': U 1984 50..61 '{ loop {} }': U
1993 113..120 'loop {}': ! 1985 52..59 'loop {}': !
1994 118..120 '{}': () 1986 57..59 '{}': ()
1995 156..157 'f': F 1987 95..96 'f': F
1996 162..163 'x': T 1988 101..102 'x': T
1997 173..184 '{ loop {} }': U 1989 112..123 '{ loop {} }': U
1998 175..182 'loop {}': ! 1990 114..121 'loop {}': !
1999 180..182 '{}': () 1991 119..121 '{}': ()
2000 219..223 'self': S 1992 158..162 'self': S
2001 271..275 'self': S 1993 210..214 'self': S
2002 277..278 'x': T 1994 216..217 'x': T
2003 283..284 'f': F 1995 222..223 'f': F
2004 294..305 '{ loop {} }': U 1996 233..244 '{ loop {} }': U
2005 296..303 'loop {}': ! 1997 235..242 'loop {}': !
2006 301..303 '{}': () 1998 240..242 '{}': ()
2007 343..347 'self': S 1999 282..286 'self': S
2008 349..350 'f': F 2000 288..289 'f': F
2009 355..356 'x': T 2001 294..295 'x': T
2010 366..377 '{ loop {} }': U 2002 305..316 '{ loop {} }': U
2011 368..375 'loop {}': ! 2003 307..314 'loop {}': !
2012 373..375 '{}': () 2004 312..314 '{}': ()
2013 391..550 '{ ... S); }': () 2005 330..489 '{ ... S); }': ()
2014 401..403 'x1': u64 2006 340..342 'x1': u64
2015 406..410 'foo1': fn foo1<S, u64, |S| -> u64>(S, |S| -> u64) -> u64 2007 345..349 'foo1': fn foo1<S, u64, |S| -> u64>(S, |S| -> u64) -> u64
2016 406..429 'foo1(S...hod())': u64 2008 345..368 'foo1(S...hod())': u64
2017 411..412 'S': S 2009 350..351 'S': S
2018 414..428 '|s| s.method()': |S| -> u64 2010 353..367 '|s| s.method()': |S| -> u64
2019 415..416 's': S 2011 354..355 's': S
2020 418..419 's': S 2012 357..358 's': S
2021 418..428 's.method()': u64 2013 357..367 's.method()': u64
2022 439..441 'x2': u64 2014 378..380 'x2': u64
2023 444..448 'foo2': fn foo2<S, u64, |S| -> u64>(|S| -> u64, S) -> u64 2015 383..387 'foo2': fn foo2<S, u64, |S| -> u64>(|S| -> u64, S) -> u64
2024 444..467 'foo2(|...(), S)': u64 2016 383..406 'foo2(|...(), S)': u64
2025 449..463 '|s| s.method()': |S| -> u64 2017 388..402 '|s| s.method()': |S| -> u64
2026 450..451 's': S 2018 389..390 's': S
2027 453..454 's': S 2019 392..393 's': S
2028 453..463 's.method()': u64 2020 392..402 's.method()': u64
2029 465..466 'S': S 2021 404..405 'S': S
2030 477..479 'x3': u64 2022 416..418 'x3': u64
2031 482..483 'S': S 2023 421..422 'S': S
2032 482..507 'S.foo1...hod())': u64 2024 421..446 'S.foo1...hod())': u64
2033 489..490 'S': S 2025 428..429 'S': S
2034 492..506 '|s| s.method()': |S| -> u64 2026 431..445 '|s| s.method()': |S| -> u64
2035 493..494 's': S 2027 432..433 's': S
2036 496..497 's': S 2028 435..436 's': S
2037 496..506 's.method()': u64 2029 435..445 's.method()': u64
2038 517..519 'x4': u64 2030 456..458 'x4': u64
2039 522..523 'S': S 2031 461..462 'S': S
2040 522..547 'S.foo2...(), S)': u64 2032 461..486 'S.foo2...(), S)': u64
2041 529..543 '|s| s.method()': |S| -> u64 2033 468..482 '|s| s.method()': |S| -> u64
2042 530..531 's': S 2034 469..470 's': S
2043 533..534 's': S 2035 472..473 's': S
2044 533..543 's.method()': u64 2036 472..482 's.method()': u64
2045 545..546 'S': S 2037 484..485 'S': S
2046 "#]], 2038 "#]],
2047 ); 2039 );
2048} 2040}
@@ -2051,11 +2043,7 @@ fn test() {
2051fn fn_item_fn_trait() { 2043fn fn_item_fn_trait() {
2052 check_types( 2044 check_types(
2053 r#" 2045 r#"
2054#[lang = "fn_once"] 2046//- minicore: fn
2055trait FnOnce<Args> {
2056 type Output;
2057}
2058
2059struct S; 2047struct S;
2060 2048
2061fn foo() -> S {} 2049fn foo() -> S {}
@@ -2494,12 +2482,7 @@ fn test() -> impl Trait<i32> {
2494fn assoc_types_from_bounds() { 2482fn assoc_types_from_bounds() {
2495 check_infer( 2483 check_infer(
2496 r#" 2484 r#"
2497//- /main.rs 2485//- minicore: fn
2498#[lang = "fn_once"]
2499trait FnOnce<Args> {
2500 type Output;
2501}
2502
2503trait T { 2486trait T {
2504 type O; 2487 type O;
2505} 2488}
@@ -2518,15 +2501,15 @@ fn main() {
2518 f::<(), _>(|z| { z; }); 2501 f::<(), _>(|z| { z; });
2519}"#, 2502}"#,
2520 expect![[r#" 2503 expect![[r#"
2521 133..135 '_v': F 2504 72..74 '_v': F
2522 178..181 '{ }': () 2505 117..120 '{ }': ()
2523 193..224 '{ ... }); }': () 2506 132..163 '{ ... }); }': ()
2524 199..209 'f::<(), _>': fn f<(), |&()| -> ()>(|&()| -> ()) 2507 138..148 'f::<(), _>': fn f<(), |&()| -> ()>(|&()| -> ())
2525 199..221 'f::<()... z; })': () 2508 138..160 'f::<()... z; })': ()
2526 210..220 '|z| { z; }': |&()| -> () 2509 149..159 '|z| { z; }': |&()| -> ()
2527 211..212 'z': &() 2510 150..151 'z': &()
2528 214..220 '{ z; }': () 2511 153..159 '{ z; }': ()
2529 216..217 'z': &() 2512 155..156 'z': &()
2530 "#]], 2513 "#]],
2531 ); 2514 );
2532} 2515}
@@ -2599,17 +2582,7 @@ fn test() {
2599fn iterator_chain() { 2582fn iterator_chain() {
2600 check_infer_with_mismatches( 2583 check_infer_with_mismatches(
2601 r#" 2584 r#"
2602//- /main.rs 2585//- minicore: fn, option
2603#[lang = "fn_once"]
2604trait FnOnce<Args> {
2605 type Output;
2606}
2607#[lang = "fn_mut"]
2608trait FnMut<Args>: FnOnce<Args> { }
2609
2610enum Option<T> { Some(T), None }
2611use Option::*;
2612
2613pub trait Iterator { 2586pub trait Iterator {
2614 type Item; 2587 type Item;
2615 2588
@@ -2669,46 +2642,46 @@ fn main() {
2669 .for_each(|y| { y; }); 2642 .for_each(|y| { y; });
2670}"#, 2643}"#,
2671 expect![[r#" 2644 expect![[r#"
2672 226..230 'self': Self 2645 61..65 'self': Self
2673 232..233 'f': F 2646 67..68 'f': F
2674 317..328 '{ loop {} }': FilterMap<Self, F> 2647 152..163 '{ loop {} }': FilterMap<Self, F>
2675 319..326 'loop {}': ! 2648 154..161 'loop {}': !
2676 324..326 '{}': () 2649 159..161 '{}': ()
2677 349..353 'self': Self 2650 184..188 'self': Self
2678 355..356 'f': F 2651 190..191 'f': F
2679 405..416 '{ loop {} }': () 2652 240..251 '{ loop {} }': ()
2680 407..414 'loop {}': ! 2653 242..249 'loop {}': !
2681 412..414 '{}': () 2654 247..249 '{}': ()
2682 525..529 'self': Self 2655 360..364 'self': Self
2683 854..858 'self': I 2656 689..693 'self': I
2684 865..885 '{ ... }': I 2657 700..720 '{ ... }': I
2685 875..879 'self': I 2658 710..714 'self': I
2686 944..955 '{ loop {} }': Vec<T> 2659 779..790 '{ loop {} }': Vec<T>
2687 946..953 'loop {}': ! 2660 781..788 'loop {}': !
2688 951..953 '{}': () 2661 786..788 '{}': ()
2689 1142..1269 '{ ... }); }': () 2662 977..1104 '{ ... }); }': ()
2690 1148..1163 'Vec::<i32>::new': fn new<i32>() -> Vec<i32> 2663 983..998 'Vec::<i32>::new': fn new<i32>() -> Vec<i32>
2691 1148..1165 'Vec::<...:new()': Vec<i32> 2664 983..1000 'Vec::<...:new()': Vec<i32>
2692 1148..1177 'Vec::<...iter()': IntoIter<i32> 2665 983..1012 'Vec::<...iter()': IntoIter<i32>
2693 1148..1240 'Vec::<...one })': FilterMap<IntoIter<i32>, |i32| -> Option<u32>> 2666 983..1075 'Vec::<...one })': FilterMap<IntoIter<i32>, |i32| -> Option<u32>>
2694 1148..1266 'Vec::<... y; })': () 2667 983..1101 'Vec::<... y; })': ()
2695 1194..1239 '|x| if...None }': |i32| -> Option<u32> 2668 1029..1074 '|x| if...None }': |i32| -> Option<u32>
2696 1195..1196 'x': i32 2669 1030..1031 'x': i32
2697 1198..1239 'if x >...None }': Option<u32> 2670 1033..1074 'if x >...None }': Option<u32>
2698 1201..1202 'x': i32 2671 1036..1037 'x': i32
2699 1201..1206 'x > 0': bool 2672 1036..1041 'x > 0': bool
2700 1205..1206 '0': i32 2673 1040..1041 '0': i32
2701 1207..1225 '{ Some...u32) }': Option<u32> 2674 1042..1060 '{ Some...u32) }': Option<u32>
2702 1209..1213 'Some': Some<u32>(u32) -> Option<u32> 2675 1044..1048 'Some': Some<u32>(u32) -> Option<u32>
2703 1209..1223 'Some(x as u32)': Option<u32> 2676 1044..1058 'Some(x as u32)': Option<u32>
2704 1214..1215 'x': i32 2677 1049..1050 'x': i32
2705 1214..1222 'x as u32': u32 2678 1049..1057 'x as u32': u32
2706 1231..1239 '{ None }': Option<u32> 2679 1066..1074 '{ None }': Option<u32>
2707 1233..1237 'None': Option<u32> 2680 1068..1072 'None': Option<u32>
2708 1255..1265 '|y| { y; }': |u32| -> () 2681 1090..1100 '|y| { y; }': |u32| -> ()
2709 1256..1257 'y': u32 2682 1091..1092 'y': u32
2710 1259..1265 '{ y; }': () 2683 1094..1100 '{ y; }': ()
2711 1261..1262 'y': u32 2684 1096..1097 'y': u32
2712 "#]], 2685 "#]],
2713 ); 2686 );
2714} 2687}
@@ -2995,45 +2968,23 @@ fn foo() {
2995fn infer_fn_trait_arg() { 2968fn infer_fn_trait_arg() {
2996 check_infer_with_mismatches( 2969 check_infer_with_mismatches(
2997 r#" 2970 r#"
2998 //- /lib.rs deps:std 2971//- minicore: fn, option
2999 2972fn foo<F, T>(f: F) -> T
3000 #[lang = "fn_once"] 2973where
3001 pub trait FnOnce<Args> { 2974 F: Fn(Option<i32>) -> T,
3002 type Output; 2975{
3003 2976 let s = None;
3004 extern "rust-call" fn call_once(&self, args: Args) -> Self::Output; 2977 f(s)
3005 } 2978}
3006 2979"#,
3007 #[lang = "fn"]
3008 pub trait Fn<Args>:FnOnce<Args> {
3009 extern "rust-call" fn call(&self, args: Args) -> Self::Output;
3010 }
3011
3012 enum Option<T> {
3013 None,
3014 Some(T)
3015 }
3016
3017 fn foo<F, T>(f: F) -> T
3018 where
3019 F: Fn(Option<i32>) -> T,
3020 {
3021 let s = None;
3022 f(s)
3023 }
3024 "#,
3025 expect![[r#" 2980 expect![[r#"
3026 101..105 'self': &Self 2981 13..14 'f': F
3027 107..111 'args': Args 2982 59..89 '{ ...f(s) }': T
3028 220..224 'self': &Self 2983 69..70 's': Option<i32>
3029 226..230 'args': Args 2984 73..77 'None': Option<i32>
3030 313..314 'f': F 2985 83..84 'f': F
3031 359..389 '{ ...f(s) }': T 2986 83..87 'f(s)': T
3032 369..370 's': Option<i32> 2987 85..86 's': Option<i32>
3033 373..377 'None': Option<i32>
3034 383..384 'f': F
3035 383..387 'f(s)': T
3036 385..386 's': Option<i32>
3037 "#]], 2988 "#]],
3038 ); 2989 );
3039} 2990}
@@ -3112,17 +3063,7 @@ fn foo() {
3112fn infer_dyn_fn_output() { 3063fn infer_dyn_fn_output() {
3113 check_types( 3064 check_types(
3114 r#" 3065 r#"
3115#[lang = "fn_once"] 3066//- minicore: fn
3116pub trait FnOnce<Args> {
3117 type Output;
3118 extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
3119}
3120
3121#[lang = "fn"]
3122pub trait Fn<Args>: FnOnce<Args> {
3123 extern "rust-call" fn call(&self, args: Args) -> Self::Output;
3124}
3125
3126fn foo() { 3067fn foo() {
3127 let f: &dyn Fn() -> i32; 3068 let f: &dyn Fn() -> i32;
3128 f(); 3069 f();
@@ -3135,12 +3076,7 @@ fn foo() {
3135fn infer_dyn_fn_once_output() { 3076fn infer_dyn_fn_once_output() {
3136 check_types( 3077 check_types(
3137 r#" 3078 r#"
3138#[lang = "fn_once"] 3079//- minicore: fn
3139pub trait FnOnce<Args> {
3140 type Output;
3141 extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
3142}
3143
3144fn foo() { 3080fn foo() {
3145 let f: dyn FnOnce() -> i32; 3081 let f: dyn FnOnce() -> i32;
3146 f(); 3082 f();
@@ -3575,20 +3511,16 @@ fn main() {
3575fn fn_returning_unit() { 3511fn fn_returning_unit() {
3576 check_infer_with_mismatches( 3512 check_infer_with_mismatches(
3577 r#" 3513 r#"
3578#[lang = "fn_once"] 3514//- minicore: fn
3579trait FnOnce<Args> {
3580 type Output;
3581}
3582
3583fn test<F: FnOnce()>(f: F) { 3515fn test<F: FnOnce()>(f: F) {
3584 let _: () = f(); 3516 let _: () = f();
3585}"#, 3517}"#,
3586 expect![[r#" 3518 expect![[r#"
3587 82..83 'f': F 3519 21..22 'f': F
3588 88..112 '{ ...f(); }': () 3520 27..51 '{ ...f(); }': ()
3589 98..99 '_': () 3521 37..38 '_': ()
3590 106..107 'f': F 3522 45..46 'f': F
3591 106..109 'f()': () 3523 45..48 'f()': ()
3592 "#]], 3524 "#]],
3593 ); 3525 );
3594} 3526}
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs
index 14cf94d60..529cf5f33 100644
--- a/crates/ide/src/hover.rs
+++ b/crates/ide/src/hover.rs
@@ -3016,8 +3016,8 @@ fn foo() {
3016 file_id: FileId( 3016 file_id: FileId(
3017 1, 3017 1,
3018 ), 3018 ),
3019 full_range: 244..426, 3019 full_range: 245..427,
3020 focus_range: 283..289, 3020 focus_range: 284..290,
3021 name: "Future", 3021 name: "Future",
3022 kind: Trait, 3022 kind: Trait,
3023 description: "pub trait Future", 3023 description: "pub trait Future",
diff --git a/crates/ide_completion/src/render.rs b/crates/ide_completion/src/render.rs
index 3eb51e80b..fac83b650 100644
--- a/crates/ide_completion/src/render.rs
+++ b/crates/ide_completion/src/render.rs
@@ -1191,21 +1191,11 @@ fn main() {
1191 fn suggest_deref_mut() { 1191 fn suggest_deref_mut() {
1192 check_relevance( 1192 check_relevance(
1193 r#" 1193 r#"
1194#[lang = "deref"] 1194//- minicore: deref_mut
1195trait Deref {
1196 type Target;
1197 fn deref(&self) -> &Self::Target;
1198}
1199
1200#[lang = "deref_mut"]
1201pub trait DerefMut: Deref {
1202 fn deref_mut(&mut self) -> &mut Self::Target;
1203}
1204
1205struct S; 1195struct S;
1206struct T(S); 1196struct T(S);
1207 1197
1208impl Deref for T { 1198impl core::ops::Deref for T {
1209 type Target = S; 1199 type Target = S;
1210 1200
1211 fn deref(&self) -> &Self::Target { 1201 fn deref(&self) -> &Self::Target {
@@ -1213,7 +1203,7 @@ impl Deref for T {
1213 } 1203 }
1214} 1204}
1215 1205
1216impl DerefMut for T { 1206impl core::ops::DerefMut for T {
1217 fn deref_mut(&mut self) -> &mut Self::Target { 1207 fn deref_mut(&mut self) -> &mut Self::Target {
1218 &mut self.0 1208 &mut self.0
1219 } 1209 }
@@ -1232,12 +1222,12 @@ fn main() {
1232 lc m [local] 1222 lc m [local]
1233 lc t [local] 1223 lc t [local]
1234 lc &mut t [type+local] 1224 lc &mut t [type+local]
1235 tt DerefMut []
1236 tt Deref []
1237 fn foo(…) []
1238 st T [] 1225 st T []
1239 st S [] 1226 st S []
1240 fn main() [] 1227 fn main() []
1228 fn foo(…) []
1229 md core []
1230 tt Sized []
1241 "#]], 1231 "#]],
1242 ) 1232 )
1243 } 1233 }
diff --git a/crates/test_utils/src/fixture.rs b/crates/test_utils/src/fixture.rs
index 6ba112de8..005a5c092 100644
--- a/crates/test_utils/src/fixture.rs
+++ b/crates/test_utils/src/fixture.rs
@@ -129,8 +129,18 @@ impl Fixture {
129 if line.starts_with("//-") { 129 if line.starts_with("//-") {
130 let meta = Fixture::parse_meta_line(line); 130 let meta = Fixture::parse_meta_line(line);
131 res.push(meta) 131 res.push(meta)
132 } else if let Some(entry) = res.last_mut() { 132 } else {
133 entry.text.push_str(line); 133 if line.starts_with("// ")
134 && line.contains(":")
135 && !line.contains("::")
136 && line.chars().all(|it| !it.is_uppercase())
137 {
138 panic!("looks like invalid metadata line: {:?}", line)
139 }
140
141 if let Some(entry) = res.last_mut() {
142 entry.text.push_str(line);
143 }
134 } 144 }
135 } 145 }
136 146
@@ -154,7 +164,9 @@ impl Fixture {
154 let mut env = FxHashMap::default(); 164 let mut env = FxHashMap::default();
155 let mut introduce_new_source_root = false; 165 let mut introduce_new_source_root = false;
156 for component in components[1..].iter() { 166 for component in components[1..].iter() {
157 let (key, value) = component.split_once(':').unwrap(); 167 let (key, value) = component
168 .split_once(':')
169 .unwrap_or_else(|| panic!("invalid meta line: {:?}", meta));
158 match key { 170 match key {
159 "crate" => krate = Some(value.to_string()), 171 "crate" => krate = Some(value.to_string()),
160 "deps" => deps = value.split(',').map(|it| it.to_string()).collect(), 172 "deps" => deps = value.split(',').map(|it| it.to_string()).collect(),
@@ -276,38 +288,44 @@ impl MiniCore {
276 } 288 }
277 } 289 }
278 290
279 let mut curr_region = ""; 291 let mut active_regions = Vec::new();
280 let mut seen_regions = Vec::new(); 292 let mut seen_regions = Vec::new();
281 for line in lines { 293 for line in lines {
282 let trimmed = line.trim(); 294 let trimmed = line.trim();
283 if let Some(region) = trimmed.strip_prefix("// region:") { 295 if let Some(region) = trimmed.strip_prefix("// region:") {
284 assert_eq!(curr_region, ""); 296 active_regions.push(region);
285 curr_region = region;
286 continue; 297 continue;
287 } 298 }
288 if let Some(region) = trimmed.strip_prefix("// endregion:") { 299 if let Some(region) = trimmed.strip_prefix("// endregion:") {
289 assert_eq!(curr_region, region); 300 let prev = active_regions.pop().unwrap();
290 curr_region = ""; 301 assert_eq!(prev, region);
291 continue; 302 continue;
292 } 303 }
293 seen_regions.push(curr_region);
294 304
295 let mut flag = curr_region; 305 let mut line_region = false;
296 if let Some(idx) = trimmed.find("// :") { 306 if let Some(idx) = trimmed.find("// :") {
297 flag = &trimmed[idx + "// :".len()..]; 307 line_region = true;
308 active_regions.push(&trimmed[idx + "// :".len()..]);
298 } 309 }
299 310
300 let skip = if flag == "" { 311 let mut keep = true;
301 false 312 for &region in &active_regions {
302 } else { 313 assert!(
303 assert!(!flag.starts_with(' '), "region marker starts with a space: {:?}", flag); 314 !region.starts_with(' '),
304 self.assert_valid_flag(flag); 315 "region marker starts with a space: {:?}",
305 !self.has_flag(flag) 316 region
306 }; 317 );
318 self.assert_valid_flag(region);
319 seen_regions.push(region);
320 keep &= self.has_flag(region);
321 }
307 322
308 if !skip { 323 if keep {
309 buf.push_str(line) 324 buf.push_str(line)
310 } 325 }
326 if line_region {
327 active_regions.pop().unwrap();
328 }
311 } 329 }
312 330
313 for flag in &self.valid_flags { 331 for flag in &self.valid_flags {
@@ -315,7 +333,7 @@ impl MiniCore {
315 panic!("unused minicore flag: {:?}", flag); 333 panic!("unused minicore flag: {:?}", flag);
316 } 334 }
317 } 335 }
318 336 format!("{}", buf);
319 buf 337 buf
320 } 338 }
321} 339}
diff --git a/crates/test_utils/src/minicore.rs b/crates/test_utils/src/minicore.rs
index 5ff60178c..e04ca58d2 100644
--- a/crates/test_utils/src/minicore.rs
+++ b/crates/test_utils/src/minicore.rs
@@ -9,11 +9,13 @@
9//! 9//!
10//! Available flags: 10//! Available flags:
11//! sized: 11//! sized:
12//! unsize: sized
13//! coerce_unsized: unsize
12//! slice: 14//! slice:
13//! range: 15//! range:
14//! unsize: sized
15//! deref: sized 16//! deref: sized
16//! coerce_unsized: unsize 17//! deref_mut: deref
18//! fn:
17//! pin: 19//! pin:
18//! future: pin 20//! future: pin
19//! option: 21//! option:
@@ -64,9 +66,16 @@ pub mod ops {
64 type Target: ?Sized; 66 type Target: ?Sized;
65 fn deref(&self) -> &Self::Target; 67 fn deref(&self) -> &Self::Target;
66 } 68 }
69 // region:deref_mut
70 #[lang = "deref_mut"]
71 pub trait DerefMut: Deref {
72 fn deref_mut(&mut self) -> &mut Self::Target;
73 }
74 // endregion:deref_mut
67 } 75 }
68 pub use self::deref::Deref; 76 pub use self::deref::Deref;
69 // endregion:deref 77 pub use self::deref::DerefMut; //:deref_mut
78 // endregion:deref
70 79
71 // region:range 80 // region:range
72 mod range { 81 mod range {
@@ -104,6 +113,26 @@ pub mod ops {
104 pub use self::range::{Range, RangeFrom, RangeFull, RangeTo}; 113 pub use self::range::{Range, RangeFrom, RangeFull, RangeTo};
105 pub use self::range::{RangeInclusive, RangeToInclusive}; 114 pub use self::range::{RangeInclusive, RangeToInclusive};
106 // endregion:range 115 // endregion:range
116
117 // region:fn
118 mod function {
119 #[lang = "fn"]
120 #[fundamental]
121 pub trait Fn<Args>: FnMut<Args> {}
122
123 #[lang = "fn_mut"]
124 #[fundamental]
125 pub trait FnMut<Args>: FnOnce<Args> {}
126
127 #[lang = "fn_once"]
128 #[fundamental]
129 pub trait FnOnce<Args> {
130 #[lang = "fn_once_output"]
131 type Output;
132 }
133 }
134 pub use self::function::{Fn, FnMut, FnOnce};
135 // endregion:fn
107} 136}
108 137
109// region:slice 138// region:slice
@@ -181,6 +210,7 @@ pub mod prelude {
181 pub mod v1 { 210 pub mod v1 {
182 pub use crate::{ 211 pub use crate::{
183 marker::Sized, // :sized 212 marker::Sized, // :sized
213 ops::{Fn, FnMut, FnOnce}, // :fn
184 option::Option::{self, None, Some}, // :option 214 option::Option::{self, None, Some}, // :option
185 result::Result::{self, Err, Ok}, // :result 215 result::Result::{self, Err, Ok}, // :result
186 }; 216 };