aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--PRIVACY.md18
-rw-r--r--README.md4
-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
-rw-r--r--docs/user/.gitignore1
-rw-r--r--docs/user/manual.adoc20
-rw-r--r--editors/code/package.json2
-rw-r--r--editors/code/src/main.ts14
-rw-r--r--editors/code/src/net.ts8
-rw-r--r--editors/code/src/toolchain.ts16
-rw-r--r--xtask/src/tidy.rs2
37 files changed, 1546 insertions, 1409 deletions
diff --git a/PRIVACY.md b/PRIVACY.md
index 27e39ca60..718fbed12 100644
--- a/PRIVACY.md
+++ b/PRIVACY.md
@@ -1,17 +1 @@
1# Privacy Notes See the [Privacy](https://rust-analyzer.github.io/manual.html#security) section of the user manual.
2
3## LSP server binary
4
5The LSP server performs no network access in itself, but runs `cargo metadata` which will update or download the crate registry and the source code of the project dependencies.
6
7## Visual Studio Code extension
8
9The Code extension connects to GitHub to download updated LSP binaries and, if the nightly channel is selected, to perform update checks.
10
11## Other editor plugins
12
13Any other editor plugins that integrate with `rust-analyzer` are not under the control of the `rust-analyzer` developers. For any privacy concerns, you should check with their respective developers.
14
15## Others
16
17If `cargo check` is enabled (the default), any build scripts or procedural macros used by the project or its dependencies will be executed. This is also the case when `cargo check` is disabled, but build script or procedural macro support is enabled in `rust-analyzer` (on by default).
diff --git a/README.md b/README.md
index 5fbc03964..e01542416 100644
--- a/README.md
+++ b/README.md
@@ -27,6 +27,10 @@ If you want to **use** rust-analyzer's language server with your editor of
27choice, check [the manual](https://rust-analyzer.github.io/manual.html) folder. 27choice, check [the manual](https://rust-analyzer.github.io/manual.html) folder.
28It also contains some tips & tricks to help you be more productive when using rust-analyzer. 28It also contains some tips & tricks to help you be more productive when using rust-analyzer.
29 29
30## Security and Privacy
31
32See the corresponding sections of [the manual](https://rust-analyzer.github.io/manual.html#security).
33
30## Communication 34## Communication
31 35
32For usage and troubleshooting requests, please use "IDEs and Editors" category of the Rust forum: 36For usage and troubleshooting requests, please use "IDEs and Editors" category of the Rust forum:
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::*;
diff --git a/docs/user/.gitignore b/docs/user/.gitignore
new file mode 100644
index 000000000..c32b1bcec
--- /dev/null
+++ b/docs/user/.gitignore
@@ -0,0 +1 @@
manual.html
diff --git a/docs/user/manual.adoc b/docs/user/manual.adoc
index 9a8d76700..816e094c2 100644
--- a/docs/user/manual.adoc
+++ b/docs/user/manual.adoc
@@ -201,6 +201,15 @@ $ eselect repository enable guru && emaint sync -r guru
201$ emerge rust-analyzer-bin 201$ emerge rust-analyzer-bin
202---- 202----
203 203
204==== macOS
205
206The `rust-analyzer` binary can be installed via https://brew.sh/[Homebrew].
207
208[source,bash]
209----
210$ brew install rust-analyzer
211----
212
204=== Emacs 213=== Emacs
205 214
206Note this excellent https://robert.kra.hn/posts/2021-02-07_rust-with-emacs/[guide] from https://github.com/rksm[@rksm]. 215Note this excellent https://robert.kra.hn/posts/2021-02-07_rust-with-emacs/[guide] from https://github.com/rksm[@rksm].
@@ -609,9 +618,14 @@ Here is a **non-exhaustive** list of ways to make rust-analyzer execute arbitrar
609* VS Code plugin reads configuration from project directory, and that can be used to override paths to various executables, like `rustfmt` or `rust-analyzer` itself. 618* VS Code plugin reads configuration from project directory, and that can be used to override paths to various executables, like `rustfmt` or `rust-analyzer` itself.
610* rust-analyzer's syntax trees library uses a lot of `unsafe` and hasn't been properly audited for memory safety. 619* rust-analyzer's syntax trees library uses a lot of `unsafe` and hasn't been properly audited for memory safety.
611 620
612rust-analyzer itself doesn't access the network. 621== Privacy
613The VS Code plugin doesn't access the network unless the nightly channel is selected in the settings. 622
614In that case, the plugin uses the GitHub API to check for and download updates. 623The LSP server performs no network access in itself, but runs `cargo metadata` which will update or download the crate registry and the source code of the project dependencies.
624If enabled (the default), build scripts and procedural macros can do anything.
625
626The Code extension automatically connects to GitHub to download updated LSP binaries and, if the nightly channel is selected, to perform update checks using the GitHub API. For `rust-analyzer` developers, using `cargo xtask release` uses the same API to put together the release notes.
627
628Any other editor plugins are not under the control of the `rust-analyzer` developers. For any privacy concerns, you should check with their respective developers.
615 629
616== Features 630== Features
617 631
diff --git a/editors/code/package.json b/editors/code/package.json
index a88a5c44e..aa47bd0ed 100644
--- a/editors/code/package.json
+++ b/editors/code/package.json
@@ -313,7 +313,7 @@
313 }, 313 },
314 "rust-analyzer.updates.askBeforeDownload": { 314 "rust-analyzer.updates.askBeforeDownload": {
315 "type": "boolean", 315 "type": "boolean",
316 "default": true, 316 "default": false,
317 "description": "Whether to ask for permission before downloading any files from the Internet." 317 "description": "Whether to ask for permission before downloading any files from the Internet."
318 }, 318 },
319 "rust-analyzer.server.path": { 319 "rust-analyzer.server.path": {
diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts
index f58d26215..15f2151ad 100644
--- a/editors/code/src/main.ts
+++ b/editors/code/src/main.ts
@@ -158,7 +158,7 @@ export async function deactivate() {
158} 158}
159 159
160async function bootstrap(config: Config, state: PersistentState): Promise<string> { 160async function bootstrap(config: Config, state: PersistentState): Promise<string> {
161 await vscode.workspace.fs.createDirectory(config.globalStorageUri); 161 await vscode.workspace.fs.createDirectory(config.globalStorageUri).then();
162 162
163 if (!config.currentExtensionIsNightly) { 163 if (!config.currentExtensionIsNightly) {
164 await state.updateNightlyReleaseId(undefined); 164 await state.updateNightlyReleaseId(undefined);
@@ -277,11 +277,11 @@ async function patchelf(dest: vscode.Uri): Promise<void> {
277 ''; 277 '';
278 } 278 }
279 `; 279 `;
280 const origFile = vscode.Uri.file(dest.path + "-orig"); 280 const origFile = vscode.Uri.file(dest.fsPath + "-orig");
281 await vscode.workspace.fs.rename(dest, origFile); 281 await vscode.workspace.fs.rename(dest, origFile);
282 progress.report({ message: "Patching executable", increment: 20 }); 282 progress.report({ message: "Patching executable", increment: 20 });
283 await new Promise((resolve, reject) => { 283 await new Promise((resolve, reject) => {
284 const handle = exec(`nix-build -E - --argstr srcStr '${origFile.path}' -o '${dest.path}'`, 284 const handle = exec(`nix-build -E - --argstr srcStr '${origFile.fsPath}' -o '${dest.fsPath}'`,
285 (err, stdout, stderr) => { 285 (err, stdout, stderr) => {
286 if (err != null) { 286 if (err != null) {
287 reject(Error(stderr)); 287 reject(Error(stderr));
@@ -338,14 +338,14 @@ async function getServer(config: Config, state: PersistentState): Promise<string
338 await state.updateServerVersion(undefined); 338 await state.updateServerVersion(undefined);
339 } 339 }
340 340
341 if (state.serverVersion === config.package.version) return dest.path; 341 if (state.serverVersion === config.package.version) return dest.fsPath;
342 342
343 if (config.askBeforeDownload) { 343 if (config.askBeforeDownload) {
344 const userResponse = await vscode.window.showInformationMessage( 344 const userResponse = await vscode.window.showInformationMessage(
345 `Language server version ${config.package.version} for rust-analyzer is not installed.`, 345 `Language server version ${config.package.version} for rust-analyzer is not installed.`,
346 "Download now" 346 "Download now"
347 ); 347 );
348 if (userResponse !== "Download now") return dest.path; 348 if (userResponse !== "Download now") return dest.fsPath;
349 } 349 }
350 350
351 const releaseTag = config.package.releaseTag; 351 const releaseTag = config.package.releaseTag;
@@ -372,7 +372,7 @@ async function getServer(config: Config, state: PersistentState): Promise<string
372 } 372 }
373 373
374 await state.updateServerVersion(config.package.version); 374 await state.updateServerVersion(config.package.version);
375 return dest.path; 375 return dest.fsPath;
376} 376}
377 377
378function serverPath(config: Config): string | null { 378function serverPath(config: Config): string | null {
@@ -383,7 +383,7 @@ async function isNixOs(): Promise<boolean> {
383 try { 383 try {
384 const contents = (await vscode.workspace.fs.readFile(vscode.Uri.file("/etc/os-release"))).toString(); 384 const contents = (await vscode.workspace.fs.readFile(vscode.Uri.file("/etc/os-release"))).toString();
385 return contents.indexOf("ID=nixos") !== -1; 385 return contents.indexOf("ID=nixos") !== -1;
386 } catch (e) { 386 } catch {
387 return false; 387 return false;
388 } 388 }
389} 389}
diff --git a/editors/code/src/net.ts b/editors/code/src/net.ts
index 5c48c74e8..722dab756 100644
--- a/editors/code/src/net.ts
+++ b/editors/code/src/net.ts
@@ -91,7 +91,7 @@ export async function download(opts: DownloadOpts) {
91 // to prevent partially downloaded files when user kills vscode 91 // to prevent partially downloaded files when user kills vscode
92 // This also avoids overwriting running executables 92 // This also avoids overwriting running executables
93 const randomHex = crypto.randomBytes(5).toString("hex"); 93 const randomHex = crypto.randomBytes(5).toString("hex");
94 const rawDest = path.parse(opts.dest.path); 94 const rawDest = path.parse(opts.dest.fsPath);
95 const tempFilePath = vscode.Uri.joinPath(vscode.Uri.file(rawDest.dir), `${rawDest.name}${randomHex}`); 95 const tempFilePath = vscode.Uri.joinPath(vscode.Uri.file(rawDest.dir), `${rawDest.name}${randomHex}`);
96 96
97 await vscode.window.withProgress( 97 await vscode.window.withProgress(
@@ -116,7 +116,7 @@ export async function download(opts: DownloadOpts) {
116 } 116 }
117 ); 117 );
118 118
119 await vscode.workspace.fs.rename(tempFilePath, opts.dest); 119 await vscode.workspace.fs.rename(tempFilePath, opts.dest, { overwrite: true });
120} 120}
121 121
122async function downloadFile( 122async function downloadFile(
@@ -148,7 +148,7 @@ async function downloadFile(
148 const totalBytes = Number(res.headers.get('content-length')); 148 const totalBytes = Number(res.headers.get('content-length'));
149 assert(!Number.isNaN(totalBytes), "Sanity check of content-length protocol"); 149 assert(!Number.isNaN(totalBytes), "Sanity check of content-length protocol");
150 150
151 log.debug("Downloading file of", totalBytes, "bytes size from", urlString, "to", destFilePath.path); 151 log.debug("Downloading file of", totalBytes, "bytes size from", urlString, "to", destFilePath.fsPath);
152 152
153 let readBytes = 0; 153 let readBytes = 0;
154 res.body.on("data", (chunk: Buffer) => { 154 res.body.on("data", (chunk: Buffer) => {
@@ -156,7 +156,7 @@ async function downloadFile(
156 onProgress(readBytes, totalBytes); 156 onProgress(readBytes, totalBytes);
157 }); 157 });
158 158
159 const destFileStream = fs.createWriteStream(destFilePath.path, { mode }); 159 const destFileStream = fs.createWriteStream(destFilePath.fsPath, { mode });
160 const srcStream = gunzip ? res.body.pipe(zlib.createGunzip()) : res.body; 160 const srcStream = gunzip ? res.body.pipe(zlib.createGunzip()) : res.body;
161 161
162 await pipeline(srcStream, destFileStream); 162 await pipeline(srcStream, destFileStream);
diff --git a/editors/code/src/toolchain.ts b/editors/code/src/toolchain.ts
index 902d0ddda..355dd76fe 100644
--- a/editors/code/src/toolchain.ts
+++ b/editors/code/src/toolchain.ts
@@ -159,7 +159,7 @@ export const getPathForExecutable = memoize(
159 // it is not mentioned in docs and cannot be infered by the type signature... 159 // it is not mentioned in docs and cannot be infered by the type signature...
160 const standardPath = vscode.Uri.joinPath(vscode.Uri.file(os.homedir()), ".cargo", "bin", executableName); 160 const standardPath = vscode.Uri.joinPath(vscode.Uri.file(os.homedir()), ".cargo", "bin", executableName);
161 161
162 if (isFile(standardPath.path)) return standardPath.path; 162 if (isFileAtUri(standardPath)) return standardPath.fsPath;
163 } catch (err) { 163 } catch (err) {
164 log.error("Failed to read the fs info", err); 164 log.error("Failed to read the fs info", err);
165 } 165 }
@@ -177,9 +177,17 @@ function lookupInPath(exec: string): boolean {
177 : [candidate]; 177 : [candidate];
178 }); 178 });
179 179
180 return candidates.some(isFile); 180 return candidates.some(isFileAtPath);
181} 181}
182 182
183async function isFile(path: string): Promise<boolean> { 183async function isFileAtPath(path: string): Promise<boolean> {
184 return ((await vscode.workspace.fs.stat(vscode.Uri.file(path))).type & vscode.FileType.File) !== 0; 184 return isFileAtUri(vscode.Uri.file(path));
185}
186
187async function isFileAtUri(uri: vscode.Uri): Promise<boolean> {
188 try {
189 return ((await vscode.workspace.fs.stat(uri)).type & vscode.FileType.File) !== 0;
190 } catch {
191 return false;
192 }
185} 193}
diff --git a/xtask/src/tidy.rs b/xtask/src/tidy.rs
index 25ddb43b2..06219d155 100644
--- a/xtask/src/tidy.rs
+++ b/xtask/src/tidy.rs
@@ -354,7 +354,7 @@ fn check_test_attrs(path: &Path, text: &str) {
354 } 354 }
355 355
356 let panic_rule = 356 let panic_rule =
357 "https://github.com/rust-analyzer/rust-analyzer/blob/master/docs/dev/style.md#panic"; 357 "https://github.com/rust-analyzer/rust-analyzer/blob/master/docs/dev/style.md#should_panic";
358 let need_panic: &[&str] = &["test_utils/src/fixture.rs"]; 358 let need_panic: &[&str] = &["test_utils/src/fixture.rs"];
359 if text.contains("#[should_panic") && !need_panic.iter().any(|p| path.ends_with(p)) { 359 if text.contains("#[should_panic") && !need_panic.iter().any(|p| path.ends_with(p)) {
360 panic!( 360 panic!(