diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-06-22 15:37:45 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2020-06-22 15:37:45 +0100 |
commit | 87615166af84a4822adc4686fd9ee44fafa51f53 (patch) | |
tree | 91494d99d4805fca96815079b8dd29d9d649beea | |
parent | 5a0331e5575034a145956f76316ee0fcdf72077e (diff) | |
parent | bdf7e70820243812dd27d96c38fb6d5db359c2f1 (diff) |
Merge #4900
4900: Self variant enum res fix r=BGluth a=BGluth
Fixes #4789.
This is my first PR for this project, so it's probably worth giving it an extra close look.
A few things that I wasn't sure about:
- Is `resolve_path` really the best place to perform this check? It seemed like a natural place, but perhaps there's a better place?
- When handling the new variant `PathResolution::VariantDef`, I couldn't see an obvious variant of `TypeNs` to return in `in_type_ns` for Unions and Structs.
Co-authored-by: BGluth <[email protected]>
-rw-r--r-- | crates/ra_hir/src/source_analyzer.rs | 30 | ||||
-rw-r--r-- | crates/ra_ide/src/goto_definition.rs | 80 |
2 files changed, 110 insertions, 0 deletions
diff --git a/crates/ra_hir/src/source_analyzer.rs b/crates/ra_hir/src/source_analyzer.rs index 757d1e397..1d6c47103 100644 --- a/crates/ra_hir/src/source_analyzer.rs +++ b/crates/ra_hir/src/source_analyzer.rs | |||
@@ -216,13 +216,43 @@ impl SourceAnalyzer { | |||
216 | if let Some(assoc) = self.infer.as_ref()?.assoc_resolutions_for_expr(expr_id) { | 216 | if let Some(assoc) = self.infer.as_ref()?.assoc_resolutions_for_expr(expr_id) { |
217 | return Some(PathResolution::AssocItem(assoc.into())); | 217 | return Some(PathResolution::AssocItem(assoc.into())); |
218 | } | 218 | } |
219 | if let Some(VariantId::EnumVariantId(variant)) = | ||
220 | self.infer.as_ref()?.variant_resolution_for_expr(expr_id) | ||
221 | { | ||
222 | return Some(PathResolution::Def(ModuleDef::EnumVariant(variant.into()))); | ||
223 | } | ||
219 | } | 224 | } |
225 | |||
220 | if let Some(path_pat) = path.syntax().parent().and_then(ast::PathPat::cast) { | 226 | if let Some(path_pat) = path.syntax().parent().and_then(ast::PathPat::cast) { |
221 | let pat_id = self.pat_id(&path_pat.into())?; | 227 | let pat_id = self.pat_id(&path_pat.into())?; |
222 | if let Some(assoc) = self.infer.as_ref()?.assoc_resolutions_for_pat(pat_id) { | 228 | if let Some(assoc) = self.infer.as_ref()?.assoc_resolutions_for_pat(pat_id) { |
223 | return Some(PathResolution::AssocItem(assoc.into())); | 229 | return Some(PathResolution::AssocItem(assoc.into())); |
224 | } | 230 | } |
231 | if let Some(VariantId::EnumVariantId(variant)) = | ||
232 | self.infer.as_ref()?.variant_resolution_for_pat(pat_id) | ||
233 | { | ||
234 | return Some(PathResolution::Def(ModuleDef::EnumVariant(variant.into()))); | ||
235 | } | ||
236 | } | ||
237 | |||
238 | if let Some(rec_lit) = path.syntax().parent().and_then(ast::RecordLit::cast) { | ||
239 | let expr_id = self.expr_id(db, &rec_lit.into())?; | ||
240 | if let Some(VariantId::EnumVariantId(variant)) = | ||
241 | self.infer.as_ref()?.variant_resolution_for_expr(expr_id) | ||
242 | { | ||
243 | return Some(PathResolution::Def(ModuleDef::EnumVariant(variant.into()))); | ||
244 | } | ||
225 | } | 245 | } |
246 | |||
247 | if let Some(rec_pat) = path.syntax().parent().and_then(ast::RecordPat::cast) { | ||
248 | let pat_id = self.pat_id(&rec_pat.into())?; | ||
249 | if let Some(VariantId::EnumVariantId(variant)) = | ||
250 | self.infer.as_ref()?.variant_resolution_for_pat(pat_id) | ||
251 | { | ||
252 | return Some(PathResolution::Def(ModuleDef::EnumVariant(variant.into()))); | ||
253 | } | ||
254 | } | ||
255 | |||
226 | // This must be a normal source file rather than macro file. | 256 | // This must be a normal source file rather than macro file. |
227 | let hir_path = | 257 | let hir_path = |
228 | crate::Path::from_src(path.clone(), &Hygiene::new(db.upcast(), self.file_id))?; | 258 | crate::Path::from_src(path.clone(), &Hygiene::new(db.upcast(), self.file_id))?; |
diff --git a/crates/ra_ide/src/goto_definition.rs b/crates/ra_ide/src/goto_definition.rs index 0798d2c36..450ce0ba7 100644 --- a/crates/ra_ide/src/goto_definition.rs +++ b/crates/ra_ide/src/goto_definition.rs | |||
@@ -908,4 +908,84 @@ mod tests { | |||
908 | "x: i32|x", | 908 | "x: i32|x", |
909 | ); | 909 | ); |
910 | } | 910 | } |
911 | |||
912 | #[test] | ||
913 | fn goto_def_for_enum_variant_self_pattern_const() { | ||
914 | check_goto( | ||
915 | " | ||
916 | //- /lib.rs | ||
917 | enum Foo { | ||
918 | Bar, | ||
919 | } | ||
920 | impl Foo { | ||
921 | fn baz(self) { | ||
922 | match self { | ||
923 | Self::Bar<|> => {} | ||
924 | } | ||
925 | } | ||
926 | } | ||
927 | ", | ||
928 | "Bar ENUM_VARIANT FileId(1) 15..18 15..18", | ||
929 | "Bar|Bar", | ||
930 | ); | ||
931 | } | ||
932 | |||
933 | #[test] | ||
934 | fn goto_def_for_enum_variant_self_pattern_record() { | ||
935 | check_goto( | ||
936 | " | ||
937 | //- /lib.rs | ||
938 | enum Foo { | ||
939 | Bar { val: i32 }, | ||
940 | } | ||
941 | impl Foo { | ||
942 | fn baz(self) -> i32 { | ||
943 | match self { | ||
944 | Self::Bar<|> { val } => {} | ||
945 | } | ||
946 | } | ||
947 | } | ||
948 | ", | ||
949 | "Bar ENUM_VARIANT FileId(1) 15..31 15..18", | ||
950 | "Bar { val: i32 }|Bar", | ||
951 | ); | ||
952 | } | ||
953 | |||
954 | #[test] | ||
955 | fn goto_def_for_enum_variant_self_expr_const() { | ||
956 | check_goto( | ||
957 | " | ||
958 | //- /lib.rs | ||
959 | enum Foo { | ||
960 | Bar, | ||
961 | } | ||
962 | impl Foo { | ||
963 | fn baz(self) { | ||
964 | Self::Bar<|>; | ||
965 | } | ||
966 | } | ||
967 | ", | ||
968 | "Bar ENUM_VARIANT FileId(1) 15..18 15..18", | ||
969 | "Bar|Bar", | ||
970 | ); | ||
971 | } | ||
972 | |||
973 | #[test] | ||
974 | fn goto_def_for_enum_variant_self_expr_record() { | ||
975 | check_goto( | ||
976 | " | ||
977 | //- /lib.rs | ||
978 | enum Foo { | ||
979 | Bar { val: i32 }, | ||
980 | } | ||
981 | impl Foo { | ||
982 | fn baz(self) { | ||
983 | Self::Bar<|> {val: 4}; | ||
984 | } | ||
985 | } | ||
986 | ", | ||
987 | "Bar ENUM_VARIANT FileId(1) 15..31 15..18", | ||
988 | "Bar { val: i32 }|Bar", | ||
989 | ); | ||
990 | } | ||
911 | } | 991 | } |