Skip to content

Commit 4741ae7

Browse files
Merge #3359
3359: Remove AnalysisHost::type_of r=matklad a=edwin0cheng This PR remove ` AnalysisHost::type_of` (It is subsume by hover now) and use `Semantics::type_of_x` to infer the type inside `hover` directly. And this also solved a bug : Right now hovering on a string literal inside a macro will show up a `&str` popup correctly. (Except if that involved builtin macro, e.g. `println`) Co-authored-by: Edwin Cheng <[email protected]>
2 parents 901edac + cda04d2 commit 4741ae7

File tree

2 files changed

+24
-79
lines changed

2 files changed

+24
-79
lines changed

crates/ra_ide/src/hover.rs

Lines changed: 24 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use ra_ide_db::{
66
RootDatabase,
77
};
88
use ra_syntax::{
9-
algo::find_covering_element,
109
ast::{self, DocCommentsOwner},
1110
match_ast, AstNode,
1211
SyntaxKind::*,
@@ -16,7 +15,7 @@ use ra_syntax::{
1615
use crate::{
1716
display::{macro_label, rust_code_markup, rust_code_markup_with_doc, ShortLabel},
1817
references::classify_name_ref,
19-
FilePosition, FileRange, RangeInfo,
18+
FilePosition, RangeInfo,
2019
};
2120

2221
/// Contains the results when hovering over an item
@@ -174,23 +173,25 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn
174173
.ancestors()
175174
.find(|n| ast::Expr::cast(n.clone()).is_some() || ast::Pat::cast(n.clone()).is_some())?;
176175

177-
// if this node is a MACRO_CALL, it means that `descend_into_macros` is failed to resolve.
178-
// (e.g expanding a builtin macro). So we give up here.
179-
if node.kind() == MACRO_CALL {
180-
return None;
181-
}
182-
183-
// FIXME: Currently `hover::typeof` do not work inside
184-
// macro expansion such that if the hover range is pointing to
185-
// a string literal, the following type_of will return None.
186-
// See also `test_hover_through_literal_string_in_macro`
187-
let frange = sema.original_range(&node);
188-
res.extend(type_of(db, frange).map(rust_code_markup));
189-
if res.is_empty() {
190-
return None;
191-
}
192-
let range = node.text_range();
176+
let ty = match_ast! {
177+
match node {
178+
ast::MacroCall(_it) => {
179+
// If this node is a MACRO_CALL, it means that `descend_into_macros` failed to resolve.
180+
// (e.g expanding a builtin macro). So we give up here.
181+
return None;
182+
},
183+
ast::Expr(it) => {
184+
sema.type_of_expr(&it)
185+
},
186+
ast::Pat(it) => {
187+
sema.type_of_pat(&it)
188+
},
189+
_ => None,
190+
}
191+
}?;
193192

193+
res.extend(Some(rust_code_markup(ty.display_truncated(db, None).to_string())));
194+
let range = sema.original_range(&node).range;
194195
Some(RangeInfo::new(range, res))
195196
}
196197

@@ -206,33 +207,12 @@ fn pick_best(tokens: TokenAtOffset<SyntaxToken>) -> Option<SyntaxToken> {
206207
}
207208
}
208209

209-
pub(crate) fn type_of(db: &RootDatabase, frange: FileRange) -> Option<String> {
210-
let sema = Semantics::new(db);
211-
let source_file = sema.parse(frange.file_id);
212-
let leaf_node = find_covering_element(source_file.syntax(), frange.range);
213-
// if we picked identifier, expand to pattern/expression
214-
let node = leaf_node
215-
.ancestors()
216-
.take_while(|it| it.text_range() == leaf_node.text_range())
217-
.find(|it| ast::Expr::cast(it.clone()).is_some() || ast::Pat::cast(it.clone()).is_some())?;
218-
let ty = if let Some(ty) = ast::Expr::cast(node.clone()).and_then(|e| sema.type_of_expr(&e)) {
219-
ty
220-
} else if let Some(ty) = ast::Pat::cast(node).and_then(|p| sema.type_of_pat(&p)) {
221-
ty
222-
} else {
223-
return None;
224-
};
225-
Some(ty.display_truncated(db, None).to_string())
226-
}
227-
228210
#[cfg(test)]
229211
mod tests {
230212
use ra_db::FileLoader;
231213
use ra_syntax::TextRange;
232214

233-
use crate::mock_analysis::{
234-
analysis_and_position, single_file_with_position, single_file_with_range,
235-
};
215+
use crate::mock_analysis::{analysis_and_position, single_file_with_position};
236216

237217
fn trim_markup(s: &str) -> &str {
238218
s.trim_start_matches("```rust\n").trim_end_matches("\n```")
@@ -524,37 +504,6 @@ fn func(foo: i32) { if true { <|>foo; }; }
524504
assert_eq!(trim_markup_opt(hover.info.first()), Some("i32"));
525505
}
526506

527-
#[test]
528-
fn test_type_of_for_function() {
529-
let (analysis, range) = single_file_with_range(
530-
"
531-
pub fn foo() -> u32 { 1 };
532-
533-
fn main() {
534-
let foo_test = <|>foo()<|>;
535-
}
536-
",
537-
);
538-
539-
let type_name = analysis.type_of(range).unwrap().unwrap();
540-
assert_eq!("u32", &type_name);
541-
}
542-
543-
#[test]
544-
fn test_type_of_for_expr() {
545-
let (analysis, range) = single_file_with_range(
546-
"
547-
fn main() {
548-
let foo: usize = 1;
549-
let bar = <|>1 + foo<|>;
550-
}
551-
",
552-
);
553-
554-
let type_name = analysis.type_of(range).unwrap().unwrap();
555-
assert_eq!("usize", &type_name);
556-
}
557-
558507
#[test]
559508
fn test_hover_infer_associated_method_result() {
560509
let (analysis, position) = single_file_with_position(
@@ -791,9 +740,7 @@ fn func(foo: i32) { if true { <|>foo; }; }
791740

792741
#[test]
793742
fn test_hover_through_literal_string_in_macro() {
794-
// FIXME: Currently `hover::type_of` do not work inside
795-
// macro expansion
796-
check_hover_no_result(
743+
let hover_on = check_hover_result(
797744
r#"
798745
//- /lib.rs
799746
macro_rules! arr {
@@ -804,7 +751,10 @@ fn func(foo: i32) { if true { <|>foo; }; }
804751
let _ = arr!("Tr<|>acks", &mastered_for_itunes);
805752
}
806753
"#,
754+
&["&str"],
807755
);
756+
757+
assert_eq!(hover_on, "\"Tracks\"");
808758
}
809759

810760
#[test]

crates/ra_ide/src/lib.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -455,11 +455,6 @@ impl Analysis {
455455
self.with_db(|db| diagnostics::diagnostics(db, file_id))
456456
}
457457

458-
/// Computes the type of the expression at the given position.
459-
pub fn type_of(&self, frange: FileRange) -> Cancelable<Option<String>> {
460-
self.with_db(|db| hover::type_of(db, frange))
461-
}
462-
463458
/// Returns the edit required to rename reference at the position to the new
464459
/// name.
465460
pub fn rename(

0 commit comments

Comments
 (0)