From b7fdad8448cbd3a94c2cb877a1d209f3182ca0d5 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sat, 2 Mar 2019 14:53:26 +0100 Subject: Add a bunch of tests for type inference involving traits None of them works correctly yet, of course. --- .../tests__infer_associated_type_bound.snap | 10 + ...infer_call_trait_method_on_generic_param_1.snap | 11 + ...infer_call_trait_method_on_generic_param_2.snap | 11 + .../ty/snapshots/tests__infer_from_bound_1.snap | 17 ++ .../ty/snapshots/tests__infer_from_bound_2.snap | 18 ++ .../tests__infer_project_associated_type.snap | 12 ++ .../snapshots/tests__infer_trait_assoc_method.snap | 17 ++ .../tests__infer_trait_method_generic_1.snap | 11 + .../tests__infer_trait_method_generic_2.snap | 13 ++ .../tests__infer_trait_method_scoped.snap | 15 ++ .../tests__infer_trait_method_simple.snap | 14 ++ .../tests__infer_with_multiple_trait_impls.snap | 19 ++ crates/ra_hir/src/ty/tests.rs | 235 +++++++++++++++++++++ 13 files changed, 403 insertions(+) create mode 100644 crates/ra_hir/src/ty/snapshots/tests__infer_associated_type_bound.snap create mode 100644 crates/ra_hir/src/ty/snapshots/tests__infer_call_trait_method_on_generic_param_1.snap create mode 100644 crates/ra_hir/src/ty/snapshots/tests__infer_call_trait_method_on_generic_param_2.snap create mode 100644 crates/ra_hir/src/ty/snapshots/tests__infer_from_bound_1.snap create mode 100644 crates/ra_hir/src/ty/snapshots/tests__infer_from_bound_2.snap create mode 100644 crates/ra_hir/src/ty/snapshots/tests__infer_project_associated_type.snap create mode 100644 crates/ra_hir/src/ty/snapshots/tests__infer_trait_assoc_method.snap create mode 100644 crates/ra_hir/src/ty/snapshots/tests__infer_trait_method_generic_1.snap create mode 100644 crates/ra_hir/src/ty/snapshots/tests__infer_trait_method_generic_2.snap create mode 100644 crates/ra_hir/src/ty/snapshots/tests__infer_trait_method_scoped.snap create mode 100644 crates/ra_hir/src/ty/snapshots/tests__infer_trait_method_simple.snap create mode 100644 crates/ra_hir/src/ty/snapshots/tests__infer_with_multiple_trait_impls.snap (limited to 'crates/ra_hir/src') diff --git a/crates/ra_hir/src/ty/snapshots/tests__infer_associated_type_bound.snap b/crates/ra_hir/src/ty/snapshots/tests__infer_associated_type_bound.snap new file mode 100644 index 000000000..4dbde99f9 --- /dev/null +++ b/crates/ra_hir/src/ty/snapshots/tests__infer_associated_type_bound.snap @@ -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] + diff --git a/crates/ra_hir/src/ty/snapshots/tests__infer_call_trait_method_on_generic_param_1.snap b/crates/ra_hir/src/ty/snapshots/tests__infer_call_trait_method_on_generic_param_1.snap new file mode 100644 index 000000000..c56e6ba42 --- /dev/null +++ b/crates/ra_hir/src/ty/snapshots/tests__infer_call_trait_method_on_generic_param_1.snap @@ -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] + diff --git a/crates/ra_hir/src/ty/snapshots/tests__infer_call_trait_method_on_generic_param_2.snap b/crates/ra_hir/src/ty/snapshots/tests__infer_call_trait_method_on_generic_param_2.snap new file mode 100644 index 000000000..7791a57da --- /dev/null +++ b/crates/ra_hir/src/ty/snapshots/tests__infer_call_trait_method_on_generic_param_2.snap @@ -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] + diff --git a/crates/ra_hir/src/ty/snapshots/tests__infer_from_bound_1.snap b/crates/ra_hir/src/ty/snapshots/tests__infer_from_bound_1.snap new file mode 100644 index 000000000..c8d8e9806 --- /dev/null +++ b/crates/ra_hir/src/ty/snapshots/tests__infer_from_bound_1.snap @@ -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 +[119; 129) 'S(unknown)': S<[unknown]> +[121; 128) 'unknown': [unknown] +[135; 138) 'foo': fn foo>(T) -> () +[135; 141) 'foo(s)': () +[139; 140) 's': S<[unknown]> + diff --git a/crates/ra_hir/src/ty/snapshots/tests__infer_from_bound_2.snap b/crates/ra_hir/src/ty/snapshots/tests__infer_from_bound_2.snap new file mode 100644 index 000000000..37def29c3 --- /dev/null +++ b/crates/ra_hir/src/ty/snapshots/tests__infer_from_bound_2.snap @@ -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 +[125; 135) 'S(unknown)': S<[unknown]> +[127; 134) 'unknown': [unknown] +[145; 146) 'x': u32 +[154; 157) 'foo': fn foo>(T) -> U +[154; 160) 'foo(s)': u32 +[158; 159) 's': S<[unknown]> + diff --git a/crates/ra_hir/src/ty/snapshots/tests__infer_project_associated_type.snap b/crates/ra_hir/src/ty/snapshots/tests__infer_project_associated_type.snap new file mode 100644 index 000000000..6d5331799 --- /dev/null +++ b/crates/ra_hir/src/ty/snapshots/tests__infer_project_associated_type.snap @@ -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] + diff --git a/crates/ra_hir/src/ty/snapshots/tests__infer_trait_assoc_method.snap b/crates/ra_hir/src/ty/snapshots/tests__infer_trait_assoc_method.snap new file mode 100644 index 000000000..c09e1cf44 --- /dev/null +++ b/crates/ra_hir/src/ty/snapshots/tests__infer_trait_assoc_method.snap @@ -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) '(T) -> S +[108; 115) 'S(1u32)': S +[108; 124) 'S(1u32...thod()': [unknown] +[110; 114) '1u32': u32 + diff --git a/crates/ra_hir/src/ty/snapshots/tests__infer_trait_method_scoped.snap b/crates/ra_hir/src/ty/snapshots/tests__infer_trait_method_scoped.snap new file mode 100644 index 000000000..f2cce656d --- /dev/null +++ b/crates/ra_hir/src/ty/snapshots/tests__infer_trait_method_scoped.snap @@ -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] + diff --git a/crates/ra_hir/src/ty/snapshots/tests__infer_trait_method_simple.snap b/crates/ra_hir/src/ty/snapshots/tests__infer_trait_method_simple.snap new file mode 100644 index 000000000..22e83722d --- /dev/null +++ b/crates/ra_hir/src/ty/snapshots/tests__infer_trait_method_simple.snap @@ -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] + diff --git a/crates/ra_hir/src/ty/snapshots/tests__infer_with_multiple_trait_impls.snap b/crates/ra_hir/src/ty/snapshots/tests__infer_with_multiple_trait_impls.snap new file mode 100644 index 000000000..82c8bae58 --- /dev/null +++ b/crates/ra_hir/src/ty/snapshots/tests__infer_with_multiple_trait_impls.snap @@ -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 + diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index 2fdfb54f4..c1bd8d423 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs @@ -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 { + fn method(&self) -> T; +} +struct S; +impl Trait 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 { + fn method(&self) -> T; +} +struct S(T); +impl Trait for S {} +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 = ::default(); +} +"#, + ); +} + +#[test] +fn infer_from_bound_1() { + check_inference( + "infer_from_bound_1", + r#" +trait Trait {} +struct S(T); +impl Trait for S {} +fn foo>(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 {} +struct S(T); +impl Trait for S {} +fn foo>(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: 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 { + fn method() -> T; +} +fn test>(t: T) { + t.method(); +} +"#, + ); +} + +#[test] +fn infer_with_multiple_trait_impls() { + check_inference( + "infer_with_multiple_trait_impls", + r#" +trait Into { + fn into(self) -> T; +} +struct S; +impl Into for S; +impl Into for S; +fn test() { + let x: u32 = S.into(); + let y: u64 = S.into(); + let z = Into::::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() { + let x: ::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>() { + 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); -- cgit v1.2.3