From aac421b1351d6c6dddb37a92a33d929b79ed1d70 Mon Sep 17 00:00:00 2001 From: kjeremy Date: Wed, 6 Mar 2019 11:39:11 -0500 Subject: Hover for associated items in patterns --- crates/ra_hir/src/lib.rs | 2 +- crates/ra_ide_api/src/goto_definition.rs | 40 +++++++++++++++++++++++++------- crates/ra_ide_api/src/hover.rs | 23 ++++++++++++++++++ 3 files changed, 56 insertions(+), 9 deletions(-) diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index a6e744ea7..74c718e72 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs @@ -60,7 +60,7 @@ pub use self::{ impl_block::{ImplBlock, ImplItem}, docs::{Docs, Documentation}, adt::AdtDef, - expr::{ExprScopes, ScopesWithSourceMap, ScopeEntryWithSyntax}, + expr::{ExprScopes, ScopesWithSourceMap, ScopeEntryWithSyntax, Pat}, resolve::{Resolver, Resolution}, }; diff --git a/crates/ra_ide_api/src/goto_definition.rs b/crates/ra_ide_api/src/goto_definition.rs index 364263d9b..286ade0a4 100644 --- a/crates/ra_ide_api/src/goto_definition.rs +++ b/crates/ra_ide_api/src/goto_definition.rs @@ -5,7 +5,7 @@ use ra_syntax::{ SyntaxNode, }; use test_utils::tested_by; -use hir::Resolution; +use hir::{Pat, Resolution}; use crate::{FilePosition, NavigationTarget, db::RootDatabase, RangeInfo}; @@ -100,6 +100,7 @@ pub(crate) fn reference_definition( } } } + // Try name resolution let resolver = hir::source_binder::resolver_for_node(db, file_id, name_ref.syntax()); if let Some(path) = @@ -126,19 +127,42 @@ pub(crate) fn reference_definition( None => { // If we failed to resolve then check associated items if let Some(function) = function { - // Should we do this above and then grab path from the PathExpr? + // Resolve associated item for path expressions if let Some(path_expr) = name_ref.syntax().ancestors().find_map(ast::PathExpr::cast) { let infer_result = function.infer(db); let source_map = function.body_source_map(db); - let expr = ast::Expr::cast(path_expr.syntax()).unwrap(); - if let Some(res) = source_map - .node_expr(expr) - .and_then(|it| infer_result.assoc_resolutions_for_expr(it.into())) - { - return Exact(NavigationTarget::from_impl_item(db, res)); + if let Some(expr) = ast::Expr::cast(path_expr.syntax()) { + if let Some(res) = source_map + .node_expr(expr) + .and_then(|it| infer_result.assoc_resolutions_for_expr(it.into())) + { + return Exact(NavigationTarget::from_impl_item(db, res)); + } + } + } + + // Resolve associated item for path patterns + if let Some(path_pat) = + name_ref.syntax().ancestors().find_map(ast::PathPat::cast) + { + let infer_result = function.infer(db); + + if let Some(p) = path_pat.path().and_then(hir::Path::from_ast) { + if let Some(pat_id) = + function.body(db).pats().find_map(|(pat_id, pat)| match pat { + Pat::Path(ref path) if *path == p => Some(pat_id), + _ => None, + }) + { + if let Some(res) = + infer_result.assoc_resolutions_for_pat(pat_id.into()) + { + return Exact(NavigationTarget::from_impl_item(db, res)); + } + } } } } diff --git a/crates/ra_ide_api/src/hover.rs b/crates/ra_ide_api/src/hover.rs index bcd052c8b..638c24e31 100644 --- a/crates/ra_ide_api/src/hover.rs +++ b/crates/ra_ide_api/src/hover.rs @@ -534,4 +534,27 @@ mod tests { assert_eq!(trim_markup_opt(hover.info.first()), Some("fn new() -> Thing")); assert_eq!(hover.info.is_exact(), true); } + + #[test] + fn test_hover_infer_associated_const_in_pattern() { + let (analysis, position) = single_file_with_position( + " + struct X; + impl X { + const C: u32 = 1; + } + + fn main() { + match 1 { + X::C<|> => {}, + 2 => {}, + _ => {} + }; + } + ", + ); + let hover = analysis.hover(position).unwrap().unwrap(); + assert_eq!(trim_markup_opt(hover.info.first()), Some("const C: u32")); + assert_eq!(hover.info.is_exact(), true); + } } -- cgit v1.2.3