mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 21:13:37 +00:00
Add a bunch of tests for type inference involving traits
None of them works correctly yet, of course.
This commit is contained in:
parent
00b09bcd8c
commit
b7fdad8448
13 changed files with 403 additions and 0 deletions
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
created: "2019-03-02T13:52:02.767222917Z"
|
||||
creator: insta@0.6.3
|
||||
source: crates/ra_hir/src/ty/tests.rs
|
||||
expression: "&result"
|
||||
---
|
||||
[67; 100) '{ ...own; }': ()
|
||||
[77; 78) 'y': [unknown]
|
||||
[90; 97) 'unknown': [unknown]
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
---
|
||||
created: "2019-03-02T13:49:53.509955706Z"
|
||||
creator: insta@0.6.3
|
||||
source: crates/ra_hir/src/ty/tests.rs
|
||||
expression: "&result"
|
||||
---
|
||||
[59; 60) 't': T
|
||||
[65; 84) '{ ...d(); }': ()
|
||||
[71; 72) 't': T
|
||||
[71; 81) 't.method()': [unknown]
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
---
|
||||
created: "2019-03-02T13:49:53.477633667Z"
|
||||
creator: insta@0.6.3
|
||||
source: crates/ra_hir/src/ty/tests.rs
|
||||
expression: "&result"
|
||||
---
|
||||
[66; 67) 't': T
|
||||
[72; 91) '{ ...d(); }': ()
|
||||
[78; 79) 't': T
|
||||
[78; 88) 't.method()': [unknown]
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
---
|
||||
created: "2019-03-02T13:49:53.558635265Z"
|
||||
creator: insta@0.6.3
|
||||
source: crates/ra_hir/src/ty/tests.rs
|
||||
expression: "&result"
|
||||
---
|
||||
[86; 87) 't': T
|
||||
[92; 94) '{}': ()
|
||||
[105; 144) '{ ...(s); }': ()
|
||||
[115; 116) 's': S<[unknown]>
|
||||
[119; 120) 'S': S<[unknown]>(T) -> S<T>
|
||||
[119; 129) 'S(unknown)': S<[unknown]>
|
||||
[121; 128) 'unknown': [unknown]
|
||||
[135; 138) 'foo': fn foo<S<[unknown]>>(T) -> ()
|
||||
[135; 141) 'foo(s)': ()
|
||||
[139; 140) 's': S<[unknown]>
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
---
|
||||
created: "2019-03-02T13:49:53.572131028Z"
|
||||
creator: insta@0.6.3
|
||||
source: crates/ra_hir/src/ty/tests.rs
|
||||
expression: "&result"
|
||||
---
|
||||
[87; 88) 't': T
|
||||
[98; 100) '{}': ()
|
||||
[111; 163) '{ ...(s); }': ()
|
||||
[121; 122) 's': S<[unknown]>
|
||||
[125; 126) 'S': S<[unknown]>(T) -> S<T>
|
||||
[125; 135) 'S(unknown)': S<[unknown]>
|
||||
[127; 134) 'unknown': [unknown]
|
||||
[145; 146) 'x': u32
|
||||
[154; 157) 'foo': fn foo<u32, S<[unknown]>>(T) -> U
|
||||
[154; 160) 'foo(s)': u32
|
||||
[158; 159) 's': S<[unknown]>
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
created: "2019-03-02T13:49:53.680954394Z"
|
||||
creator: insta@0.6.3
|
||||
source: crates/ra_hir/src/ty/tests.rs
|
||||
expression: "&result"
|
||||
---
|
||||
[108; 181) '{ ...ter; }': ()
|
||||
[118; 119) 'x': i32
|
||||
[145; 146) '1': i32
|
||||
[156; 157) 'y': [unknown]
|
||||
[169; 178) 'no_matter': [unknown]
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
---
|
||||
created: "2019-03-02T13:49:53.756157395Z"
|
||||
creator: insta@0.6.3
|
||||
source: crates/ra_hir/src/ty/tests.rs
|
||||
expression: "&result"
|
||||
---
|
||||
[87; 193) '{ ...t(); }': ()
|
||||
[97; 99) 's1': S
|
||||
[105; 121) 'Defaul...efault': [unknown]
|
||||
[105; 123) 'Defaul...ault()': S
|
||||
[133; 135) 's2': [unknown]
|
||||
[138; 148) 'S::default': [unknown]
|
||||
[138; 150) 'S::default()': [unknown]
|
||||
[160; 162) 's3': [unknown]
|
||||
[165; 188) '<S as ...efault': [unknown]
|
||||
[165; 190) '<S as ...ault()': [unknown]
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
---
|
||||
created: "2019-03-02T13:49:53.771466423Z"
|
||||
creator: insta@0.6.3
|
||||
source: crates/ra_hir/src/ty/tests.rs
|
||||
expression: "&result"
|
||||
---
|
||||
[33; 37) 'self': &[unknown]
|
||||
[92; 111) '{ ...d(); }': ()
|
||||
[98; 99) 'S': S
|
||||
[98; 108) 'S.method()': [unknown]
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
---
|
||||
created: "2019-03-02T13:49:53.765202736Z"
|
||||
creator: insta@0.6.3
|
||||
source: crates/ra_hir/src/ty/tests.rs
|
||||
expression: "&result"
|
||||
---
|
||||
[33; 37) 'self': &[unknown]
|
||||
[102; 127) '{ ...d(); }': ()
|
||||
[108; 109) 'S': S<u32>(T) -> S<T>
|
||||
[108; 115) 'S(1u32)': S<u32>
|
||||
[108; 124) 'S(1u32...thod()': [unknown]
|
||||
[110; 114) '1u32': u32
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
---
|
||||
created: "2019-03-02T15:41:07.568155273Z"
|
||||
creator: insta@0.6.3
|
||||
source: crates/ra_hir/src/ty/tests.rs
|
||||
expression: "&result"
|
||||
---
|
||||
[63; 67) 'self': &[unknown]
|
||||
[169; 173) 'self': &[unknown]
|
||||
[300; 337) '{ ... }': ()
|
||||
[310; 311) 'S': S
|
||||
[310; 320) 'S.method()': [unknown]
|
||||
[416; 454) '{ ... }': ()
|
||||
[426; 427) 'S': S
|
||||
[426; 436) 'S.method()': [unknown]
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
---
|
||||
created: "2019-03-02T15:41:07.562949721Z"
|
||||
creator: insta@0.6.3
|
||||
source: crates/ra_hir/src/ty/tests.rs
|
||||
expression: "&result"
|
||||
---
|
||||
[31; 35) 'self': &[unknown]
|
||||
[110; 114) 'self': &[unknown]
|
||||
[170; 228) '{ ...i128 }': ()
|
||||
[176; 178) 'S1': S1
|
||||
[176; 187) 'S1.method()': [unknown]
|
||||
[203; 205) 'S2': S2
|
||||
[203; 214) 'S2.method()': [unknown]
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
---
|
||||
created: "2019-03-02T13:49:53.860659428Z"
|
||||
creator: insta@0.6.3
|
||||
source: crates/ra_hir/src/ty/tests.rs
|
||||
expression: "&result"
|
||||
---
|
||||
[29; 33) 'self': [unknown]
|
||||
[107; 198) '{ ...(S); }': ()
|
||||
[117; 118) 'x': u32
|
||||
[126; 127) 'S': S
|
||||
[126; 134) 'S.into()': u32
|
||||
[144; 145) 'y': u64
|
||||
[153; 154) 'S': S
|
||||
[153; 161) 'S.into()': u64
|
||||
[171; 172) 'z': [unknown]
|
||||
[175; 192) 'Into::...::into': [unknown]
|
||||
[175; 195) 'Into::...nto(S)': [unknown]
|
||||
[193; 194) 'S': S
|
||||
|
|
@ -1043,6 +1043,241 @@ fn test() {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn infer_trait_method_simple() {
|
||||
// the trait implementation is intentionally incomplete -- it shouldn't matter
|
||||
check_inference(
|
||||
"infer_trait_method_simple",
|
||||
r#"
|
||||
trait Trait1 {
|
||||
fn method(&self) -> u32;
|
||||
}
|
||||
struct S1;
|
||||
impl Trait1 for S1 {}
|
||||
trait Trait2 {
|
||||
fn method(&self) -> i128;
|
||||
}
|
||||
struct S2;
|
||||
impl Trait2 for S2 {}
|
||||
fn test() {
|
||||
S1.method(); // -> u32
|
||||
S2.method(); // -> i128
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn infer_trait_method_scoped() {
|
||||
// the trait implementation is intentionally incomplete -- it shouldn't matter
|
||||
check_inference(
|
||||
"infer_trait_method_scoped",
|
||||
r#"
|
||||
struct S;
|
||||
mod foo {
|
||||
pub trait Trait1 {
|
||||
fn method(&self) -> u32;
|
||||
}
|
||||
impl Trait1 for super::S {}
|
||||
}
|
||||
mod bar {
|
||||
pub trait Trait2 {
|
||||
fn method(&self) -> i128;
|
||||
}
|
||||
impl Trait2 for super::S {}
|
||||
}
|
||||
|
||||
mod foo_test {
|
||||
use super::S;
|
||||
use super::foo::Trait1;
|
||||
fn test() {
|
||||
S.method(); // -> u32
|
||||
}
|
||||
}
|
||||
|
||||
mod bar_test {
|
||||
use super::S;
|
||||
use super::bar::Trait2;
|
||||
fn test() {
|
||||
S.method(); // -> i128
|
||||
}
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn infer_trait_method_generic_1() {
|
||||
// the trait implementation is intentionally incomplete -- it shouldn't matter
|
||||
check_inference(
|
||||
"infer_trait_method_generic_1",
|
||||
r#"
|
||||
trait Trait<T> {
|
||||
fn method(&self) -> T;
|
||||
}
|
||||
struct S;
|
||||
impl Trait<u32> for S {}
|
||||
fn test() {
|
||||
S.method();
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn infer_trait_method_generic_2() {
|
||||
// the trait implementation is intentionally incomplete -- it shouldn't matter
|
||||
check_inference(
|
||||
"infer_trait_method_generic_2",
|
||||
r#"
|
||||
trait Trait<T> {
|
||||
fn method(&self) -> T;
|
||||
}
|
||||
struct S<T>(T);
|
||||
impl<U> Trait<U> for S<U> {}
|
||||
fn test() {
|
||||
S(1u32).method();
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn infer_trait_assoc_method() {
|
||||
check_inference(
|
||||
"infer_trait_assoc_method",
|
||||
r#"
|
||||
trait Default {
|
||||
fn default() -> Self;
|
||||
}
|
||||
struct S;
|
||||
impl Default for S {}
|
||||
fn test() {
|
||||
let s1: S = Default::default();
|
||||
let s2 = S::default();
|
||||
let s3 = <S as Default>::default();
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn infer_from_bound_1() {
|
||||
check_inference(
|
||||
"infer_from_bound_1",
|
||||
r#"
|
||||
trait Trait<T> {}
|
||||
struct S<T>(T);
|
||||
impl<U> Trait<U> for S<U> {}
|
||||
fn foo<T: Trait<u32>>(t: T) {}
|
||||
fn test() {
|
||||
let s = S(unknown);
|
||||
foo(s);
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn infer_from_bound_2() {
|
||||
check_inference(
|
||||
"infer_from_bound_2",
|
||||
r#"
|
||||
trait Trait<T> {}
|
||||
struct S<T>(T);
|
||||
impl<U> Trait<U> for S<U> {}
|
||||
fn foo<U, T: Trait<U>>(t: T) -> U {}
|
||||
fn test() {
|
||||
let s = S(unknown);
|
||||
let x: u32 = foo(s);
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn infer_call_trait_method_on_generic_param_1() {
|
||||
check_inference(
|
||||
"infer_call_trait_method_on_generic_param_1",
|
||||
r#"
|
||||
trait Trait {
|
||||
fn method() -> u32;
|
||||
}
|
||||
fn test<T: Trait>(t: T) {
|
||||
t.method();
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn infer_call_trait_method_on_generic_param_2() {
|
||||
check_inference(
|
||||
"infer_call_trait_method_on_generic_param_2",
|
||||
r#"
|
||||
trait Trait<T> {
|
||||
fn method() -> T;
|
||||
}
|
||||
fn test<U, T: Trait<U>>(t: T) {
|
||||
t.method();
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn infer_with_multiple_trait_impls() {
|
||||
check_inference(
|
||||
"infer_with_multiple_trait_impls",
|
||||
r#"
|
||||
trait Into<T> {
|
||||
fn into(self) -> T;
|
||||
}
|
||||
struct S;
|
||||
impl Into<u32> for S;
|
||||
impl Into<u64> for S;
|
||||
fn test() {
|
||||
let x: u32 = S.into();
|
||||
let y: u64 = S.into();
|
||||
let z = Into::<u64>::into(S);
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn infer_project_associated_type() {
|
||||
check_inference(
|
||||
"infer_project_associated_type",
|
||||
r#"
|
||||
trait Iterable {
|
||||
type Item;
|
||||
}
|
||||
struct S;
|
||||
impl Iterable for S { type Item = u32; }
|
||||
fn test<T: Iterable>() {
|
||||
let x: <S as Iterable>::Item = 1;
|
||||
let y: T::Item = no_matter;
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn infer_associated_type_bound() {
|
||||
check_inference(
|
||||
"infer_associated_type_bound",
|
||||
r#"
|
||||
trait Iterable {
|
||||
type Item;
|
||||
}
|
||||
fn test<T: Iterable<Item=u32>>() {
|
||||
let y: T::Item = unknown;
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String {
|
||||
let func = source_binder::function_from_position(db, pos).unwrap();
|
||||
let body_source_map = func.body_source_map(db);
|
||||
|
|
Loading…
Reference in a new issue