diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-06-16 21:28:23 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2021-06-16 21:28:23 +0100 |
commit | 7b4f5c0262bbdf7e9db81734eb9c82dd04eb82cb (patch) | |
tree | c96519e0107b3f844ba4e7d3dc988ef6c3735886 /crates | |
parent | d6b8af44829521a9f925c4d87599efa3fef38edc (diff) | |
parent | 35772256f8ff3c52e469fc2bd388ad80ff8d79c7 (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.rs | 47 | ||||
-rw-r--r-- | crates/hir_ty/src/tests/traits.rs | 16 | ||||
-rw-r--r-- | crates/ide_assists/src/handlers/fill_match_arms.rs | 34 | ||||
-rw-r--r-- | crates/ide_assists/src/handlers/generate_deref.rs | 27 | ||||
-rw-r--r-- | crates/ide_assists/src/handlers/replace_for_loop_with_for_each.rs | 185 | ||||
-rw-r--r-- | crates/test_utils/src/minicore.rs | 62 |
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() { | |||
418 | fn issue_2683_chars_impl() { | 418 | fn issue_2683_chars_impl() { |
419 | check_types( | 419 | check_types( |
420 | r#" | 420 | r#" |
421 | //- /main.rs crate:main deps:std | 421 | //- minicore: iterator |
422 | pub struct Chars<'a> {} | ||
423 | impl<'a> Iterator for Chars<'a> { | ||
424 | type Item = char; | ||
425 | fn next(&mut self) -> Option<char> {} | ||
426 | } | ||
427 | |||
422 | fn test() { | 428 | fn 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] | ||
429 | use self::prelude::rust_2018::*; | ||
430 | pub mod prelude { | ||
431 | pub mod rust_2018 { | ||
432 | pub use crate::iter::Iterator; | ||
433 | pub use crate::option::Option; | ||
434 | } | ||
435 | } | ||
436 | |||
437 | pub 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 | |||
452 | pub mod option { | ||
453 | pub enum Option<T> {} | ||
454 | } | ||
455 | |||
456 | pub 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>) { | |||
1492 | fn impl_trait_assoc_binding_projection_bug() { | 1492 | fn 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 |
1496 | pub trait Language { | 1496 | pub 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::*; | ||
1518 | mod 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)] |
280 | mod tests { | 280 | mod 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 | ||
720 | fn main() { | 721 | fn 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#" |
733 | fn main() { | 731 | fn 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 | ||
750 | fn main() { | 751 | fn 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 | ||
1011 | fn foo(opt: Option<i32>) { | 1012 | fn 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#" |
1022 | fn foo(opt: Option<i32>) { | 1018 | fn 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 | ||
192 | struct A { } | ||
199 | struct B { $0a: A } | 193 | struct B { $0a: A } |
200 | 194 | ||
201 | impl std::ops::Deref for B { | 195 | impl 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 | ||
212 | struct A { } | ||
216 | struct B($0A) | 213 | struct B($0A) |
217 | 214 | ||
218 | impl std::ops::Deref for B { | 215 | impl 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 |
104 | fn impls_core_iter(sema: &hir::Semantics<ide_db::RootDatabase>, iterable: &ast::Expr) -> bool { | 111 | fn 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 | ||
130 | pub struct EmptyIter; | ||
131 | impl Iterator for EmptyIter { | ||
132 | type Item = usize; | ||
133 | fn next(&mut self) -> Option<Self::Item> { None } | ||
134 | } | ||
135 | |||
136 | pub struct Empty; | ||
137 | impl Empty { | ||
138 | pub fn iter(&self) -> EmptyIter { EmptyIter } | ||
139 | pub fn iter_mut(&self) -> EmptyIter { EmptyIter } | ||
140 | } | ||
141 | |||
142 | pub 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" |
206 | use empty_iter::*; | 190 | //- minicore: iterator |
191 | struct Iter; | ||
192 | impl Iterator for Iter { | ||
193 | type Item = usize; | ||
194 | fn next(&mut self) -> Option<Self::Item> { None } | ||
195 | } | ||
196 | |||
197 | struct S; | ||
198 | impl S { | ||
199 | fn iter(&self) -> Iter { Iter } | ||
200 | fn iter_mut(&mut self) -> Iter { Iter } | ||
201 | } | ||
202 | |||
207 | fn main() { | 203 | fn 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" |
215 | use empty_iter::*; | 211 | struct Iter; |
212 | impl Iterator for Iter { | ||
213 | type Item = usize; | ||
214 | fn next(&mut self) -> Option<Self::Item> { None } | ||
215 | } | ||
216 | |||
217 | struct S; | ||
218 | impl S { | ||
219 | fn iter(&self) -> Iter { Iter } | ||
220 | fn iter_mut(&mut self) -> Iter { Iter } | ||
221 | } | ||
222 | |||
216 | fn main() { | 223 | fn 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" |
230 | use empty_iter::*; | 238 | struct NoIterMethod; |
231 | fn main() { | 239 | fn 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" |
239 | use empty_iter::*; | 247 | struct NoIterMethod; |
240 | fn main() { | 248 | fn 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" |
254 | use empty_iter::*; | 263 | //- minicore: iterator |
264 | struct Iter; | ||
265 | impl Iterator for Iter { | ||
266 | type Item = usize; | ||
267 | fn next(&mut self) -> Option<Self::Item> { None } | ||
268 | } | ||
269 | |||
270 | struct S; | ||
271 | impl S { | ||
272 | fn iter(&self) -> Iter { Iter } | ||
273 | fn iter_mut(&mut self) -> Iter { Iter } | ||
274 | } | ||
275 | |||
255 | fn main() { | 276 | fn 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" |
263 | use empty_iter::*; | 284 | struct Iter; |
285 | impl Iterator for Iter { | ||
286 | type Item = usize; | ||
287 | fn next(&mut self) -> Option<Self::Item> { None } | ||
288 | } | ||
289 | |||
290 | struct S; | ||
291 | impl S { | ||
292 | fn iter(&self) -> Iter { Iter } | ||
293 | fn iter_mut(&mut self) -> Iter { Iter } | ||
294 | } | ||
295 | |||
264 | fn main() { | 296 | fn 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#" |
301 | use empty_iter::*; | 335 | //- minicore: iterator |
336 | struct Iter; | ||
337 | impl Iterator for Iter { | ||
338 | type Item = usize; | ||
339 | fn next(&mut self) -> Option<Self::Item> { None } | ||
340 | } | ||
341 | |||
302 | fn main() { | 342 | fn 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#" |
310 | use empty_iter::*; | 349 | struct Iter; |
350 | impl Iterator for Iter { | ||
351 | type Item = usize; | ||
352 | fn next(&mut self) -> Option<Self::Item> { None } | ||
353 | } | ||
354 | |||
311 | fn main() { | 355 | fn 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 | ||
24 | pub mod marker { | 25 | pub 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 | ||
211 | pub 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 | |||
209 | pub mod prelude { | 270 | pub 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 |