aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/base_db/src/fixture.rs31
-rw-r--r--crates/hir_ty/src/tests/coercion.rs629
-rw-r--r--crates/hir_ty/src/tests/method_resolution.rs99
-rw-r--r--crates/hir_ty/src/tests/regression.rs98
-rw-r--r--crates/hir_ty/src/tests/simple.rs767
-rw-r--r--crates/hir_ty/src/tests/traits.rs124
-rw-r--r--crates/ide/src/hover.rs15
-rw-r--r--crates/ide_completion/src/completions/keyword.rs20
-rw-r--r--crates/ide_completion/src/render.rs12
-rw-r--r--crates/rust-analyzer/tests/slow-tests/support.rs4
-rw-r--r--crates/test_utils/src/fixture.rs168
-rw-r--r--crates/test_utils/src/lib.rs5
-rw-r--r--crates/test_utils/src/minicore.rs204
13 files changed, 1149 insertions, 1027 deletions
diff --git a/crates/base_db/src/fixture.rs b/crates/base_db/src/fixture.rs
index 1b17db102..d56b20b83 100644
--- a/crates/base_db/src/fixture.rs
+++ b/crates/base_db/src/fixture.rs
@@ -9,8 +9,8 @@ use test_utils::{
9use vfs::{file_set::FileSet, VfsPath}; 9use vfs::{file_set::FileSet, VfsPath};
10 10
11use crate::{ 11use crate::{
12 input::CrateName, Change, CrateGraph, CrateId, Edition, Env, FileId, FilePosition, FileRange, 12 input::CrateName, Change, CrateDisplayName, CrateGraph, CrateId, Edition, Env, FileId,
13 SourceDatabaseExt, SourceRoot, SourceRootId, 13 FilePosition, FileRange, SourceDatabaseExt, SourceRoot, SourceRootId,
14}; 14};
15 15
16pub const WORKSPACE: SourceRootId = SourceRootId(0); 16pub const WORKSPACE: SourceRootId = SourceRootId(0);
@@ -81,7 +81,7 @@ pub struct ChangeFixture {
81 81
82impl ChangeFixture { 82impl ChangeFixture {
83 pub fn parse(ra_fixture: &str) -> ChangeFixture { 83 pub fn parse(ra_fixture: &str) -> ChangeFixture {
84 let fixture = Fixture::parse(ra_fixture); 84 let (mini_core, fixture) = Fixture::parse(ra_fixture);
85 let mut change = Change::new(); 85 let mut change = Change::new();
86 86
87 let mut files = Vec::new(); 87 let mut files = Vec::new();
@@ -166,6 +166,31 @@ impl ChangeFixture {
166 } 166 }
167 } 167 }
168 168
169 if let Some(mini_core) = mini_core {
170 let core_file = file_id;
171 file_id.0 += 1;
172
173 let mut fs = FileSet::default();
174 fs.insert(core_file, VfsPath::new_virtual_path("/sysroot/core/lib.rs".to_string()));
175 roots.push(SourceRoot::new_library(fs));
176
177 change.change_file(core_file, Some(Arc::new(mini_core.source_code())));
178
179 let all_crates = crate_graph.crates_in_topological_order();
180
181 let core_crate = crate_graph.add_crate_root(
182 core_file,
183 Edition::Edition2021,
184 Some(CrateDisplayName::from_canonical_name("core".to_string())),
185 CfgOptions::default(),
186 Env::default(),
187 Vec::new(),
188 );
189
190 for krate in all_crates {
191 crate_graph.add_dep(krate, CrateName::new("core").unwrap(), core_crate).unwrap();
192 }
193 }
169 roots.push(SourceRoot::new_local(mem::take(&mut file_set))); 194 roots.push(SourceRoot::new_local(mem::take(&mut file_set)));
170 change.set_roots(roots); 195 change.set_roots(roots);
171 change.set_crate_graph(crate_graph); 196 change.set_crate_graph(crate_graph);
diff --git a/crates/hir_ty/src/tests/coercion.rs b/crates/hir_ty/src/tests/coercion.rs
index 4f859fc85..713b74165 100644
--- a/crates/hir_ty/src/tests/coercion.rs
+++ b/crates/hir_ty/src/tests/coercion.rs
@@ -23,38 +23,29 @@ fn infer_block_expr_type_mismatch() {
23fn coerce_places() { 23fn coerce_places() {
24 check_infer( 24 check_infer(
25 r#" 25 r#"
26 struct S<T> { a: T } 26//- minicore: coerce_unsized
27struct S<T> { a: T }
27 28
28 fn f<T>(_: &[T]) -> T { loop {} } 29fn f<T>(_: &[T]) -> T { loop {} }
29 fn g<T>(_: S<&[T]>) -> T { loop {} } 30fn g<T>(_: S<&[T]>) -> T { loop {} }
30 31
31 fn gen<T>() -> *mut [T; 2] { loop {} } 32fn gen<T>() -> *mut [T; 2] { loop {} }
32 fn test1<U>() -> *mut [U] { 33fn test1<U>() -> *mut [U] {
33 gen() 34 gen()
34 } 35}
35
36 fn test2() {
37 let arr: &[u8; 1] = &[1];
38
39 let a: &[_] = arr;
40 let b = f(arr);
41 let c: &[_] = { arr };
42 let d = g(S { a: arr });
43 let e: [&[_]; 1] = [arr];
44 let f: [&[_]; 2] = [arr; 2];
45 let g: (&[_], &[_]) = (arr, arr);
46 }
47 36
48 #[lang = "sized"] 37fn test2() {
49 pub trait Sized {} 38 let arr: &[u8; 1] = &[1];
50 #[lang = "unsize"]
51 pub trait Unsize<T: ?Sized> {}
52 #[lang = "coerce_unsized"]
53 pub trait CoerceUnsized<T> {}
54 39
55 impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} 40 let a: &[_] = arr;
56 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {} 41 let b = f(arr);
57 "#, 42 let c: &[_] = { arr };
43 let d = g(S { a: arr });
44 let e: [&[_]; 1] = [arr];
45 let f: [&[_]; 2] = [arr; 2];
46 let g: (&[_], &[_]) = (arr, arr);
47}
48"#,
58 expect![[r#" 49 expect![[r#"
59 30..31 '_': &[T] 50 30..31 '_': &[T]
60 44..55 '{ loop {} }': T 51 44..55 '{ loop {} }': T
@@ -131,60 +122,52 @@ fn infer_let_stmt_coerce() {
131fn infer_custom_coerce_unsized() { 122fn infer_custom_coerce_unsized() {
132 check_infer( 123 check_infer(
133 r#" 124 r#"
134 struct A<T: ?Sized>(*const T); 125//- minicore: coerce_unsized
135 struct B<T: ?Sized>(*const T); 126use core::{marker::Unsize, ops::CoerceUnsized};
136 struct C<T: ?Sized> { inner: *const T }
137 127
138 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<B<U>> for B<T> {} 128struct A<T: ?Sized>(*const T);
139 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<C<U>> for C<T> {} 129struct B<T: ?Sized>(*const T);
130struct C<T: ?Sized> { inner: *const T }
140 131
141 fn foo1<T>(x: A<[T]>) -> A<[T]> { x } 132impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<B<U>> for B<T> {}
142 fn foo2<T>(x: B<[T]>) -> B<[T]> { x } 133impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<C<U>> for C<T> {}
143 fn foo3<T>(x: C<[T]>) -> C<[T]> { x }
144 134
145 fn test(a: A<[u8; 2]>, b: B<[u8; 2]>, c: C<[u8; 2]>) { 135fn foo1<T>(x: A<[T]>) -> A<[T]> { x }
146 let d = foo1(a); 136fn foo2<T>(x: B<[T]>) -> B<[T]> { x }
147 let e = foo2(b); 137fn foo3<T>(x: C<[T]>) -> C<[T]> { x }
148 let f = foo3(c);
149 }
150
151
152 #[lang = "sized"]
153 pub trait Sized {}
154 #[lang = "unsize"]
155 pub trait Unsize<T: ?Sized> {}
156 #[lang = "coerce_unsized"]
157 pub trait CoerceUnsized<T> {}
158 138
159 impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} 139fn test(a: A<[u8; 2]>, b: B<[u8; 2]>, c: C<[u8; 2]>) {
160 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {} 140 let d = foo1(a);
161 "#, 141 let e = foo2(b);
142 let f = foo3(c);
143}
144"#,
162 expect![[r#" 145 expect![[r#"
163 257..258 'x': A<[T]> 146 306..307 'x': A<[T]>
164 278..283 '{ x }': A<[T]> 147 327..332 '{ x }': A<[T]>
165 280..281 'x': A<[T]> 148 329..330 'x': A<[T]>
166 295..296 'x': B<[T]> 149 344..345 'x': B<[T]>
167 316..321 '{ x }': B<[T]> 150 365..370 '{ x }': B<[T]>
168 318..319 'x': B<[T]> 151 367..368 'x': B<[T]>
169 333..334 'x': C<[T]> 152 382..383 'x': C<[T]>
170 354..359 '{ x }': C<[T]> 153 403..408 '{ x }': C<[T]>
171 356..357 'x': C<[T]> 154 405..406 'x': C<[T]>
172 369..370 'a': A<[u8; 2]> 155 418..419 'a': A<[u8; 2]>
173 384..385 'b': B<[u8; 2]> 156 433..434 'b': B<[u8; 2]>
174 399..400 'c': C<[u8; 2]> 157 448..449 'c': C<[u8; 2]>
175 414..480 '{ ...(c); }': () 158 463..529 '{ ...(c); }': ()
176 424..425 'd': A<[{unknown}]> 159 473..474 'd': A<[{unknown}]>
177 428..432 'foo1': fn foo1<{unknown}>(A<[{unknown}]>) -> A<[{unknown}]> 160 477..481 'foo1': fn foo1<{unknown}>(A<[{unknown}]>) -> A<[{unknown}]>
178 428..435 'foo1(a)': A<[{unknown}]> 161 477..484 'foo1(a)': A<[{unknown}]>
179 433..434 'a': A<[u8; 2]> 162 482..483 'a': A<[u8; 2]>
180 445..446 'e': B<[u8]> 163 494..495 'e': B<[u8]>
181 449..453 'foo2': fn foo2<u8>(B<[u8]>) -> B<[u8]> 164 498..502 'foo2': fn foo2<u8>(B<[u8]>) -> B<[u8]>
182 449..456 'foo2(b)': B<[u8]> 165 498..505 'foo2(b)': B<[u8]>
183 454..455 'b': B<[u8; 2]> 166 503..504 'b': B<[u8; 2]>
184 466..467 'f': C<[u8]> 167 515..516 'f': C<[u8]>
185 470..474 'foo3': fn foo3<u8>(C<[u8]>) -> C<[u8]> 168 519..523 'foo3': fn foo3<u8>(C<[u8]>) -> C<[u8]>
186 470..477 'foo3(c)': C<[u8]> 169 519..526 'foo3(c)': C<[u8]>
187 475..476 'c': C<[u8; 2]> 170 524..525 'c': C<[u8; 2]>
188 "#]], 171 "#]],
189 ); 172 );
190} 173}
@@ -193,21 +176,16 @@ fn infer_custom_coerce_unsized() {
193fn infer_if_coerce() { 176fn infer_if_coerce() {
194 check_infer( 177 check_infer(
195 r#" 178 r#"
196 fn foo<T>(x: &[T]) -> &[T] { loop {} } 179//- minicore: unsize
197 fn test() { 180fn foo<T>(x: &[T]) -> &[T] { loop {} }
198 let x = if true { 181fn test() {
199 foo(&[1]) 182 let x = if true {
200 } else { 183 foo(&[1])
201 &[1] 184 } else {
202 }; 185 &[1]
203 } 186 };
204 187}
205 188"#,
206 #[lang = "sized"]
207 pub trait Sized {}
208 #[lang = "unsize"]
209 pub trait Unsize<T: ?Sized> {}
210 "#,
211 expect![[r#" 189 expect![[r#"
212 10..11 'x': &[T] 190 10..11 'x': &[T]
213 27..38 '{ loop {} }': &[T] 191 27..38 '{ loop {} }': &[T]
@@ -235,25 +213,16 @@ fn infer_if_coerce() {
235fn infer_if_else_coerce() { 213fn infer_if_else_coerce() {
236 check_infer( 214 check_infer(
237 r#" 215 r#"
238 fn foo<T>(x: &[T]) -> &[T] { loop {} } 216//- minicore: coerce_unsized
239 fn test() { 217fn foo<T>(x: &[T]) -> &[T] { loop {} }
240 let x = if true { 218fn test() {
241 &[1] 219 let x = if true {
242 } else { 220 &[1]
243 foo(&[1]) 221 } else {
244 }; 222 foo(&[1])
245 } 223 };
246 224}
247 #[lang = "sized"] 225"#,
248 pub trait Sized {}
249 #[lang = "unsize"]
250 pub trait Unsize<T: ?Sized> {}
251 #[lang = "coerce_unsized"]
252 pub trait CoerceUnsized<T> {}
253
254 impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
255 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
256 "#,
257 expect![[r#" 226 expect![[r#"
258 10..11 'x': &[T] 227 10..11 'x': &[T]
259 27..38 '{ loop {} }': &[T] 228 27..38 '{ loop {} }': &[T]
@@ -281,20 +250,16 @@ fn infer_if_else_coerce() {
281fn infer_match_first_coerce() { 250fn infer_match_first_coerce() {
282 check_infer( 251 check_infer(
283 r#" 252 r#"
284 fn foo<T>(x: &[T]) -> &[T] { loop {} } 253//- minicore: unsize
285 fn test(i: i32) { 254fn foo<T>(x: &[T]) -> &[T] { loop {} }
286 let x = match i { 255fn test(i: i32) {
287 2 => foo(&[2]), 256 let x = match i {
288 1 => &[1], 257 2 => foo(&[2]),
289 _ => &[3], 258 1 => &[1],
290 }; 259 _ => &[3],
291 } 260 };
292 261}
293 #[lang = "sized"] 262"#,
294 pub trait Sized {}
295 #[lang = "unsize"]
296 pub trait Unsize<T: ?Sized> {}
297 "#,
298 expect![[r#" 263 expect![[r#"
299 10..11 'x': &[T] 264 10..11 'x': &[T]
300 27..38 '{ loop {} }': &[T] 265 27..38 '{ loop {} }': &[T]
@@ -329,25 +294,16 @@ fn infer_match_first_coerce() {
329fn infer_match_second_coerce() { 294fn infer_match_second_coerce() {
330 check_infer( 295 check_infer(
331 r#" 296 r#"
332 fn foo<T>(x: &[T]) -> &[T] { loop {} } 297//- minicore: coerce_unsized
333 fn test(i: i32) { 298fn foo<T>(x: &[T]) -> &[T] { loop {} }
334 let x = match i { 299fn test(i: i32) {
335 1 => &[1], 300 let x = match i {
336 2 => foo(&[2]), 301 1 => &[1],
337 _ => &[3], 302 2 => foo(&[2]),
338 }; 303 _ => &[3],
339 } 304 };
340 305}
341 #[lang = "sized"] 306"#,
342 pub trait Sized {}
343 #[lang = "unsize"]
344 pub trait Unsize<T: ?Sized> {}
345 #[lang = "coerce_unsized"]
346 pub trait CoerceUnsized<T> {}
347
348 impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
349 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
350 "#,
351 expect![[r#" 307 expect![[r#"
352 10..11 'x': &[T] 308 10..11 'x': &[T]
353 27..38 '{ loop {} }': &[T] 309 27..38 '{ loop {} }': &[T]
@@ -470,15 +426,15 @@ fn coerce_autoderef() {
470#[test] 426#[test]
471fn coerce_autoderef_generic() { 427fn coerce_autoderef_generic() {
472 check_infer_with_mismatches( 428 check_infer_with_mismatches(
473 r" 429 r#"
474 struct Foo; 430struct Foo;
475 fn takes_ref<T>(x: &T) -> T { *x } 431fn takes_ref<T>(x: &T) -> T { *x }
476 fn test() { 432fn test() {
477 takes_ref(&Foo); 433 takes_ref(&Foo);
478 takes_ref(&&Foo); 434 takes_ref(&&Foo);
479 takes_ref(&&&Foo); 435 takes_ref(&&&Foo);
480 } 436}
481 ", 437"#,
482 expect![[r" 438 expect![[r"
483 28..29 'x': &T 439 28..29 'x': &T
484 40..46 '{ *x }': T 440 40..46 '{ *x }': T
@@ -508,30 +464,29 @@ fn coerce_autoderef_generic() {
508fn coerce_autoderef_block() { 464fn coerce_autoderef_block() {
509 check_infer_with_mismatches( 465 check_infer_with_mismatches(
510 r#" 466 r#"
511 struct String {} 467//- minicore: deref
512 #[lang = "deref"] 468struct String {}
513 trait Deref { type Target; } 469impl core::ops::Deref for String { type Target = str; }
514 impl Deref for String { type Target = str; } 470fn takes_ref_str(x: &str) {}
515 fn takes_ref_str(x: &str) {} 471fn returns_string() -> String { loop {} }
516 fn returns_string() -> String { loop {} } 472fn test() {
517 fn test() { 473 takes_ref_str(&{ returns_string() });
518 takes_ref_str(&{ returns_string() }); 474}
519 } 475"#,
520 "#, 476 expect![[r#"
521 expect![[r" 477 90..91 'x': &str
522 126..127 'x': &str 478 99..101 '{}': ()
523 135..137 '{}': () 479 132..143 '{ loop {} }': String
524 168..179 '{ loop {} }': String 480 134..141 'loop {}': !
525 170..177 'loop {}': ! 481 139..141 '{}': ()
526 175..177 '{}': () 482 154..199 '{ ... }); }': ()
527 190..235 '{ ... }); }': () 483 160..173 'takes_ref_str': fn takes_ref_str(&str)
528 196..209 'takes_ref_str': fn takes_ref_str(&str) 484 160..196 'takes_...g() })': ()
529 196..232 'takes_...g() })': () 485 174..195 '&{ ret...ng() }': &String
530 210..231 '&{ ret...ng() }': &String 486 175..195 '{ retu...ng() }': String
531 211..231 '{ retu...ng() }': String 487 177..191 'returns_string': fn returns_string() -> String
532 213..227 'returns_string': fn returns_string() -> String 488 177..193 'return...ring()': String
533 213..229 'return...ring()': String 489 "#]],
534 "]],
535 ); 490 );
536} 491}
537 492
@@ -674,25 +629,19 @@ fn coerce_placeholder_ref() {
674fn coerce_unsize_array() { 629fn coerce_unsize_array() {
675 check_infer_with_mismatches( 630 check_infer_with_mismatches(
676 r#" 631 r#"
677 #[lang = "unsize"] 632//- minicore: coerce_unsized
678 pub trait Unsize<T> {} 633fn test() {
679 #[lang = "coerce_unsized"] 634 let f: &[usize] = &[1, 2, 3];
680 pub trait CoerceUnsized<T> {} 635}
681
682 impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {}
683
684 fn test() {
685 let f: &[usize] = &[1, 2, 3];
686 }
687 "#, 636 "#,
688 expect![[r#" 637 expect![[r#"
689 161..198 '{ ... 3]; }': () 638 10..47 '{ ... 3]; }': ()
690 171..172 'f': &[usize] 639 20..21 'f': &[usize]
691 185..195 '&[1, 2, 3]': &[usize; 3] 640 34..44 '&[1, 2, 3]': &[usize; 3]
692 186..195 '[1, 2, 3]': [usize; 3] 641 35..44 '[1, 2, 3]': [usize; 3]
693 187..188 '1': usize 642 36..37 '1': usize
694 190..191 '2': usize 643 39..40 '2': usize
695 193..194 '3': usize 644 42..43 '3': usize
696 "#]], 645 "#]],
697 ); 646 );
698} 647}
@@ -701,42 +650,34 @@ fn coerce_unsize_array() {
701fn coerce_unsize_trait_object_simple() { 650fn coerce_unsize_trait_object_simple() {
702 check_infer_with_mismatches( 651 check_infer_with_mismatches(
703 r#" 652 r#"
704 #[lang = "sized"] 653//- minicore: coerce_unsized
705 pub trait Sized {} 654trait Foo<T, U> {}
706 #[lang = "unsize"] 655trait Bar<U, T, X>: Foo<T, U> {}
707 pub trait Unsize<T> {} 656trait Baz<T, X>: Bar<usize, T, X> {}
708 #[lang = "coerce_unsized"] 657
709 pub trait CoerceUnsized<T> {} 658struct S<T, X>;
710 659impl<T, X> Foo<T, usize> for S<T, X> {}
711 impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} 660impl<T, X> Bar<usize, T, X> for S<T, X> {}
712 661impl<T, X> Baz<T, X> for S<T, X> {}
713 trait Foo<T, U> {} 662
714 trait Bar<U, T, X>: Foo<T, U> {} 663fn test() {
715 trait Baz<T, X>: Bar<usize, T, X> {} 664 let obj: &dyn Baz<i8, i16> = &S;
716 665 let obj: &dyn Bar<_, i8, i16> = &S;
717 struct S<T, X>; 666 let obj: &dyn Foo<i8, _> = &S;
718 impl<T, X> Foo<T, usize> for S<T, X> {} 667}
719 impl<T, X> Bar<usize, T, X> for S<T, X> {} 668"#,
720 impl<T, X> Baz<T, X> for S<T, X> {} 669 expect![[r#"
721 670 236..351 '{ ... &S; }': ()
722 fn test() { 671 246..249 'obj': &dyn Baz<i8, i16>
723 let obj: &dyn Baz<i8, i16> = &S; 672 271..273 '&S': &S<i8, i16>
724 let obj: &dyn Bar<_, i8, i16> = &S; 673 272..273 'S': S<i8, i16>
725 let obj: &dyn Foo<i8, _> = &S; 674 283..286 'obj': &dyn Bar<usize, i8, i16>
726 } 675 311..313 '&S': &S<i8, i16>
727 "#, 676 312..313 'S': S<i8, i16>
728 expect![[r" 677 323..326 'obj': &dyn Foo<i8, usize>
729 424..539 '{ ... &S; }': () 678 346..348 '&S': &S<i8, {unknown}>
730 434..437 'obj': &dyn Baz<i8, i16> 679 347..348 'S': S<i8, {unknown}>
731 459..461 '&S': &S<i8, i16> 680 "#]],
732 460..461 'S': S<i8, i16>
733 471..474 'obj': &dyn Bar<usize, i8, i16>
734 499..501 '&S': &S<i8, i16>
735 500..501 'S': S<i8, i16>
736 511..514 'obj': &dyn Foo<i8, usize>
737 534..536 '&S': &S<i8, {unknown}>
738 535..536 'S': S<i8, {unknown}>
739 "]],
740 ); 681 );
741} 682}
742 683
@@ -761,49 +702,41 @@ fn coerce_unsize_trait_object_to_trait_object() {
761 // 602..606 'obj2': &dyn Baz<i8, i16> 702 // 602..606 'obj2': &dyn Baz<i8, i16>
762 check_infer_with_mismatches( 703 check_infer_with_mismatches(
763 r#" 704 r#"
764 #[lang = "sized"] 705//- minicore: coerce_unsized
765 pub trait Sized {} 706trait Foo<T, U> {}
766 #[lang = "unsize"] 707trait Bar<U, T, X>: Foo<T, U> {}
767 pub trait Unsize<T> {} 708trait Baz<T, X>: Bar<usize, T, X> {}
768 #[lang = "coerce_unsized"] 709
769 pub trait CoerceUnsized<T> {} 710struct S<T, X>;
770 711impl<T, X> Foo<T, usize> for S<T, X> {}
771 impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} 712impl<T, X> Bar<usize, T, X> for S<T, X> {}
772 713impl<T, X> Baz<T, X> for S<T, X> {}
773 trait Foo<T, U> {} 714
774 trait Bar<U, T, X>: Foo<T, U> {} 715fn test() {
775 trait Baz<T, X>: Bar<usize, T, X> {} 716 let obj: &dyn Baz<i8, i16> = &S;
776 717 let obj: &dyn Bar<_, _, _> = obj;
777 struct S<T, X>; 718 let obj: &dyn Foo<_, _> = obj;
778 impl<T, X> Foo<T, usize> for S<T, X> {} 719 let obj2: &dyn Baz<i8, i16> = &S;
779 impl<T, X> Bar<usize, T, X> for S<T, X> {} 720 let _: &dyn Foo<_, _> = obj2;
780 impl<T, X> Baz<T, X> for S<T, X> {} 721}
781 722"#,
782 fn test() {
783 let obj: &dyn Baz<i8, i16> = &S;
784 let obj: &dyn Bar<_, _, _> = obj;
785 let obj: &dyn Foo<_, _> = obj;
786 let obj2: &dyn Baz<i8, i16> = &S;
787 let _: &dyn Foo<_, _> = obj2;
788 }
789 "#,
790 expect![[r#" 723 expect![[r#"
791 424..609 '{ ...bj2; }': () 724 236..421 '{ ...bj2; }': ()
792 434..437 'obj': &dyn Baz<i8, i16> 725 246..249 'obj': &dyn Baz<i8, i16>
793 459..461 '&S': &S<i8, i16> 726 271..273 '&S': &S<i8, i16>
794 460..461 'S': S<i8, i16> 727 272..273 'S': S<i8, i16>
795 471..474 'obj': &dyn Bar<{unknown}, {unknown}, {unknown}> 728 283..286 'obj': &dyn Bar<{unknown}, {unknown}, {unknown}>
796 496..499 'obj': &dyn Baz<i8, i16> 729 308..311 'obj': &dyn Baz<i8, i16>
797 509..512 'obj': &dyn Foo<{unknown}, {unknown}> 730 321..324 'obj': &dyn Foo<{unknown}, {unknown}>
798 531..534 'obj': &dyn Bar<{unknown}, {unknown}, {unknown}> 731 343..346 'obj': &dyn Bar<{unknown}, {unknown}, {unknown}>
799 544..548 'obj2': &dyn Baz<i8, i16> 732 356..360 'obj2': &dyn Baz<i8, i16>
800 570..572 '&S': &S<i8, i16> 733 382..384 '&S': &S<i8, i16>
801 571..572 'S': S<i8, i16> 734 383..384 'S': S<i8, i16>
802 582..583 '_': &dyn Foo<{unknown}, {unknown}> 735 394..395 '_': &dyn Foo<{unknown}, {unknown}>
803 602..606 'obj2': &dyn Baz<i8, i16> 736 414..418 'obj2': &dyn Baz<i8, i16>
804 496..499: expected &dyn Bar<{unknown}, {unknown}, {unknown}>, got &dyn Baz<i8, i16> 737 308..311: expected &dyn Bar<{unknown}, {unknown}, {unknown}>, got &dyn Baz<i8, i16>
805 531..534: expected &dyn Foo<{unknown}, {unknown}>, got &dyn Bar<{unknown}, {unknown}, {unknown}> 738 343..346: expected &dyn Foo<{unknown}, {unknown}>, got &dyn Bar<{unknown}, {unknown}, {unknown}>
806 602..606: expected &dyn Foo<{unknown}, {unknown}>, got &dyn Baz<i8, i16> 739 414..418: expected &dyn Foo<{unknown}, {unknown}>, got &dyn Baz<i8, i16>
807 "#]], 740 "#]],
808 ); 741 );
809} 742}
@@ -812,40 +745,32 @@ fn coerce_unsize_trait_object_to_trait_object() {
812fn coerce_unsize_super_trait_cycle() { 745fn coerce_unsize_super_trait_cycle() {
813 check_infer_with_mismatches( 746 check_infer_with_mismatches(
814 r#" 747 r#"
815 #[lang = "sized"] 748//- minicore: coerce_unsized
816 pub trait Sized {} 749trait A {}
817 #[lang = "unsize"] 750trait B: C + A {}
818 pub trait Unsize<T> {} 751trait C: B {}
819 #[lang = "coerce_unsized"] 752trait D: C
820 pub trait CoerceUnsized<T> {} 753
821 754struct S;
822 impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} 755impl A for S {}
823 756impl B for S {}
824 trait A {} 757impl C for S {}
825 trait B: C + A {} 758impl D for S {}
826 trait C: B {} 759
827 trait D: C 760fn test() {
828 761 let obj: &dyn D = &S;
829 struct S; 762 let obj: &dyn A = &S;
830 impl A for S {} 763}
831 impl B for S {} 764"#,
832 impl C for S {} 765 expect![[r#"
833 impl D for S {} 766 140..195 '{ ... &S; }': ()
834 767 150..153 'obj': &dyn D
835 fn test() { 768 164..166 '&S': &S
836 let obj: &dyn D = &S; 769 165..166 'S': S
837 let obj: &dyn A = &S; 770 176..179 'obj': &dyn A
838 } 771 190..192 '&S': &S
839 "#, 772 191..192 'S': S
840 expect![[r" 773 "#]],
841 328..383 '{ ... &S; }': ()
842 338..341 'obj': &dyn D
843 352..354 '&S': &S
844 353..354 'S': S
845 364..367 'obj': &dyn A
846 378..380 '&S': &S
847 379..380 'S': S
848 "]],
849 ); 774 );
850} 775}
851 776
@@ -854,41 +779,35 @@ fn coerce_unsize_generic() {
854 // FIXME: fix the type mismatches here 779 // FIXME: fix the type mismatches here
855 check_infer_with_mismatches( 780 check_infer_with_mismatches(
856 r#" 781 r#"
857 #[lang = "unsize"] 782//- minicore: coerce_unsized
858 pub trait Unsize<T> {} 783struct Foo<T> { t: T };
859 #[lang = "coerce_unsized"] 784struct Bar<T>(Foo<T>);
860 pub trait CoerceUnsized<T> {}
861
862 impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {}
863 785
864 struct Foo<T> { t: T }; 786fn test() {
865 struct Bar<T>(Foo<T>); 787 let _: &Foo<[usize]> = &Foo { t: [1, 2, 3] };
866 788 let _: &Bar<[usize]> = &Bar(Foo { t: [1, 2, 3] });
867 fn test() { 789}
868 let _: &Foo<[usize]> = &Foo { t: [1, 2, 3] }; 790"#,
869 let _: &Bar<[usize]> = &Bar(Foo { t: [1, 2, 3] });
870 }
871 "#,
872 expect![[r#" 791 expect![[r#"
873 209..317 '{ ... }); }': () 792 58..166 '{ ... }); }': ()
874 219..220 '_': &Foo<[usize]> 793 68..69 '_': &Foo<[usize]>
875 238..259 '&Foo {..., 3] }': &Foo<[usize]> 794 87..108 '&Foo {..., 3] }': &Foo<[usize]>
876 239..259 'Foo { ..., 3] }': Foo<[usize]> 795 88..108 'Foo { ..., 3] }': Foo<[usize]>
877 248..257 '[1, 2, 3]': [usize; 3] 796 97..106 '[1, 2, 3]': [usize; 3]
878 249..250 '1': usize 797 98..99 '1': usize
879 252..253 '2': usize 798 101..102 '2': usize
880 255..256 '3': usize 799 104..105 '3': usize
881 269..270 '_': &Bar<[usize]> 800 118..119 '_': &Bar<[usize]>
882 288..314 '&Bar(F... 3] })': &Bar<[i32; 3]> 801 137..163 '&Bar(F... 3] })': &Bar<[i32; 3]>
883 289..292 'Bar': Bar<[i32; 3]>(Foo<[i32; 3]>) -> Bar<[i32; 3]> 802 138..141 'Bar': Bar<[i32; 3]>(Foo<[i32; 3]>) -> Bar<[i32; 3]>
884 289..314 'Bar(Fo... 3] })': Bar<[i32; 3]> 803 138..163 'Bar(Fo... 3] })': Bar<[i32; 3]>
885 293..313 'Foo { ..., 3] }': Foo<[i32; 3]> 804 142..162 'Foo { ..., 3] }': Foo<[i32; 3]>
886 302..311 '[1, 2, 3]': [i32; 3] 805 151..160 '[1, 2, 3]': [i32; 3]
887 303..304 '1': i32 806 152..153 '1': i32
888 306..307 '2': i32 807 155..156 '2': i32
889 309..310 '3': i32 808 158..159 '3': i32
890 248..257: expected [usize], got [usize; 3] 809 97..106: expected [usize], got [usize; 3]
891 288..314: expected &Bar<[usize]>, got &Bar<[i32; 3]> 810 137..163: expected &Bar<[usize]>, got &Bar<[i32; 3]>
892 "#]], 811 "#]],
893 ); 812 );
894} 813}
@@ -898,15 +817,7 @@ fn coerce_unsize_apit() {
898 // FIXME: #8984 817 // FIXME: #8984
899 check_infer_with_mismatches( 818 check_infer_with_mismatches(
900 r#" 819 r#"
901#[lang = "sized"] 820//- minicore: coerce_unsized
902pub trait Sized {}
903#[lang = "unsize"]
904pub trait Unsize<T> {}
905#[lang = "coerce_unsized"]
906pub trait CoerceUnsized<T> {}
907
908impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {}
909
910trait Foo {} 821trait Foo {}
911 822
912fn test(f: impl Foo) { 823fn test(f: impl Foo) {
@@ -914,12 +825,12 @@ fn test(f: impl Foo) {
914} 825}
915 "#, 826 "#,
916 expect![[r#" 827 expect![[r#"
917 210..211 'f': impl Foo 828 22..23 'f': impl Foo
918 223..252 '{ ... &f; }': () 829 35..64 '{ ... &f; }': ()
919 233..234 '_': &dyn Foo 830 45..46 '_': &dyn Foo
920 247..249 '&f': &impl Foo 831 59..61 '&f': &impl Foo
921 248..249 'f': impl Foo 832 60..61 'f': impl Foo
922 247..249: expected &dyn Foo, got &impl Foo 833 59..61: expected &dyn Foo, got &impl Foo
923 "#]], 834 "#]],
924 ); 835 );
925} 836}
@@ -1015,15 +926,7 @@ fn main() {
1015fn coerce_unsize_expected_type() { 926fn coerce_unsize_expected_type() {
1016 check_no_mismatches( 927 check_no_mismatches(
1017 r#" 928 r#"
1018#[lang = "sized"] 929//- minicore: coerce_unsized
1019pub trait Sized {}
1020#[lang = "unsize"]
1021pub trait Unsize<T> {}
1022#[lang = "coerce_unsized"]
1023pub trait CoerceUnsized<T> {}
1024
1025impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {}
1026
1027fn main() { 930fn main() {
1028 let foo: &[u32] = &[1, 2]; 931 let foo: &[u32] = &[1, 2];
1029 let foo: &[u32] = match true { 932 let foo: &[u32] = match true {
diff --git a/crates/hir_ty/src/tests/method_resolution.rs b/crates/hir_ty/src/tests/method_resolution.rs
index f26b2c8a7..d9b5ee9cf 100644
--- a/crates/hir_ty/src/tests/method_resolution.rs
+++ b/crates/hir_ty/src/tests/method_resolution.rs
@@ -780,10 +780,7 @@ fn test() { (&S).foo(); }
780fn method_resolution_unsize_array() { 780fn method_resolution_unsize_array() {
781 check_types( 781 check_types(
782 r#" 782 r#"
783#[lang = "slice"] 783//- minicore: slice
784impl<T> [T] {
785 fn len(&self) -> usize { loop {} }
786}
787fn test() { 784fn test() {
788 let a = [1, 2, 3]; 785 let a = [1, 2, 3];
789 a.len(); 786 a.len();
@@ -1178,11 +1175,7 @@ fn main() {
1178fn autoderef_visibility_field() { 1175fn autoderef_visibility_field() {
1179 check_infer( 1176 check_infer(
1180 r#" 1177 r#"
1181#[lang = "deref"] 1178//- minicore: deref
1182pub trait Deref {
1183 type Target;
1184 fn deref(&self) -> &Self::Target;
1185}
1186mod a { 1179mod a {
1187 pub struct Foo(pub char); 1180 pub struct Foo(pub char);
1188 pub struct Bar(i32); 1181 pub struct Bar(i32);
@@ -1191,7 +1184,7 @@ mod a {
1191 Self(0) 1184 Self(0)
1192 } 1185 }
1193 } 1186 }
1194 impl super::Deref for Bar { 1187 impl core::ops::Deref for Bar {
1195 type Target = Foo; 1188 type Target = Foo;
1196 fn deref(&self) -> &Foo { 1189 fn deref(&self) -> &Foo {
1197 &Foo('z') 1190 &Foo('z')
@@ -1205,22 +1198,21 @@ mod b {
1205} 1198}
1206 "#, 1199 "#,
1207 expect![[r#" 1200 expect![[r#"
1208 67..71 'self': &Self 1201 107..138 '{ ... }': Bar
1209 200..231 '{ ... }': Bar 1202 121..125 'Self': Bar(i32) -> Bar
1210 214..218 'Self': Bar(i32) -> Bar 1203 121..128 'Self(0)': Bar
1211 214..221 'Self(0)': Bar 1204 126..127 '0': i32
1212 219..220 '0': i32 1205 226..230 'self': &Bar
1213 315..319 'self': &Bar 1206 240..273 '{ ... }': &Foo
1214 329..362 '{ ... }': &Foo 1207 254..263 '&Foo('z')': &Foo
1215 343..352 '&Foo('z')': &Foo 1208 255..258 'Foo': Foo(char) -> Foo
1216 344..347 'Foo': Foo(char) -> Foo 1209 255..263 'Foo('z')': Foo
1217 344..352 'Foo('z')': Foo 1210 259..262 ''z'': char
1218 348..351 ''z'': char 1211 303..350 '{ ... }': ()
1219 392..439 '{ ... }': () 1212 317..318 'x': char
1220 406..407 'x': char 1213 321..339 'super:...r::new': fn new() -> Bar
1221 410..428 'super:...r::new': fn new() -> Bar 1214 321..341 'super:...:new()': Bar
1222 410..430 'super:...:new()': Bar 1215 321..343 'super:...ew().0': char
1223 410..432 'super:...ew().0': char
1224 "#]], 1216 "#]],
1225 ) 1217 )
1226} 1218}
@@ -1230,11 +1222,7 @@ fn autoderef_visibility_method() {
1230 cov_mark::check!(autoderef_candidate_not_visible); 1222 cov_mark::check!(autoderef_candidate_not_visible);
1231 check_infer( 1223 check_infer(
1232 r#" 1224 r#"
1233#[lang = "deref"] 1225//- minicore: deref
1234pub trait Deref {
1235 type Target;
1236 fn deref(&self) -> &Self::Target;
1237}
1238mod a { 1226mod a {
1239 pub struct Foo(pub char); 1227 pub struct Foo(pub char);
1240 impl Foo { 1228 impl Foo {
@@ -1251,7 +1239,7 @@ mod a {
1251 self.0 1239 self.0
1252 } 1240 }
1253 } 1241 }
1254 impl super::Deref for Bar { 1242 impl core::ops::Deref for Bar {
1255 type Target = Foo; 1243 type Target = Foo;
1256 fn deref(&self) -> &Foo { 1244 fn deref(&self) -> &Foo {
1257 &Foo('z') 1245 &Foo('z')
@@ -1265,30 +1253,29 @@ mod b {
1265} 1253}
1266 "#, 1254 "#,
1267 expect![[r#" 1255 expect![[r#"
1268 67..71 'self': &Self 1256 75..79 'self': &Foo
1269 168..172 'self': &Foo 1257 89..119 '{ ... }': char
1270 182..212 '{ ... }': char 1258 103..107 'self': &Foo
1271 196..200 'self': &Foo 1259 103..109 'self.0': char
1272 196..202 'self.0': char 1260 195..226 '{ ... }': Bar
1273 288..319 '{ ... }': Bar 1261 209..213 'Self': Bar(i32) -> Bar
1274 302..306 'Self': Bar(i32) -> Bar 1262 209..216 'Self(0)': Bar
1275 302..309 'Self(0)': Bar 1263 214..215 '0': i32
1276 307..308 '0': i32 1264 245..249 'self': &Bar
1277 338..342 'self': &Bar 1265 258..288 '{ ... }': i32
1278 351..381 '{ ... }': i32 1266 272..276 'self': &Bar
1279 365..369 'self': &Bar 1267 272..278 'self.0': i32
1280 365..371 'self.0': i32 1268 376..380 'self': &Bar
1281 465..469 'self': &Bar 1269 390..423 '{ ... }': &Foo
1282 479..512 '{ ... }': &Foo 1270 404..413 '&Foo('z')': &Foo
1283 493..502 '&Foo('z')': &Foo 1271 405..408 'Foo': Foo(char) -> Foo
1284 494..497 'Foo': Foo(char) -> Foo 1272 405..413 'Foo('z')': Foo
1285 494..502 'Foo('z')': Foo 1273 409..412 ''z'': char
1286 498..501 ''z'': char 1274 453..506 '{ ... }': ()
1287 542..595 '{ ... }': () 1275 467..468 'x': char
1288 556..557 'x': char 1276 471..489 'super:...r::new': fn new() -> Bar
1289 560..578 'super:...r::new': fn new() -> Bar 1277 471..491 'super:...:new()': Bar
1290 560..580 'super:...:new()': Bar 1278 471..499 'super:...ango()': char
1291 560..588 'super:...ango()': char
1292 "#]], 1279 "#]],
1293 ) 1280 )
1294} 1281}
diff --git a/crates/hir_ty/src/tests/regression.rs b/crates/hir_ty/src/tests/regression.rs
index 1019e783b..abd9c385a 100644
--- a/crates/hir_ty/src/tests/regression.rs
+++ b/crates/hir_ty/src/tests/regression.rs
@@ -927,35 +927,33 @@ fn issue_6628() {
927fn issue_6852() { 927fn issue_6852() {
928 check_infer( 928 check_infer(
929 r#" 929 r#"
930 #[lang = "deref"] 930//- minicore: deref
931 pub trait Deref { 931use core::ops::Deref;
932 type Target;
933 }
934 932
935 struct BufWriter {} 933struct BufWriter {}
936 934
937 struct Mutex<T> {} 935struct Mutex<T> {}
938 struct MutexGuard<'a, T> {} 936struct MutexGuard<'a, T> {}
939 impl<T> Mutex<T> { 937impl<T> Mutex<T> {
940 fn lock(&self) -> MutexGuard<'_, T> {} 938 fn lock(&self) -> MutexGuard<'_, T> {}
941 } 939}
942 impl<'a, T: 'a> Deref for MutexGuard<'a, T> { 940impl<'a, T: 'a> Deref for MutexGuard<'a, T> {
943 type Target = T; 941 type Target = T;
944 } 942}
945 fn flush(&self) { 943fn flush(&self) {
946 let w: &Mutex<BufWriter>; 944 let w: &Mutex<BufWriter>;
947 *(w.lock()); 945 *(w.lock());
948 } 946}
949 "#, 947"#,
950 expect![[r#" 948 expect![[r#"
951 156..160 'self': &Mutex<T> 949 123..127 'self': &Mutex<T>
952 183..185 '{}': () 950 150..152 '{}': ()
953 267..271 'self': &{unknown} 951 234..238 'self': &{unknown}
954 273..323 '{ ...()); }': () 952 240..290 '{ ...()); }': ()
955 283..284 'w': &Mutex<BufWriter> 953 250..251 'w': &Mutex<BufWriter>
956 309..320 '*(w.lock())': BufWriter 954 276..287 '*(w.lock())': BufWriter
957 311..312 'w': &Mutex<BufWriter> 955 278..279 'w': &Mutex<BufWriter>
958 311..319 'w.lock()': MutexGuard<BufWriter> 956 278..286 'w.lock()': MutexGuard<BufWriter>
959 "#]], 957 "#]],
960 ); 958 );
961} 959}
@@ -977,37 +975,33 @@ fn param_overrides_fn() {
977fn lifetime_from_chalk_during_deref() { 975fn lifetime_from_chalk_during_deref() {
978 check_types( 976 check_types(
979 r#" 977 r#"
980 #[lang = "deref"] 978//- minicore: deref
981 pub trait Deref { 979struct Box<T: ?Sized> {}
982 type Target; 980impl<T> core::ops::Deref for Box<T> {
983 } 981 type Target = T;
984
985 struct Box<T: ?Sized> {}
986 impl<T> Deref for Box<T> {
987 type Target = T;
988 982
989 fn deref(&self) -> &Self::Target { 983 fn deref(&self) -> &Self::Target {
990 loop {} 984 loop {}
991 } 985 }
992 } 986}
993 987
994 trait Iterator { 988trait Iterator {
995 type Item; 989 type Item;
996 } 990}
997 991
998 pub struct Iter<'a, T: 'a> { 992pub struct Iter<'a, T: 'a> {
999 inner: Box<dyn IterTrait<'a, T, Item = &'a T> + 'a>, 993 inner: Box<dyn IterTrait<'a, T, Item = &'a T> + 'a>,
1000 } 994}
1001 995
1002 trait IterTrait<'a, T: 'a>: Iterator<Item = &'a T> { 996trait IterTrait<'a, T: 'a>: Iterator<Item = &'a T> {
1003 fn clone_box(&self); 997 fn clone_box(&self);
1004 } 998}
1005 999
1006 fn clone_iter<T>(s: Iter<T>) { 1000fn clone_iter<T>(s: Iter<T>) {
1007 s.inner.clone_box(); 1001 s.inner.clone_box();
1008 //^^^^^^^^^^^^^^^^^^^ () 1002 //^^^^^^^^^^^^^^^^^^^ ()
1009 } 1003}
1010 "#, 1004"#,
1011 ) 1005 )
1012} 1006}
1013 1007
diff --git a/crates/hir_ty/src/tests/simple.rs b/crates/hir_ty/src/tests/simple.rs
index 3418ed21e..68776f3c0 100644
--- a/crates/hir_ty/src/tests/simple.rs
+++ b/crates/hir_ty/src/tests/simple.rs
@@ -113,7 +113,7 @@ fn type_alias_in_struct_lit() {
113fn infer_ranges() { 113fn infer_ranges() {
114 check_types( 114 check_types(
115 r#" 115 r#"
116//- /main.rs crate:main deps:core 116//- minicore: range
117fn test() { 117fn test() {
118 let a = ..; 118 let a = ..;
119 let b = 1..; 119 let b = 1..;
@@ -125,32 +125,6 @@ fn test() {
125 let t = (a, b, c, d, e, f); 125 let t = (a, b, c, d, e, f);
126 t; 126 t;
127} //^ (RangeFull, RangeFrom<i32>, RangeTo<u32>, Range<usize>, RangeToInclusive<i32>, RangeInclusive<char>) 127} //^ (RangeFull, RangeFrom<i32>, RangeTo<u32>, Range<usize>, RangeToInclusive<i32>, RangeInclusive<char>)
128
129//- /core.rs crate:core
130#[prelude_import] use prelude::*;
131mod prelude {}
132
133pub mod ops {
134 pub struct Range<Idx> {
135 pub start: Idx,
136 pub end: Idx,
137 }
138 pub struct RangeFrom<Idx> {
139 pub start: Idx,
140 }
141 struct RangeFull;
142 pub struct RangeInclusive<Idx> {
143 start: Idx,
144 end: Idx,
145 is_empty: u8,
146 }
147 pub struct RangeTo<Idx> {
148 pub end: Idx,
149 }
150 pub struct RangeToInclusive<Idx> {
151 pub end: Idx,
152 }
153}
154"#, 128"#,
155 ); 129 );
156} 130}
@@ -175,16 +149,17 @@ fn test() {
175fn infer_basics() { 149fn infer_basics() {
176 check_infer( 150 check_infer(
177 r#" 151 r#"
178 fn test(a: u32, b: isize, c: !, d: &str) { 152fn test(a: u32, b: isize, c: !, d: &str) {
179 a; 153 a;
180 b; 154 b;
181 c; 155 c;
182 d; 156 d;
183 1usize; 157 1usize;
184 1isize; 158 1isize;
185 "test"; 159 "test";
186 1.0f32; 160 1.0f32;
187 }"#, 161}
162"#,
188 expect![[r#" 163 expect![[r#"
189 8..9 'a': u32 164 8..9 'a': u32
190 16..17 'b': isize 165 16..17 'b': isize
@@ -207,15 +182,15 @@ fn infer_basics() {
207fn infer_let() { 182fn infer_let() {
208 check_infer( 183 check_infer(
209 r#" 184 r#"
210 fn test() { 185fn test() {
211 let a = 1isize; 186 let a = 1isize;
212 let b: usize = 1; 187 let b: usize = 1;
213 let c = b; 188 let c = b;
214 let d: u32; 189 let d: u32;
215 let e; 190 let e;
216 let f: i32 = e; 191 let f: i32 = e;
217 } 192}
218 "#, 193"#,
219 expect![[r#" 194 expect![[r#"
220 10..117 '{ ...= e; }': () 195 10..117 '{ ...= e; }': ()
221 20..21 'a': isize 196 20..21 'a': isize
@@ -236,17 +211,17 @@ fn infer_let() {
236fn infer_paths() { 211fn infer_paths() {
237 check_infer( 212 check_infer(
238 r#" 213 r#"
239 fn a() -> u32 { 1 } 214fn a() -> u32 { 1 }
240 215
241 mod b { 216mod b {
242 fn c() -> u32 { 1 } 217 fn c() -> u32 { 1 }
243 } 218}
244 219
245 fn test() { 220fn test() {
246 a(); 221 a();
247 b::c(); 222 b::c();
248 } 223}
249 "#, 224"#,
250 expect![[r#" 225 expect![[r#"
251 14..19 '{ 1 }': u32 226 14..19 '{ 1 }': u32
252 16..17 '1': u32 227 16..17 '1': u32
@@ -265,17 +240,17 @@ fn infer_paths() {
265fn infer_path_type() { 240fn infer_path_type() {
266 check_infer( 241 check_infer(
267 r#" 242 r#"
268 struct S; 243struct S;
269 244
270 impl S { 245impl S {
271 fn foo() -> i32 { 1 } 246 fn foo() -> i32 { 1 }
272 } 247}
273 248
274 fn test() { 249fn test() {
275 S::foo(); 250 S::foo();
276 <S>::foo(); 251 <S>::foo();
277 } 252}
278 "#, 253"#,
279 expect![[r#" 254 expect![[r#"
280 40..45 '{ 1 }': i32 255 40..45 '{ 1 }': i32
281 42..43 '1': i32 256 42..43 '1': i32
@@ -292,21 +267,21 @@ fn infer_path_type() {
292fn infer_struct() { 267fn infer_struct() {
293 check_infer( 268 check_infer(
294 r#" 269 r#"
295 struct A { 270struct A {
296 b: B, 271 b: B,
297 c: C, 272 c: C,
298 } 273}
299 struct B; 274struct B;
300 struct C(usize); 275struct C(usize);
301 276
302 fn test() { 277fn test() {
303 let c = C(1); 278 let c = C(1);
304 B; 279 B;
305 let a: A = A { b: B, c: C(1) }; 280 let a: A = A { b: B, c: C(1) };
306 a.b; 281 a.b;
307 a.c; 282 a.c;
308 } 283}
309 "#, 284"#,
310 expect![[r#" 285 expect![[r#"
311 71..153 '{ ...a.c; }': () 286 71..153 '{ ...a.c; }': ()
312 81..82 'c': C 287 81..82 'c': C
@@ -332,14 +307,15 @@ fn infer_struct() {
332fn infer_enum() { 307fn infer_enum() {
333 check_infer( 308 check_infer(
334 r#" 309 r#"
335 enum E { 310enum E {
336 V1 { field: u32 }, 311 V1 { field: u32 },
337 V2 312 V2
338 } 313}
339 fn test() { 314fn test() {
340 E::V1 { field: 1 }; 315 E::V1 { field: 1 };
341 E::V2; 316 E::V2;
342 }"#, 317}
318"#,
343 expect![[r#" 319 expect![[r#"
344 51..89 '{ ...:V2; }': () 320 51..89 '{ ...:V2; }': ()
345 57..75 'E::V1 ...d: 1 }': E 321 57..75 'E::V1 ...d: 1 }': E
@@ -353,23 +329,23 @@ fn infer_enum() {
353fn infer_union() { 329fn infer_union() {
354 check_infer( 330 check_infer(
355 r#" 331 r#"
356 union MyUnion { 332union MyUnion {
357 foo: u32, 333 foo: u32,
358 bar: f32, 334 bar: f32,
359 } 335}
360 336
361 fn test() { 337fn test() {
362 let u = MyUnion { foo: 0 }; 338 let u = MyUnion { foo: 0 };
363 unsafe { baz(u); } 339 unsafe { baz(u); }
364 let u = MyUnion { bar: 0.0 }; 340 let u = MyUnion { bar: 0.0 };
365 unsafe { baz(u); } 341 unsafe { baz(u); }
366 } 342}
367 343
368 unsafe fn baz(u: MyUnion) { 344unsafe fn baz(u: MyUnion) {
369 let inner = u.foo; 345 let inner = u.foo;
370 let inner = u.bar; 346 let inner = u.bar;
371 } 347}
372 "#, 348"#,
373 expect![[r#" 349 expect![[r#"
374 57..172 '{ ...); } }': () 350 57..172 '{ ...); } }': ()
375 67..68 'u': MyUnion 351 67..68 'u': MyUnion
@@ -404,19 +380,19 @@ fn infer_union() {
404fn infer_refs() { 380fn infer_refs() {
405 check_infer( 381 check_infer(
406 r#" 382 r#"
407 fn test(a: &u32, b: &mut u32, c: *const u32, d: *mut u32) { 383fn test(a: &u32, b: &mut u32, c: *const u32, d: *mut u32) {
408 a; 384 a;
409 *a; 385 *a;
410 &a; 386 &a;
411 &mut a; 387 &mut a;
412 b; 388 b;
413 *b; 389 *b;
414 &b; 390 &b;
415 c; 391 c;
416 *c; 392 *c;
417 d; 393 d;
418 *d; 394 *d;
419 } 395}
420 "#, 396 "#,
421 expect![[r#" 397 expect![[r#"
422 8..9 'a': &u32 398 8..9 'a': &u32
@@ -450,11 +426,11 @@ fn infer_refs() {
450fn infer_raw_ref() { 426fn infer_raw_ref() {
451 check_infer( 427 check_infer(
452 r#" 428 r#"
453 fn test(a: i32) { 429fn test(a: i32) {
454 &raw mut a; 430 &raw mut a;
455 &raw const a; 431 &raw const a;
456 } 432}
457 "#, 433"#,
458 expect![[r#" 434 expect![[r#"
459 8..9 'a': i32 435 8..9 'a': i32
460 16..53 '{ ...t a; }': () 436 16..53 '{ ...t a; }': ()
@@ -524,26 +500,26 @@ h";
524fn infer_unary_op() { 500fn infer_unary_op() {
525 check_infer( 501 check_infer(
526 r#" 502 r#"
527 enum SomeType {} 503enum SomeType {}
528 504
529 fn test(x: SomeType) { 505fn test(x: SomeType) {
530 let b = false; 506 let b = false;
531 let c = !b; 507 let c = !b;
532 let a = 100; 508 let a = 100;
533 let d: i128 = -a; 509 let d: i128 = -a;
534 let e = -100; 510 let e = -100;
535 let f = !!!true; 511 let f = !!!true;
536 let g = !42; 512 let g = !42;
537 let h = !10u32; 513 let h = !10u32;
538 let j = !a; 514 let j = !a;
539 -3.14; 515 -3.14;
540 !3; 516 !3;
541 -x; 517 -x;
542 !x; 518 !x;
543 -"hello"; 519 -"hello";
544 !"hello"; 520 !"hello";
545 } 521}
546 "#, 522"#,
547 expect![[r#" 523 expect![[r#"
548 26..27 'x': SomeType 524 26..27 'x': SomeType
549 39..271 '{ ...lo"; }': () 525 39..271 '{ ...lo"; }': ()
@@ -594,19 +570,19 @@ fn infer_unary_op() {
594fn infer_backwards() { 570fn infer_backwards() {
595 check_infer( 571 check_infer(
596 r#" 572 r#"
597 fn takes_u32(x: u32) {} 573fn takes_u32(x: u32) {}
598 574
599 struct S { i32_field: i32 } 575struct S { i32_field: i32 }
600 576
601 fn test() -> &mut &f64 { 577fn test() -> &mut &f64 {
602 let a = unknown_function(); 578 let a = unknown_function();
603 takes_u32(a); 579 takes_u32(a);
604 let b = unknown_function(); 580 let b = unknown_function();
605 S { i32_field: b }; 581 S { i32_field: b };
606 let c = unknown_function(); 582 let c = unknown_function();
607 &mut &c 583 &mut &c
608 } 584}
609 "#, 585"#,
610 expect![[r#" 586 expect![[r#"
611 13..14 'x': u32 587 13..14 'x': u32
612 21..23 '{}': () 588 21..23 '{}': ()
@@ -636,23 +612,23 @@ fn infer_backwards() {
636fn infer_self() { 612fn infer_self() {
637 check_infer( 613 check_infer(
638 r#" 614 r#"
639 struct S; 615struct S;
640 616
641 impl S { 617impl S {
642 fn test(&self) { 618 fn test(&self) {
643 self; 619 self;
644 } 620 }
645 fn test2(self: &Self) { 621 fn test2(self: &Self) {
646 self; 622 self;
647 } 623 }
648 fn test3() -> Self { 624 fn test3() -> Self {
649 S {} 625 S {}
650 } 626 }
651 fn test4() -> Self { 627 fn test4() -> Self {
652 Self {} 628 Self {}
653 } 629 }
654 } 630}
655 "#, 631"#,
656 expect![[r#" 632 expect![[r#"
657 33..37 'self': &S 633 33..37 'self': &S
658 39..60 '{ ... }': () 634 39..60 '{ ... }': ()
@@ -672,30 +648,30 @@ fn infer_self() {
672fn infer_self_as_path() { 648fn infer_self_as_path() {
673 check_infer( 649 check_infer(
674 r#" 650 r#"
675 struct S1; 651struct S1;
676 struct S2(isize); 652struct S2(isize);
677 enum E { 653enum E {
678 V1, 654 V1,
679 V2(u32), 655 V2(u32),
680 } 656}
681 657
682 impl S1 { 658impl S1 {
683 fn test() { 659 fn test() {
684 Self; 660 Self;
685 } 661 }
686 } 662}
687 impl S2 { 663impl S2 {
688 fn test() { 664 fn test() {
689 Self(1); 665 Self(1);
690 } 666 }
691 } 667}
692 impl E { 668impl E {
693 fn test() { 669 fn test() {
694 Self::V1; 670 Self::V1;
695 Self::V2(1); 671 Self::V2(1);
696 } 672 }
697 } 673}
698 "#, 674"#,
699 expect![[r#" 675 expect![[r#"
700 86..107 '{ ... }': () 676 86..107 '{ ... }': ()
701 96..100 'Self': S1 677 96..100 'Self': S1
@@ -716,26 +692,26 @@ fn infer_self_as_path() {
716fn infer_binary_op() { 692fn infer_binary_op() {
717 check_infer( 693 check_infer(
718 r#" 694 r#"
719 fn f(x: bool) -> i32 { 695fn f(x: bool) -> i32 {
720 0i32 696 0i32
721 } 697}
722 698
723 fn test() -> bool { 699fn test() -> bool {
724 let x = a && b; 700 let x = a && b;
725 let y = true || false; 701 let y = true || false;
726 let z = x == y; 702 let z = x == y;
727 let t = x != y; 703 let t = x != y;
728 let minus_forty: isize = -40isize; 704 let minus_forty: isize = -40isize;
729 let h = minus_forty <= CONST_2; 705 let h = minus_forty <= CONST_2;
730 let c = f(z || y) + 5; 706 let c = f(z || y) + 5;
731 let d = b; 707 let d = b;
732 let g = minus_forty ^= i; 708 let g = minus_forty ^= i;
733 let ten: usize = 10; 709 let ten: usize = 10;
734 let ten_is_eleven = ten == some_num; 710 let ten_is_eleven = ten == some_num;
735 711
736 ten < 3 712 ten < 3
737 } 713}
738 "#, 714"#,
739 expect![[r#" 715 expect![[r#"
740 5..6 'x': bool 716 5..6 'x': bool
741 21..33 '{ 0i32 }': i32 717 21..33 '{ 0i32 }': i32
@@ -795,11 +771,11 @@ fn infer_binary_op() {
795fn infer_shift_op() { 771fn infer_shift_op() {
796 check_infer( 772 check_infer(
797 r#" 773 r#"
798 fn test() { 774fn test() {
799 1u32 << 5u8; 775 1u32 << 5u8;
800 1u32 >> 5u8; 776 1u32 >> 5u8;
801 } 777}
802 "#, 778"#,
803 expect![[r#" 779 expect![[r#"
804 10..47 '{ ...5u8; }': () 780 10..47 '{ ...5u8; }': ()
805 16..20 '1u32': u32 781 16..20 '1u32': u32
@@ -816,29 +792,29 @@ fn infer_shift_op() {
816fn infer_field_autoderef() { 792fn infer_field_autoderef() {
817 check_infer( 793 check_infer(
818 r#" 794 r#"
819 struct A { 795struct A {
820 b: B, 796 b: B,
821 } 797}
822 struct B; 798struct B;
823
824 fn test1(a: A) {
825 let a1 = a;
826 a1.b;
827 let a2 = &a;
828 a2.b;
829 let a3 = &mut a;
830 a3.b;
831 let a4 = &&&&&&&a;
832 a4.b;
833 let a5 = &mut &&mut &&mut a;
834 a5.b;
835 }
836 799
837 fn test2(a1: *const A, a2: *mut A) { 800fn test1(a: A) {
838 a1.b; 801 let a1 = a;
839 a2.b; 802 a1.b;
840 } 803 let a2 = &a;
841 "#, 804 a2.b;
805 let a3 = &mut a;
806 a3.b;
807 let a4 = &&&&&&&a;
808 a4.b;
809 let a5 = &mut &&mut &&mut a;
810 a5.b;
811}
812
813fn test2(a1: *const A, a2: *mut A) {
814 a1.b;
815 a2.b;
816}
817"#,
842 expect![[r#" 818 expect![[r#"
843 43..44 'a': A 819 43..44 'a': A
844 49..212 '{ ...5.b; }': () 820 49..212 '{ ...5.b; }': ()
@@ -891,58 +867,53 @@ fn infer_field_autoderef() {
891fn infer_argument_autoderef() { 867fn infer_argument_autoderef() {
892 check_infer( 868 check_infer(
893 r#" 869 r#"
894 #[lang = "deref"] 870//- minicore: deref
895 pub trait Deref { 871use core::ops::Deref;
896 type Target; 872struct A<T>(T);
897 fn deref(&self) -> &Self::Target;
898 }
899
900 struct A<T>(T);
901 873
902 impl<T> A<T> { 874impl<T> A<T> {
903 fn foo(&self) -> &T { 875 fn foo(&self) -> &T {
904 &self.0 876 &self.0
905 } 877 }
906 } 878}
907 879
908 struct B<T>(T); 880struct B<T>(T);
909 881
910 impl<T> Deref for B<T> { 882impl<T> Deref for B<T> {
911 type Target = T; 883 type Target = T;
912 fn deref(&self) -> &Self::Target { 884 fn deref(&self) -> &Self::Target {
913 &self.0 885 &self.0
914 } 886 }
915 } 887}
916 888
917 fn test() { 889fn test() {
918 let t = A::foo(&&B(B(A(42)))); 890 let t = A::foo(&&B(B(A(42))));
919 } 891}
920 "#, 892"#,
921 expect![[r#" 893 expect![[r#"
922 67..71 'self': &Self 894 66..70 'self': &A<T>
923 138..142 'self': &A<T> 895 78..101 '{ ... }': &T
924 150..173 '{ ... }': &T 896 88..95 '&self.0': &T
925 160..167 '&self.0': &T 897 89..93 'self': &A<T>
926 161..165 'self': &A<T> 898 89..95 'self.0': T
927 161..167 'self.0': T 899 182..186 'self': &B<T>
928 254..258 'self': &B<T> 900 205..228 '{ ... }': &T
929 277..300 '{ ... }': &T 901 215..222 '&self.0': &T
930 287..294 '&self.0': &T 902 216..220 'self': &B<T>
931 288..292 'self': &B<T> 903 216..222 'self.0': T
932 288..294 'self.0': T 904 242..280 '{ ...))); }': ()
933 314..352 '{ ...))); }': () 905 252..253 't': &i32
934 324..325 't': &i32 906 256..262 'A::foo': fn foo<i32>(&A<i32>) -> &i32
935 328..334 'A::foo': fn foo<i32>(&A<i32>) -> &i32 907 256..277 'A::foo...42))))': &i32
936 328..349 'A::foo...42))))': &i32 908 263..276 '&&B(B(A(42)))': &&B<B<A<i32>>>
937 335..348 '&&B(B(A(42)))': &&B<B<A<i32>>> 909 264..276 '&B(B(A(42)))': &B<B<A<i32>>>
938 336..348 '&B(B(A(42)))': &B<B<A<i32>>> 910 265..266 'B': B<B<A<i32>>>(B<A<i32>>) -> B<B<A<i32>>>
939 337..338 'B': B<B<A<i32>>>(B<A<i32>>) -> B<B<A<i32>>> 911 265..276 'B(B(A(42)))': B<B<A<i32>>>
940 337..348 'B(B(A(42)))': B<B<A<i32>>> 912 267..268 'B': B<A<i32>>(A<i32>) -> B<A<i32>>
941 339..340 'B': B<A<i32>>(A<i32>) -> B<A<i32>> 913 267..275 'B(A(42))': B<A<i32>>
942 339..347 'B(A(42))': B<A<i32>> 914 269..270 'A': A<i32>(i32) -> A<i32>
943 341..342 'A': A<i32>(i32) -> A<i32> 915 269..274 'A(42)': A<i32>
944 341..346 'A(42)': A<i32> 916 271..273 '42': i32
945 343..345 '42': i32
946 "#]], 917 "#]],
947 ); 918 );
948} 919}
@@ -951,62 +922,57 @@ fn infer_argument_autoderef() {
951fn infer_method_argument_autoderef() { 922fn infer_method_argument_autoderef() {
952 check_infer( 923 check_infer(
953 r#" 924 r#"
954 #[lang = "deref"] 925//- minicore: deref
955 pub trait Deref { 926use core::ops::Deref;
956 type Target; 927struct A<T>(*mut T);
957 fn deref(&self) -> &Self::Target;
958 }
959 928
960 struct A<T>(*mut T); 929impl<T> A<T> {
961 930 fn foo(&self, x: &A<T>) -> &T {
962 impl<T> A<T> { 931 &*x.0
963 fn foo(&self, x: &A<T>) -> &T { 932 }
964 &*x.0 933}
965 }
966 }
967 934
968 struct B<T>(T); 935struct B<T>(T);
969 936
970 impl<T> Deref for B<T> { 937impl<T> Deref for B<T> {
971 type Target = T; 938 type Target = T;
972 fn deref(&self) -> &Self::Target { 939 fn deref(&self) -> &Self::Target {
973 &self.0 940 &self.0
974 } 941 }
975 } 942}
976 943
977 fn test(a: A<i32>) { 944fn test(a: A<i32>) {
978 let t = A(0 as *mut _).foo(&&B(B(a))); 945 let t = A(0 as *mut _).foo(&&B(B(a)));
979 } 946}
980 "#, 947"#,
981 expect![[r#" 948 expect![[r#"
982 67..71 'self': &Self 949 71..75 'self': &A<T>
983 143..147 'self': &A<T> 950 77..78 'x': &A<T>
984 149..150 'x': &A<T> 951 93..114 '{ ... }': &T
985 165..186 '{ ... }': &T 952 103..108 '&*x.0': &T
986 175..180 '&*x.0': &T 953 104..108 '*x.0': T
987 176..180 '*x.0': T 954 105..106 'x': &A<T>
988 177..178 'x': &A<T> 955 105..108 'x.0': *mut T
989 177..180 'x.0': *mut T 956 195..199 'self': &B<T>
990 267..271 'self': &B<T> 957 218..241 '{ ... }': &T
991 290..313 '{ ... }': &T 958 228..235 '&self.0': &T
992 300..307 '&self.0': &T 959 229..233 'self': &B<T>
993 301..305 'self': &B<T> 960 229..235 'self.0': T
994 301..307 'self.0': T 961 253..254 'a': A<i32>
995 325..326 'a': A<i32> 962 264..310 '{ ...))); }': ()
996 336..382 '{ ...))); }': () 963 274..275 't': &i32
997 346..347 't': &i32 964 278..279 'A': A<i32>(*mut i32) -> A<i32>
998 350..351 'A': A<i32>(*mut i32) -> A<i32> 965 278..292 'A(0 as *mut _)': A<i32>
999 350..364 'A(0 as *mut _)': A<i32> 966 278..307 'A(0 as...B(a)))': &i32
1000 350..379 'A(0 as...B(a)))': &i32 967 280..281 '0': i32
1001 352..353 '0': i32 968 280..291 '0 as *mut _': *mut i32
1002 352..363 '0 as *mut _': *mut i32 969 297..306 '&&B(B(a))': &&B<B<A<i32>>>
1003 369..378 '&&B(B(a))': &&B<B<A<i32>>> 970 298..306 '&B(B(a))': &B<B<A<i32>>>
1004 370..378 '&B(B(a))': &B<B<A<i32>>> 971 299..300 'B': B<B<A<i32>>>(B<A<i32>>) -> B<B<A<i32>>>
1005 371..372 'B': B<B<A<i32>>>(B<A<i32>>) -> B<B<A<i32>>> 972 299..306 'B(B(a))': B<B<A<i32>>>
1006 371..378 'B(B(a))': B<B<A<i32>>> 973 301..302 'B': B<A<i32>>(A<i32>) -> B<A<i32>>
1007 373..374 'B': B<A<i32>>(A<i32>) -> B<A<i32>> 974 301..305 'B(a)': B<A<i32>>
1008 373..377 'B(a)': B<A<i32>> 975 303..304 'a': A<i32>
1009 375..376 'a': A<i32>
1010 "#]], 976 "#]],
1011 ); 977 );
1012} 978}
@@ -1015,15 +981,15 @@ fn infer_method_argument_autoderef() {
1015fn infer_in_elseif() { 981fn infer_in_elseif() {
1016 check_infer( 982 check_infer(
1017 r#" 983 r#"
1018 struct Foo { field: i32 } 984struct Foo { field: i32 }
1019 fn main(foo: Foo) { 985fn main(foo: Foo) {
1020 if true { 986 if true {
1021 987
1022 } else if false { 988 } else if false {
1023 foo.field 989 foo.field
1024 } 990 }
1025 } 991}
1026 "#, 992"#,
1027 expect![[r#" 993 expect![[r#"
1028 34..37 'foo': Foo 994 34..37 'foo': Foo
1029 44..108 '{ ... } }': () 995 44..108 '{ ... } }': ()
@@ -1043,28 +1009,29 @@ fn infer_in_elseif() {
1043fn infer_if_match_with_return() { 1009fn infer_if_match_with_return() {
1044 check_infer( 1010 check_infer(
1045 r#" 1011 r#"
1046 fn foo() { 1012fn foo() {
1047 let _x1 = if true { 1013 let _x1 = if true {
1048 1 1014 1
1049 } else { 1015 } else {
1050 return; 1016 return;
1051 }; 1017 };
1052 let _x2 = if true { 1018 let _x2 = if true {
1053 2 1019 2
1054 } else { 1020 } else {
1055 return 1021 return
1056 }; 1022 };
1057 let _x3 = match true { 1023 let _x3 = match true {
1058 true => 3, 1024 true => 3,
1059 _ => { 1025 _ => {
1060 return; 1026 return;
1061 } 1027 }
1062 }; 1028 };
1063 let _x4 = match true { 1029 let _x4 = match true {
1064 true => 4, 1030 true => 4,
1065 _ => return 1031 _ => return
1066 }; 1032 };
1067 }"#, 1033}
1034"#,
1068 expect![[r#" 1035 expect![[r#"
1069 9..322 '{ ... }; }': () 1036 9..322 '{ ... }; }': ()
1070 19..22 '_x1': i32 1037 19..22 '_x1': i32
@@ -2639,11 +2606,8 @@ fn f() {
2639fn infer_boxed_self_receiver() { 2606fn infer_boxed_self_receiver() {
2640 check_infer( 2607 check_infer(
2641 r#" 2608 r#"
2642#[lang = "deref"] 2609//- minicore: deref
2643pub trait Deref { 2610use core::ops::Deref;
2644 type Target;
2645 fn deref(&self) -> &Self::Target;
2646}
2647 2611
2648struct Box<T>(T); 2612struct Box<T>(T);
2649 2613
@@ -2675,40 +2639,39 @@ fn main() {
2675} 2639}
2676 "#, 2640 "#,
2677 expect![[r#" 2641 expect![[r#"
2678 67..71 'self': &Self 2642 104..108 'self': &Box<T>
2679 175..179 'self': &Box<T> 2643 188..192 'self': &Box<Foo<T>>
2680 259..263 'self': &Box<Foo<T>> 2644 218..220 '{}': ()
2681 289..291 '{}': () 2645 242..246 'self': &Box<Foo<T>>
2682 313..317 'self': &Box<Foo<T>> 2646 275..277 '{}': ()
2683 346..348 '{}': () 2647 297..301 'self': Box<Foo<T>>
2684 368..372 'self': Box<Foo<T>> 2648 322..324 '{}': ()
2685 393..395 '{}': () 2649 338..559 '{ ...r(); }': ()
2686 409..630 '{ ...r(); }': () 2650 348..353 'boxed': Box<Foo<i32>>
2687 419..424 'boxed': Box<Foo<i32>> 2651 356..359 'Box': Box<Foo<i32>>(Foo<i32>) -> Box<Foo<i32>>
2688 427..430 'Box': Box<Foo<i32>>(Foo<i32>) -> Box<Foo<i32>> 2652 356..371 'Box(Foo(0_i32))': Box<Foo<i32>>
2689 427..442 'Box(Foo(0_i32))': Box<Foo<i32>> 2653 360..363 'Foo': Foo<i32>(i32) -> Foo<i32>
2690 431..434 'Foo': Foo<i32>(i32) -> Foo<i32> 2654 360..370 'Foo(0_i32)': Foo<i32>
2691 431..441 'Foo(0_i32)': Foo<i32> 2655 364..369 '0_i32': i32
2692 435..440 '0_i32': i32 2656 382..386 'bad1': &i32
2693 453..457 'bad1': &i32 2657 389..394 'boxed': Box<Foo<i32>>
2694 460..465 'boxed': Box<Foo<i32>> 2658 389..406 'boxed....nner()': &i32
2695 460..477 'boxed....nner()': &i32 2659 416..421 'good1': &i32
2696 487..492 'good1': &i32 2660 424..438 'Foo::get_inner': fn get_inner<i32>(&Box<Foo<i32>>) -> &i32
2697 495..509 'Foo::get_inner': fn get_inner<i32>(&Box<Foo<i32>>) -> &i32 2661 424..446 'Foo::g...boxed)': &i32
2698 495..517 'Foo::g...boxed)': &i32 2662 439..445 '&boxed': &Box<Foo<i32>>
2699 510..516 '&boxed': &Box<Foo<i32>> 2663 440..445 'boxed': Box<Foo<i32>>
2700 511..516 'boxed': Box<Foo<i32>> 2664 457..461 'bad2': &Foo<i32>
2701 528..532 'bad2': &Foo<i32> 2665 464..469 'boxed': Box<Foo<i32>>
2702 535..540 'boxed': Box<Foo<i32>> 2666 464..480 'boxed....self()': &Foo<i32>
2703 535..551 'boxed....self()': &Foo<i32> 2667 490..495 'good2': &Foo<i32>
2704 561..566 'good2': &Foo<i32> 2668 498..511 'Foo::get_self': fn get_self<i32>(&Box<Foo<i32>>) -> &Foo<i32>
2705 569..582 'Foo::get_self': fn get_self<i32>(&Box<Foo<i32>>) -> &Foo<i32> 2669 498..519 'Foo::g...boxed)': &Foo<i32>
2706 569..590 'Foo::g...boxed)': &Foo<i32> 2670 512..518 '&boxed': &Box<Foo<i32>>
2707 583..589 '&boxed': &Box<Foo<i32>> 2671 513..518 'boxed': Box<Foo<i32>>
2708 584..589 'boxed': Box<Foo<i32>> 2672 530..535 'inner': Foo<i32>
2709 601..606 'inner': Foo<i32> 2673 538..543 'boxed': Box<Foo<i32>>
2710 609..614 'boxed': Box<Foo<i32>> 2674 538..556 'boxed....nner()': Foo<i32>
2711 609..627 'boxed....nner()': Foo<i32>
2712 "#]], 2675 "#]],
2713 ); 2676 );
2714} 2677}
diff --git a/crates/hir_ty/src/tests/traits.rs b/crates/hir_ty/src/tests/traits.rs
index c830e576e..65fed02d2 100644
--- a/crates/hir_ty/src/tests/traits.rs
+++ b/crates/hir_ty/src/tests/traits.rs
@@ -6,10 +6,10 @@ use super::{check_infer, check_infer_with_mismatches, check_types};
6fn infer_await() { 6fn infer_await() {
7 check_types( 7 check_types(
8 r#" 8 r#"
9//- /main.rs crate:main deps:core 9//- minicore: future
10struct IntFuture; 10struct IntFuture;
11 11
12impl Future for IntFuture { 12impl core::future::Future for IntFuture {
13 type Output = u64; 13 type Output = u64;
14} 14}
15 15
@@ -18,16 +18,6 @@ fn test() {
18 let v = r.await; 18 let v = r.await;
19 v; 19 v;
20} //^ u64 20} //^ u64
21
22//- /core.rs crate:core
23pub mod prelude {
24 pub mod rust_2018 {
25 #[lang = "future_trait"]
26 pub trait Future {
27 type Output;
28 }
29 }
30}
31"#, 21"#,
32 ); 22 );
33} 23}
@@ -36,25 +26,14 @@ pub mod prelude {
36fn infer_async() { 26fn infer_async() {
37 check_types( 27 check_types(
38 r#" 28 r#"
39//- /main.rs crate:main deps:core 29//- minicore: future
40async fn foo() -> u64 { 30async fn foo() -> u64 { 128 }
41 128
42}
43 31
44fn test() { 32fn test() {
45 let r = foo(); 33 let r = foo();
46 let v = r.await; 34 let v = r.await;
47 v; 35 v;
48} //^ u64 36} //^ u64
49
50//- /core.rs crate:core
51#[prelude_import] use future::*;
52mod future {
53 #[lang = "future_trait"]
54 trait Future {
55 type Output;
56 }
57}
58"#, 37"#,
59 ); 38 );
60} 39}
@@ -63,24 +42,13 @@ mod future {
63fn infer_desugar_async() { 42fn infer_desugar_async() {
64 check_types( 43 check_types(
65 r#" 44 r#"
66//- /main.rs crate:main deps:core 45//- minicore: future
67async fn foo() -> u64 { 46async fn foo() -> u64 { 128 }
68 128
69}
70 47
71fn test() { 48fn test() {
72 let r = foo(); 49 let r = foo();
73 r; 50 r;
74} //^ impl Future<Output = u64> 51} //^ impl Future<Output = u64>
75
76//- /core.rs crate:core
77#[prelude_import] use future::*;
78mod future {
79 trait Future {
80 type Output;
81 }
82}
83
84"#, 52"#,
85 ); 53 );
86} 54}
@@ -89,7 +57,7 @@ mod future {
89fn infer_async_block() { 57fn infer_async_block() {
90 check_types( 58 check_types(
91 r#" 59 r#"
92//- /main.rs crate:main deps:core 60//- minicore: future, option
93async fn test() { 61async fn test() {
94 let a = async { 42 }; 62 let a = async { 42 };
95 a; 63 a;
@@ -101,7 +69,7 @@ async fn test() {
101 b; 69 b;
102// ^ () 70// ^ ()
103 let c = async { 71 let c = async {
104 let y = Option::None; 72 let y = None;
105 y 73 y
106 // ^ Option<u64> 74 // ^ Option<u64>
107 }; 75 };
@@ -109,18 +77,6 @@ async fn test() {
109 c; 77 c;
110// ^ impl Future<Output = Option<u64>> 78// ^ impl Future<Output = Option<u64>>
111} 79}
112
113enum Option<T> { None, Some(T) }
114
115//- /core.rs crate:core
116#[prelude_import] use future::*;
117mod future {
118 #[lang = "future_trait"]
119 trait Future {
120 type Output;
121 }
122}
123
124"#, 80"#,
125 ); 81 );
126} 82}
@@ -704,14 +660,9 @@ mod ops {
704fn deref_trait() { 660fn deref_trait() {
705 check_types( 661 check_types(
706 r#" 662 r#"
707#[lang = "deref"] 663//- minicore: deref
708trait Deref {
709 type Target;
710 fn deref(&self) -> &Self::Target;
711}
712
713struct Arc<T>; 664struct Arc<T>;
714impl<T> Deref for Arc<T> { 665impl<T> core::ops::Deref for Arc<T> {
715 type Target = T; 666 type Target = T;
716} 667}
717 668
@@ -731,16 +682,10 @@ fn test(s: Arc<S>) {
731fn deref_trait_with_inference_var() { 682fn deref_trait_with_inference_var() {
732 check_types( 683 check_types(
733 r#" 684 r#"
734//- /main.rs 685//- minicore: deref
735#[lang = "deref"]
736trait Deref {
737 type Target;
738 fn deref(&self) -> &Self::Target;
739}
740
741struct Arc<T>; 686struct Arc<T>;
742fn new_arc<T>() -> Arc<T> {} 687fn new_arc<T>() -> Arc<T> {}
743impl<T> Deref for Arc<T> { 688impl<T> core::ops::Deref for Arc<T> {
744 type Target = T; 689 type Target = T;
745} 690}
746 691
@@ -761,15 +706,10 @@ fn test() {
761fn deref_trait_infinite_recursion() { 706fn deref_trait_infinite_recursion() {
762 check_types( 707 check_types(
763 r#" 708 r#"
764#[lang = "deref"] 709//- minicore: deref
765trait Deref {
766 type Target;
767 fn deref(&self) -> &Self::Target;
768}
769
770struct S; 710struct S;
771 711
772impl Deref for S { 712impl core::ops::Deref for S {
773 type Target = S; 713 type Target = S;
774} 714}
775 715
@@ -784,14 +724,9 @@ fn test(s: S) {
784fn deref_trait_with_question_mark_size() { 724fn deref_trait_with_question_mark_size() {
785 check_types( 725 check_types(
786 r#" 726 r#"
787#[lang = "deref"] 727//- minicore: deref
788trait Deref {
789 type Target;
790 fn deref(&self) -> &Self::Target;
791}
792
793struct Arc<T>; 728struct Arc<T>;
794impl<T> Deref for Arc<T> { 729impl<T: ?Sized> core::ops::Deref for Arc<T> {
795 type Target = T; 730 type Target = T;
796} 731}
797 732
@@ -2625,12 +2560,9 @@ fn test<T: Trait>() {
2625fn dyn_trait_through_chalk() { 2560fn dyn_trait_through_chalk() {
2626 check_types( 2561 check_types(
2627 r#" 2562 r#"
2563//- minicore: deref
2628struct Box<T> {} 2564struct Box<T> {}
2629#[lang = "deref"] 2565impl<T> core::ops::Deref for Box<T> {
2630trait Deref {
2631 type Target;
2632}
2633impl<T> Deref for Box<T> {
2634 type Target = T; 2566 type Target = T;
2635} 2567}
2636trait Trait { 2568trait Trait {
@@ -3695,16 +3627,7 @@ impl foo::Foo for u32 {
3695fn infer_async_ret_type() { 3627fn infer_async_ret_type() {
3696 check_types( 3628 check_types(
3697 r#" 3629 r#"
3698//- /main.rs crate:main deps:core 3630//- minicore: future, result
3699
3700enum Result<T, E> {
3701 Ok(T),
3702 Err(E),
3703}
3704
3705use Result::*;
3706
3707
3708struct Fooey; 3631struct Fooey;
3709 3632
3710impl Fooey { 3633impl Fooey {
@@ -3727,15 +3650,6 @@ async fn get_accounts() -> Result<u32, ()> {
3727 // ^ u32 3650 // ^ u32
3728 Ok(ret) 3651 Ok(ret)
3729} 3652}
3730
3731//- /core.rs crate:core
3732#[prelude_import] use future::*;
3733mod future {
3734 #[lang = "future_trait"]
3735 trait Future {
3736 type Output;
3737 }
3738}
3739"#, 3653"#,
3740 ); 3654 );
3741} 3655}
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs
index afeded315..14cf94d60 100644
--- a/crates/ide/src/hover.rs
+++ b/crates/ide/src/hover.rs
@@ -3000,29 +3000,24 @@ fn foo(ar$0g: &impl Foo + Bar<S>) {}
3000 fn test_hover_async_block_impl_trait_has_goto_type_action() { 3000 fn test_hover_async_block_impl_trait_has_goto_type_action() {
3001 check_actions( 3001 check_actions(
3002 r#" 3002 r#"
3003//- minicore: future
3003struct S; 3004struct S;
3004fn foo() { 3005fn foo() {
3005 let fo$0o = async { S }; 3006 let fo$0o = async { S };
3006} 3007}
3007
3008#[prelude_import] use future::*;
3009mod future {
3010 #[lang = "future_trait"]
3011 pub trait Future { type Output; }
3012}
3013"#, 3008"#,
3014 expect![[r#" 3009 expect![[r#"
3015 [ 3010 [
3016 GoToType( 3011 GoToType(
3017 [ 3012 [
3018 HoverGotoTypeData { 3013 HoverGotoTypeData {
3019 mod_path: "test::future::Future", 3014 mod_path: "core::future::Future",
3020 nav: NavigationTarget { 3015 nav: NavigationTarget {
3021 file_id: FileId( 3016 file_id: FileId(
3022 0, 3017 1,
3023 ), 3018 ),
3024 full_range: 101..163, 3019 full_range: 244..426,
3025 focus_range: 140..146, 3020 focus_range: 283..289,
3026 name: "Future", 3021 name: "Future",
3027 kind: Trait, 3022 kind: Trait,
3028 description: "pub trait Future", 3023 description: "pub trait Future",
diff --git a/crates/ide_completion/src/completions/keyword.rs b/crates/ide_completion/src/completions/keyword.rs
index ba13d3707..0fccbeccf 100644
--- a/crates/ide_completion/src/completions/keyword.rs
+++ b/crates/ide_completion/src/completions/keyword.rs
@@ -536,17 +536,11 @@ Some multi-line comment$0
536 fn test_completion_await_impls_future() { 536 fn test_completion_await_impls_future() {
537 check( 537 check(
538 r#" 538 r#"
539//- /main.rs crate:main deps:std 539//- minicore: future
540use std::future::*; 540use core::future::*;
541struct A {} 541struct A {}
542impl Future for A {} 542impl Future for A {}
543fn foo(a: A) { a.$0 } 543fn foo(a: A) { a.$0 }
544
545//- /std/lib.rs crate:std
546pub mod future {
547 #[lang = "future_trait"]
548 pub trait Future {}
549}
550"#, 544"#,
551 expect![[r#" 545 expect![[r#"
552 kw await expr.await 546 kw await expr.await
@@ -555,20 +549,12 @@ pub mod future {
555 549
556 check( 550 check(
557 r#" 551 r#"
558//- /main.rs crate:main deps:std 552//- minicore: future
559use std::future::*; 553use std::future::*;
560fn foo() { 554fn foo() {
561 let a = async {}; 555 let a = async {};
562 a.$0 556 a.$0
563} 557}
564
565//- /std/lib.rs crate:std
566pub mod future {
567 #[lang = "future_trait"]
568 pub trait Future {
569 type Output;
570 }
571}
572"#, 558"#,
573 expect![[r#" 559 expect![[r#"
574 kw await expr.await 560 kw await expr.await
diff --git a/crates/ide_completion/src/render.rs b/crates/ide_completion/src/render.rs
index d8ca18c73..3eb51e80b 100644
--- a/crates/ide_completion/src/render.rs
+++ b/crates/ide_completion/src/render.rs
@@ -1152,16 +1152,11 @@ fn main() {
1152 fn suggest_deref() { 1152 fn suggest_deref() {
1153 check_relevance( 1153 check_relevance(
1154 r#" 1154 r#"
1155#[lang = "deref"] 1155//- minicore: deref
1156trait Deref {
1157 type Target;
1158 fn deref(&self) -> &Self::Target;
1159}
1160
1161struct S; 1156struct S;
1162struct T(S); 1157struct T(S);
1163 1158
1164impl Deref for T { 1159impl core::ops::Deref for T {
1165 type Target = S; 1160 type Target = S;
1166 1161
1167 fn deref(&self) -> &Self::Target { 1162 fn deref(&self) -> &Self::Target {
@@ -1185,8 +1180,9 @@ fn main() {
1185 st T [] 1180 st T []
1186 st S [] 1181 st S []
1187 fn main() [] 1182 fn main() []
1188 tt Deref []
1189 fn foo(…) [] 1183 fn foo(…) []
1184 md core []
1185 tt Sized []
1190 "#]], 1186 "#]],
1191 ) 1187 )
1192 } 1188 }
diff --git a/crates/rust-analyzer/tests/slow-tests/support.rs b/crates/rust-analyzer/tests/slow-tests/support.rs
index e22c295f9..260a504e7 100644
--- a/crates/rust-analyzer/tests/slow-tests/support.rs
+++ b/crates/rust-analyzer/tests/slow-tests/support.rs
@@ -75,7 +75,9 @@ impl<'a> Project<'a> {
75 profile::init_from(crate::PROFILE); 75 profile::init_from(crate::PROFILE);
76 }); 76 });
77 77
78 for entry in Fixture::parse(self.fixture) { 78 let (mini_core, fixtures) = Fixture::parse(self.fixture);
79 assert!(mini_core.is_none());
80 for entry in fixtures {
79 let path = tmp_dir.path().join(&entry.path['/'.len_utf8()..]); 81 let path = tmp_dir.path().join(&entry.path['/'.len_utf8()..]);
80 fs::create_dir_all(path.parent().unwrap()).unwrap(); 82 fs::create_dir_all(path.parent().unwrap()).unwrap();
81 fs::write(path.as_path(), entry.text.as_bytes()).unwrap(); 83 fs::write(path.as_path(), entry.text.as_bytes()).unwrap();
diff --git a/crates/test_utils/src/fixture.rs b/crates/test_utils/src/fixture.rs
index d0bddf7d8..6ba112de8 100644
--- a/crates/test_utils/src/fixture.rs
+++ b/crates/test_utils/src/fixture.rs
@@ -77,6 +77,11 @@ pub struct Fixture {
77 pub introduce_new_source_root: bool, 77 pub introduce_new_source_root: bool,
78} 78}
79 79
80pub struct MiniCore {
81 activated_flags: Vec<String>,
82 valid_flags: Vec<String>,
83}
84
80impl Fixture { 85impl Fixture {
81 /// Parses text which looks like this: 86 /// Parses text which looks like this:
82 /// 87 ///
@@ -86,12 +91,28 @@ impl Fixture {
86 /// line 2 91 /// line 2
87 /// //- other meta 92 /// //- other meta
88 /// ``` 93 /// ```
89 pub fn parse(ra_fixture: &str) -> Vec<Fixture> { 94 ///
95 /// Fixture can also start with a minicore declaration:
96 ///
97 /// ```
98 /// //- minicore: sized
99 /// ```
100 ///
101 /// That will include a subset of `libcore` into the fixture, see
102 /// `minicore.rs` for what's available.
103 pub fn parse(ra_fixture: &str) -> (Option<MiniCore>, Vec<Fixture>) {
90 let fixture = trim_indent(ra_fixture); 104 let fixture = trim_indent(ra_fixture);
91 105 let mut fixture = fixture.as_str();
106 let mut mini_core = None;
92 let mut res: Vec<Fixture> = Vec::new(); 107 let mut res: Vec<Fixture> = Vec::new();
93 108
94 let default = if ra_fixture.contains("//-") { None } else { Some("//- /main.rs") }; 109 if fixture.starts_with("//- minicore:") {
110 let first_line = fixture.split_inclusive('\n').next().unwrap();
111 mini_core = Some(MiniCore::parse(first_line));
112 fixture = &fixture[first_line.len()..];
113 }
114
115 let default = if fixture.contains("//-") { None } else { Some("//- /main.rs") };
95 116
96 for (ix, line) in default.into_iter().chain(fixture.split_inclusive('\n')).enumerate() { 117 for (ix, line) in default.into_iter().chain(fixture.split_inclusive('\n')).enumerate() {
97 if line.contains("//-") { 118 if line.contains("//-") {
@@ -113,7 +134,7 @@ impl Fixture {
113 } 134 }
114 } 135 }
115 136
116 res 137 (mini_core, res)
117 } 138 }
118 139
119 //- /lib.rs crate:foo deps:bar,baz cfg:foo=a,bar=b env:OUTDIR=path/to,OTHER=foo 140 //- /lib.rs crate:foo deps:bar,baz cfg:foo=a,bar=b env:OUTDIR=path/to,OTHER=foo
@@ -172,6 +193,133 @@ impl Fixture {
172 } 193 }
173} 194}
174 195
196impl MiniCore {
197 fn has_flag(&self, flag: &str) -> bool {
198 self.activated_flags.iter().any(|it| it == flag)
199 }
200
201 #[track_caller]
202 fn assert_valid_flag(&self, flag: &str) {
203 if !self.valid_flags.iter().any(|it| it == flag) {
204 panic!("invalid flag: {:?}, valid flags: {:?}", flag, self.valid_flags);
205 }
206 }
207
208 fn parse(line: &str) -> MiniCore {
209 let mut res = MiniCore { activated_flags: Vec::new(), valid_flags: Vec::new() };
210
211 let line = line.strip_prefix("//- minicore:").unwrap().trim();
212 for entry in line.split(", ") {
213 if res.has_flag(entry) {
214 panic!("duplicate minicore flag: {:?}", entry)
215 }
216 res.activated_flags.push(entry.to_string())
217 }
218
219 res
220 }
221
222 /// Strips parts of minicore.rs which are flagged by inactive flags.
223 ///
224 /// This is probably over-engineered to support flags dependencies.
225 pub fn source_code(mut self) -> String {
226 let mut buf = String::new();
227 let raw_mini_core = include_str!("./minicore.rs");
228 let mut lines = raw_mini_core.split_inclusive('\n');
229
230 let mut parsing_flags = false;
231 let mut implications = Vec::new();
232
233 // Parse `//!` preamble and extract flags and dependencies.
234 for line in lines.by_ref() {
235 let line = match line.strip_prefix("//!") {
236 Some(it) => it,
237 None => {
238 assert!(line.trim().is_empty());
239 break;
240 }
241 };
242
243 if parsing_flags {
244 let (flag, deps) = line.split_once(':').unwrap();
245 let flag = flag.trim();
246 self.valid_flags.push(flag.to_string());
247 for dep in deps.split(", ") {
248 let dep = dep.trim();
249 if !dep.is_empty() {
250 self.assert_valid_flag(dep);
251 implications.push((flag, dep));
252 }
253 }
254 }
255
256 if line.contains("Available flags:") {
257 parsing_flags = true;
258 }
259 }
260
261 for flag in &self.activated_flags {
262 self.assert_valid_flag(flag);
263 }
264
265 // Fixed point loop to compute transitive closure of flags.
266 loop {
267 let mut changed = false;
268 for &(u, v) in implications.iter() {
269 if self.has_flag(u) && !self.has_flag(v) {
270 self.activated_flags.push(v.to_string());
271 changed = true;
272 }
273 }
274 if !changed {
275 break;
276 }
277 }
278
279 let mut curr_region = "";
280 let mut seen_regions = Vec::new();
281 for line in lines {
282 let trimmed = line.trim();
283 if let Some(region) = trimmed.strip_prefix("// region:") {
284 assert_eq!(curr_region, "");
285 curr_region = region;
286 continue;
287 }
288 if let Some(region) = trimmed.strip_prefix("// endregion:") {
289 assert_eq!(curr_region, region);
290 curr_region = "";
291 continue;
292 }
293 seen_regions.push(curr_region);
294
295 let mut flag = curr_region;
296 if let Some(idx) = trimmed.find("// :") {
297 flag = &trimmed[idx + "// :".len()..];
298 }
299
300 let skip = if flag == "" {
301 false
302 } else {
303 assert!(!flag.starts_with(' '), "region marker starts with a space: {:?}", flag);
304 self.assert_valid_flag(flag);
305 !self.has_flag(flag)
306 };
307
308 if !skip {
309 buf.push_str(line)
310 }
311 }
312
313 for flag in &self.valid_flags {
314 if !seen_regions.iter().any(|it| it == flag) {
315 panic!("unused minicore flag: {:?}", flag);
316 }
317 }
318
319 buf
320 }
321}
322
175#[test] 323#[test]
176#[should_panic] 324#[should_panic]
177fn parse_fixture_checks_further_indented_metadata() { 325fn parse_fixture_checks_further_indented_metadata() {
@@ -189,12 +337,14 @@ fn parse_fixture_checks_further_indented_metadata() {
189 337
190#[test] 338#[test]
191fn parse_fixture_gets_full_meta() { 339fn parse_fixture_gets_full_meta() {
192 let parsed = Fixture::parse( 340 let (mini_core, parsed) = Fixture::parse(
193 r" 341 r#"
194 //- /lib.rs crate:foo deps:bar,baz cfg:foo=a,bar=b,atom env:OUTDIR=path/to,OTHER=foo 342//- minicore: coerce_unsized
195 mod m; 343//- /lib.rs crate:foo deps:bar,baz cfg:foo=a,bar=b,atom env:OUTDIR=path/to,OTHER=foo
196 ", 344mod m;
345"#,
197 ); 346 );
347 assert_eq!(mini_core.unwrap().activated_flags, vec!["coerce_unsized".to_string()]);
198 assert_eq!(1, parsed.len()); 348 assert_eq!(1, parsed.len());
199 349
200 let meta = &parsed[0]; 350 let meta = &parsed[0];
diff --git a/crates/test_utils/src/lib.rs b/crates/test_utils/src/lib.rs
index b2fe25f82..d55bae62a 100644
--- a/crates/test_utils/src/lib.rs
+++ b/crates/test_utils/src/lib.rs
@@ -23,7 +23,10 @@ use text_size::{TextRange, TextSize};
23pub use dissimilar::diff as __diff; 23pub use dissimilar::diff as __diff;
24pub use rustc_hash::FxHashMap; 24pub use rustc_hash::FxHashMap;
25 25
26pub use crate::{assert_linear::AssertLinear, fixture::Fixture}; 26pub use crate::{
27 assert_linear::AssertLinear,
28 fixture::{Fixture, MiniCore},
29};
27 30
28pub const CURSOR_MARKER: &str = "$0"; 31pub const CURSOR_MARKER: &str = "$0";
29pub const ESCAPED_CURSOR_MARKER: &str = "\\$0"; 32pub const ESCAPED_CURSOR_MARKER: &str = "\\$0";
diff --git a/crates/test_utils/src/minicore.rs b/crates/test_utils/src/minicore.rs
new file mode 100644
index 000000000..5ff60178c
--- /dev/null
+++ b/crates/test_utils/src/minicore.rs
@@ -0,0 +1,204 @@
1//! This is a fixture we use for tests that need lang items.
2//!
3//! We want to include the minimal subset of core for each test, so this file
4//! supports "conditional compilation". Tests use the following syntax to include minicore:
5//!
6//! //- minicore: flag1, flag2
7//!
8//! We then strip all the code marked with other flags.
9//!
10//! Available flags:
11//! sized:
12//! slice:
13//! range:
14//! unsize: sized
15//! deref: sized
16//! coerce_unsized: unsize
17//! pin:
18//! future: pin
19//! option:
20//! result:
21
22pub mod marker {
23 // region:sized
24 #[lang = "sized"]
25 #[fundamental]
26 #[rustc_specialization_trait]
27 pub trait Sized {}
28 // endregion:sized
29
30 // region:unsize
31 #[lang = "unsize"]
32 pub trait Unsize<T: ?Sized> {}
33 // endregion:unsize
34}
35
36pub mod ops {
37 // region:coerce_unsized
38 mod unsize {
39 use crate::marker::Unsize;
40
41 #[lang = "coerce_unsized"]
42 pub trait CoerceUnsized<T: ?Sized> {}
43
44 impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a mut U> for &'a mut T {}
45 impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b mut T {}
46 impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for &'a mut T {}
47 impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for &'a mut T {}
48
49 impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
50 impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for &'a T {}
51
52 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
53 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *mut T {}
54 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *const T {}
55 }
56 pub use self::unsize::CoerceUnsized;
57 // endregion:coerce_unsized
58
59 // region:deref
60 mod deref {
61 #[lang = "deref"]
62 pub trait Deref {
63 #[lang = "deref_target"]
64 type Target: ?Sized;
65 fn deref(&self) -> &Self::Target;
66 }
67 }
68 pub use self::deref::Deref;
69 // endregion:deref
70
71 // region:range
72 mod range {
73 #[lang = "RangeFull"]
74 pub struct RangeFull;
75
76 #[lang = "Range"]
77 pub struct Range<Idx> {
78 pub start: Idx,
79 pub end: Idx,
80 }
81
82 #[lang = "RangeFrom"]
83 pub struct RangeFrom<Idx> {
84 pub start: Idx,
85 }
86
87 #[lang = "RangeTo"]
88 pub struct RangeTo<Idx> {
89 pub end: Idx,
90 }
91
92 #[lang = "RangeInclusive"]
93 pub struct RangeInclusive<Idx> {
94 pub(crate) start: Idx,
95 pub(crate) end: Idx,
96 pub(crate) exhausted: bool,
97 }
98
99 #[lang = "RangeToInclusive"]
100 pub struct RangeToInclusive<Idx> {
101 pub end: Idx,
102 }
103 }
104 pub use self::range::{Range, RangeFrom, RangeFull, RangeTo};
105 pub use self::range::{RangeInclusive, RangeToInclusive};
106 // endregion:range
107}
108
109// region:slice
110pub mod slice {
111 #[lang = "slice"]
112 impl<T> [T] {
113 pub fn len(&self) -> usize {
114 loop {}
115 }
116 }
117}
118// endregion:slice
119
120// region:option
121pub mod option {
122 pub enum Option<T> {
123 #[lang = "None"]
124 None,
125 #[lang = "Some"]
126 Some(T),
127 }
128}
129// endregion:option
130
131// region:result
132pub mod result {
133 pub enum Result<T, E> {
134 #[lang = "Ok"]
135 Ok(T),
136 #[lang = "Err"]
137 Err(E),
138 }
139}
140// endregion:result
141
142// region:pin
143pub mod pin {
144 #[lang = "pin"]
145 #[fundamental]
146 pub struct Pin<P> {
147 pointer: P,
148 }
149}
150// endregion:pin
151
152// region:future
153pub mod future {
154 use crate::{
155 pin::Pin,
156 task::{Context, Poll},
157 };
158
159 #[lang = "future_trait"]
160 pub trait Future {
161 type Output;
162 #[lang = "poll"]
163 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>;
164 }
165}
166pub mod task {
167 pub enum Poll<T> {
168 #[lang = "Ready"]
169 Ready(T),
170 #[lang = "Pending"]
171 Pending,
172 }
173
174 pub struct Context<'a> {
175 waker: &'a (),
176 }
177}
178// endregion:future
179
180pub mod prelude {
181 pub mod v1 {
182 pub use crate::{
183 marker::Sized, // :sized
184 option::Option::{self, None, Some}, // :option
185 result::Result::{self, Err, Ok}, // :result
186 };
187 }
188
189 pub mod rust_2015 {
190 pub use super::v1::*;
191 }
192
193 pub mod rust_2018 {
194 pub use super::v1::*;
195 }
196
197 pub mod rust_2021 {
198 pub use super::v1::*;
199 }
200}
201
202#[prelude_import]
203#[allow(unused)]
204use prelude::v1::*;