Merge #9304
9304: internal: cleanup tests r=matklad a=matklad
bors r+
🤖
Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
commit
7b4f5c0262
6 changed files with 212 additions and 159 deletions
|
|
@ -418,48 +418,17 @@ fn issue_2705() {
|
|||
fn issue_2683_chars_impl() {
|
||||
check_types(
|
||||
r#"
|
||||
//- /main.rs crate:main deps:std
|
||||
//- minicore: iterator
|
||||
pub struct Chars<'a> {}
|
||||
impl<'a> Iterator for Chars<'a> {
|
||||
type Item = char;
|
||||
fn next(&mut self) -> Option<char> {}
|
||||
}
|
||||
|
||||
fn test() {
|
||||
let chars: std::str::Chars<'_>;
|
||||
let chars: Chars<'_>;
|
||||
(chars.next(), chars.nth(1));
|
||||
} //^ (Option<char>, Option<char>)
|
||||
|
||||
//- /std.rs crate:std
|
||||
#[prelude_import]
|
||||
use self::prelude::rust_2018::*;
|
||||
pub mod prelude {
|
||||
pub mod rust_2018 {
|
||||
pub use crate::iter::Iterator;
|
||||
pub use crate::option::Option;
|
||||
}
|
||||
}
|
||||
|
||||
pub mod iter {
|
||||
pub use self::traits::Iterator;
|
||||
pub mod traits {
|
||||
pub use self::iterator::Iterator;
|
||||
|
||||
pub mod iterator {
|
||||
pub trait Iterator {
|
||||
type Item;
|
||||
fn next(&mut self) -> Option<Self::Item>;
|
||||
fn nth(&mut self, n: usize) -> Option<Self::Item> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub mod option {
|
||||
pub enum Option<T> {}
|
||||
}
|
||||
|
||||
pub mod str {
|
||||
pub struct Chars<'a> {}
|
||||
impl<'a> Iterator for Chars<'a> {
|
||||
type Item = char;
|
||||
fn next(&mut self) -> Option<char> {}
|
||||
}
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1492,7 +1492,7 @@ fn test<T: Trait<Type = u32>>(x: T, y: impl Trait<Type = i64>) {
|
|||
fn impl_trait_assoc_binding_projection_bug() {
|
||||
check_types(
|
||||
r#"
|
||||
//- /main.rs crate:main deps:std
|
||||
//- minicore: iterator
|
||||
pub trait Language {
|
||||
type Kind;
|
||||
}
|
||||
|
|
@ -1512,20 +1512,6 @@ fn api_walkthrough() {
|
|||
node.clone();
|
||||
} //^ {unknown}
|
||||
}
|
||||
|
||||
//- /std.rs crate:std
|
||||
#[prelude_import] use iter::*;
|
||||
mod iter {
|
||||
trait IntoIterator {
|
||||
type Item;
|
||||
}
|
||||
trait Iterator {
|
||||
type Item;
|
||||
}
|
||||
impl<T: Iterator> IntoIterator for T {
|
||||
type Item = <T as Iterator>::Item;
|
||||
}
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -278,8 +278,6 @@ fn build_pat(db: &RootDatabase, module: hir::Module, var: ExtendedVariant) -> Op
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use ide_db::helpers::FamousDefs;
|
||||
|
||||
use crate::tests::{
|
||||
check_assist, check_assist_not_applicable, check_assist_target, check_assist_unresolved,
|
||||
};
|
||||
|
|
@ -716,7 +714,10 @@ fn main() {
|
|||
|
||||
#[test]
|
||||
fn fill_match_arms_tuple_of_enum_partial_with_wildcards() {
|
||||
let ra_fixture = r#"
|
||||
check_assist(
|
||||
fill_match_arms,
|
||||
r#"
|
||||
//- minicore: option
|
||||
fn main() {
|
||||
let a = Some(1);
|
||||
let b = Some(());
|
||||
|
|
@ -725,10 +726,7 @@ fn main() {
|
|||
(None, Some(_)) => {}
|
||||
}
|
||||
}
|
||||
"#;
|
||||
check_assist(
|
||||
fill_match_arms,
|
||||
&format!("//- /main.rs crate:main deps:core{}{}", ra_fixture, FamousDefs::FIXTURE),
|
||||
"#,
|
||||
r#"
|
||||
fn main() {
|
||||
let a = Some(1);
|
||||
|
|
@ -746,17 +744,17 @@ fn main() {
|
|||
#[test]
|
||||
fn fill_match_arms_partial_with_deep_pattern() {
|
||||
// Fixme: cannot handle deep patterns
|
||||
let ra_fixture = r#"
|
||||
check_assist_not_applicable(
|
||||
fill_match_arms,
|
||||
r#"
|
||||
//- minicore: option
|
||||
fn main() {
|
||||
match $0Some(true) {
|
||||
Some(true) => {}
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
"#;
|
||||
check_assist_not_applicable(
|
||||
fill_match_arms,
|
||||
&format!("//- /main.rs crate:main deps:core{}{}", ra_fixture, FamousDefs::FIXTURE),
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -1007,17 +1005,15 @@ fn foo(a: A) {
|
|||
#[test]
|
||||
fn option_order() {
|
||||
cov_mark::check!(option_order);
|
||||
let before = r#"
|
||||
check_assist(
|
||||
fill_match_arms,
|
||||
r#"
|
||||
//- minicore: option
|
||||
fn foo(opt: Option<i32>) {
|
||||
match opt$0 {
|
||||
}
|
||||
}
|
||||
"#;
|
||||
let before = &format!("//- /main.rs crate:main deps:core{}{}", before, FamousDefs::FIXTURE);
|
||||
|
||||
check_assist(
|
||||
fill_match_arms,
|
||||
before,
|
||||
"#,
|
||||
r#"
|
||||
fn foo(opt: Option<i32>) {
|
||||
match opt {
|
||||
|
|
|
|||
|
|
@ -182,23 +182,17 @@ impl std::ops::Deref for B {
|
|||
);
|
||||
}
|
||||
|
||||
fn check_not_applicable(ra_fixture: &str) {
|
||||
let fixture = format!(
|
||||
"//- /main.rs crate:main deps:core,std\n{}\n{}",
|
||||
ra_fixture,
|
||||
FamousDefs::FIXTURE
|
||||
);
|
||||
check_assist_not_applicable(generate_deref, &fixture)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_generate_record_deref_not_applicable_if_already_impl() {
|
||||
cov_mark::check!(test_add_record_deref_impl_already_exists);
|
||||
check_not_applicable(
|
||||
r#"struct A { }
|
||||
check_assist_not_applicable(
|
||||
generate_deref,
|
||||
r#"
|
||||
//- minicore: deref
|
||||
struct A { }
|
||||
struct B { $0a: A }
|
||||
|
||||
impl std::ops::Deref for B {
|
||||
impl core::ops::Deref for B {
|
||||
type Target = A;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
|
|
@ -211,11 +205,14 @@ impl std::ops::Deref for B {
|
|||
#[test]
|
||||
fn test_generate_field_deref_not_applicable_if_already_impl() {
|
||||
cov_mark::check!(test_add_field_deref_impl_already_exists);
|
||||
check_not_applicable(
|
||||
r#"struct A { }
|
||||
check_assist_not_applicable(
|
||||
generate_deref,
|
||||
r#"
|
||||
//- minicore: deref
|
||||
struct A { }
|
||||
struct B($0A)
|
||||
|
||||
impl std::ops::Deref for B {
|
||||
impl core::ops::Deref for B {
|
||||
type Target = A;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
|
|
|
|||
|
|
@ -85,38 +85,48 @@ fn is_ref_and_impls_iter_method(
|
|||
let krate = scope.module()?.krate();
|
||||
let traits_in_scope = scope.traits_in_scope();
|
||||
let iter_trait = FamousDefs(sema, Some(krate)).core_iter_Iterator()?;
|
||||
let has_wanted_method = typ.iterate_method_candidates(
|
||||
sema.db,
|
||||
krate,
|
||||
&traits_in_scope,
|
||||
Some(&wanted_method),
|
||||
|_, func| {
|
||||
if func.ret_type(sema.db).impls_trait(sema.db, iter_trait, &[]) {
|
||||
return Some(());
|
||||
}
|
||||
None
|
||||
},
|
||||
);
|
||||
has_wanted_method.and(Some((expr_behind_ref, wanted_method)))
|
||||
|
||||
let has_wanted_method = typ
|
||||
.iterate_method_candidates(
|
||||
sema.db,
|
||||
krate,
|
||||
&traits_in_scope,
|
||||
Some(&wanted_method),
|
||||
|_, func| {
|
||||
if func.ret_type(sema.db).impls_trait(sema.db, iter_trait, &[]) {
|
||||
return Some(());
|
||||
}
|
||||
None
|
||||
},
|
||||
)
|
||||
.is_some();
|
||||
if !has_wanted_method {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some((expr_behind_ref, wanted_method))
|
||||
}
|
||||
|
||||
/// Whether iterable implements core::Iterator
|
||||
fn impls_core_iter(sema: &hir::Semantics<ide_db::RootDatabase>, iterable: &ast::Expr) -> bool {
|
||||
let it_typ = if let Some(i) = sema.type_of_expr(iterable) {
|
||||
i
|
||||
} else {
|
||||
return false;
|
||||
let it_typ = match sema.type_of_expr(iterable) {
|
||||
Some(it) => it,
|
||||
None => return false,
|
||||
};
|
||||
let module = if let Some(m) = sema.scope(iterable.syntax()).module() {
|
||||
m
|
||||
} else {
|
||||
return false;
|
||||
|
||||
let module = match sema.scope(iterable.syntax()).module() {
|
||||
Some(it) => it,
|
||||
None => return false,
|
||||
};
|
||||
|
||||
let krate = module.krate();
|
||||
if let Some(iter_trait) = FamousDefs(sema, Some(krate)).core_iter_Iterator() {
|
||||
return it_typ.impls_trait(sema.db, iter_trait, &[]);
|
||||
match FamousDefs(sema, Some(krate)).core_iter_Iterator() {
|
||||
Some(iter_trait) => {
|
||||
cov_mark::hit!(test_already_impls_iterator);
|
||||
it_typ.impls_trait(sema.db, iter_trait, &[])
|
||||
}
|
||||
None => false,
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
@ -125,33 +135,6 @@ mod tests {
|
|||
|
||||
use super::*;
|
||||
|
||||
const EMPTY_ITER_FIXTURE: &'static str = r"
|
||||
//- /lib.rs deps:core crate:empty_iter
|
||||
pub struct EmptyIter;
|
||||
impl Iterator for EmptyIter {
|
||||
type Item = usize;
|
||||
fn next(&mut self) -> Option<Self::Item> { None }
|
||||
}
|
||||
|
||||
pub struct Empty;
|
||||
impl Empty {
|
||||
pub fn iter(&self) -> EmptyIter { EmptyIter }
|
||||
pub fn iter_mut(&self) -> EmptyIter { EmptyIter }
|
||||
}
|
||||
|
||||
pub struct NoIterMethod;
|
||||
";
|
||||
|
||||
fn check_assist_with_fixtures(before: &str, after: &str) {
|
||||
let before = &format!(
|
||||
"//- /main.rs crate:main deps:core,empty_iter{}{}{}",
|
||||
before,
|
||||
FamousDefs::FIXTURE,
|
||||
EMPTY_ITER_FIXTURE
|
||||
);
|
||||
check_assist(replace_for_loop_with_for_each, before, after);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_not_for() {
|
||||
check_assist_not_applicable(
|
||||
|
|
@ -201,20 +184,44 @@ fn main() {
|
|||
|
||||
#[test]
|
||||
fn test_for_borrowed() {
|
||||
check_assist_with_fixtures(
|
||||
check_assist(
|
||||
replace_for_loop_with_for_each,
|
||||
r"
|
||||
use empty_iter::*;
|
||||
//- minicore: iterator
|
||||
struct Iter;
|
||||
impl Iterator for Iter {
|
||||
type Item = usize;
|
||||
fn next(&mut self) -> Option<Self::Item> { None }
|
||||
}
|
||||
|
||||
struct S;
|
||||
impl S {
|
||||
fn iter(&self) -> Iter { Iter }
|
||||
fn iter_mut(&mut self) -> Iter { Iter }
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = Empty;
|
||||
let x = S;
|
||||
for $0v in &x {
|
||||
let a = v * 2;
|
||||
}
|
||||
}
|
||||
",
|
||||
r"
|
||||
use empty_iter::*;
|
||||
struct Iter;
|
||||
impl Iterator for Iter {
|
||||
type Item = usize;
|
||||
fn next(&mut self) -> Option<Self::Item> { None }
|
||||
}
|
||||
|
||||
struct S;
|
||||
impl S {
|
||||
fn iter(&self) -> Iter { Iter }
|
||||
fn iter_mut(&mut self) -> Iter { Iter }
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = Empty;
|
||||
let x = S;
|
||||
x.iter().for_each(|v| {
|
||||
let a = v * 2;
|
||||
});
|
||||
|
|
@ -225,9 +232,10 @@ fn main() {
|
|||
|
||||
#[test]
|
||||
fn test_for_borrowed_no_iter_method() {
|
||||
check_assist_with_fixtures(
|
||||
check_assist(
|
||||
replace_for_loop_with_for_each,
|
||||
r"
|
||||
use empty_iter::*;
|
||||
struct NoIterMethod;
|
||||
fn main() {
|
||||
let x = NoIterMethod;
|
||||
for $0v in &x {
|
||||
|
|
@ -236,7 +244,7 @@ fn main() {
|
|||
}
|
||||
",
|
||||
r"
|
||||
use empty_iter::*;
|
||||
struct NoIterMethod;
|
||||
fn main() {
|
||||
let x = NoIterMethod;
|
||||
(&x).into_iter().for_each(|v| {
|
||||
|
|
@ -249,20 +257,44 @@ fn main() {
|
|||
|
||||
#[test]
|
||||
fn test_for_borrowed_mut() {
|
||||
check_assist_with_fixtures(
|
||||
check_assist(
|
||||
replace_for_loop_with_for_each,
|
||||
r"
|
||||
use empty_iter::*;
|
||||
//- minicore: iterator
|
||||
struct Iter;
|
||||
impl Iterator for Iter {
|
||||
type Item = usize;
|
||||
fn next(&mut self) -> Option<Self::Item> { None }
|
||||
}
|
||||
|
||||
struct S;
|
||||
impl S {
|
||||
fn iter(&self) -> Iter { Iter }
|
||||
fn iter_mut(&mut self) -> Iter { Iter }
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = Empty;
|
||||
let x = S;
|
||||
for $0v in &mut x {
|
||||
let a = v * 2;
|
||||
}
|
||||
}
|
||||
",
|
||||
r"
|
||||
use empty_iter::*;
|
||||
struct Iter;
|
||||
impl Iterator for Iter {
|
||||
type Item = usize;
|
||||
fn next(&mut self) -> Option<Self::Item> { None }
|
||||
}
|
||||
|
||||
struct S;
|
||||
impl S {
|
||||
fn iter(&self) -> Iter { Iter }
|
||||
fn iter_mut(&mut self) -> Iter { Iter }
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = Empty;
|
||||
let x = S;
|
||||
x.iter_mut().for_each(|v| {
|
||||
let a = v * 2;
|
||||
});
|
||||
|
|
@ -296,21 +328,32 @@ fn main() {
|
|||
|
||||
#[test]
|
||||
fn test_already_impls_iterator() {
|
||||
check_assist_with_fixtures(
|
||||
cov_mark::check!(test_already_impls_iterator);
|
||||
check_assist(
|
||||
replace_for_loop_with_for_each,
|
||||
r#"
|
||||
use empty_iter::*;
|
||||
//- minicore: iterator
|
||||
struct Iter;
|
||||
impl Iterator for Iter {
|
||||
type Item = usize;
|
||||
fn next(&mut self) -> Option<Self::Item> { None }
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = Empty;
|
||||
for$0 a in x.iter().take(1) {
|
||||
for$0 a in Iter.take(1) {
|
||||
println!("{}", a);
|
||||
}
|
||||
}
|
||||
"#,
|
||||
r#"
|
||||
use empty_iter::*;
|
||||
struct Iter;
|
||||
impl Iterator for Iter {
|
||||
type Item = usize;
|
||||
fn next(&mut self) -> Option<Self::Item> { None }
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = Empty;
|
||||
x.iter().take(1).for_each(|a| {
|
||||
Iter.take(1).for_each(|a| {
|
||||
println!("{}", a);
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
//! future: pin
|
||||
//! option:
|
||||
//! result:
|
||||
//! iterator: option
|
||||
|
||||
pub mod marker {
|
||||
// region:sized
|
||||
|
|
@ -206,9 +207,70 @@ pub mod task {
|
|||
}
|
||||
// endregion:future
|
||||
|
||||
// region:iterator
|
||||
pub mod iter {
|
||||
mod adapters {
|
||||
pub struct Take<I> {
|
||||
iter: I,
|
||||
n: usize,
|
||||
}
|
||||
|
||||
impl<I> Iterator for Take<I>
|
||||
where
|
||||
I: Iterator,
|
||||
{
|
||||
type Item = <I as Iterator>::Item;
|
||||
|
||||
fn next(&mut self) -> Option<<I as Iterator>::Item> {
|
||||
loop {}
|
||||
}
|
||||
}
|
||||
}
|
||||
pub use self::adapters::Take;
|
||||
|
||||
mod traits {
|
||||
mod iterator {
|
||||
use super::super::Take;
|
||||
|
||||
pub trait Iterator {
|
||||
type Item;
|
||||
#[lang = "next"]
|
||||
fn next(&mut self) -> Option<Self::Item>;
|
||||
fn nth(&mut self, n: usize) -> Option<Self::Item> {
|
||||
loop {}
|
||||
}
|
||||
fn take(self, n: usize) -> crate::iter::Take<Self> {
|
||||
loop {}
|
||||
}
|
||||
}
|
||||
}
|
||||
pub use self::iterator::Iterator;
|
||||
|
||||
mod collect {
|
||||
pub trait IntoIterator {
|
||||
type Item;
|
||||
type IntoIter: Iterator<Item = Self::Item>;
|
||||
#[lang = "into_iter"]
|
||||
fn into_iter(self) -> Self::IntoIter;
|
||||
}
|
||||
impl<I: Iterator> IntoIterator for I {
|
||||
type Item = I::Item;
|
||||
type IntoIter = I;
|
||||
fn into_iter(self) -> I {
|
||||
self
|
||||
}
|
||||
}
|
||||
}
|
||||
pub use self::collect::IntoIterator;
|
||||
}
|
||||
pub use self::traits::{IntoIterator, Iterator};
|
||||
}
|
||||
// endregion:iterator
|
||||
|
||||
pub mod prelude {
|
||||
pub mod v1 {
|
||||
pub use crate::{
|
||||
iter::{IntoIterator, Iterator}, // :iterator
|
||||
marker::Sized, // :sized
|
||||
ops::{Fn, FnMut, FnOnce}, // :fn
|
||||
option::Option::{self, None, Some}, // :option
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue