aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-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/patterns.rs76
-rw-r--r--crates/hir_ty/src/tests/regression.rs162
-rw-r--r--crates/hir_ty/src/tests/simple.rs767
-rw-r--r--crates/hir_ty/src/tests/traits.rs516
-rw-r--r--crates/ide/src/hover.rs15
-rw-r--r--crates/ide/src/lib.rs7
-rw-r--r--crates/ide/src/syntax_highlighting/highlight.rs50
-rw-r--r--crates/ide/src/syntax_highlighting/html.rs1
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlight_assoc_functions.html1
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html1
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlight_extern_crate.html1
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlight_injection.html1
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlight_strings.html1
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html6
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlighting.html1
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/injection.html1
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/rainbow_highlighting.html1
-rw-r--r--crates/ide/src/syntax_highlighting/tests.rs5
-rw-r--r--crates/ide_completion/src/completions/keyword.rs20
-rw-r--r--crates/ide_completion/src/render.rs34
-rw-r--r--crates/rust-analyzer/tests/slow-tests/support.rs4
-rw-r--r--crates/syntax/src/ast/node_ext.rs9
-rw-r--r--crates/test_utils/src/fixture.rs192
-rw-r--r--crates/test_utils/src/lib.rs5
-rw-r--r--crates/test_utils/src/minicore.rs234
28 files changed, 1498 insertions, 1372 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/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 1019e783b..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}
@@ -927,35 +923,33 @@ fn issue_6628() {
927fn issue_6852() { 923fn issue_6852() {
928 check_infer( 924 check_infer(
929 r#" 925 r#"
930 #[lang = "deref"] 926//- minicore: deref
931 pub trait Deref { 927use core::ops::Deref;
932 type Target;
933 }
934 928
935 struct BufWriter {} 929struct BufWriter {}
936 930
937 struct Mutex<T> {} 931struct Mutex<T> {}
938 struct MutexGuard<'a, T> {} 932struct MutexGuard<'a, T> {}
939 impl<T> Mutex<T> { 933impl<T> Mutex<T> {
940 fn lock(&self) -> MutexGuard<'_, T> {} 934 fn lock(&self) -> MutexGuard<'_, T> {}
941 } 935}
942 impl<'a, T: 'a> Deref for MutexGuard<'a, T> { 936impl<'a, T: 'a> Deref for MutexGuard<'a, T> {
943 type Target = T; 937 type Target = T;
944 } 938}
945 fn flush(&self) { 939fn flush(&self) {
946 let w: &Mutex<BufWriter>; 940 let w: &Mutex<BufWriter>;
947 *(w.lock()); 941 *(w.lock());
948 } 942}
949 "#, 943"#,
950 expect![[r#" 944 expect![[r#"
951 156..160 'self': &Mutex<T> 945 123..127 'self': &Mutex<T>
952 183..185 '{}': () 946 150..152 '{}': ()
953 267..271 'self': &{unknown} 947 234..238 'self': &{unknown}
954 273..323 '{ ...()); }': () 948 240..290 '{ ...()); }': ()
955 283..284 'w': &Mutex<BufWriter> 949 250..251 'w': &Mutex<BufWriter>
956 309..320 '*(w.lock())': BufWriter 950 276..287 '*(w.lock())': BufWriter
957 311..312 'w': &Mutex<BufWriter> 951 278..279 'w': &Mutex<BufWriter>
958 311..319 'w.lock()': MutexGuard<BufWriter> 952 278..286 'w.lock()': MutexGuard<BufWriter>
959 "#]], 953 "#]],
960 ); 954 );
961} 955}
@@ -977,37 +971,33 @@ fn param_overrides_fn() {
977fn lifetime_from_chalk_during_deref() { 971fn lifetime_from_chalk_during_deref() {
978 check_types( 972 check_types(
979 r#" 973 r#"
980 #[lang = "deref"] 974//- minicore: deref
981 pub trait Deref { 975struct Box<T: ?Sized> {}
982 type Target; 976impl<T> core::ops::Deref for Box<T> {
983 } 977 type Target = T;
984
985 struct Box<T: ?Sized> {}
986 impl<T> Deref for Box<T> {
987 type Target = T;
988 978
989 fn deref(&self) -> &Self::Target { 979 fn deref(&self) -> &Self::Target {
990 loop {} 980 loop {}
991 } 981 }
992 } 982}
993 983
994 trait Iterator { 984trait Iterator {
995 type Item; 985 type Item;
996 } 986}
997 987
998 pub struct Iter<'a, T: 'a> { 988pub struct Iter<'a, T: 'a> {
999 inner: Box<dyn IterTrait<'a, T, Item = &'a T> + 'a>, 989 inner: Box<dyn IterTrait<'a, T, Item = &'a T> + 'a>,
1000 } 990}
1001 991
1002 trait IterTrait<'a, T: 'a>: Iterator<Item = &'a T> { 992trait IterTrait<'a, T: 'a>: Iterator<Item = &'a T> {
1003 fn clone_box(&self); 993 fn clone_box(&self);
1004 } 994}
1005 995
1006 fn clone_iter<T>(s: Iter<T>) { 996fn clone_iter<T>(s: Iter<T>) {
1007 s.inner.clone_box(); 997 s.inner.clone_box();
1008 //^^^^^^^^^^^^^^^^^^^ () 998 //^^^^^^^^^^^^^^^^^^^ ()
1009 } 999}
1010 "#, 1000"#,
1011 ) 1001 )
1012} 1002}
1013 1003
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..065cca74f 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
@@ -1911,11 +1846,7 @@ fn test() {
1911fn closure_1() { 1846fn closure_1() {
1912 check_infer_with_mismatches( 1847 check_infer_with_mismatches(
1913 r#" 1848 r#"
1914#[lang = "fn_once"] 1849//- minicore: fn
1915trait FnOnce<Args> {
1916 type Output;
1917}
1918
1919enum Option<T> { Some(T), None } 1850enum Option<T> { Some(T), None }
1920impl<T> Option<T> { 1851impl<T> Option<T> {
1921 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 {} }
@@ -1928,34 +1859,34 @@ fn test() {
1928 let y: Option<i64> = x.map(|_v| 1); 1859 let y: Option<i64> = x.map(|_v| 1);
1929}"#, 1860}"#,
1930 expect![[r#" 1861 expect![[r#"
1931 147..151 'self': Option<T> 1862 86..90 'self': Option<T>
1932 153..154 'f': F 1863 92..93 'f': F
1933 172..183 '{ loop {} }': Option<U> 1864 111..122 '{ loop {} }': Option<U>
1934 174..181 'loop {}': ! 1865 113..120 'loop {}': !
1935 179..181 '{}': () 1866 118..120 '{}': ()
1936 197..316 '{ ... 1); }': () 1867 136..255 '{ ... 1); }': ()
1937 207..208 'x': Option<u32> 1868 146..147 'x': Option<u32>
1938 211..223 'Option::Some': Some<u32>(u32) -> Option<u32> 1869 150..162 'Option::Some': Some<u32>(u32) -> Option<u32>
1939 211..229 'Option...(1u32)': Option<u32> 1870 150..168 'Option...(1u32)': Option<u32>
1940 224..228 '1u32': u32 1871 163..167 '1u32': u32
1941 235..236 'x': Option<u32> 1872 174..175 'x': Option<u32>
1942 235..251 'x.map(...v + 1)': Option<u32> 1873 174..190 'x.map(...v + 1)': Option<u32>
1943 241..250 '|v| v + 1': |u32| -> u32 1874 180..189 '|v| v + 1': |u32| -> u32
1944 242..243 'v': u32 1875 181..182 'v': u32
1945 245..246 'v': u32 1876 184..185 'v': u32
1946 245..250 'v + 1': u32 1877 184..189 'v + 1': u32
1947 249..250 '1': u32 1878 188..189 '1': u32
1948 257..258 'x': Option<u32> 1879 196..197 'x': Option<u32>
1949 257..273 'x.map(... 1u64)': Option<u64> 1880 196..212 'x.map(... 1u64)': Option<u64>
1950 263..272 '|_v| 1u64': |u32| -> u64 1881 202..211 '|_v| 1u64': |u32| -> u64
1951 264..266 '_v': u32 1882 203..205 '_v': u32
1952 268..272 '1u64': u64 1883 207..211 '1u64': u64
1953 283..284 'y': Option<i64> 1884 222..223 'y': Option<i64>
1954 300..301 'x': Option<u32> 1885 239..240 'x': Option<u32>
1955 300..313 'x.map(|_v| 1)': Option<i64> 1886 239..252 'x.map(|_v| 1)': Option<i64>
1956 306..312 '|_v| 1': |u32| -> i64 1887 245..251 '|_v| 1': |u32| -> i64
1957 307..309 '_v': u32 1888 246..248 '_v': u32
1958 311..312 '1': i64 1889 250..251 '1': i64
1959 "#]], 1890 "#]],
1960 ); 1891 );
1961} 1892}
@@ -2029,11 +1960,7 @@ fn test<F: FnOnce(u32) -> u64>(f: F) {
2029fn closure_as_argument_inference_order() { 1960fn closure_as_argument_inference_order() {
2030 check_infer_with_mismatches( 1961 check_infer_with_mismatches(
2031 r#" 1962 r#"
2032#[lang = "fn_once"] 1963//- minicore: fn
2033trait FnOnce<Args> {
2034 type Output;
2035}
2036
2037fn 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 {} }
2038fn 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 {} }
2039 1966
@@ -2052,62 +1979,62 @@ fn test() {
2052 let x4 = S.foo2(|s| s.method(), S); 1979 let x4 = S.foo2(|s| s.method(), S);
2053}"#, 1980}"#,
2054 expect![[r#" 1981 expect![[r#"
2055 94..95 'x': T 1982 33..34 'x': T
2056 100..101 'f': F 1983 39..40 'f': F
2057 111..122 '{ loop {} }': U 1984 50..61 '{ loop {} }': U
2058 113..120 'loop {}': ! 1985 52..59 'loop {}': !
2059 118..120 '{}': () 1986 57..59 '{}': ()
2060 156..157 'f': F 1987 95..96 'f': F
2061 162..163 'x': T 1988 101..102 'x': T
2062 173..184 '{ loop {} }': U 1989 112..123 '{ loop {} }': U
2063 175..182 'loop {}': ! 1990 114..121 'loop {}': !
2064 180..182 '{}': () 1991 119..121 '{}': ()
2065 219..223 'self': S 1992 158..162 'self': S
2066 271..275 'self': S 1993 210..214 'self': S
2067 277..278 'x': T 1994 216..217 'x': T
2068 283..284 'f': F 1995 222..223 'f': F
2069 294..305 '{ loop {} }': U 1996 233..244 '{ loop {} }': U
2070 296..303 'loop {}': ! 1997 235..242 'loop {}': !
2071 301..303 '{}': () 1998 240..242 '{}': ()
2072 343..347 'self': S 1999 282..286 'self': S
2073 349..350 'f': F 2000 288..289 'f': F
2074 355..356 'x': T 2001 294..295 'x': T
2075 366..377 '{ loop {} }': U 2002 305..316 '{ loop {} }': U
2076 368..375 'loop {}': ! 2003 307..314 'loop {}': !
2077 373..375 '{}': () 2004 312..314 '{}': ()
2078 391..550 '{ ... S); }': () 2005 330..489 '{ ... S); }': ()
2079 401..403 'x1': u64 2006 340..342 'x1': u64
2080 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
2081 406..429 'foo1(S...hod())': u64 2008 345..368 'foo1(S...hod())': u64
2082 411..412 'S': S 2009 350..351 'S': S
2083 414..428 '|s| s.method()': |S| -> u64 2010 353..367 '|s| s.method()': |S| -> u64
2084 415..416 's': S 2011 354..355 's': S
2085 418..419 's': S 2012 357..358 's': S
2086 418..428 's.method()': u64 2013 357..367 's.method()': u64
2087 439..441 'x2': u64 2014 378..380 'x2': u64
2088 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
2089 444..467 'foo2(|...(), S)': u64 2016 383..406 'foo2(|...(), S)': u64
2090 449..463 '|s| s.method()': |S| -> u64 2017 388..402 '|s| s.method()': |S| -> u64
2091 450..451 's': S 2018 389..390 's': S
2092 453..454 's': S 2019 392..393 's': S
2093 453..463 's.method()': u64 2020 392..402 's.method()': u64
2094 465..466 'S': S 2021 404..405 'S': S
2095 477..479 'x3': u64 2022 416..418 'x3': u64
2096 482..483 'S': S 2023 421..422 'S': S
2097 482..507 'S.foo1...hod())': u64 2024 421..446 'S.foo1...hod())': u64
2098 489..490 'S': S 2025 428..429 'S': S
2099 492..506 '|s| s.method()': |S| -> u64 2026 431..445 '|s| s.method()': |S| -> u64
2100 493..494 's': S 2027 432..433 's': S
2101 496..497 's': S 2028 435..436 's': S
2102 496..506 's.method()': u64 2029 435..445 's.method()': u64
2103 517..519 'x4': u64 2030 456..458 'x4': u64
2104 522..523 'S': S 2031 461..462 'S': S
2105 522..547 'S.foo2...(), S)': u64 2032 461..486 'S.foo2...(), S)': u64
2106 529..543 '|s| s.method()': |S| -> u64 2033 468..482 '|s| s.method()': |S| -> u64
2107 530..531 's': S 2034 469..470 's': S
2108 533..534 's': S 2035 472..473 's': S
2109 533..543 's.method()': u64 2036 472..482 's.method()': u64
2110 545..546 'S': S 2037 484..485 'S': S
2111 "#]], 2038 "#]],
2112 ); 2039 );
2113} 2040}
@@ -2116,11 +2043,7 @@ fn test() {
2116fn fn_item_fn_trait() { 2043fn fn_item_fn_trait() {
2117 check_types( 2044 check_types(
2118 r#" 2045 r#"
2119#[lang = "fn_once"] 2046//- minicore: fn
2120trait FnOnce<Args> {
2121 type Output;
2122}
2123
2124struct S; 2047struct S;
2125 2048
2126fn foo() -> S {} 2049fn foo() -> S {}
@@ -2559,12 +2482,7 @@ fn test() -> impl Trait<i32> {
2559fn assoc_types_from_bounds() { 2482fn assoc_types_from_bounds() {
2560 check_infer( 2483 check_infer(
2561 r#" 2484 r#"
2562//- /main.rs 2485//- minicore: fn
2563#[lang = "fn_once"]
2564trait FnOnce<Args> {
2565 type Output;
2566}
2567
2568trait T { 2486trait T {
2569 type O; 2487 type O;
2570} 2488}
@@ -2583,15 +2501,15 @@ fn main() {
2583 f::<(), _>(|z| { z; }); 2501 f::<(), _>(|z| { z; });
2584}"#, 2502}"#,
2585 expect![[r#" 2503 expect![[r#"
2586 133..135 '_v': F 2504 72..74 '_v': F
2587 178..181 '{ }': () 2505 117..120 '{ }': ()
2588 193..224 '{ ... }); }': () 2506 132..163 '{ ... }); }': ()
2589 199..209 'f::<(), _>': fn f<(), |&()| -> ()>(|&()| -> ()) 2507 138..148 'f::<(), _>': fn f<(), |&()| -> ()>(|&()| -> ())
2590 199..221 'f::<()... z; })': () 2508 138..160 'f::<()... z; })': ()
2591 210..220 '|z| { z; }': |&()| -> () 2509 149..159 '|z| { z; }': |&()| -> ()
2592 211..212 'z': &() 2510 150..151 'z': &()
2593 214..220 '{ z; }': () 2511 153..159 '{ z; }': ()
2594 216..217 'z': &() 2512 155..156 'z': &()
2595 "#]], 2513 "#]],
2596 ); 2514 );
2597} 2515}
@@ -2625,12 +2543,9 @@ fn test<T: Trait>() {
2625fn dyn_trait_through_chalk() { 2543fn dyn_trait_through_chalk() {
2626 check_types( 2544 check_types(
2627 r#" 2545 r#"
2546//- minicore: deref
2628struct Box<T> {} 2547struct Box<T> {}
2629#[lang = "deref"] 2548impl<T> core::ops::Deref for Box<T> {
2630trait Deref {
2631 type Target;
2632}
2633impl<T> Deref for Box<T> {
2634 type Target = T; 2549 type Target = T;
2635} 2550}
2636trait Trait { 2551trait Trait {
@@ -2667,17 +2582,7 @@ fn test() {
2667fn iterator_chain() { 2582fn iterator_chain() {
2668 check_infer_with_mismatches( 2583 check_infer_with_mismatches(
2669 r#" 2584 r#"
2670//- /main.rs 2585//- minicore: fn, option
2671#[lang = "fn_once"]
2672trait FnOnce<Args> {
2673 type Output;
2674}
2675#[lang = "fn_mut"]
2676trait FnMut<Args>: FnOnce<Args> { }
2677
2678enum Option<T> { Some(T), None }
2679use Option::*;
2680
2681pub trait Iterator { 2586pub trait Iterator {
2682 type Item; 2587 type Item;
2683 2588
@@ -2737,46 +2642,46 @@ fn main() {
2737 .for_each(|y| { y; }); 2642 .for_each(|y| { y; });
2738}"#, 2643}"#,
2739 expect![[r#" 2644 expect![[r#"
2740 226..230 'self': Self 2645 61..65 'self': Self
2741 232..233 'f': F 2646 67..68 'f': F
2742 317..328 '{ loop {} }': FilterMap<Self, F> 2647 152..163 '{ loop {} }': FilterMap<Self, F>
2743 319..326 'loop {}': ! 2648 154..161 'loop {}': !
2744 324..326 '{}': () 2649 159..161 '{}': ()
2745 349..353 'self': Self 2650 184..188 'self': Self
2746 355..356 'f': F 2651 190..191 'f': F
2747 405..416 '{ loop {} }': () 2652 240..251 '{ loop {} }': ()
2748 407..414 'loop {}': ! 2653 242..249 'loop {}': !
2749 412..414 '{}': () 2654 247..249 '{}': ()
2750 525..529 'self': Self 2655 360..364 'self': Self
2751 854..858 'self': I 2656 689..693 'self': I
2752 865..885 '{ ... }': I 2657 700..720 '{ ... }': I
2753 875..879 'self': I 2658 710..714 'self': I
2754 944..955 '{ loop {} }': Vec<T> 2659 779..790 '{ loop {} }': Vec<T>
2755 946..953 'loop {}': ! 2660 781..788 'loop {}': !
2756 951..953 '{}': () 2661 786..788 '{}': ()
2757 1142..1269 '{ ... }); }': () 2662 977..1104 '{ ... }); }': ()
2758 1148..1163 'Vec::<i32>::new': fn new<i32>() -> Vec<i32> 2663 983..998 'Vec::<i32>::new': fn new<i32>() -> Vec<i32>
2759 1148..1165 'Vec::<...:new()': Vec<i32> 2664 983..1000 'Vec::<...:new()': Vec<i32>
2760 1148..1177 'Vec::<...iter()': IntoIter<i32> 2665 983..1012 'Vec::<...iter()': IntoIter<i32>
2761 1148..1240 'Vec::<...one })': FilterMap<IntoIter<i32>, |i32| -> Option<u32>> 2666 983..1075 'Vec::<...one })': FilterMap<IntoIter<i32>, |i32| -> Option<u32>>
2762 1148..1266 'Vec::<... y; })': () 2667 983..1101 'Vec::<... y; })': ()
2763 1194..1239 '|x| if...None }': |i32| -> Option<u32> 2668 1029..1074 '|x| if...None }': |i32| -> Option<u32>
2764 1195..1196 'x': i32 2669 1030..1031 'x': i32
2765 1198..1239 'if x >...None }': Option<u32> 2670 1033..1074 'if x >...None }': Option<u32>
2766 1201..1202 'x': i32 2671 1036..1037 'x': i32
2767 1201..1206 'x > 0': bool 2672 1036..1041 'x > 0': bool
2768 1205..1206 '0': i32 2673 1040..1041 '0': i32
2769 1207..1225 '{ Some...u32) }': Option<u32> 2674 1042..1060 '{ Some...u32) }': Option<u32>
2770 1209..1213 'Some': Some<u32>(u32) -> Option<u32> 2675 1044..1048 'Some': Some<u32>(u32) -> Option<u32>
2771 1209..1223 'Some(x as u32)': Option<u32> 2676 1044..1058 'Some(x as u32)': Option<u32>
2772 1214..1215 'x': i32 2677 1049..1050 'x': i32
2773 1214..1222 'x as u32': u32 2678 1049..1057 'x as u32': u32
2774 1231..1239 '{ None }': Option<u32> 2679 1066..1074 '{ None }': Option<u32>
2775 1233..1237 'None': Option<u32> 2680 1068..1072 'None': Option<u32>
2776 1255..1265 '|y| { y; }': |u32| -> () 2681 1090..1100 '|y| { y; }': |u32| -> ()
2777 1256..1257 'y': u32 2682 1091..1092 'y': u32
2778 1259..1265 '{ y; }': () 2683 1094..1100 '{ y; }': ()
2779 1261..1262 'y': u32 2684 1096..1097 'y': u32
2780 "#]], 2685 "#]],
2781 ); 2686 );
2782} 2687}
@@ -3063,45 +2968,23 @@ fn foo() {
3063fn infer_fn_trait_arg() { 2968fn infer_fn_trait_arg() {
3064 check_infer_with_mismatches( 2969 check_infer_with_mismatches(
3065 r#" 2970 r#"
3066 //- /lib.rs deps:std 2971//- minicore: fn, option
3067 2972fn foo<F, T>(f: F) -> T
3068 #[lang = "fn_once"] 2973where
3069 pub trait FnOnce<Args> { 2974 F: Fn(Option<i32>) -> T,
3070 type Output; 2975{
3071 2976 let s = None;
3072 extern "rust-call" fn call_once(&self, args: Args) -> Self::Output; 2977 f(s)
3073 } 2978}
3074 2979"#,
3075 #[lang = "fn"]
3076 pub trait Fn<Args>:FnOnce<Args> {
3077 extern "rust-call" fn call(&self, args: Args) -> Self::Output;
3078 }
3079
3080 enum Option<T> {
3081 None,
3082 Some(T)
3083 }
3084
3085 fn foo<F, T>(f: F) -> T
3086 where
3087 F: Fn(Option<i32>) -> T,
3088 {
3089 let s = None;
3090 f(s)
3091 }
3092 "#,
3093 expect![[r#" 2980 expect![[r#"
3094 101..105 'self': &Self 2981 13..14 'f': F
3095 107..111 'args': Args 2982 59..89 '{ ...f(s) }': T
3096 220..224 'self': &Self 2983 69..70 's': Option<i32>
3097 226..230 'args': Args 2984 73..77 'None': Option<i32>
3098 313..314 'f': F 2985 83..84 'f': F
3099 359..389 '{ ...f(s) }': T 2986 83..87 'f(s)': T
3100 369..370 's': Option<i32> 2987 85..86 's': Option<i32>
3101 373..377 'None': Option<i32>
3102 383..384 'f': F
3103 383..387 'f(s)': T
3104 385..386 's': Option<i32>
3105 "#]], 2988 "#]],
3106 ); 2989 );
3107} 2990}
@@ -3180,17 +3063,7 @@ fn foo() {
3180fn infer_dyn_fn_output() { 3063fn infer_dyn_fn_output() {
3181 check_types( 3064 check_types(
3182 r#" 3065 r#"
3183#[lang = "fn_once"] 3066//- minicore: fn
3184pub trait FnOnce<Args> {
3185 type Output;
3186 extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
3187}
3188
3189#[lang = "fn"]
3190pub trait Fn<Args>: FnOnce<Args> {
3191 extern "rust-call" fn call(&self, args: Args) -> Self::Output;
3192}
3193
3194fn foo() { 3067fn foo() {
3195 let f: &dyn Fn() -> i32; 3068 let f: &dyn Fn() -> i32;
3196 f(); 3069 f();
@@ -3203,12 +3076,7 @@ fn foo() {
3203fn infer_dyn_fn_once_output() { 3076fn infer_dyn_fn_once_output() {
3204 check_types( 3077 check_types(
3205 r#" 3078 r#"
3206#[lang = "fn_once"] 3079//- minicore: fn
3207pub trait FnOnce<Args> {
3208 type Output;
3209 extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
3210}
3211
3212fn foo() { 3080fn foo() {
3213 let f: dyn FnOnce() -> i32; 3081 let f: dyn FnOnce() -> i32;
3214 f(); 3082 f();
@@ -3643,20 +3511,16 @@ fn main() {
3643fn fn_returning_unit() { 3511fn fn_returning_unit() {
3644 check_infer_with_mismatches( 3512 check_infer_with_mismatches(
3645 r#" 3513 r#"
3646#[lang = "fn_once"] 3514//- minicore: fn
3647trait FnOnce<Args> {
3648 type Output;
3649}
3650
3651fn test<F: FnOnce()>(f: F) { 3515fn test<F: FnOnce()>(f: F) {
3652 let _: () = f(); 3516 let _: () = f();
3653}"#, 3517}"#,
3654 expect![[r#" 3518 expect![[r#"
3655 82..83 'f': F 3519 21..22 'f': F
3656 88..112 '{ ...f(); }': () 3520 27..51 '{ ...f(); }': ()
3657 98..99 '_': () 3521 37..38 '_': ()
3658 106..107 'f': F 3522 45..46 'f': F
3659 106..109 'f()': () 3523 45..48 'f()': ()
3660 "#]], 3524 "#]],
3661 ); 3525 );
3662} 3526}
@@ -3695,16 +3559,7 @@ impl foo::Foo for u32 {
3695fn infer_async_ret_type() { 3559fn infer_async_ret_type() {
3696 check_types( 3560 check_types(
3697 r#" 3561 r#"
3698//- /main.rs crate:main deps:core 3562//- minicore: future, result
3699
3700enum Result<T, E> {
3701 Ok(T),
3702 Err(E),
3703}
3704
3705use Result::*;
3706
3707
3708struct Fooey; 3563struct Fooey;
3709 3564
3710impl Fooey { 3565impl Fooey {
@@ -3727,15 +3582,6 @@ async fn get_accounts() -> Result<u32, ()> {
3727 // ^ u32 3582 // ^ u32
3728 Ok(ret) 3583 Ok(ret)
3729} 3584}
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"#, 3585"#,
3740 ); 3586 );
3741} 3587}
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs
index afeded315..529cf5f33 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: 245..427,
3025 focus_range: 140..146, 3020 focus_range: 284..290,
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/src/lib.rs b/crates/ide/src/lib.rs
index 9db387d26..4bd073cc3 100644
--- a/crates/ide/src/lib.rs
+++ b/crates/ide/src/lib.rs
@@ -567,7 +567,6 @@ impl Analysis {
567 }; 567 };
568 568
569 self.with_db(|db| { 569 self.with_db(|db| {
570 let ssr_assists = ssr::ssr_assists(db, &resolve, frange);
571 let diagnostic_assists = if include_fixes { 570 let diagnostic_assists = if include_fixes {
572 ide_diagnostics::diagnostics(db, diagnostics_config, &resolve, frange.file_id) 571 ide_diagnostics::diagnostics(db, diagnostics_config, &resolve, frange.file_id)
573 .into_iter() 572 .into_iter()
@@ -577,10 +576,12 @@ impl Analysis {
577 } else { 576 } else {
578 Vec::new() 577 Vec::new()
579 }; 578 };
579 let ssr_assists = ssr::ssr_assists(db, &resolve, frange);
580 let assists = ide_assists::assists(db, assist_config, resolve, frange);
580 581
581 let mut res = ide_assists::assists(db, assist_config, resolve, frange); 582 let mut res = diagnostic_assists;
582 res.extend(ssr_assists.into_iter()); 583 res.extend(ssr_assists.into_iter());
583 res.extend(diagnostic_assists.into_iter()); 584 res.extend(assists.into_iter());
584 585
585 res 586 res
586 }) 587 })
diff --git a/crates/ide/src/syntax_highlighting/highlight.rs b/crates/ide/src/syntax_highlighting/highlight.rs
index 7a53268e8..6834fe11a 100644
--- a/crates/ide/src/syntax_highlighting/highlight.rs
+++ b/crates/ide/src/syntax_highlighting/highlight.rs
@@ -48,7 +48,13 @@ pub(super) fn element(
48 match name_kind { 48 match name_kind {
49 Some(NameClass::ExternCrate(_)) => SymbolKind::Module.into(), 49 Some(NameClass::ExternCrate(_)) => SymbolKind::Module.into(),
50 Some(NameClass::Definition(def)) => { 50 Some(NameClass::Definition(def)) => {
51 highlight_def(db, krate, def) | HlMod::Definition 51 let mut h = highlight_def(db, krate, def) | HlMod::Definition;
52 if let Definition::ModuleDef(hir::ModuleDef::Trait(trait_)) = &def {
53 if trait_.is_unsafe(db) {
54 h |= HlMod::Unsafe;
55 }
56 }
57 h
52 } 58 }
53 Some(NameClass::ConstReference(def)) => highlight_def(db, krate, def), 59 Some(NameClass::ConstReference(def)) => highlight_def(db, krate, def),
54 Some(NameClass::PatFieldShorthand { field_ref, .. }) => { 60 Some(NameClass::PatFieldShorthand { field_ref, .. }) => {
@@ -87,20 +93,34 @@ pub(super) fn element(
87 93
88 let mut h = highlight_def(db, krate, def); 94 let mut h = highlight_def(db, krate, def);
89 95
90 if let Definition::Local(local) = &def { 96 match def {
91 if is_consumed_lvalue(name_ref.syntax().clone().into(), local, db) { 97 Definition::Local(local)
98 if is_consumed_lvalue(
99 name_ref.syntax().clone().into(),
100 &local,
101 db,
102 ) =>
103 {
92 h |= HlMod::Consuming; 104 h |= HlMod::Consuming;
93 } 105 }
94 } 106 Definition::ModuleDef(hir::ModuleDef::Trait(trait_))
95 107 if trait_.is_unsafe(db) =>
96 if let Some(parent) = name_ref.syntax().parent() { 108 {
97 if matches!(parent.kind(), FIELD_EXPR | RECORD_PAT_FIELD) { 109 if ast::Impl::for_trait_name_ref(&name_ref).is_some() {
98 if let Definition::Field(field) = def { 110 h |= HlMod::Unsafe;
99 if let hir::VariantDef::Union(_) = field.parent_def(db) { 111 }
100 h |= HlMod::Unsafe; 112 }
113 Definition::Field(field) => {
114 if let Some(parent) = name_ref.syntax().parent() {
115 if matches!(parent.kind(), FIELD_EXPR | RECORD_PAT_FIELD) {
116 if let hir::VariantDef::Union(_) = field.parent_def(db)
117 {
118 h |= HlMod::Unsafe;
119 }
101 } 120 }
102 } 121 }
103 } 122 }
123 _ => (),
104 } 124 }
105 125
106 h 126 h
@@ -354,15 +374,7 @@ fn highlight_def(db: &RootDatabase, krate: Option<hir::Crate>, def: Definition)
354 374
355 h 375 h
356 } 376 }
357 hir::ModuleDef::Trait(trait_) => { 377 hir::ModuleDef::Trait(_) => Highlight::new(HlTag::Symbol(SymbolKind::Trait)),
358 let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Trait));
359
360 if trait_.is_unsafe(db) {
361 h |= HlMod::Unsafe;
362 }
363
364 h
365 }
366 hir::ModuleDef::TypeAlias(type_) => { 378 hir::ModuleDef::TypeAlias(type_) => {
367 let mut h = Highlight::new(HlTag::Symbol(SymbolKind::TypeAlias)); 379 let mut h = Highlight::new(HlTag::Symbol(SymbolKind::TypeAlias));
368 380
diff --git a/crates/ide/src/syntax_highlighting/html.rs b/crates/ide/src/syntax_highlighting/html.rs
index 478facfee..21376a7ae 100644
--- a/crates/ide/src/syntax_highlighting/html.rs
+++ b/crates/ide/src/syntax_highlighting/html.rs
@@ -67,6 +67,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
67.field { color: #94BFF3; } 67.field { color: #94BFF3; }
68.function { color: #93E0E3; } 68.function { color: #93E0E3; }
69.function.unsafe { color: #BC8383; } 69.function.unsafe { color: #BC8383; }
70.trait.unsafe { color: #BC8383; }
70.operator.unsafe { color: #BC8383; } 71.operator.unsafe { color: #BC8383; }
71.parameter { color: #94BFF3; } 72.parameter { color: #94BFF3; }
72.text { color: #DCDCCC; } 73.text { color: #DCDCCC; }
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_assoc_functions.html b/crates/ide/src/syntax_highlighting/test_data/highlight_assoc_functions.html
index a0ea1db34..4e85f7c0b 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_assoc_functions.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_assoc_functions.html
@@ -15,6 +15,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
15.field { color: #94BFF3; } 15.field { color: #94BFF3; }
16.function { color: #93E0E3; } 16.function { color: #93E0E3; }
17.function.unsafe { color: #BC8383; } 17.function.unsafe { color: #BC8383; }
18.trait.unsafe { color: #BC8383; }
18.operator.unsafe { color: #BC8383; } 19.operator.unsafe { color: #BC8383; }
19.parameter { color: #94BFF3; } 20.parameter { color: #94BFF3; }
20.text { color: #DCDCCC; } 21.text { color: #DCDCCC; }
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html b/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html
index 921a956e6..79a285107 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html
@@ -15,6 +15,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
15.field { color: #94BFF3; } 15.field { color: #94BFF3; }
16.function { color: #93E0E3; } 16.function { color: #93E0E3; }
17.function.unsafe { color: #BC8383; } 17.function.unsafe { color: #BC8383; }
18.trait.unsafe { color: #BC8383; }
18.operator.unsafe { color: #BC8383; } 19.operator.unsafe { color: #BC8383; }
19.parameter { color: #94BFF3; } 20.parameter { color: #94BFF3; }
20.text { color: #DCDCCC; } 21.text { color: #DCDCCC; }
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_extern_crate.html b/crates/ide/src/syntax_highlighting/test_data/highlight_extern_crate.html
index ca9bb1e7d..13f589cc0 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_extern_crate.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_extern_crate.html
@@ -15,6 +15,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
15.field { color: #94BFF3; } 15.field { color: #94BFF3; }
16.function { color: #93E0E3; } 16.function { color: #93E0E3; }
17.function.unsafe { color: #BC8383; } 17.function.unsafe { color: #BC8383; }
18.trait.unsafe { color: #BC8383; }
18.operator.unsafe { color: #BC8383; } 19.operator.unsafe { color: #BC8383; }
19.parameter { color: #94BFF3; } 20.parameter { color: #94BFF3; }
20.text { color: #DCDCCC; } 21.text { color: #DCDCCC; }
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html b/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html
index 6202a03ce..50df376ae 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html
@@ -15,6 +15,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
15.field { color: #94BFF3; } 15.field { color: #94BFF3; }
16.function { color: #93E0E3; } 16.function { color: #93E0E3; }
17.function.unsafe { color: #BC8383; } 17.function.unsafe { color: #BC8383; }
18.trait.unsafe { color: #BC8383; }
18.operator.unsafe { color: #BC8383; } 19.operator.unsafe { color: #BC8383; }
19.parameter { color: #94BFF3; } 20.parameter { color: #94BFF3; }
20.text { color: #DCDCCC; } 21.text { color: #DCDCCC; }
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html b/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html
index e860d713e..96cb09642 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html
@@ -15,6 +15,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
15.field { color: #94BFF3; } 15.field { color: #94BFF3; }
16.function { color: #93E0E3; } 16.function { color: #93E0E3; }
17.function.unsafe { color: #BC8383; } 17.function.unsafe { color: #BC8383; }
18.trait.unsafe { color: #BC8383; }
18.operator.unsafe { color: #BC8383; } 19.operator.unsafe { color: #BC8383; }
19.parameter { color: #94BFF3; } 20.parameter { color: #94BFF3; }
20.text { color: #DCDCCC; } 21.text { color: #DCDCCC; }
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html b/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html
index 68165bdbf..55453468b 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html
@@ -15,6 +15,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
15.field { color: #94BFF3; } 15.field { color: #94BFF3; }
16.function { color: #93E0E3; } 16.function { color: #93E0E3; }
17.function.unsafe { color: #BC8383; } 17.function.unsafe { color: #BC8383; }
18.trait.unsafe { color: #BC8383; }
18.operator.unsafe { color: #BC8383; } 19.operator.unsafe { color: #BC8383; }
19.parameter { color: #94BFF3; } 20.parameter { color: #94BFF3; }
20.text { color: #DCDCCC; } 21.text { color: #DCDCCC; }
@@ -61,6 +62,11 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
61 <span class="field declaration">a</span><span class="colon">:</span> <span class="builtin_type">u16</span><span class="comma">,</span> 62 <span class="field declaration">a</span><span class="colon">:</span> <span class="builtin_type">u16</span><span class="comma">,</span>
62<span class="brace">}</span> 63<span class="brace">}</span>
63 64
65<span class="keyword unsafe">unsafe</span> <span class="keyword">trait</span> <span class="trait declaration unsafe">UnsafeTrait</span> <span class="brace">{</span><span class="brace">}</span>
66<span class="keyword unsafe">unsafe</span> <span class="keyword">impl</span> <span class="trait unsafe">UnsafeTrait</span> <span class="keyword">for</span> <span class="struct">Packed</span> <span class="brace">{</span><span class="brace">}</span>
67
68<span class="keyword">fn</span> <span class="function declaration">require_unsafe_trait</span><span class="angle">&lt;</span><span class="type_param declaration">T</span><span class="colon">:</span> <span class="trait">UnsafeTrait</span><span class="angle">&gt;</span><span class="parenthesis">(</span><span class="punctuation">_</span><span class="colon">:</span> <span class="type_param">T</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
69
64<span class="keyword">trait</span> <span class="trait declaration">DoTheAutoref</span> <span class="brace">{</span> 70<span class="keyword">trait</span> <span class="trait declaration">DoTheAutoref</span> <span class="brace">{</span>
65 <span class="keyword">fn</span> <span class="function associated declaration trait">calls_autoref</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration">self</span><span class="parenthesis">)</span><span class="semicolon">;</span> 71 <span class="keyword">fn</span> <span class="function associated declaration trait">calls_autoref</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration">self</span><span class="parenthesis">)</span><span class="semicolon">;</span>
66<span class="brace">}</span> 72<span class="brace">}</span>
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlighting.html b/crates/ide/src/syntax_highlighting/test_data/highlighting.html
index 59f1e8e4c..9232cf905 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlighting.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlighting.html
@@ -15,6 +15,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
15.field { color: #94BFF3; } 15.field { color: #94BFF3; }
16.function { color: #93E0E3; } 16.function { color: #93E0E3; }
17.function.unsafe { color: #BC8383; } 17.function.unsafe { color: #BC8383; }
18.trait.unsafe { color: #BC8383; }
18.operator.unsafe { color: #BC8383; } 19.operator.unsafe { color: #BC8383; }
19.parameter { color: #94BFF3; } 20.parameter { color: #94BFF3; }
20.text { color: #DCDCCC; } 21.text { color: #DCDCCC; }
diff --git a/crates/ide/src/syntax_highlighting/test_data/injection.html b/crates/ide/src/syntax_highlighting/test_data/injection.html
index 9ab46d05c..082837328 100644
--- a/crates/ide/src/syntax_highlighting/test_data/injection.html
+++ b/crates/ide/src/syntax_highlighting/test_data/injection.html
@@ -15,6 +15,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
15.field { color: #94BFF3; } 15.field { color: #94BFF3; }
16.function { color: #93E0E3; } 16.function { color: #93E0E3; }
17.function.unsafe { color: #BC8383; } 17.function.unsafe { color: #BC8383; }
18.trait.unsafe { color: #BC8383; }
18.operator.unsafe { color: #BC8383; } 19.operator.unsafe { color: #BC8383; }
19.parameter { color: #94BFF3; } 20.parameter { color: #94BFF3; }
20.text { color: #DCDCCC; } 21.text { color: #DCDCCC; }
diff --git a/crates/ide/src/syntax_highlighting/test_data/rainbow_highlighting.html b/crates/ide/src/syntax_highlighting/test_data/rainbow_highlighting.html
index 666b0b228..763917714 100644
--- a/crates/ide/src/syntax_highlighting/test_data/rainbow_highlighting.html
+++ b/crates/ide/src/syntax_highlighting/test_data/rainbow_highlighting.html
@@ -15,6 +15,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
15.field { color: #94BFF3; } 15.field { color: #94BFF3; }
16.function { color: #93E0E3; } 16.function { color: #93E0E3; }
17.function.unsafe { color: #BC8383; } 17.function.unsafe { color: #BC8383; }
18.trait.unsafe { color: #BC8383; }
18.operator.unsafe { color: #BC8383; } 19.operator.unsafe { color: #BC8383; }
19.parameter { color: #94BFF3; } 20.parameter { color: #94BFF3; }
20.text { color: #DCDCCC; } 21.text { color: #DCDCCC; }
diff --git a/crates/ide/src/syntax_highlighting/tests.rs b/crates/ide/src/syntax_highlighting/tests.rs
index f7d8334a0..4f0b1ce85 100644
--- a/crates/ide/src/syntax_highlighting/tests.rs
+++ b/crates/ide/src/syntax_highlighting/tests.rs
@@ -527,6 +527,11 @@ struct Packed {
527 a: u16, 527 a: u16,
528} 528}
529 529
530unsafe trait UnsafeTrait {}
531unsafe impl UnsafeTrait for Packed {}
532
533fn require_unsafe_trait<T: UnsafeTrait>(_: T) {}
534
530trait DoTheAutoref { 535trait DoTheAutoref {
531 fn calls_autoref(&self); 536 fn calls_autoref(&self);
532} 537}
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 add296124..70bf26cf4 100644
--- a/crates/ide_completion/src/render.rs
+++ b/crates/ide_completion/src/render.rs
@@ -1149,16 +1149,11 @@ fn main() {
1149 fn suggest_deref() { 1149 fn suggest_deref() {
1150 check_relevance( 1150 check_relevance(
1151 r#" 1151 r#"
1152#[lang = "deref"] 1152//- minicore: deref
1153trait Deref {
1154 type Target;
1155 fn deref(&self) -> &Self::Target;
1156}
1157
1158struct S; 1153struct S;
1159struct T(S); 1154struct T(S);
1160 1155
1161impl Deref for T { 1156impl core::ops::Deref for T {
1162 type Target = S; 1157 type Target = S;
1163 1158
1164 fn deref(&self) -> &Self::Target { 1159 fn deref(&self) -> &Self::Target {
@@ -1182,8 +1177,9 @@ fn main() {
1182 st T [] 1177 st T []
1183 st S [] 1178 st S []
1184 fn main() [] 1179 fn main() []
1185 tt Deref []
1186 fn foo(…) [] 1180 fn foo(…) []
1181 md core []
1182 tt Sized []
1187 "#]], 1183 "#]],
1188 ) 1184 )
1189 } 1185 }
@@ -1192,21 +1188,11 @@ fn main() {
1192 fn suggest_deref_mut() { 1188 fn suggest_deref_mut() {
1193 check_relevance( 1189 check_relevance(
1194 r#" 1190 r#"
1195#[lang = "deref"] 1191//- minicore: deref_mut
1196trait Deref {
1197 type Target;
1198 fn deref(&self) -> &Self::Target;
1199}
1200
1201#[lang = "deref_mut"]
1202pub trait DerefMut: Deref {
1203 fn deref_mut(&mut self) -> &mut Self::Target;
1204}
1205
1206struct S; 1192struct S;
1207struct T(S); 1193struct T(S);
1208 1194
1209impl Deref for T { 1195impl core::ops::Deref for T {
1210 type Target = S; 1196 type Target = S;
1211 1197
1212 fn deref(&self) -> &Self::Target { 1198 fn deref(&self) -> &Self::Target {
@@ -1214,7 +1200,7 @@ impl Deref for T {
1214 } 1200 }
1215} 1201}
1216 1202
1217impl DerefMut for T { 1203impl core::ops::DerefMut for T {
1218 fn deref_mut(&mut self) -> &mut Self::Target { 1204 fn deref_mut(&mut self) -> &mut Self::Target {
1219 &mut self.0 1205 &mut self.0
1220 } 1206 }
@@ -1233,12 +1219,12 @@ fn main() {
1233 lc m [local] 1219 lc m [local]
1234 lc t [local] 1220 lc t [local]
1235 lc &mut t [type+local] 1221 lc &mut t [type+local]
1236 tt DerefMut []
1237 tt Deref []
1238 fn foo(…) []
1239 st T [] 1222 st T []
1240 st S [] 1223 st S []
1241 fn main() [] 1224 fn main() []
1225 fn foo(…) []
1226 md core []
1227 tt Sized []
1242 "#]], 1228 "#]],
1243 ) 1229 )
1244 } 1230 }
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/syntax/src/ast/node_ext.rs b/crates/syntax/src/ast/node_ext.rs
index 3d27d2c1a..2bd9ad867 100644
--- a/crates/syntax/src/ast/node_ext.rs
+++ b/crates/syntax/src/ast/node_ext.rs
@@ -325,6 +325,15 @@ impl ast::Impl {
325 let second = types.next(); 325 let second = types.next();
326 (first, second) 326 (first, second)
327 } 327 }
328
329 pub fn for_trait_name_ref(name_ref: &ast::NameRef) -> Option<ast::Impl> {
330 let this = name_ref.syntax().ancestors().find_map(ast::Impl::cast)?;
331 if this.trait_()?.syntax().text_range().start() == name_ref.syntax().text_range().start() {
332 Some(this)
333 } else {
334 None
335 }
336 }
328} 337}
329 338
330#[derive(Debug, Clone, PartialEq, Eq)] 339#[derive(Debug, Clone, PartialEq, Eq)]
diff --git a/crates/test_utils/src/fixture.rs b/crates/test_utils/src/fixture.rs
index d0bddf7d8..005a5c092 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("//-") {
@@ -108,12 +129,22 @@ impl Fixture {
108 if line.starts_with("//-") { 129 if line.starts_with("//-") {
109 let meta = Fixture::parse_meta_line(line); 130 let meta = Fixture::parse_meta_line(line);
110 res.push(meta) 131 res.push(meta)
111 } else if let Some(entry) = res.last_mut() { 132 } else {
112 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 }
113 } 144 }
114 } 145 }
115 146
116 res 147 (mini_core, res)
117 } 148 }
118 149
119 //- /lib.rs crate:foo deps:bar,baz cfg:foo=a,bar=b env:OUTDIR=path/to,OTHER=foo 150 //- /lib.rs crate:foo deps:bar,baz cfg:foo=a,bar=b env:OUTDIR=path/to,OTHER=foo
@@ -133,7 +164,9 @@ impl Fixture {
133 let mut env = FxHashMap::default(); 164 let mut env = FxHashMap::default();
134 let mut introduce_new_source_root = false; 165 let mut introduce_new_source_root = false;
135 for component in components[1..].iter() { 166 for component in components[1..].iter() {
136 let (key, value) = component.split_once(':').unwrap(); 167 let (key, value) = component
168 .split_once(':')
169 .unwrap_or_else(|| panic!("invalid meta line: {:?}", meta));
137 match key { 170 match key {
138 "crate" => krate = Some(value.to_string()), 171 "crate" => krate = Some(value.to_string()),
139 "deps" => deps = value.split(',').map(|it| it.to_string()).collect(), 172 "deps" => deps = value.split(',').map(|it| it.to_string()).collect(),
@@ -172,6 +205,139 @@ impl Fixture {
172 } 205 }
173} 206}
174 207
208impl MiniCore {
209 fn has_flag(&self, flag: &str) -> bool {
210 self.activated_flags.iter().any(|it| it == flag)
211 }
212
213 #[track_caller]
214 fn assert_valid_flag(&self, flag: &str) {
215 if !self.valid_flags.iter().any(|it| it == flag) {
216 panic!("invalid flag: {:?}, valid flags: {:?}", flag, self.valid_flags);
217 }
218 }
219
220 fn parse(line: &str) -> MiniCore {
221 let mut res = MiniCore { activated_flags: Vec::new(), valid_flags: Vec::new() };
222
223 let line = line.strip_prefix("//- minicore:").unwrap().trim();
224 for entry in line.split(", ") {
225 if res.has_flag(entry) {
226 panic!("duplicate minicore flag: {:?}", entry)
227 }
228 res.activated_flags.push(entry.to_string())
229 }
230
231 res
232 }
233
234 /// Strips parts of minicore.rs which are flagged by inactive flags.
235 ///
236 /// This is probably over-engineered to support flags dependencies.
237 pub fn source_code(mut self) -> String {
238 let mut buf = String::new();
239 let raw_mini_core = include_str!("./minicore.rs");
240 let mut lines = raw_mini_core.split_inclusive('\n');
241
242 let mut parsing_flags = false;
243 let mut implications = Vec::new();
244
245 // Parse `//!` preamble and extract flags and dependencies.
246 for line in lines.by_ref() {
247 let line = match line.strip_prefix("//!") {
248 Some(it) => it,
249 None => {
250 assert!(line.trim().is_empty());
251 break;
252 }
253 };
254
255 if parsing_flags {
256 let (flag, deps) = line.split_once(':').unwrap();
257 let flag = flag.trim();
258 self.valid_flags.push(flag.to_string());
259 for dep in deps.split(", ") {
260 let dep = dep.trim();
261 if !dep.is_empty() {
262 self.assert_valid_flag(dep);
263 implications.push((flag, dep));
264 }
265 }
266 }
267
268 if line.contains("Available flags:") {
269 parsing_flags = true;
270 }
271 }
272
273 for flag in &self.activated_flags {
274 self.assert_valid_flag(flag);
275 }
276
277 // Fixed point loop to compute transitive closure of flags.
278 loop {
279 let mut changed = false;
280 for &(u, v) in implications.iter() {
281 if self.has_flag(u) && !self.has_flag(v) {
282 self.activated_flags.push(v.to_string());
283 changed = true;
284 }
285 }
286 if !changed {
287 break;
288 }
289 }
290
291 let mut active_regions = Vec::new();
292 let mut seen_regions = Vec::new();
293 for line in lines {
294 let trimmed = line.trim();
295 if let Some(region) = trimmed.strip_prefix("// region:") {
296 active_regions.push(region);
297 continue;
298 }
299 if let Some(region) = trimmed.strip_prefix("// endregion:") {
300 let prev = active_regions.pop().unwrap();
301 assert_eq!(prev, region);
302 continue;
303 }
304
305 let mut line_region = false;
306 if let Some(idx) = trimmed.find("// :") {
307 line_region = true;
308 active_regions.push(&trimmed[idx + "// :".len()..]);
309 }
310
311 let mut keep = true;
312 for &region in &active_regions {
313 assert!(
314 !region.starts_with(' '),
315 "region marker starts with a space: {:?}",
316 region
317 );
318 self.assert_valid_flag(region);
319 seen_regions.push(region);
320 keep &= self.has_flag(region);
321 }
322
323 if keep {
324 buf.push_str(line)
325 }
326 if line_region {
327 active_regions.pop().unwrap();
328 }
329 }
330
331 for flag in &self.valid_flags {
332 if !seen_regions.iter().any(|it| it == flag) {
333 panic!("unused minicore flag: {:?}", flag);
334 }
335 }
336 format!("{}", buf);
337 buf
338 }
339}
340
175#[test] 341#[test]
176#[should_panic] 342#[should_panic]
177fn parse_fixture_checks_further_indented_metadata() { 343fn parse_fixture_checks_further_indented_metadata() {
@@ -189,12 +355,14 @@ fn parse_fixture_checks_further_indented_metadata() {
189 355
190#[test] 356#[test]
191fn parse_fixture_gets_full_meta() { 357fn parse_fixture_gets_full_meta() {
192 let parsed = Fixture::parse( 358 let (mini_core, parsed) = Fixture::parse(
193 r" 359 r#"
194 //- /lib.rs crate:foo deps:bar,baz cfg:foo=a,bar=b,atom env:OUTDIR=path/to,OTHER=foo 360//- minicore: coerce_unsized
195 mod m; 361//- /lib.rs crate:foo deps:bar,baz cfg:foo=a,bar=b,atom env:OUTDIR=path/to,OTHER=foo
196 ", 362mod m;
363"#,
197 ); 364 );
365 assert_eq!(mini_core.unwrap().activated_flags, vec!["coerce_unsized".to_string()]);
198 assert_eq!(1, parsed.len()); 366 assert_eq!(1, parsed.len());
199 367
200 let meta = &parsed[0]; 368 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..e04ca58d2
--- /dev/null
+++ b/crates/test_utils/src/minicore.rs
@@ -0,0 +1,234 @@
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//! unsize: sized
13//! coerce_unsized: unsize
14//! slice:
15//! range:
16//! deref: sized
17//! deref_mut: deref
18//! fn:
19//! pin:
20//! future: pin
21//! option:
22//! result:
23
24pub mod marker {
25 // region:sized
26 #[lang = "sized"]
27 #[fundamental]
28 #[rustc_specialization_trait]
29 pub trait Sized {}
30 // endregion:sized
31
32 // region:unsize
33 #[lang = "unsize"]
34 pub trait Unsize<T: ?Sized> {}
35 // endregion:unsize
36}
37
38pub mod ops {
39 // region:coerce_unsized
40 mod unsize {
41 use crate::marker::Unsize;
42
43 #[lang = "coerce_unsized"]
44 pub trait CoerceUnsized<T: ?Sized> {}
45
46 impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a mut U> for &'a mut T {}
47 impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b mut T {}
48 impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for &'a mut T {}
49 impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for &'a mut T {}
50
51 impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
52 impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for &'a T {}
53
54 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
55 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *mut T {}
56 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *const T {}
57 }
58 pub use self::unsize::CoerceUnsized;
59 // endregion:coerce_unsized
60
61 // region:deref
62 mod deref {
63 #[lang = "deref"]
64 pub trait Deref {
65 #[lang = "deref_target"]
66 type Target: ?Sized;
67 fn deref(&self) -> &Self::Target;
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
75 }
76 pub use self::deref::Deref;
77 pub use self::deref::DerefMut; //:deref_mut
78 // endregion:deref
79
80 // region:range
81 mod range {
82 #[lang = "RangeFull"]
83 pub struct RangeFull;
84
85 #[lang = "Range"]
86 pub struct Range<Idx> {
87 pub start: Idx,
88 pub end: Idx,
89 }
90
91 #[lang = "RangeFrom"]
92 pub struct RangeFrom<Idx> {
93 pub start: Idx,
94 }
95
96 #[lang = "RangeTo"]
97 pub struct RangeTo<Idx> {
98 pub end: Idx,
99 }
100
101 #[lang = "RangeInclusive"]
102 pub struct RangeInclusive<Idx> {
103 pub(crate) start: Idx,
104 pub(crate) end: Idx,
105 pub(crate) exhausted: bool,
106 }
107
108 #[lang = "RangeToInclusive"]
109 pub struct RangeToInclusive<Idx> {
110 pub end: Idx,
111 }
112 }
113 pub use self::range::{Range, RangeFrom, RangeFull, RangeTo};
114 pub use self::range::{RangeInclusive, RangeToInclusive};
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
136}
137
138// region:slice
139pub mod slice {
140 #[lang = "slice"]
141 impl<T> [T] {
142 pub fn len(&self) -> usize {
143 loop {}
144 }
145 }
146}
147// endregion:slice
148
149// region:option
150pub mod option {
151 pub enum Option<T> {
152 #[lang = "None"]
153 None,
154 #[lang = "Some"]
155 Some(T),
156 }
157}
158// endregion:option
159
160// region:result
161pub mod result {
162 pub enum Result<T, E> {
163 #[lang = "Ok"]
164 Ok(T),
165 #[lang = "Err"]
166 Err(E),
167 }
168}
169// endregion:result
170
171// region:pin
172pub mod pin {
173 #[lang = "pin"]
174 #[fundamental]
175 pub struct Pin<P> {
176 pointer: P,
177 }
178}
179// endregion:pin
180
181// region:future
182pub mod future {
183 use crate::{
184 pin::Pin,
185 task::{Context, Poll},
186 };
187
188 #[lang = "future_trait"]
189 pub trait Future {
190 type Output;
191 #[lang = "poll"]
192 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>;
193 }
194}
195pub mod task {
196 pub enum Poll<T> {
197 #[lang = "Ready"]
198 Ready(T),
199 #[lang = "Pending"]
200 Pending,
201 }
202
203 pub struct Context<'a> {
204 waker: &'a (),
205 }
206}
207// endregion:future
208
209pub mod prelude {
210 pub mod v1 {
211 pub use crate::{
212 marker::Sized, // :sized
213 ops::{Fn, FnMut, FnOnce}, // :fn
214 option::Option::{self, None, Some}, // :option
215 result::Result::{self, Err, Ok}, // :result
216 };
217 }
218
219 pub mod rust_2015 {
220 pub use super::v1::*;
221 }
222
223 pub mod rust_2018 {
224 pub use super::v1::*;
225 }
226
227 pub mod rust_2021 {
228 pub use super::v1::*;
229 }
230}
231
232#[prelude_import]
233#[allow(unused)]
234use prelude::v1::*;