From 816971ebc9207c5fb5779d448613dd171c27f398 Mon Sep 17 00:00:00 2001 From: Ville Penttinen Date: Thu, 21 Feb 2019 12:04:14 +0200 Subject: Implement basic support for Associated Methods and Constants This is done in `infer_path_expr`. When `Resolver::resolve_path` returns `PartiallyResolved`, we use the returned `Resolution` together with the given `segment_index` to check if we can find something matching the segment at segment_index in the impls for that particular type. --- .../snapshots/tests__infer_associated_const.snap | 14 +++ .../tests__infer_associated_method_enum.snap | 20 ++++ .../tests__infer_associated_method_generics.snap | 16 +++ .../tests__infer_associated_method_struct.snap | 16 +++ ...ests__infer_associated_method_with_modules.snap | 23 ++++ crates/ra_hir/src/ty/tests.rs | 133 +++++++++++++++++++++ 6 files changed, 222 insertions(+) create mode 100644 crates/ra_hir/src/ty/snapshots/tests__infer_associated_const.snap create mode 100644 crates/ra_hir/src/ty/snapshots/tests__infer_associated_method_enum.snap create mode 100644 crates/ra_hir/src/ty/snapshots/tests__infer_associated_method_generics.snap create mode 100644 crates/ra_hir/src/ty/snapshots/tests__infer_associated_method_struct.snap create mode 100644 crates/ra_hir/src/ty/snapshots/tests__infer_associated_method_with_modules.snap (limited to 'crates/ra_hir/src/ty') diff --git a/crates/ra_hir/src/ty/snapshots/tests__infer_associated_const.snap b/crates/ra_hir/src/ty/snapshots/tests__infer_associated_const.snap new file mode 100644 index 000000000..14ab8ba96 --- /dev/null +++ b/crates/ra_hir/src/ty/snapshots/tests__infer_associated_const.snap @@ -0,0 +1,14 @@ +--- +created: "2019-02-20T11:04:56.553382800Z" +creator: insta@0.6.3 +source: crates/ra_hir/src/ty/tests.rs +expression: "&result" +--- +[227; 305) '{ ...:ID; }': () +[237; 238) 'x': u32 +[241; 252) 'Struct::FOO': u32 +[262; 263) 'y': u32 +[266; 275) 'Enum::BAR': u32 +[285; 286) 'z': u32 +[289; 302) 'TraitTest::ID': u32 + diff --git a/crates/ra_hir/src/ty/snapshots/tests__infer_associated_method_enum.snap b/crates/ra_hir/src/ty/snapshots/tests__infer_associated_method_enum.snap new file mode 100644 index 000000000..8f27af88c --- /dev/null +++ b/crates/ra_hir/src/ty/snapshots/tests__infer_associated_method_enum.snap @@ -0,0 +1,20 @@ +--- +created: "2019-02-20T11:04:56.553382800Z" +creator: insta@0.6.3 +source: crates/ra_hir/src/ty/tests.rs +expression: "&result" +--- +[48; 68) '{ ... }': A +[58; 62) 'A::B': A +[89; 109) '{ ... }': A +[99; 103) 'A::C': A +[122; 179) '{ ... c; }': () +[132; 133) 'a': A +[136; 140) 'A::b': fn b() -> A +[136; 142) 'A::b()': A +[148; 149) 'a': A +[159; 160) 'c': A +[163; 167) 'A::c': fn c() -> A +[163; 169) 'A::c()': A +[175; 176) 'c': A + diff --git a/crates/ra_hir/src/ty/snapshots/tests__infer_associated_method_generics.snap b/crates/ra_hir/src/ty/snapshots/tests__infer_associated_method_generics.snap new file mode 100644 index 000000000..fe5d6590e --- /dev/null +++ b/crates/ra_hir/src/ty/snapshots/tests__infer_associated_method_generics.snap @@ -0,0 +1,16 @@ +--- +created: "2019-02-21T10:25:18.568887300Z" +creator: insta@0.6.3 +source: crates/ra_hir/src/ty/tests.rs +expression: "&result" +--- +[64; 67) 'val': T +[82; 109) '{ ... }': Gen +[92; 103) 'Gen { val }': Gen +[98; 101) 'val': T +[123; 155) '{ ...32); }': () +[133; 134) 'a': Gen<[unknown]> +[137; 146) 'Gen::make': fn make<[unknown]>(T) -> Gen +[137; 152) 'Gen::make(0u32)': Gen<[unknown]> +[147; 151) '0u32': u32 + diff --git a/crates/ra_hir/src/ty/snapshots/tests__infer_associated_method_struct.snap b/crates/ra_hir/src/ty/snapshots/tests__infer_associated_method_struct.snap new file mode 100644 index 000000000..29ca9b0ea --- /dev/null +++ b/crates/ra_hir/src/ty/snapshots/tests__infer_associated_method_struct.snap @@ -0,0 +1,16 @@ +--- +created: "2019-02-20T11:04:56.553382800Z" +creator: insta@0.6.3 +source: crates/ra_hir/src/ty/tests.rs +expression: "&result" +--- +[50; 76) '{ ... }': A +[60; 70) 'A { x: 0 }': A +[67; 68) '0': u32 +[89; 123) '{ ...a.x; }': () +[99; 100) 'a': A +[103; 109) 'A::new': fn new() -> A +[103; 111) 'A::new()': A +[117; 118) 'a': A +[117; 120) 'a.x': u32 + diff --git a/crates/ra_hir/src/ty/snapshots/tests__infer_associated_method_with_modules.snap b/crates/ra_hir/src/ty/snapshots/tests__infer_associated_method_with_modules.snap new file mode 100644 index 000000000..6584bef39 --- /dev/null +++ b/crates/ra_hir/src/ty/snapshots/tests__infer_associated_method_with_modules.snap @@ -0,0 +1,23 @@ +--- +created: "2019-02-21T08:55:53.926725400Z" +creator: insta@0.6.3 +source: crates/ra_hir/src/ty/tests.rs +expression: "&result" +--- +[56; 64) '{ A {} }': A +[58; 62) 'A {}': A +[126; 132) '{ 99 }': u32 +[128; 130) '99': u32 +[202; 210) '{ C {} }': C +[204; 208) 'C {}': C +[241; 325) '{ ...g(); }': () +[251; 252) 'x': A +[255; 266) 'a::A::thing': fn thing() -> A +[255; 268) 'a::A::thing()': A +[278; 279) 'y': u32 +[282; 293) 'b::B::thing': fn thing() -> u32 +[282; 295) 'b::B::thing()': u32 +[305; 306) 'z': C +[309; 320) 'c::C::thing': fn thing() -> C +[309; 322) 'c::C::thing()': C + diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index 4ab442b8a..c4b452ba4 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs @@ -586,6 +586,139 @@ fn test() -> i128 { ); } +#[test] +fn infer_associated_const() { + check_inference( + "infer_associated_const", + r#" +struct Struct; + +impl Struct { + const FOO: u32 = 1; +} + +enum Enum; + +impl Enum { + const BAR: u32 = 2; +} + +trait Trait { + const ID: u32; +} + +struct TraitTest; + +impl Trait for TraitTest { + const ID: u32 = 5; +} + +fn test() { + let x = Struct::FOO; + let y = Enum::BAR; + let z = TraitTest::ID; +} +"#, + ); +} + +#[test] +fn infer_associated_method_struct() { + check_inference( + "infer_associated_method_struct", + r#" +struct A { x: u32 }; + +impl A { + fn new() -> A { + A { x: 0 } + } +} +fn test() { + let a = A::new(); + a.x; +} +"#, + ); +} + +#[test] +fn infer_associated_method_enum() { + check_inference( + "infer_associated_method_enum", + r#" +enum A { B, C }; + +impl A { + pub fn b() -> A { + A::B + } + pub fn c() -> A { + A::C + } +} +fn test() { + let a = A::b(); + a; + let c = A::c(); + c; +} +"#, + ); +} + +#[test] +fn infer_associated_method_with_modules() { + check_inference( + "infer_associated_method_with_modules", + r#" +mod a { + struct A; + impl A { pub fn thing() -> A { A {} }} +} + +mod b { + struct B; + impl B { pub fn thing() -> u32 { 99 }} + + mod c { + struct C; + impl C { pub fn thing() -> C { C {} }} + } +} +use b::c; + +fn test() { + let x = a::A::thing(); + let y = b::B::thing(); + let z = c::C::thing(); +} +"#, + ); +} + +#[test] +fn infer_associated_method_generics() { + check_inference( + "infer_associated_method_generics", + r#" +struct Gen { + val: T +} + +impl Gen { + pub fn make(val: T) -> Gen { + Gen { val } + } +} + +fn test() { + let a = Gen::make(0u32); +} +"#, + ); +} + #[test] fn no_panic_on_field_of_enum() { check_inference( -- cgit v1.2.3