aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-06-16 21:28:23 +0100
committerGitHub <[email protected]>2021-06-16 21:28:23 +0100
commit7b4f5c0262bbdf7e9db81734eb9c82dd04eb82cb (patch)
treec96519e0107b3f844ba4e7d3dc988ef6c3735886 /crates
parentd6b8af44829521a9f925c4d87599efa3fef38edc (diff)
parent35772256f8ff3c52e469fc2bd388ad80ff8d79c7 (diff)
Merge #9304
9304: internal: cleanup tests r=matklad a=matklad bors r+ 🤖 Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates')
-rw-r--r--crates/hir_ty/src/tests/regression.rs47
-rw-r--r--crates/hir_ty/src/tests/traits.rs16
-rw-r--r--crates/ide_assists/src/handlers/fill_match_arms.rs34
-rw-r--r--crates/ide_assists/src/handlers/generate_deref.rs27
-rw-r--r--crates/ide_assists/src/handlers/replace_for_loop_with_for_each.rs185
-rw-r--r--crates/test_utils/src/minicore.rs62
6 files changed, 212 insertions, 159 deletions
diff --git a/crates/hir_ty/src/tests/regression.rs b/crates/hir_ty/src/tests/regression.rs
index 1edec1615..e0ad41fb9 100644
--- a/crates/hir_ty/src/tests/regression.rs
+++ b/crates/hir_ty/src/tests/regression.rs
@@ -418,48 +418,17 @@ fn issue_2705() {
418fn issue_2683_chars_impl() { 418fn issue_2683_chars_impl() {
419 check_types( 419 check_types(
420 r#" 420 r#"
421//- /main.rs crate:main deps:std 421//- minicore: iterator
422pub struct Chars<'a> {}
423impl<'a> Iterator for Chars<'a> {
424 type Item = char;
425 fn next(&mut self) -> Option<char> {}
426}
427
422fn test() { 428fn test() {
423 let chars: std::str::Chars<'_>; 429 let chars: Chars<'_>;
424 (chars.next(), chars.nth(1)); 430 (chars.next(), chars.nth(1));
425} //^ (Option<char>, Option<char>) 431} //^ (Option<char>, Option<char>)
426
427//- /std.rs crate:std
428#[prelude_import]
429use self::prelude::rust_2018::*;
430pub mod prelude {
431 pub mod rust_2018 {
432 pub use crate::iter::Iterator;
433 pub use crate::option::Option;
434 }
435}
436
437pub mod iter {
438 pub use self::traits::Iterator;
439 pub mod traits {
440 pub use self::iterator::Iterator;
441
442 pub mod iterator {
443 pub trait Iterator {
444 type Item;
445 fn next(&mut self) -> Option<Self::Item>;
446 fn nth(&mut self, n: usize) -> Option<Self::Item> {}
447 }
448 }
449 }
450}
451
452pub mod option {
453 pub enum Option<T> {}
454}
455
456pub mod str {
457 pub struct Chars<'a> {}
458 impl<'a> Iterator for Chars<'a> {
459 type Item = char;
460 fn next(&mut self) -> Option<char> {}
461 }
462}
463"#, 432"#,
464 ); 433 );
465} 434}
diff --git a/crates/hir_ty/src/tests/traits.rs b/crates/hir_ty/src/tests/traits.rs
index 065cca74f..22e0bfc49 100644
--- a/crates/hir_ty/src/tests/traits.rs
+++ b/crates/hir_ty/src/tests/traits.rs
@@ -1492,7 +1492,7 @@ fn test<T: Trait<Type = u32>>(x: T, y: impl Trait<Type = i64>) {
1492fn impl_trait_assoc_binding_projection_bug() { 1492fn impl_trait_assoc_binding_projection_bug() {
1493 check_types( 1493 check_types(
1494 r#" 1494 r#"
1495//- /main.rs crate:main deps:std 1495//- minicore: iterator
1496pub trait Language { 1496pub trait Language {
1497 type Kind; 1497 type Kind;
1498} 1498}
@@ -1512,20 +1512,6 @@ fn api_walkthrough() {
1512 node.clone(); 1512 node.clone();
1513 } //^ {unknown} 1513 } //^ {unknown}
1514} 1514}
1515
1516//- /std.rs crate:std
1517#[prelude_import] use iter::*;
1518mod iter {
1519 trait IntoIterator {
1520 type Item;
1521 }
1522 trait Iterator {
1523 type Item;
1524 }
1525 impl<T: Iterator> IntoIterator for T {
1526 type Item = <T as Iterator>::Item;
1527 }
1528}
1529"#, 1515"#,
1530 ); 1516 );
1531} 1517}
diff --git a/crates/ide_assists/src/handlers/fill_match_arms.rs b/crates/ide_assists/src/handlers/fill_match_arms.rs
index 5a43bdd6f..cd0f6dba9 100644
--- a/crates/ide_assists/src/handlers/fill_match_arms.rs
+++ b/crates/ide_assists/src/handlers/fill_match_arms.rs
@@ -278,8 +278,6 @@ fn build_pat(db: &RootDatabase, module: hir::Module, var: ExtendedVariant) -> Op
278 278
279#[cfg(test)] 279#[cfg(test)]
280mod tests { 280mod tests {
281 use ide_db::helpers::FamousDefs;
282
283 use crate::tests::{ 281 use crate::tests::{
284 check_assist, check_assist_not_applicable, check_assist_target, check_assist_unresolved, 282 check_assist, check_assist_not_applicable, check_assist_target, check_assist_unresolved,
285 }; 283 };
@@ -716,7 +714,10 @@ fn main() {
716 714
717 #[test] 715 #[test]
718 fn fill_match_arms_tuple_of_enum_partial_with_wildcards() { 716 fn fill_match_arms_tuple_of_enum_partial_with_wildcards() {
719 let ra_fixture = r#" 717 check_assist(
718 fill_match_arms,
719 r#"
720//- minicore: option
720fn main() { 721fn main() {
721 let a = Some(1); 722 let a = Some(1);
722 let b = Some(()); 723 let b = Some(());
@@ -725,10 +726,7 @@ fn main() {
725 (None, Some(_)) => {} 726 (None, Some(_)) => {}
726 } 727 }
727} 728}
728"#; 729"#,
729 check_assist(
730 fill_match_arms,
731 &format!("//- /main.rs crate:main deps:core{}{}", ra_fixture, FamousDefs::FIXTURE),
732 r#" 730 r#"
733fn main() { 731fn main() {
734 let a = Some(1); 732 let a = Some(1);
@@ -746,17 +744,17 @@ fn main() {
746 #[test] 744 #[test]
747 fn fill_match_arms_partial_with_deep_pattern() { 745 fn fill_match_arms_partial_with_deep_pattern() {
748 // Fixme: cannot handle deep patterns 746 // Fixme: cannot handle deep patterns
749 let ra_fixture = r#" 747 check_assist_not_applicable(
748 fill_match_arms,
749 r#"
750//- minicore: option
750fn main() { 751fn main() {
751 match $0Some(true) { 752 match $0Some(true) {
752 Some(true) => {} 753 Some(true) => {}
753 None => {} 754 None => {}
754 } 755 }
755} 756}
756"#; 757"#,
757 check_assist_not_applicable(
758 fill_match_arms,
759 &format!("//- /main.rs crate:main deps:core{}{}", ra_fixture, FamousDefs::FIXTURE),
760 ); 758 );
761 } 759 }
762 760
@@ -1007,17 +1005,15 @@ fn foo(a: A) {
1007 #[test] 1005 #[test]
1008 fn option_order() { 1006 fn option_order() {
1009 cov_mark::check!(option_order); 1007 cov_mark::check!(option_order);
1010 let before = r#" 1008 check_assist(
1009 fill_match_arms,
1010 r#"
1011//- minicore: option
1011fn foo(opt: Option<i32>) { 1012fn foo(opt: Option<i32>) {
1012 match opt$0 { 1013 match opt$0 {
1013 } 1014 }
1014} 1015}
1015"#; 1016"#,
1016 let before = &format!("//- /main.rs crate:main deps:core{}{}", before, FamousDefs::FIXTURE);
1017
1018 check_assist(
1019 fill_match_arms,
1020 before,
1021 r#" 1017 r#"
1022fn foo(opt: Option<i32>) { 1018fn foo(opt: Option<i32>) {
1023 match opt { 1019 match opt {
diff --git a/crates/ide_assists/src/handlers/generate_deref.rs b/crates/ide_assists/src/handlers/generate_deref.rs
index 4998ff7a4..4e10fdb85 100644
--- a/crates/ide_assists/src/handlers/generate_deref.rs
+++ b/crates/ide_assists/src/handlers/generate_deref.rs
@@ -182,23 +182,17 @@ impl std::ops::Deref for B {
182 ); 182 );
183 } 183 }
184 184
185 fn check_not_applicable(ra_fixture: &str) {
186 let fixture = format!(
187 "//- /main.rs crate:main deps:core,std\n{}\n{}",
188 ra_fixture,
189 FamousDefs::FIXTURE
190 );
191 check_assist_not_applicable(generate_deref, &fixture)
192 }
193
194 #[test] 185 #[test]
195 fn test_generate_record_deref_not_applicable_if_already_impl() { 186 fn test_generate_record_deref_not_applicable_if_already_impl() {
196 cov_mark::check!(test_add_record_deref_impl_already_exists); 187 cov_mark::check!(test_add_record_deref_impl_already_exists);
197 check_not_applicable( 188 check_assist_not_applicable(
198 r#"struct A { } 189 generate_deref,
190 r#"
191//- minicore: deref
192struct A { }
199struct B { $0a: A } 193struct B { $0a: A }
200 194
201impl std::ops::Deref for B { 195impl core::ops::Deref for B {
202 type Target = A; 196 type Target = A;
203 197
204 fn deref(&self) -> &Self::Target { 198 fn deref(&self) -> &Self::Target {
@@ -211,11 +205,14 @@ impl std::ops::Deref for B {
211 #[test] 205 #[test]
212 fn test_generate_field_deref_not_applicable_if_already_impl() { 206 fn test_generate_field_deref_not_applicable_if_already_impl() {
213 cov_mark::check!(test_add_field_deref_impl_already_exists); 207 cov_mark::check!(test_add_field_deref_impl_already_exists);
214 check_not_applicable( 208 check_assist_not_applicable(
215 r#"struct A { } 209 generate_deref,
210 r#"
211//- minicore: deref
212struct A { }
216struct B($0A) 213struct B($0A)
217 214
218impl std::ops::Deref for B { 215impl core::ops::Deref for B {
219 type Target = A; 216 type Target = A;
220 217
221 fn deref(&self) -> &Self::Target { 218 fn deref(&self) -> &Self::Target {
diff --git a/crates/ide_assists/src/handlers/replace_for_loop_with_for_each.rs b/crates/ide_assists/src/handlers/replace_for_loop_with_for_each.rs
index 50b05ab0b..8e571723d 100644
--- a/crates/ide_assists/src/handlers/replace_for_loop_with_for_each.rs
+++ b/crates/ide_assists/src/handlers/replace_for_loop_with_for_each.rs
@@ -85,38 +85,48 @@ fn is_ref_and_impls_iter_method(
85 let krate = scope.module()?.krate(); 85 let krate = scope.module()?.krate();
86 let traits_in_scope = scope.traits_in_scope(); 86 let traits_in_scope = scope.traits_in_scope();
87 let iter_trait = FamousDefs(sema, Some(krate)).core_iter_Iterator()?; 87 let iter_trait = FamousDefs(sema, Some(krate)).core_iter_Iterator()?;
88 let has_wanted_method = typ.iterate_method_candidates( 88
89 sema.db, 89 let has_wanted_method = typ
90 krate, 90 .iterate_method_candidates(
91 &traits_in_scope, 91 sema.db,
92 Some(&wanted_method), 92 krate,
93 |_, func| { 93 &traits_in_scope,
94 if func.ret_type(sema.db).impls_trait(sema.db, iter_trait, &[]) { 94 Some(&wanted_method),
95 return Some(()); 95 |_, func| {
96 } 96 if func.ret_type(sema.db).impls_trait(sema.db, iter_trait, &[]) {
97 None 97 return Some(());
98 }, 98 }
99 ); 99 None
100 has_wanted_method.and(Some((expr_behind_ref, wanted_method))) 100 },
101 )
102 .is_some();
103 if !has_wanted_method {
104 return None;
105 }
106
107 Some((expr_behind_ref, wanted_method))
101} 108}
102 109
103/// Whether iterable implements core::Iterator 110/// Whether iterable implements core::Iterator
104fn impls_core_iter(sema: &hir::Semantics<ide_db::RootDatabase>, iterable: &ast::Expr) -> bool { 111fn impls_core_iter(sema: &hir::Semantics<ide_db::RootDatabase>, iterable: &ast::Expr) -> bool {
105 let it_typ = if let Some(i) = sema.type_of_expr(iterable) { 112 let it_typ = match sema.type_of_expr(iterable) {
106 i 113 Some(it) => it,
107 } else { 114 None => return false,
108 return false;
109 }; 115 };
110 let module = if let Some(m) = sema.scope(iterable.syntax()).module() { 116
111 m 117 let module = match sema.scope(iterable.syntax()).module() {
112 } else { 118 Some(it) => it,
113 return false; 119 None => return false,
114 }; 120 };
121
115 let krate = module.krate(); 122 let krate = module.krate();
116 if let Some(iter_trait) = FamousDefs(sema, Some(krate)).core_iter_Iterator() { 123 match FamousDefs(sema, Some(krate)).core_iter_Iterator() {
117 return it_typ.impls_trait(sema.db, iter_trait, &[]); 124 Some(iter_trait) => {
125 cov_mark::hit!(test_already_impls_iterator);
126 it_typ.impls_trait(sema.db, iter_trait, &[])
127 }
128 None => false,
118 } 129 }
119 false
120} 130}
121 131
122#[cfg(test)] 132#[cfg(test)]
@@ -125,33 +135,6 @@ mod tests {
125 135
126 use super::*; 136 use super::*;
127 137
128 const EMPTY_ITER_FIXTURE: &'static str = r"
129//- /lib.rs deps:core crate:empty_iter
130pub struct EmptyIter;
131impl Iterator for EmptyIter {
132 type Item = usize;
133 fn next(&mut self) -> Option<Self::Item> { None }
134}
135
136pub struct Empty;
137impl Empty {
138 pub fn iter(&self) -> EmptyIter { EmptyIter }
139 pub fn iter_mut(&self) -> EmptyIter { EmptyIter }
140}
141
142pub struct NoIterMethod;
143";
144
145 fn check_assist_with_fixtures(before: &str, after: &str) {
146 let before = &format!(
147 "//- /main.rs crate:main deps:core,empty_iter{}{}{}",
148 before,
149 FamousDefs::FIXTURE,
150 EMPTY_ITER_FIXTURE
151 );
152 check_assist(replace_for_loop_with_for_each, before, after);
153 }
154
155 #[test] 138 #[test]
156 fn test_not_for() { 139 fn test_not_for() {
157 check_assist_not_applicable( 140 check_assist_not_applicable(
@@ -201,20 +184,44 @@ fn main() {
201 184
202 #[test] 185 #[test]
203 fn test_for_borrowed() { 186 fn test_for_borrowed() {
204 check_assist_with_fixtures( 187 check_assist(
188 replace_for_loop_with_for_each,
205 r" 189 r"
206use empty_iter::*; 190//- minicore: iterator
191struct Iter;
192impl Iterator for Iter {
193 type Item = usize;
194 fn next(&mut self) -> Option<Self::Item> { None }
195}
196
197struct S;
198impl S {
199 fn iter(&self) -> Iter { Iter }
200 fn iter_mut(&mut self) -> Iter { Iter }
201}
202
207fn main() { 203fn main() {
208 let x = Empty; 204 let x = S;
209 for $0v in &x { 205 for $0v in &x {
210 let a = v * 2; 206 let a = v * 2;
211 } 207 }
212} 208}
213", 209",
214 r" 210 r"
215use empty_iter::*; 211struct Iter;
212impl Iterator for Iter {
213 type Item = usize;
214 fn next(&mut self) -> Option<Self::Item> { None }
215}
216
217struct S;
218impl S {
219 fn iter(&self) -> Iter { Iter }
220 fn iter_mut(&mut self) -> Iter { Iter }
221}
222
216fn main() { 223fn main() {
217 let x = Empty; 224 let x = S;
218 x.iter().for_each(|v| { 225 x.iter().for_each(|v| {
219 let a = v * 2; 226 let a = v * 2;
220 }); 227 });
@@ -225,9 +232,10 @@ fn main() {
225 232
226 #[test] 233 #[test]
227 fn test_for_borrowed_no_iter_method() { 234 fn test_for_borrowed_no_iter_method() {
228 check_assist_with_fixtures( 235 check_assist(
236 replace_for_loop_with_for_each,
229 r" 237 r"
230use empty_iter::*; 238struct NoIterMethod;
231fn main() { 239fn main() {
232 let x = NoIterMethod; 240 let x = NoIterMethod;
233 for $0v in &x { 241 for $0v in &x {
@@ -236,7 +244,7 @@ fn main() {
236} 244}
237", 245",
238 r" 246 r"
239use empty_iter::*; 247struct NoIterMethod;
240fn main() { 248fn main() {
241 let x = NoIterMethod; 249 let x = NoIterMethod;
242 (&x).into_iter().for_each(|v| { 250 (&x).into_iter().for_each(|v| {
@@ -249,20 +257,44 @@ fn main() {
249 257
250 #[test] 258 #[test]
251 fn test_for_borrowed_mut() { 259 fn test_for_borrowed_mut() {
252 check_assist_with_fixtures( 260 check_assist(
261 replace_for_loop_with_for_each,
253 r" 262 r"
254use empty_iter::*; 263//- minicore: iterator
264struct Iter;
265impl Iterator for Iter {
266 type Item = usize;
267 fn next(&mut self) -> Option<Self::Item> { None }
268}
269
270struct S;
271impl S {
272 fn iter(&self) -> Iter { Iter }
273 fn iter_mut(&mut self) -> Iter { Iter }
274}
275
255fn main() { 276fn main() {
256 let x = Empty; 277 let x = S;
257 for $0v in &mut x { 278 for $0v in &mut x {
258 let a = v * 2; 279 let a = v * 2;
259 } 280 }
260} 281}
261", 282",
262 r" 283 r"
263use empty_iter::*; 284struct Iter;
285impl Iterator for Iter {
286 type Item = usize;
287 fn next(&mut self) -> Option<Self::Item> { None }
288}
289
290struct S;
291impl S {
292 fn iter(&self) -> Iter { Iter }
293 fn iter_mut(&mut self) -> Iter { Iter }
294}
295
264fn main() { 296fn main() {
265 let x = Empty; 297 let x = S;
266 x.iter_mut().for_each(|v| { 298 x.iter_mut().for_each(|v| {
267 let a = v * 2; 299 let a = v * 2;
268 }); 300 });
@@ -296,21 +328,32 @@ fn main() {
296 328
297 #[test] 329 #[test]
298 fn test_already_impls_iterator() { 330 fn test_already_impls_iterator() {
299 check_assist_with_fixtures( 331 cov_mark::check!(test_already_impls_iterator);
332 check_assist(
333 replace_for_loop_with_for_each,
300 r#" 334 r#"
301use empty_iter::*; 335//- minicore: iterator
336struct Iter;
337impl Iterator for Iter {
338 type Item = usize;
339 fn next(&mut self) -> Option<Self::Item> { None }
340}
341
302fn main() { 342fn main() {
303 let x = Empty; 343 for$0 a in Iter.take(1) {
304 for$0 a in x.iter().take(1) {
305 println!("{}", a); 344 println!("{}", a);
306 } 345 }
307} 346}
308"#, 347"#,
309 r#" 348 r#"
310use empty_iter::*; 349struct Iter;
350impl Iterator for Iter {
351 type Item = usize;
352 fn next(&mut self) -> Option<Self::Item> { None }
353}
354
311fn main() { 355fn main() {
312 let x = Empty; 356 Iter.take(1).for_each(|a| {
313 x.iter().take(1).for_each(|a| {
314 println!("{}", a); 357 println!("{}", a);
315 }); 358 });
316} 359}
diff --git a/crates/test_utils/src/minicore.rs b/crates/test_utils/src/minicore.rs
index e04ca58d2..2f0da7fe5 100644
--- a/crates/test_utils/src/minicore.rs
+++ b/crates/test_utils/src/minicore.rs
@@ -20,6 +20,7 @@
20//! future: pin 20//! future: pin
21//! option: 21//! option:
22//! result: 22//! result:
23//! iterator: option
23 24
24pub mod marker { 25pub mod marker {
25 // region:sized 26 // region:sized
@@ -206,9 +207,70 @@ pub mod task {
206} 207}
207// endregion:future 208// endregion:future
208 209
210// region:iterator
211pub mod iter {
212 mod adapters {
213 pub struct Take<I> {
214 iter: I,
215 n: usize,
216 }
217
218 impl<I> Iterator for Take<I>
219 where
220 I: Iterator,
221 {
222 type Item = <I as Iterator>::Item;
223
224 fn next(&mut self) -> Option<<I as Iterator>::Item> {
225 loop {}
226 }
227 }
228 }
229 pub use self::adapters::Take;
230
231 mod traits {
232 mod iterator {
233 use super::super::Take;
234
235 pub trait Iterator {
236 type Item;
237 #[lang = "next"]
238 fn next(&mut self) -> Option<Self::Item>;
239 fn nth(&mut self, n: usize) -> Option<Self::Item> {
240 loop {}
241 }
242 fn take(self, n: usize) -> crate::iter::Take<Self> {
243 loop {}
244 }
245 }
246 }
247 pub use self::iterator::Iterator;
248
249 mod collect {
250 pub trait IntoIterator {
251 type Item;
252 type IntoIter: Iterator<Item = Self::Item>;
253 #[lang = "into_iter"]
254 fn into_iter(self) -> Self::IntoIter;
255 }
256 impl<I: Iterator> IntoIterator for I {
257 type Item = I::Item;
258 type IntoIter = I;
259 fn into_iter(self) -> I {
260 self
261 }
262 }
263 }
264 pub use self::collect::IntoIterator;
265 }
266 pub use self::traits::{IntoIterator, Iterator};
267}
268// endregion:iterator
269
209pub mod prelude { 270pub mod prelude {
210 pub mod v1 { 271 pub mod v1 {
211 pub use crate::{ 272 pub use crate::{
273 iter::{IntoIterator, Iterator}, // :iterator
212 marker::Sized, // :sized 274 marker::Sized, // :sized
213 ops::{Fn, FnMut, FnOnce}, // :fn 275 ops::{Fn, FnMut, FnOnce}, // :fn
214 option::Option::{self, None, Some}, // :option 276 option::Option::{self, None, Some}, // :option