summaryrefslogtreecommitdiffstats
path: root/src/tools/rust-analyzer/crates/ide
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/rust-analyzer/crates/ide')
-rw-r--r--src/tools/rust-analyzer/crates/ide/Cargo.toml6
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/annotations.rs307
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/annotations/fn_references.rs (renamed from src/tools/rust-analyzer/crates/ide/src/fn_references.rs)37
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/call_hierarchy.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/doc_links.rs11
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/expand_macro.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/goto_definition.rs221
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/goto_implementation.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/highlight_related.rs30
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/hover.rs25
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/hover/render.rs34
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/hover/tests.rs270
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs267
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/join_lines.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/lib.rs48
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/matching_brace.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/moniker.rs143
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/move_item.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/parent_module.rs20
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/prime_caches.rs5
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/references.rs25
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/runnables.rs267
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/shuffle_crate_graph.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/static_index.rs13
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/status.rs6
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs74
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs11
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/html.rs21
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/inject.rs21
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tags.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_assoc_functions.html6
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html4
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_general.html12
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html2
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_lifetimes.html4
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html8
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html8
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs30
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_tree.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/view_crate_graph.rs7
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/view_hir.rs16
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/view_item_tree.rs2
42 files changed, 1647 insertions, 344 deletions
diff --git a/src/tools/rust-analyzer/crates/ide/Cargo.toml b/src/tools/rust-analyzer/crates/ide/Cargo.toml
index 0e9771cd2..712459a7e 100644
--- a/src/tools/rust-analyzer/crates/ide/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/ide/Cargo.toml
@@ -13,12 +13,12 @@ doctest = false
cov-mark = "2.0.0-pre.1"
crossbeam-channel = "0.5.5"
either = "1.7.0"
-itertools = "0.10.3"
+itertools = "0.10.5"
tracing = "0.1.35"
oorandom = "11.1.3"
-pulldown-cmark-to-cmark = "10.0.1"
+pulldown-cmark-to-cmark = "10.0.4"
pulldown-cmark = { version = "0.9.1", default-features = false }
-url = "2.2.2"
+url = "2.3.1"
dot = "0.1.4"
stdx = { path = "../stdx", version = "0.0.0" }
diff --git a/src/tools/rust-analyzer/crates/ide/src/annotations.rs b/src/tools/rust-analyzer/crates/ide/src/annotations.rs
index 210c5c7fa..f994c284c 100644
--- a/src/tools/rust-analyzer/crates/ide/src/annotations.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/annotations.rs
@@ -8,13 +8,15 @@ use ide_db::{
use syntax::{ast::HasName, AstNode, TextRange};
use crate::{
- fn_references::find_all_methods,
+ annotations::fn_references::find_all_methods,
goto_implementation::goto_implementation,
references::find_all_refs,
runnables::{runnables, Runnable},
NavigationTarget, RunnableKind,
};
+mod fn_references;
+
// Feature: Annotations
//
// Provides user with annotations above items for looking up references or impl blocks
@@ -30,8 +32,8 @@ pub struct Annotation {
#[derive(Debug)]
pub enum AnnotationKind {
Runnable(Runnable),
- HasImpls { file_id: FileId, data: Option<Vec<NavigationTarget>> },
- HasReferences { file_id: FileId, data: Option<Vec<FileRange>> },
+ HasImpls { pos: FilePosition, data: Option<Vec<NavigationTarget>> },
+ HasReferences { pos: FilePosition, data: Option<Vec<FileRange>> },
}
pub struct AnnotationConfig {
@@ -41,6 +43,12 @@ pub struct AnnotationConfig {
pub annotate_references: bool,
pub annotate_method_references: bool,
pub annotate_enum_variant_references: bool,
+ pub location: AnnotationLocation,
+}
+
+pub enum AnnotationLocation {
+ AboveName,
+ AboveWholeItem,
}
pub(crate) fn annotations(
@@ -62,6 +70,16 @@ pub(crate) fn annotations(
}
}
+ let mk_ranges = |(range, focus): (_, Option<_>)| {
+ let cmd_target: TextRange = focus.unwrap_or(range);
+ let annotation_range = match config.location {
+ AnnotationLocation::AboveName => cmd_target,
+ AnnotationLocation::AboveWholeItem => range,
+ };
+ let target_pos = FilePosition { file_id, offset: cmd_target.start() };
+ (annotation_range, target_pos)
+ };
+
visit_file_defs(&Semantics::new(db), file_id, &mut |def| {
let range = match def {
Definition::Const(konst) if config.annotate_references => {
@@ -81,9 +99,13 @@ pub(crate) fn annotations(
})
.flatten()
.for_each(|range| {
+ let (annotation_range, target_position) = mk_ranges(range);
annotations.push(Annotation {
- range,
- kind: AnnotationKind::HasReferences { file_id, data: None },
+ range: annotation_range,
+ kind: AnnotationKind::HasReferences {
+ pos: target_position,
+ data: None,
+ },
})
})
}
@@ -108,15 +130,18 @@ pub(crate) fn annotations(
Some(range) => range,
None => return,
};
-
+ let (annotation_range, target_pos) = mk_ranges(range);
if config.annotate_impls && !matches!(def, Definition::Const(_)) {
- annotations
- .push(Annotation { range, kind: AnnotationKind::HasImpls { file_id, data: None } });
+ annotations.push(Annotation {
+ range: annotation_range,
+ kind: AnnotationKind::HasImpls { pos: target_pos, data: None },
+ });
}
+
if config.annotate_references {
annotations.push(Annotation {
- range,
- kind: AnnotationKind::HasReferences { file_id, data: None },
+ range: annotation_range,
+ kind: AnnotationKind::HasReferences { pos: target_pos, data: None },
});
}
@@ -124,10 +149,13 @@ pub(crate) fn annotations(
db: &RootDatabase,
node: InFile<T>,
source_file_id: FileId,
- ) -> Option<TextRange> {
+ ) -> Option<(TextRange, Option<TextRange>)> {
if let Some(InFile { file_id, value }) = node.original_ast_node(db) {
if file_id == source_file_id.into() {
- return value.name().map(|it| it.syntax().text_range());
+ return Some((
+ value.syntax().text_range(),
+ value.name().map(|name| name.syntax().text_range()),
+ ));
}
}
None
@@ -135,12 +163,13 @@ pub(crate) fn annotations(
});
if config.annotate_method_references {
- annotations.extend(find_all_methods(db, file_id).into_iter().map(
- |FileRange { file_id, range }| Annotation {
- range,
- kind: AnnotationKind::HasReferences { file_id, data: None },
- },
- ));
+ annotations.extend(find_all_methods(db, file_id).into_iter().map(|range| {
+ let (annotation_range, target_range) = mk_ranges(range);
+ Annotation {
+ range: annotation_range,
+ kind: AnnotationKind::HasReferences { pos: target_range, data: None },
+ }
+ }));
}
annotations
@@ -148,18 +177,11 @@ pub(crate) fn annotations(
pub(crate) fn resolve_annotation(db: &RootDatabase, mut annotation: Annotation) -> Annotation {
match annotation.kind {
- AnnotationKind::HasImpls { file_id, ref mut data } => {
- *data =
- goto_implementation(db, FilePosition { file_id, offset: annotation.range.start() })
- .map(|range| range.info);
+ AnnotationKind::HasImpls { pos, ref mut data } => {
+ *data = goto_implementation(db, pos).map(|range| range.info);
}
- AnnotationKind::HasReferences { file_id, ref mut data } => {
- *data = find_all_refs(
- &Semantics::new(db),
- FilePosition { file_id, offset: annotation.range.start() },
- None,
- )
- .map(|result| {
+ AnnotationKind::HasReferences { pos, ref mut data } => {
+ *data = find_all_refs(&Semantics::new(db), pos, None).map(|result| {
result
.into_iter()
.flat_map(|res| res.references)
@@ -188,21 +210,23 @@ mod tests {
use crate::{fixture, Annotation, AnnotationConfig};
- fn check(ra_fixture: &str, expect: Expect) {
+ use super::AnnotationLocation;
+
+ const DEFAULT_CONFIG: AnnotationConfig = AnnotationConfig {
+ binary_target: true,
+ annotate_runnables: true,
+ annotate_impls: true,
+ annotate_references: true,
+ annotate_method_references: true,
+ annotate_enum_variant_references: true,
+ location: AnnotationLocation::AboveName,
+ };
+
+ fn check_with_config(ra_fixture: &str, expect: Expect, config: &AnnotationConfig) {
let (analysis, file_id) = fixture::file(ra_fixture);
let annotations: Vec<Annotation> = analysis
- .annotations(
- &AnnotationConfig {
- binary_target: true,
- annotate_runnables: true,
- annotate_impls: true,
- annotate_references: true,
- annotate_method_references: true,
- annotate_enum_variant_references: true,
- },
- file_id,
- )
+ .annotations(config, file_id)
.unwrap()
.into_iter()
.map(|annotation| analysis.resolve_annotation(annotation).unwrap())
@@ -211,6 +235,10 @@ mod tests {
expect.assert_debug_eq(&annotations);
}
+ fn check(ra_fixture: &str, expect: Expect) {
+ check_with_config(ra_fixture, expect, &DEFAULT_CONFIG);
+ }
+
#[test]
fn const_annotations() {
check(
@@ -247,9 +275,12 @@ fn main() {
Annotation {
range: 6..10,
kind: HasReferences {
- file_id: FileId(
- 0,
- ),
+ pos: FilePosition {
+ file_id: FileId(
+ 0,
+ ),
+ offset: 6,
+ },
data: Some(
[
FileRange {
@@ -265,9 +296,12 @@ fn main() {
Annotation {
range: 30..36,
kind: HasReferences {
- file_id: FileId(
- 0,
- ),
+ pos: FilePosition {
+ file_id: FileId(
+ 0,
+ ),
+ offset: 30,
+ },
data: Some(
[],
),
@@ -276,9 +310,12 @@ fn main() {
Annotation {
range: 53..57,
kind: HasReferences {
- file_id: FileId(
- 0,
- ),
+ pos: FilePosition {
+ file_id: FileId(
+ 0,
+ ),
+ offset: 53,
+ },
data: Some(
[],
),
@@ -323,9 +360,12 @@ fn main() {
Annotation {
range: 7..11,
kind: HasImpls {
- file_id: FileId(
- 0,
- ),
+ pos: FilePosition {
+ file_id: FileId(
+ 0,
+ ),
+ offset: 7,
+ },
data: Some(
[],
),
@@ -334,9 +374,12 @@ fn main() {
Annotation {
range: 7..11,
kind: HasReferences {
- file_id: FileId(
- 0,
- ),
+ pos: FilePosition {
+ file_id: FileId(
+ 0,
+ ),
+ offset: 7,
+ },
data: Some(
[
FileRange {
@@ -352,9 +395,12 @@ fn main() {
Annotation {
range: 17..21,
kind: HasReferences {
- file_id: FileId(
- 0,
- ),
+ pos: FilePosition {
+ file_id: FileId(
+ 0,
+ ),
+ offset: 17,
+ },
data: Some(
[],
),
@@ -403,9 +449,12 @@ fn main() {
Annotation {
range: 7..11,
kind: HasImpls {
- file_id: FileId(
- 0,
- ),
+ pos: FilePosition {
+ file_id: FileId(
+ 0,
+ ),
+ offset: 7,
+ },
data: Some(
[
NavigationTarget {
@@ -424,9 +473,12 @@ fn main() {
Annotation {
range: 7..11,
kind: HasReferences {
- file_id: FileId(
- 0,
- ),
+ pos: FilePosition {
+ file_id: FileId(
+ 0,
+ ),
+ offset: 7,
+ },
data: Some(
[
FileRange {
@@ -448,9 +500,12 @@ fn main() {
Annotation {
range: 20..31,
kind: HasImpls {
- file_id: FileId(
- 0,
- ),
+ pos: FilePosition {
+ file_id: FileId(
+ 0,
+ ),
+ offset: 20,
+ },
data: Some(
[
NavigationTarget {
@@ -469,9 +524,12 @@ fn main() {
Annotation {
range: 20..31,
kind: HasReferences {
- file_id: FileId(
- 0,
- ),
+ pos: FilePosition {
+ file_id: FileId(
+ 0,
+ ),
+ offset: 20,
+ },
data: Some(
[
FileRange {
@@ -487,9 +545,12 @@ fn main() {
Annotation {
range: 69..73,
kind: HasReferences {
- file_id: FileId(
- 0,
- ),
+ pos: FilePosition {
+ file_id: FileId(
+ 0,
+ ),
+ offset: 69,
+ },
data: Some(
[],
),
@@ -530,9 +591,12 @@ fn main() {}
Annotation {
range: 3..7,
kind: HasReferences {
- file_id: FileId(
- 0,
- ),
+ pos: FilePosition {
+ file_id: FileId(
+ 0,
+ ),
+ offset: 3,
+ },
data: Some(
[],
),
@@ -581,9 +645,12 @@ fn main() {
Annotation {
range: 7..11,
kind: HasImpls {
- file_id: FileId(
- 0,
- ),
+ pos: FilePosition {
+ file_id: FileId(
+ 0,
+ ),
+ offset: 7,
+ },
data: Some(
[
NavigationTarget {
@@ -602,9 +669,12 @@ fn main() {
Annotation {
range: 7..11,
kind: HasReferences {
- file_id: FileId(
- 0,
- ),
+ pos: FilePosition {
+ file_id: FileId(
+ 0,
+ ),
+ offset: 7,
+ },
data: Some(
[
FileRange {
@@ -626,9 +696,12 @@ fn main() {
Annotation {
range: 33..44,
kind: HasReferences {
- file_id: FileId(
- 0,
- ),
+ pos: FilePosition {
+ file_id: FileId(
+ 0,
+ ),
+ offset: 33,
+ },
data: Some(
[
FileRange {
@@ -644,9 +717,12 @@ fn main() {
Annotation {
range: 61..65,
kind: HasReferences {
- file_id: FileId(
- 0,
- ),
+ pos: FilePosition {
+ file_id: FileId(
+ 0,
+ ),
+ offset: 61,
+ },
data: Some(
[],
),
@@ -740,9 +816,12 @@ mod tests {
Annotation {
range: 3..7,
kind: HasReferences {
- file_id: FileId(
- 0,
- ),
+ pos: FilePosition {
+ file_id: FileId(
+ 0,
+ ),
+ offset: 3,
+ },
data: Some(
[],
),
@@ -786,4 +865,48 @@ m!();
"#]],
);
}
+
+ #[test]
+ fn test_annotations_appear_above_whole_item_when_configured_to_do_so() {
+ check_with_config(
+ r#"
+/// This is a struct named Foo, obviously.
+#[derive(Clone)]
+struct Foo;
+"#,
+ expect![[r#"
+ [
+ Annotation {
+ range: 0..71,
+ kind: HasImpls {
+ pos: FilePosition {
+ file_id: FileId(
+ 0,
+ ),
+ offset: 67,
+ },
+ data: Some(
+ [],
+ ),
+ },
+ },
+ Annotation {
+ range: 0..71,
+ kind: HasReferences {
+ pos: FilePosition {
+ file_id: FileId(
+ 0,
+ ),
+ offset: 67,
+ },
+ data: Some(
+ [],
+ ),
+ },
+ },
+ ]
+ "#]],
+ &AnnotationConfig { location: AnnotationLocation::AboveWholeItem, ..DEFAULT_CONFIG },
+ );
+ }
}
diff --git a/src/tools/rust-analyzer/crates/ide/src/fn_references.rs b/src/tools/rust-analyzer/crates/ide/src/annotations/fn_references.rs
index 63fb322ce..0cadf125f 100644
--- a/src/tools/rust-analyzer/crates/ide/src/fn_references.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/annotations/fn_references.rs
@@ -4,30 +4,38 @@
use hir::Semantics;
use ide_assists::utils::test_related_attribute;
use ide_db::RootDatabase;
-use syntax::{ast, ast::HasName, AstNode, SyntaxNode};
+use syntax::{ast, ast::HasName, AstNode, SyntaxNode, TextRange};
-use crate::{FileId, FileRange};
+use crate::FileId;
-pub(crate) fn find_all_methods(db: &RootDatabase, file_id: FileId) -> Vec<FileRange> {
+pub(super) fn find_all_methods(
+ db: &RootDatabase,
+ file_id: FileId,
+) -> Vec<(TextRange, Option<TextRange>)> {
let sema = Semantics::new(db);
let source_file = sema.parse(file_id);
- source_file.syntax().descendants().filter_map(|it| method_range(it, file_id)).collect()
+ source_file.syntax().descendants().filter_map(|it| method_range(it)).collect()
}
-fn method_range(item: SyntaxNode, file_id: FileId) -> Option<FileRange> {
+fn method_range(item: SyntaxNode) -> Option<(TextRange, Option<TextRange>)> {
ast::Fn::cast(item).and_then(|fn_def| {
if test_related_attribute(&fn_def).is_some() {
None
} else {
- fn_def.name().map(|name| FileRange { file_id, range: name.syntax().text_range() })
+ Some((
+ fn_def.syntax().text_range(),
+ fn_def.name().map(|name| name.syntax().text_range()),
+ ))
}
})
}
#[cfg(test)]
mod tests {
+ use syntax::TextRange;
+
use crate::fixture;
- use crate::{FileRange, TextSize};
+ use crate::TextSize;
use std::ops::RangeInclusive;
#[test]
@@ -42,7 +50,7 @@ mod tests {
"#,
);
- let refs = analysis.find_all_methods(pos.file_id).unwrap();
+ let refs = super::find_all_methods(&analysis.db, pos.file_id);
check_result(&refs, &[3..=13, 27..=33, 47..=57]);
}
@@ -57,7 +65,7 @@ mod tests {
"#,
);
- let refs = analysis.find_all_methods(pos.file_id).unwrap();
+ let refs = super::find_all_methods(&analysis.db, pos.file_id);
check_result(&refs, &[19..=22, 35..=38]);
}
@@ -78,17 +86,18 @@ mod tests {
"#,
);
- let refs = analysis.find_all_methods(pos.file_id).unwrap();
+ let refs = super::find_all_methods(&analysis.db, pos.file_id);
check_result(&refs, &[28..=34]);
}
- fn check_result(refs: &[FileRange], expected: &[RangeInclusive<u32>]) {
+ fn check_result(refs: &[(TextRange, Option<TextRange>)], expected: &[RangeInclusive<u32>]) {
assert_eq!(refs.len(), expected.len());
- for (i, item) in refs.iter().enumerate() {
+ for (i, &(full, focus)) in refs.iter().enumerate() {
let range = &expected[i];
- assert_eq!(TextSize::from(*range.start()), item.range.start());
- assert_eq!(TextSize::from(*range.end()), item.range.end());
+ let item = focus.unwrap_or(full);
+ assert_eq!(TextSize::from(*range.start()), item.start());
+ assert_eq!(TextSize::from(*range.end()), item.end());
}
}
}
diff --git a/src/tools/rust-analyzer/crates/ide/src/call_hierarchy.rs b/src/tools/rust-analyzer/crates/ide/src/call_hierarchy.rs
index a18a6bea9..5a8cda8fb 100644
--- a/src/tools/rust-analyzer/crates/ide/src/call_hierarchy.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/call_hierarchy.rs
@@ -7,7 +7,7 @@ use ide_db::{
search::FileReference,
FxIndexMap, RootDatabase,
};
-use syntax::{ast, AstNode, SyntaxKind::NAME, TextRange};
+use syntax::{ast, AstNode, SyntaxKind::IDENT, TextRange};
use crate::{goto_definition, FilePosition, NavigationTarget, RangeInfo, TryToNav};
@@ -79,7 +79,7 @@ pub(crate) fn outgoing_calls(db: &RootDatabase, position: FilePosition) -> Optio
let file = sema.parse(file_id);
let file = file.syntax();
let token = pick_best_token(file.token_at_offset(position.offset), |kind| match kind {
- NAME => 1,
+ IDENT => 1,
_ => 0,
})?;
let mut calls = CallLocations::default();
diff --git a/src/tools/rust-analyzer/crates/ide/src/doc_links.rs b/src/tools/rust-analyzer/crates/ide/src/doc_links.rs
index 582e9fe7e..d96827326 100644
--- a/src/tools/rust-analyzer/crates/ide/src/doc_links.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/doc_links.rs
@@ -184,10 +184,10 @@ pub(crate) fn resolve_doc_path_for_def(
Definition::TypeAlias(it) => it.resolve_doc_path(db, link, ns),
Definition::Macro(it) => it.resolve_doc_path(db, link, ns),
Definition::Field(it) => it.resolve_doc_path(db, link, ns),
+ Definition::SelfType(it) => it.resolve_doc_path(db, link, ns),
Definition::BuiltinAttr(_)
| Definition::ToolModule(_)
| Definition::BuiltinType(_)
- | Definition::SelfType(_)
| Definition::Local(_)
| Definition::GenericParam(_)
| Definition::Label(_)
@@ -232,8 +232,13 @@ pub(crate) fn token_as_doc_comment(doc_token: &SyntaxToken) -> Option<DocComment
(match_ast! {
match doc_token {
ast::Comment(comment) => TextSize::try_from(comment.prefix().len()).ok(),
- ast::String(string) => doc_token.parent_ancestors().find_map(ast::Attr::cast)
- .filter(|attr| attr.simple_name().as_deref() == Some("doc")).and_then(|_| string.open_quote_text_range().map(|it| it.len())),
+ ast::String(string) => {
+ doc_token.parent_ancestors().find_map(ast::Attr::cast).filter(|attr| attr.simple_name().as_deref() == Some("doc"))?;
+ if doc_token.parent_ancestors().find_map(ast::MacroCall::cast).filter(|mac| mac.path().and_then(|p| p.segment()?.name_ref()).as_ref().map(|n| n.text()).as_deref() == Some("include_str")).is_some() {
+ return None;
+ }
+ string.open_quote_text_range().map(|it| it.len())
+ },
_ => None,
}
}).map(|prefix_len| DocCommentToken { prefix_len, doc_token: doc_token.clone() })
diff --git a/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs b/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs
index efa8551a0..93252339c 100644
--- a/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs
@@ -19,7 +19,7 @@ pub struct ExpandedMacro {
// |===
// | Editor | Action Name
//
-// | VS Code | **Rust Analyzer: Expand macro recursively**
+// | VS Code | **rust-analyzer: Expand macro recursively**
// |===
//
// image::https://user-images.githubusercontent.com/48062697/113020648-b3973180-917a-11eb-84a9-ecb921293dc5.gif[]
@@ -32,7 +32,7 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option<
_ => 0,
})?;
- // due to how Rust Analyzer works internally, we need to special case derive attributes,
+ // due to how rust-analyzer works internally, we need to special case derive attributes,
// otherwise they might not get found, e.g. here with the cursor at $0 `#[attr]` would expand:
// ```
// #[attr]
diff --git a/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs b/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs
index d9c97751c..d0be1b3f4 100644
--- a/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs
@@ -1,4 +1,4 @@
-use std::{convert::TryInto, mem::discriminant};
+use std::mem::discriminant;
use crate::{doc_links::token_as_doc_comment, FilePosition, NavigationTarget, RangeInfo, TryToNav};
use hir::{AsAssocItem, AssocItem, Semantics};
@@ -39,15 +39,23 @@ pub(crate) fn goto_definition(
| T![super]
| T![crate]
| T![Self]
- | COMMENT => 2,
+ | COMMENT => 4,
+ // index and prefix ops
+ T!['['] | T![']'] | T![?] | T![*] | T![-] | T![!] => 3,
+ kind if kind.is_keyword() => 2,
+ T!['('] | T![')'] => 2,
kind if kind.is_trivia() => 0,
_ => 1,
})?;
if let Some(doc_comment) = token_as_doc_comment(&original_token) {
- return doc_comment.get_definition_with_descend_at(sema, position.offset, |def, _, _| {
- let nav = def.try_to_nav(db)?;
- Some(RangeInfo::new(original_token.text_range(), vec![nav]))
- });
+ return doc_comment.get_definition_with_descend_at(
+ sema,
+ position.offset,
+ |def, _, link_range| {
+ let nav = def.try_to_nav(db)?;
+ Some(RangeInfo::new(link_range, vec![nav]))
+ },
+ );
}
let navs = sema
.descend_into_macros(original_token.clone())
@@ -91,6 +99,14 @@ fn try_lookup_include_path(
if !matches!(&*name.text(), "include" | "include_str" | "include_bytes") {
return None;
}
+
+ // Ignore non-built-in macros to account for shadowing
+ if let Some(it) = sema.resolve_macro_call(&macro_call) {
+ if !matches!(it.kind(sema.db), hir::MacroKind::BuiltIn) {
+ return None;
+ }
+ }
+
let file_id = sema.db.resolve_path(AnchoredPath { anchor: file_id, path: &path })?;
let size = sema.db.file_text(file_id).len().try_into().ok()?;
Some(NavigationTarget {
@@ -152,9 +168,6 @@ mod tests {
fn check(ra_fixture: &str) {
let (analysis, position, expected) = fixture::annotations(ra_fixture);
let navs = analysis.goto_definition(position).unwrap().expect("no definition found").info;
- if navs.is_empty() {
- panic!("unresolved reference")
- }
let cmp = |&FileRange { file_id, range }: &_| (file_id, range.start());
let navs = navs
@@ -1344,6 +1357,10 @@ fn f(e: Enum) {
check(
r#"
//- /main.rs
+
+#[rustc_builtin_macro]
+macro_rules! include_str {}
+
fn main() {
let str = include_str!("foo.txt$0");
}
@@ -1353,6 +1370,42 @@ fn main() {
"#,
);
}
+
+ #[test]
+ fn goto_doc_include_str() {
+ check(
+ r#"
+//- /main.rs
+#[rustc_builtin_macro]
+macro_rules! include_str {}
+
+#[doc = include_str!("docs.md$0")]
+struct Item;
+
+//- /docs.md
+// docs
+//^file
+"#,
+ );
+ }
+
+ #[test]
+ fn goto_shadow_include() {
+ check(
+ r#"
+//- /main.rs
+macro_rules! include {
+ ("included.rs") => {}
+}
+
+include!("included.rs$0");
+
+//- /included.rs
+// empty
+"#,
+ );
+ }
+
#[cfg(test)]
mod goto_impl_of_trait_fn {
use super::check;
@@ -1631,4 +1684,154 @@ foo!(bar$0);
"#,
);
}
+
+ #[test]
+ fn goto_await_poll() {
+ check(
+ r#"
+//- minicore: future
+
+struct MyFut;
+
+impl core::future::Future for MyFut {
+ type Output = ();
+
+ fn poll(
+ //^^^^
+ self: std::pin::Pin<&mut Self>,
+ cx: &mut std::task::Context<'_>
+ ) -> std::task::Poll<Self::Output>
+ {
+ ()
+ }
+}
+
+fn f() {
+ MyFut.await$0;
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn goto_await_into_future_poll() {
+ check(
+ r#"
+//- minicore: future
+
+struct Futurable;
+
+impl core::future::IntoFuture for Futurable {
+ type IntoFuture = MyFut;
+}
+
+struct MyFut;
+
+impl core::future::Future for MyFut {
+ type Output = ();
+
+ fn poll(
+ //^^^^
+ self: std::pin::Pin<&mut Self>,
+ cx: &mut std::task::Context<'_>
+ ) -> std::task::Poll<Self::Output>
+ {
+ ()
+ }
+}
+
+fn f() {
+ Futurable.await$0;
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn goto_try_op() {
+ check(
+ r#"
+//- minicore: try
+
+struct Struct;
+
+impl core::ops::Try for Struct {
+ fn branch(
+ //^^^^^^
+ self
+ ) {}
+}
+
+fn f() {
+ Struct?$0;
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn goto_index_op() {
+ check(
+ r#"
+//- minicore: index
+
+struct Struct;
+
+impl core::ops::Index<usize> for Struct {
+ fn index(
+ //^^^^^
+ self
+ ) {}
+}
+
+fn f() {
+ Struct[0]$0;
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn goto_prefix_op() {
+ check(
+ r#"
+//- minicore: deref
+
+struct Struct;
+
+impl core::ops::Deref for Struct {
+ fn deref(
+ //^^^^^
+ self
+ ) {}
+}
+
+fn f() {
+ $0*Struct;
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn goto_bin_op() {
+ check(
+ r#"
+//- minicore: add
+
+struct Struct;
+
+impl core::ops::Add for Struct {
+ fn add(
+ //^^^
+ self
+ ) {}
+}
+
+fn f() {
+ Struct +$0 Struct;
+}
+"#,
+ );
+ }
}
diff --git a/src/tools/rust-analyzer/crates/ide/src/goto_implementation.rs b/src/tools/rust-analyzer/crates/ide/src/goto_implementation.rs
index 04b51c839..b3f711b6b 100644
--- a/src/tools/rust-analyzer/crates/ide/src/goto_implementation.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/goto_implementation.rs
@@ -30,7 +30,7 @@ pub(crate) fn goto_implementation(
let original_token =
pick_best_token(syntax.token_at_offset(position.offset), |kind| match kind {
- IDENT | T![self] => 1,
+ IDENT | T![self] | INT_NUMBER => 1,
_ => 0,
})?;
let range = original_token.text_range();
diff --git a/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs b/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs
index f2d7029ea..540a11583 100644
--- a/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs
@@ -333,7 +333,8 @@ fn cover_range(r0: Option<TextRange>, r1: Option<TextRange>) -> Option<TextRange
fn find_defs(sema: &Semantics<'_, RootDatabase>, token: SyntaxToken) -> FxHashSet<Definition> {
sema.descend_into_macros(token)
.into_iter()
- .filter_map(|token| IdentClass::classify_token(sema, &token).map(IdentClass::definitions))
+ .filter_map(|token| IdentClass::classify_token(sema, &token))
+ .map(IdentClass::definitions_no_ops)
.flatten()
.collect()
}
@@ -376,6 +377,7 @@ mod tests {
match it {
ReferenceCategory::Read => "read",
ReferenceCategory::Write => "write",
+ ReferenceCategory::Import => "import",
}
.to_string()
}),
@@ -422,12 +424,12 @@ struct Foo;
check(
r#"
use crate$0;
- //^^^^^
+ //^^^^^ import
use self;
- //^^^^
+ //^^^^ import
mod __ {
use super;
- //^^^^^
+ //^^^^^ import
}
"#,
);
@@ -435,7 +437,7 @@ mod __ {
r#"
//- /main.rs crate:main deps:lib
use lib$0;
- //^^^
+ //^^^ import
//- /lib.rs crate:lib
"#,
);
@@ -449,7 +451,7 @@ use lib$0;
mod foo;
//- /foo.rs
use self$0;
- // ^^^^
+ // ^^^^ import
"#,
);
}
@@ -1374,4 +1376,20 @@ fn main() {
"#,
);
}
+
+ #[test]
+ fn test_assoc_type_highlighting() {
+ check(
+ r#"
+trait Trait {
+ type Output;
+ // ^^^^^^
+}
+impl Trait for () {
+ type Output$0 = ();
+ // ^^^^^^
+}
+"#,
+ );
+ }
}
diff --git a/src/tools/rust-analyzer/crates/ide/src/hover.rs b/src/tools/rust-analyzer/crates/ide/src/hover.rs
index 59c97f2dc..3687b597f 100644
--- a/src/tools/rust-analyzer/crates/ide/src/hover.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/hover.rs
@@ -9,7 +9,7 @@ use either::Either;
use hir::{HasSource, Semantics};
use ide_db::{
base_db::FileRange,
- defs::{Definition, IdentClass},
+ defs::{Definition, IdentClass, OperatorClass},
famous_defs::FamousDefs,
helpers::pick_best_token,
FxIndexSet, RootDatabase,
@@ -27,6 +27,7 @@ use crate::{
pub struct HoverConfig {
pub links_in_hover: bool,
pub documentation: Option<HoverDocFormat>,
+ pub keywords: bool,
}
impl HoverConfig {
@@ -101,7 +102,10 @@ pub(crate) fn hover(
let offset = range.start();
let original_token = pick_best_token(file.token_at_offset(offset), |kind| match kind {
- IDENT | INT_NUMBER | LIFETIME_IDENT | T![self] | T![super] | T![crate] | T![Self] => 3,
+ IDENT | INT_NUMBER | LIFETIME_IDENT | T![self] | T![super] | T![crate] | T![Self] => 4,
+ // index and prefix ops
+ T!['['] | T![']'] | T![?] | T![*] | T![-] | T![!] => 3,
+ kind if kind.is_keyword() => 2,
T!['('] | T![')'] => 2,
kind if kind.is_trivia() => 0,
_ => 1,
@@ -116,6 +120,8 @@ pub(crate) fn hover(
}
let in_attr = matches!(original_token.parent().and_then(ast::TokenTree::cast), Some(tt) if tt.syntax().ancestors().any(|it| ast::Meta::can_cast(it.kind())));
+ // prefer descending the same token kind in attribute expansions, in normal macros text
+ // equivalency is more important
let descended = if in_attr {
[sema.descend_into_macros_with_kind_preference(original_token.clone())].into()
} else {
@@ -136,6 +142,11 @@ pub(crate) fn hover(
.filter_map(|token| {
let node = token.parent()?;
let class = IdentClass::classify_token(sema, token)?;
+ if let IdentClass::Operator(OperatorClass::Await(_)) = class {
+ // It's better for us to fall back to the keyword hover here,
+ // rendering poll is very confusing
+ return None;
+ }
Some(class.definitions().into_iter().zip(iter::once(node).cycle()))
})
.flatten()
@@ -232,10 +243,12 @@ fn hover_type_fallback(
token: &SyntaxToken,
original_token: &SyntaxToken,
) -> Option<RangeInfo<HoverResult>> {
- let node = token
- .parent_ancestors()
- .take_while(|it| !ast::Item::can_cast(it.kind()))
- .find(|n| ast::Expr::can_cast(n.kind()) || ast::Pat::can_cast(n.kind()))?;
+ let node =
+ token.parent_ancestors().take_while(|it| !ast::Item::can_cast(it.kind())).find(|n| {
+ ast::Expr::can_cast(n.kind())
+ || ast::Pat::can_cast(n.kind())
+ || ast::Type::can_cast(n.kind())
+ })?;
let expr_or_pat = match_ast! {
match node {
diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/render.rs b/src/tools/rust-analyzer/crates/ide/src/hover/render.rs
index 6c50a4e6a..d109c0769 100644
--- a/src/tools/rust-analyzer/crates/ide/src/hover/render.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/hover/render.rs
@@ -2,12 +2,13 @@
use std::fmt::Display;
use either::Either;
-use hir::{AsAssocItem, AttributeTemplate, HasAttrs, HirDisplay, Semantics, TypeInfo};
+use hir::{AsAssocItem, AttributeTemplate, HasAttrs, HasSource, HirDisplay, Semantics, TypeInfo};
use ide_db::{
base_db::SourceDatabase,
defs::Definition,
famous_defs::FamousDefs,
generated::lints::{CLIPPY_LINTS, DEFAULT_LINTS, FEATURES},
+ syntax_helpers::insert_whitespace_into_node,
RootDatabase,
};
use itertools::Itertools;
@@ -230,7 +231,7 @@ pub(super) fn keyword(
config: &HoverConfig,
token: &SyntaxToken,
) -> Option<HoverResult> {
- if !token.kind().is_keyword() || !config.documentation.is_some() {
+ if !token.kind().is_keyword() || !config.documentation.is_some() || !config.keywords {
return None;
}
let parent = token.parent()?;
@@ -345,15 +346,38 @@ pub(super) fn definition(
Definition::Module(it) => label_and_docs(db, it),
Definition::Function(it) => label_and_docs(db, it),
Definition::Adt(it) => label_and_docs(db, it),
- Definition::Variant(it) => label_and_docs(db, it),
+ Definition::Variant(it) => label_value_and_docs(db, it, |&it| {
+ if !it.parent_enum(db).is_data_carrying(db) {
+ match it.eval(db) {
+ Ok(x) => Some(format!("{}", x)),
+ Err(_) => it.value(db).map(|x| format!("{:?}", x)),
+ }
+ } else {
+ None
+ }
+ }),
Definition::Const(it) => label_value_and_docs(db, it, |it| {
let body = it.eval(db);
match body {
Ok(x) => Some(format!("{}", x)),
- Err(_) => it.value(db).map(|x| format!("{}", x)),
+ Err(_) => {
+ let source = it.source(db)?;
+ let mut body = source.value.body()?.syntax().clone();
+ if source.file_id.is_macro() {
+ body = insert_whitespace_into_node::insert_ws_into(body);
+ }
+ Some(body.to_string())
+ }
+ }
+ }),
+ Definition::Static(it) => label_value_and_docs(db, it, |it| {
+ let source = it.source(db)?;
+ let mut body = source.value.body()?.syntax().clone();
+ if source.file_id.is_macro() {
+ body = insert_whitespace_into_node::insert_ws_into(body);
}
+ Some(body.to_string())
}),
- Definition::Static(it) => label_value_and_docs(db, it, |it| it.value(db)),
Definition::Trait(it) => label_and_docs(db, it),
Definition::TypeAlias(it) => label_and_docs(db, it),
Definition::BuiltinType(it) => {
diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs
index 867d1f54d..eb997e6fe 100644
--- a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs
@@ -8,7 +8,11 @@ fn check_hover_no_result(ra_fixture: &str) {
let (analysis, position) = fixture::position(ra_fixture);
let hover = analysis
.hover(
- &HoverConfig { links_in_hover: true, documentation: Some(HoverDocFormat::Markdown) },
+ &HoverConfig {
+ links_in_hover: true,
+ documentation: Some(HoverDocFormat::Markdown),
+ keywords: true,
+ },
FileRange { file_id: position.file_id, range: TextRange::empty(position.offset) },
)
.unwrap();
@@ -20,7 +24,11 @@ fn check(ra_fixture: &str, expect: Expect) {
let (analysis, position) = fixture::position(ra_fixture);
let hover = analysis
.hover(
- &HoverConfig { links_in_hover: true, documentation: Some(HoverDocFormat::Markdown) },
+ &HoverConfig {
+ links_in_hover: true,
+ documentation: Some(HoverDocFormat::Markdown),
+ keywords: true,
+ },
FileRange { file_id: position.file_id, range: TextRange::empty(position.offset) },
)
.unwrap()
@@ -37,7 +45,11 @@ fn check_hover_no_links(ra_fixture: &str, expect: Expect) {
let (analysis, position) = fixture::position(ra_fixture);
let hover = analysis
.hover(
- &HoverConfig { links_in_hover: false, documentation: Some(HoverDocFormat::Markdown) },
+ &HoverConfig {
+ links_in_hover: false,
+ documentation: Some(HoverDocFormat::Markdown),
+ keywords: true,
+ },
FileRange { file_id: position.file_id, range: TextRange::empty(position.offset) },
)
.unwrap()
@@ -54,7 +66,11 @@ fn check_hover_no_markdown(ra_fixture: &str, expect: Expect) {
let (analysis, position) = fixture::position(ra_fixture);
let hover = analysis
.hover(
- &HoverConfig { links_in_hover: true, documentation: Some(HoverDocFormat::PlainText) },
+ &HoverConfig {
+ links_in_hover: true,
+ documentation: Some(HoverDocFormat::PlainText),
+ keywords: true,
+ },
FileRange { file_id: position.file_id, range: TextRange::empty(position.offset) },
)
.unwrap()
@@ -71,7 +87,11 @@ fn check_actions(ra_fixture: &str, expect: Expect) {
let (analysis, file_id, position) = fixture::range_or_position(ra_fixture);
let hover = analysis
.hover(
- &HoverConfig { links_in_hover: true, documentation: Some(HoverDocFormat::Markdown) },
+ &HoverConfig {
+ links_in_hover: true,
+ documentation: Some(HoverDocFormat::Markdown),
+ keywords: true,
+ },
FileRange { file_id, range: position.range_or_empty() },
)
.unwrap()
@@ -83,7 +103,11 @@ fn check_hover_range(ra_fixture: &str, expect: Expect) {
let (analysis, range) = fixture::range(ra_fixture);
let hover = analysis
.hover(
- &HoverConfig { links_in_hover: false, documentation: Some(HoverDocFormat::Markdown) },
+ &HoverConfig {
+ links_in_hover: false,
+ documentation: Some(HoverDocFormat::Markdown),
+ keywords: true,
+ },
range,
)
.unwrap()
@@ -95,7 +119,11 @@ fn check_hover_range_no_results(ra_fixture: &str) {
let (analysis, range) = fixture::range(ra_fixture);
let hover = analysis
.hover(
- &HoverConfig { links_in_hover: false, documentation: Some(HoverDocFormat::Markdown) },
+ &HoverConfig {
+ links_in_hover: false,
+ documentation: Some(HoverDocFormat::Markdown),
+ keywords: true,
+ },
range,
)
.unwrap();
@@ -670,6 +698,7 @@ fn hover_enum_variant() {
check(
r#"
enum Option<T> {
+ Some(T)
/// The None variant
Non$0e
}
@@ -3500,6 +3529,112 @@ impl<const LEN: usize> Foo<LEN$0> {}
}
#[test]
+fn hover_const_eval_variant() {
+ // show hex for <10
+ check(
+ r#"
+#[repr(u8)]
+enum E {
+ /// This is a doc
+ A$0 = 1 << 3,
+}
+"#,
+ expect![[r#"
+ *A*
+
+ ```rust
+ test::E
+ ```
+
+ ```rust
+ A = 8
+ ```
+
+ ---
+
+ This is a doc
+ "#]],
+ );
+ // show hex for >10
+ check(
+ r#"
+#[repr(u8)]
+enum E {
+ /// This is a doc
+ A$0 = (1 << 3) + (1 << 2),
+}
+"#,
+ expect![[r#"
+ *A*
+
+ ```rust
+ test::E
+ ```
+
+ ```rust
+ A = 12 (0xC)
+ ```
+
+ ---
+
+ This is a doc
+ "#]],
+ );
+ // enums in const eval
+ check(
+ r#"
+#[repr(u8)]
+enum E {
+ A = 1,
+ /// This is a doc
+ B$0 = E::A as u8 + 1,
+}
+"#,
+ expect![[r#"
+ *B*
+
+ ```rust
+ test::E
+ ```
+
+ ```rust
+ B = 2
+ ```
+
+ ---
+
+ This is a doc
+ "#]],
+ );
+ // unspecified variant should increment by one
+ check(
+ r#"
+#[repr(u8)]
+enum E {
+ A = 4,
+ /// This is a doc
+ B$0,
+}
+"#,
+ expect![[r#"
+ *B*
+
+ ```rust
+ test::E
+ ```
+
+ ```rust
+ B = 5
+ ```
+
+ ---
+
+ This is a doc
+ "#]],
+ );
+}
+
+#[test]
fn hover_const_eval() {
// show hex for <10
check(
@@ -3795,6 +3930,35 @@ fn foo() {
This is a doc
"#]],
);
+ check(
+ r#"
+enum E {
+ /// This is a doc
+ A = 3,
+}
+fn foo(e: E) {
+ match e {
+ E::A$0 => (),
+ _ => ()
+ }
+}
+"#,
+ expect![[r#"
+ *A*
+
+ ```rust
+ test::E
+ ```
+
+ ```rust
+ A = 3
+ ```
+
+ ---
+
+ This is a doc
+ "#]],
+ );
}
#[test]
@@ -5051,3 +5215,95 @@ fn f() {
```"#]],
);
}
+
+#[test]
+fn hover_deref() {
+ check(
+ r#"
+//- minicore: deref
+
+struct Struct(usize);
+
+impl core::ops::Deref for Struct {
+ type Target = usize;
+
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+}
+
+fn f() {
+ $0*Struct(0);
+}
+"#,
+ expect![[r#"
+ ***
+
+ ```rust
+ test::Struct
+ ```
+
+ ```rust
+ fn deref(&self) -> &Self::Target
+ ```
+ "#]],
+ );
+}
+
+#[test]
+fn static_const_macro_expanded_body() {
+ check(
+ r#"
+macro_rules! m {
+ () => {
+ pub const V: i8 = {
+ let e = 123;
+ f(e) // Prevent const eval from evaluating this constant, we want to print the body's code.
+ };
+ };
+}
+m!();
+fn main() { $0V; }
+"#,
+ expect![[r#"
+ *V*
+
+ ```rust
+ test
+ ```
+
+ ```rust
+ pub const V: i8 = {
+ let e = 123;
+ f(e)
+ }
+ ```
+ "#]],
+ );
+ check(
+ r#"
+macro_rules! m {
+ () => {
+ pub static V: i8 = {
+ let e = 123;
+ };
+ };
+}
+m!();
+fn main() { $0V; }
+"#,
+ expect![[r#"
+ *V*
+
+ ```rust
+ test
+ ```
+
+ ```rust
+ pub static V: i8 = {
+ let e = 123;
+ }
+ ```
+ "#]],
+ );
+}
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs
index 5aae669aa..34d8bf67a 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs
@@ -1,3 +1,5 @@
+use std::fmt;
+
use either::Either;
use hir::{known, Callable, HasVisibility, HirDisplay, Mutability, Semantics, TypeInfo};
use ide_db::{
@@ -69,7 +71,7 @@ pub enum InlayKind {
pub struct InlayHint {
pub range: TextRange,
pub kind: InlayKind,
- pub label: String,
+ pub label: InlayHintLabel,
pub tooltip: Option<InlayTooltip>,
}
@@ -80,6 +82,83 @@ pub enum InlayTooltip {
HoverOffset(FileId, TextSize),
}
+pub struct InlayHintLabel {
+ pub parts: Vec<InlayHintLabelPart>,
+}
+
+impl InlayHintLabel {
+ pub fn as_simple_str(&self) -> Option<&str> {
+ match &*self.parts {
+ [part] => part.as_simple_str(),
+ _ => None,
+ }
+ }
+
+ pub fn prepend_str(&mut self, s: &str) {
+ match &mut *self.parts {
+ [part, ..] if part.as_simple_str().is_some() => part.text = format!("{s}{}", part.text),
+ _ => self.parts.insert(0, InlayHintLabelPart { text: s.into(), linked_location: None }),
+ }
+ }
+
+ pub fn append_str(&mut self, s: &str) {
+ match &mut *self.parts {
+ [.., part] if part.as_simple_str().is_some() => part.text.push_str(s),
+ _ => self.parts.push(InlayHintLabelPart { text: s.into(), linked_location: None }),
+ }
+ }
+}
+
+impl From<String> for InlayHintLabel {
+ fn from(s: String) -> Self {
+ Self { parts: vec![InlayHintLabelPart { text: s, linked_location: None }] }
+ }
+}
+
+impl fmt::Display for InlayHintLabel {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "{}", self.parts.iter().map(|part| &part.text).format(""))
+ }
+}
+
+impl fmt::Debug for InlayHintLabel {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_list().entries(&self.parts).finish()
+ }
+}
+
+pub struct InlayHintLabelPart {
+ pub text: String,
+ /// Source location represented by this label part. The client will use this to fetch the part's
+ /// hover tooltip, and Ctrl+Clicking the label part will navigate to the definition the location
+ /// refers to (not necessarily the location itself).
+ /// When setting this, no tooltip must be set on the containing hint, or VS Code will display
+ /// them both.
+ pub linked_location: Option<FileRange>,
+}
+
+impl InlayHintLabelPart {
+ pub fn as_simple_str(&self) -> Option<&str> {
+ match self {
+ Self { text, linked_location: None } => Some(text),
+ _ => None,
+ }
+ }
+}
+
+impl fmt::Debug for InlayHintLabelPart {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ match self.as_simple_str() {
+ Some(string) => string.fmt(f),
+ None => f
+ .debug_struct("InlayHintLabelPart")
+ .field("text", &self.text)
+ .field("linked_location", &self.linked_location)
+ .finish(),
+ }
+ }
+}
+
// Feature: Inlay Hints
//
// rust-analyzer shows additional information inline with the source code.
@@ -97,12 +176,6 @@ pub enum InlayTooltip {
// * elided lifetimes
// * compiler inserted reborrows
//
-// |===
-// | Editor | Action Name
-//
-// | VS Code | **Rust Analyzer: Toggle inlay hints*
-// |===
-//
// image::https://user-images.githubusercontent.com/48062697/113020660-b5f98b80-917a-11eb-8d70-3be3fd558cdd.png[]
pub(crate) fn inlay_hints(
db: &RootDatabase,
@@ -192,10 +265,10 @@ fn closing_brace_hints(
) -> Option<()> {
let min_lines = config.closing_brace_hints_min_lines?;
- let name = |it: ast::Name| it.syntax().text_range().start();
+ let name = |it: ast::Name| it.syntax().text_range();
let mut closing_token;
- let (label, name_offset) = if let Some(item_list) = ast::AssocItemList::cast(node.clone()) {
+ let (label, name_range) = if let Some(item_list) = ast::AssocItemList::cast(node.clone()) {
closing_token = item_list.r_curly_token()?;
let parent = item_list.syntax().parent()?;
@@ -205,11 +278,11 @@ fn closing_brace_hints(
let imp = sema.to_def(&imp)?;
let ty = imp.self_ty(sema.db);
let trait_ = imp.trait_(sema.db);
-
- (match trait_ {
+ let hint_text = match trait_ {
Some(tr) => format!("impl {} for {}", tr.name(sema.db), ty.display_truncated(sema.db, config.max_length)),
None => format!("impl {}", ty.display_truncated(sema.db, config.max_length)),
- }, None)
+ };
+ (hint_text, None)
},
ast::Trait(tr) => {
(format!("trait {}", tr.name()?), tr.name().map(name))
@@ -253,7 +326,7 @@ fn closing_brace_hints(
(
format!("{}!", mac.path()?),
- mac.path().and_then(|it| it.segment()).map(|it| it.syntax().text_range().start()),
+ mac.path().and_then(|it| it.segment()).map(|it| it.syntax().text_range()),
)
} else {
return None;
@@ -278,11 +351,12 @@ fn closing_brace_hints(
return None;
}
+ let linked_location = name_range.map(|range| FileRange { file_id, range });
acc.push(InlayHint {
range: closing_token.text_range(),
kind: InlayKind::ClosingBraceHint,
- label,
- tooltip: name_offset.map(|it| InlayTooltip::HoverOffset(file_id, it)),
+ label: InlayHintLabel { parts: vec![InlayHintLabelPart { text: label, linked_location }] },
+ tooltip: None, // provided by label part location
});
None
@@ -311,7 +385,7 @@ fn implicit_static_hints(
acc.push(InlayHint {
range: t.text_range(),
kind: InlayKind::LifetimeHint,
- label: "'static".to_owned(),
+ label: "'static".to_owned().into(),
tooltip: Some(InlayTooltip::String("Elided static lifetime".into())),
});
}
@@ -329,10 +403,10 @@ fn fn_lifetime_fn_hints(
return None;
}
- let mk_lt_hint = |t: SyntaxToken, label| InlayHint {
+ let mk_lt_hint = |t: SyntaxToken, label: String| InlayHint {
range: t.text_range(),
kind: InlayKind::LifetimeHint,
- label,
+ label: label.into(),
tooltip: Some(InlayTooltip::String("Elided lifetime".into())),
};
@@ -486,7 +560,8 @@ fn fn_lifetime_fn_hints(
"{}{}",
allocated_lifetimes.iter().format(", "),
if is_empty { "" } else { ", " }
- ),
+ )
+ .into(),
tooltip: Some(InlayTooltip::String("Elided lifetimes".into())),
});
}
@@ -535,7 +610,8 @@ fn closure_ret_hints(
range: param_list.syntax().text_range(),
kind: InlayKind::ClosureReturnTypeHint,
label: hint_iterator(sema, &famous_defs, config, &ty)
- .unwrap_or_else(|| ty.display_truncated(sema.db, config.max_length).to_string()),
+ .unwrap_or_else(|| ty.display_truncated(sema.db, config.max_length).to_string())
+ .into(),
tooltip: Some(InlayTooltip::HoverRanged(file_id, param_list.syntax().text_range())),
});
Some(())
@@ -562,7 +638,7 @@ fn reborrow_hints(
acc.push(InlayHint {
range: expr.syntax().text_range(),
kind: InlayKind::ImplicitReborrowHint,
- label: label.to_string(),
+ label: label.to_string().into(),
tooltip: Some(InlayTooltip::String("Compiler inserted reborrow".into())),
});
Some(())
@@ -620,9 +696,9 @@ fn chaining_hints(
acc.push(InlayHint {
range: expr.syntax().text_range(),
kind: InlayKind::ChainingHint,
- label: hint_iterator(sema, &famous_defs, config, &ty).unwrap_or_else(|| {
- ty.display_truncated(sema.db, config.max_length).to_string()
- }),
+ label: hint_iterator(sema, &famous_defs, config, &ty)
+ .unwrap_or_else(|| ty.display_truncated(sema.db, config.max_length).to_string())
+ .into(),
tooltip: Some(InlayTooltip::HoverRanged(file_id, expr.syntax().text_range())),
});
}
@@ -674,7 +750,7 @@ fn param_name_hints(
InlayHint {
range,
kind: InlayKind::ParameterHint,
- label: param_name,
+ label: param_name.into(),
tooltip: tooltip.map(|it| InlayTooltip::HoverOffset(it.file_id, it.range.start())),
}
});
@@ -705,7 +781,7 @@ fn binding_mode_hints(
acc.push(InlayHint {
range,
kind: InlayKind::BindingModeHint,
- label: r.to_string(),
+ label: r.to_string().into(),
tooltip: Some(InlayTooltip::String("Inferred binding mode".into())),
});
});
@@ -720,7 +796,7 @@ fn binding_mode_hints(
acc.push(InlayHint {
range,
kind: InlayKind::BindingModeHint,
- label: bm.to_string(),
+ label: bm.to_string().into(),
tooltip: Some(InlayTooltip::String("Inferred binding mode".into())),
});
}
@@ -772,7 +848,7 @@ fn bind_pat_hints(
None => pat.syntax().text_range(),
},
kind: InlayKind::TypeHint,
- label,
+ label: label.into(),
tooltip: pat
.name()
.map(|it| it.syntax().text_range())
@@ -1606,6 +1682,74 @@ fn main() {
}
#[test]
+ fn iterator_hint_regression_issue_12674() {
+ // Ensure we don't crash while solving the projection type of iterators.
+ check_expect(
+ InlayHintsConfig { chaining_hints: true, ..DISABLED_CONFIG },
+ r#"
+//- minicore: iterators
+struct S<T>(T);
+impl<T> S<T> {
+ fn iter(&self) -> Iter<'_, T> { loop {} }
+}
+struct Iter<'a, T: 'a>(&'a T);
+impl<'a, T> Iterator for Iter<'a, T> {
+ type Item = &'a T;
+ fn next(&mut self) -> Option<Self::Item> { loop {} }
+}
+struct Container<'a> {
+ elements: S<&'a str>,
+}
+struct SliceIter<'a, T>(&'a T);
+impl<'a, T> Iterator for SliceIter<'a, T> {
+ type Item = &'a T;
+ fn next(&mut self) -> Option<Self::Item> { loop {} }
+}
+
+fn main(a: SliceIter<'_, Container>) {
+ a
+ .filter_map(|c| Some(c.elements.iter().filter_map(|v| Some(v))))
+ .map(|e| e);
+}
+ "#,
+ expect![[r#"
+ [
+ InlayHint {
+ range: 484..554,
+ kind: ChainingHint,
+ label: [
+ "impl Iterator<Item = impl Iterator<Item = &&str>>",
+ ],
+ tooltip: Some(
+ HoverRanged(
+ FileId(
+ 0,
+ ),
+ 484..554,
+ ),
+ ),
+ },
+ InlayHint {
+ range: 484..485,
+ kind: ChainingHint,
+ label: [
+ "SliceIter<Container>",
+ ],
+ tooltip: Some(
+ HoverRanged(
+ FileId(
+ 0,
+ ),
+ 484..485,
+ ),
+ ),
+ },
+ ]
+ "#]],
+ );
+ }
+
+ #[test]
fn infer_call_method_return_associated_types_with_generic() {
check_types(
r#"
@@ -1880,7 +2024,14 @@ impl<T> Vec<T> {
}
impl<T> IntoIterator for Vec<T> {
- type Item=T;
+ type Item = T;
+ type IntoIter = IntoIter<T>;
+}
+
+struct IntoIter<T> {}
+
+impl<T> Iterator for IntoIter<T> {
+ type Item = T;
}
fn main() {
@@ -1910,7 +2061,7 @@ impl<T> Vec<T> {
pub struct Box<T> {}
trait Display {}
-trait Sync {}
+auto trait Sync {}
fn main() {
// The block expression wrapping disables the constructor hint hiding logic
@@ -2223,7 +2374,9 @@ fn main() {
InlayHint {
range: 147..172,
kind: ChainingHint,
- label: "B",
+ label: [
+ "B",
+ ],
tooltip: Some(
HoverRanged(
FileId(
@@ -2236,7 +2389,9 @@ fn main() {
InlayHint {
range: 147..154,
kind: ChainingHint,
- label: "A",
+ label: [
+ "A",
+ ],
tooltip: Some(
HoverRanged(
FileId(
@@ -2294,7 +2449,9 @@ fn main() {
InlayHint {
range: 143..190,
kind: ChainingHint,
- label: "C",
+ label: [
+ "C",
+ ],
tooltip: Some(
HoverRanged(
FileId(
@@ -2307,7 +2464,9 @@ fn main() {
InlayHint {
range: 143..179,
kind: ChainingHint,
- label: "B",
+ label: [
+ "B",
+ ],
tooltip: Some(
HoverRanged(
FileId(
@@ -2350,7 +2509,9 @@ fn main() {
InlayHint {
range: 246..283,
kind: ChainingHint,
- label: "B<X<i32, bool>>",
+ label: [
+ "B<X<i32, bool>>",
+ ],
tooltip: Some(
HoverRanged(
FileId(
@@ -2363,7 +2524,9 @@ fn main() {
InlayHint {
range: 246..265,
kind: ChainingHint,
- label: "A<X<i32, bool>>",
+ label: [
+ "A<X<i32, bool>>",
+ ],
tooltip: Some(
HoverRanged(
FileId(
@@ -2408,7 +2571,9 @@ fn main() {
InlayHint {
range: 174..241,
kind: ChainingHint,
- label: "impl Iterator<Item = ()>",
+ label: [
+ "impl Iterator<Item = ()>",
+ ],
tooltip: Some(
HoverRanged(
FileId(
@@ -2421,7 +2586,9 @@ fn main() {
InlayHint {
range: 174..224,
kind: ChainingHint,
- label: "impl Iterator<Item = ()>",
+ label: [
+ "impl Iterator<Item = ()>",
+ ],
tooltip: Some(
HoverRanged(
FileId(
@@ -2434,7 +2601,9 @@ fn main() {
InlayHint {
range: 174..206,
kind: ChainingHint,
- label: "impl Iterator<Item = ()>",
+ label: [
+ "impl Iterator<Item = ()>",
+ ],
tooltip: Some(
HoverRanged(
FileId(
@@ -2447,7 +2616,9 @@ fn main() {
InlayHint {
range: 174..189,
kind: ChainingHint,
- label: "&mut MyIter",
+ label: [
+ "&mut MyIter",
+ ],
tooltip: Some(
HoverRanged(
FileId(
@@ -2489,7 +2660,9 @@ fn main() {
InlayHint {
range: 124..130,
kind: TypeHint,
- label: "Struct",
+ label: [
+ "Struct",
+ ],
tooltip: Some(
HoverRanged(
FileId(
@@ -2502,7 +2675,9 @@ fn main() {
InlayHint {
range: 145..185,
kind: ChainingHint,
- label: "Struct",
+ label: [
+ "Struct",
+ ],
tooltip: Some(
HoverRanged(
FileId(
@@ -2515,7 +2690,9 @@ fn main() {
InlayHint {
range: 145..168,
kind: ChainingHint,
- label: "Struct",
+ label: [
+ "Struct",
+ ],
tooltip: Some(
HoverRanged(
FileId(
@@ -2528,7 +2705,9 @@ fn main() {
InlayHint {
range: 222..228,
kind: ParameterHint,
- label: "self",
+ label: [
+ "self",
+ ],
tooltip: Some(
HoverOffset(
FileId(
diff --git a/src/tools/rust-analyzer/crates/ide/src/join_lines.rs b/src/tools/rust-analyzer/crates/ide/src/join_lines.rs
index 08621adde..edc48e84d 100644
--- a/src/tools/rust-analyzer/crates/ide/src/join_lines.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/join_lines.rs
@@ -28,7 +28,7 @@ pub struct JoinLinesConfig {
// |===
// | Editor | Action Name
//
-// | VS Code | **Rust Analyzer: Join lines**
+// | VS Code | **rust-analyzer: Join lines**
// |===
//
// image::https://user-images.githubusercontent.com/48062697/113020661-b6922200-917a-11eb-87c4-b75acc028f11.gif[]
diff --git a/src/tools/rust-analyzer/crates/ide/src/lib.rs b/src/tools/rust-analyzer/crates/ide/src/lib.rs
index dd108fa79..416817ca0 100644
--- a/src/tools/rust-analyzer/crates/ide/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/lib.rs
@@ -31,7 +31,6 @@ mod highlight_related;
mod expand_macro;
mod extend_selection;
mod file_structure;
-mod fn_references;
mod folding_ranges;
mod goto_declaration;
mod goto_definition;
@@ -74,7 +73,7 @@ use syntax::SourceFile;
use crate::navigation_target::{ToNav, TryToNav};
pub use crate::{
- annotations::{Annotation, AnnotationConfig, AnnotationKind},
+ annotations::{Annotation, AnnotationConfig, AnnotationKind, AnnotationLocation},
call_hierarchy::CallItem,
expand_macro::ExpandedMacro,
file_structure::{StructureNode, StructureNodeKind},
@@ -82,12 +81,12 @@ pub use crate::{
highlight_related::{HighlightRelatedConfig, HighlightedRange},
hover::{HoverAction, HoverConfig, HoverDocFormat, HoverGotoTypeData, HoverResult},
inlay_hints::{
- ClosureReturnTypeHints, InlayHint, InlayHintsConfig, InlayKind, InlayTooltip,
- LifetimeElisionHints, ReborrowHints,
+ ClosureReturnTypeHints, InlayHint, InlayHintLabel, InlayHintsConfig, InlayKind,
+ InlayTooltip, LifetimeElisionHints, ReborrowHints,
},
join_lines::JoinLinesConfig,
markup::Markup,
- moniker::{MonikerKind, MonikerResult, PackageInformation},
+ moniker::{MonikerDescriptorKind, MonikerKind, MonikerResult, PackageInformation},
move_item::Direction,
navigation_target::NavigationTarget,
prime_caches::ParallelPrimeCachesProgress,
@@ -98,7 +97,7 @@ pub use crate::{
static_index::{StaticIndex, StaticIndexedFile, TokenId, TokenStaticData},
syntax_highlighting::{
tags::{Highlight, HlMod, HlMods, HlOperator, HlPunct, HlTag},
- HlRange,
+ HighlightConfig, HlRange,
},
};
pub use hir::{Documentation, Semantics};
@@ -236,7 +235,7 @@ impl Analysis {
Env::default(),
Ok(Vec::new()),
false,
- CrateOrigin::CratesIo { repo: None },
+ CrateOrigin::CratesIo { repo: None, name: None },
);
change.change_file(file_id, Some(Arc::new(text)));
change.set_crate_graph(crate_graph);
@@ -429,11 +428,6 @@ impl Analysis {
self.with_db(|db| references::find_all_refs(&Semantics::new(db), position, search_scope))
}
- /// Finds all methods and free functions for the file. Does not return tests!
- pub fn find_all_methods(&self, file_id: FileId) -> Cancellable<Vec<FileRange>> {
- self.with_db(|db| fn_references::find_all_methods(db, file_id))
- }
-
/// Returns a short text describing element at position.
pub fn hover(
&self,
@@ -488,8 +482,18 @@ impl Analysis {
}
/// Returns crates this file belongs too.
- pub fn crate_for(&self, file_id: FileId) -> Cancellable<Vec<CrateId>> {
- self.with_db(|db| parent_module::crate_for(db, file_id))
+ pub fn crates_for(&self, file_id: FileId) -> Cancellable<Vec<CrateId>> {
+ self.with_db(|db| parent_module::crates_for(db, file_id))
+ }
+
+ /// Returns crates this file belongs too.
+ pub fn transitive_rev_deps(&self, crate_id: CrateId) -> Cancellable<Vec<CrateId>> {
+ self.with_db(|db| db.crate_graph().transitive_rev_deps(crate_id).collect())
+ }
+
+ /// Returns crates this file *might* belong too.
+ pub fn relevant_crates_for(&self, file_id: FileId) -> Cancellable<Vec<CrateId>> {
+ self.with_db(|db| db.relevant_crates(file_id).iter().copied().collect())
}
/// Returns the edition of the given crate.
@@ -517,8 +521,12 @@ impl Analysis {
}
/// Computes syntax highlighting for the given file
- pub fn highlight(&self, file_id: FileId) -> Cancellable<Vec<HlRange>> {
- self.with_db(|db| syntax_highlighting::highlight(db, file_id, None, false))
+ pub fn highlight(
+ &self,
+ highlight_config: HighlightConfig,
+ file_id: FileId,
+ ) -> Cancellable<Vec<HlRange>> {
+ self.with_db(|db| syntax_highlighting::highlight(db, highlight_config, file_id, None))
}
/// Computes all ranges to highlight for a given item in a file.
@@ -533,9 +541,13 @@ impl Analysis {
}
/// Computes syntax highlighting for the given file range.
- pub fn highlight_range(&self, frange: FileRange) -> Cancellable<Vec<HlRange>> {
+ pub fn highlight_range(
+ &self,
+ highlight_config: HighlightConfig,
+ frange: FileRange,
+ ) -> Cancellable<Vec<HlRange>> {
self.with_db(|db| {
- syntax_highlighting::highlight(db, frange.file_id, Some(frange.range), false)
+ syntax_highlighting::highlight(db, highlight_config, frange.file_id, Some(frange.range))
})
}
diff --git a/src/tools/rust-analyzer/crates/ide/src/matching_brace.rs b/src/tools/rust-analyzer/crates/ide/src/matching_brace.rs
index da70cecdd..6e8a6d020 100644
--- a/src/tools/rust-analyzer/crates/ide/src/matching_brace.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/matching_brace.rs
@@ -12,7 +12,7 @@ use syntax::{
// |===
// | Editor | Action Name
//
-// | VS Code | **Rust Analyzer: Find matching brace**
+// | VS Code | **rust-analyzer: Find matching brace**
// |===
//
// image::https://user-images.githubusercontent.com/48062697/113065573-04298180-91b1-11eb-8dec-d4e2a202f304.gif[]
diff --git a/src/tools/rust-analyzer/crates/ide/src/moniker.rs b/src/tools/rust-analyzer/crates/ide/src/moniker.rs
index 6bab9fa1e..852a8fd83 100644
--- a/src/tools/rust-analyzer/crates/ide/src/moniker.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/moniker.rs
@@ -14,16 +14,38 @@ use syntax::{AstNode, SyntaxKind::*, T};
use crate::{doc_links::token_as_doc_comment, RangeInfo};
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
+pub enum MonikerDescriptorKind {
+ Namespace,
+ Type,
+ Term,
+ Method,
+ TypeParameter,
+ Parameter,
+ Macro,
+ Meta,
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
+pub struct MonikerDescriptor {
+ pub name: Name,
+ pub desc: MonikerDescriptorKind,
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct MonikerIdentifier {
- crate_name: String,
- path: Vec<Name>,
+ pub crate_name: String,
+ pub description: Vec<MonikerDescriptor>,
}
impl ToString for MonikerIdentifier {
fn to_string(&self) -> String {
match self {
- MonikerIdentifier { path, crate_name } => {
- format!("{}::{}", crate_name, path.iter().map(|x| x.to_string()).join("::"))
+ MonikerIdentifier { description, crate_name } => {
+ format!(
+ "{}::{}",
+ crate_name,
+ description.iter().map(|x| x.name.to_string()).join("::")
+ )
}
}
}
@@ -42,6 +64,12 @@ pub struct MonikerResult {
pub package_information: PackageInformation,
}
+impl MonikerResult {
+ pub fn from_def(db: &RootDatabase, def: Definition, from_crate: Crate) -> Option<Self> {
+ def_to_moniker(db, def, from_crate)
+ }
+}
+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct PackageInformation {
pub name: String,
@@ -90,7 +118,7 @@ pub(crate) fn moniker(
.descend_into_macros(original_token.clone())
.into_iter()
.filter_map(|token| {
- IdentClass::classify_token(sema, &token).map(IdentClass::definitions).map(|it| {
+ IdentClass::classify_token(sema, &token).map(IdentClass::definitions_no_ops).map(|it| {
it.into_iter().flat_map(|def| def_to_moniker(sema.db, def, current_crate))
})
})
@@ -105,13 +133,23 @@ pub(crate) fn def_to_moniker(
def: Definition,
from_crate: Crate,
) -> Option<MonikerResult> {
- if matches!(def, Definition::GenericParam(_) | Definition::SelfType(_) | Definition::Local(_)) {
+ if matches!(
+ def,
+ Definition::GenericParam(_)
+ | Definition::Label(_)
+ | Definition::DeriveHelper(_)
+ | Definition::BuiltinAttr(_)
+ | Definition::ToolModule(_)
+ ) {
return None;
}
+
let module = def.module(db)?;
let krate = module.krate();
- let mut path = vec![];
- path.extend(module.path_to_root(db).into_iter().filter_map(|x| x.name(db)));
+ let mut description = vec![];
+ description.extend(module.path_to_root(db).into_iter().filter_map(|x| {
+ Some(MonikerDescriptor { name: x.name(db)?, desc: MonikerDescriptorKind::Namespace })
+ }));
// Handle associated items within a trait
if let Some(assoc) = def.as_assoc_item(db) {
@@ -120,38 +158,109 @@ pub(crate) fn def_to_moniker(
AssocItemContainer::Trait(trait_) => {
// Because different traits can have functions with the same name,
// we have to include the trait name as part of the moniker for uniqueness.
- path.push(trait_.name(db));
+ description.push(MonikerDescriptor {
+ name: trait_.name(db),
+ desc: MonikerDescriptorKind::Type,
+ });
}
AssocItemContainer::Impl(impl_) => {
// Because a struct can implement multiple traits, for implementations
// we add both the struct name and the trait name to the path
if let Some(adt) = impl_.self_ty(db).as_adt() {
- path.push(adt.name(db));
+ description.push(MonikerDescriptor {
+ name: adt.name(db),
+ desc: MonikerDescriptorKind::Type,
+ });
}
if let Some(trait_) = impl_.trait_(db) {
- path.push(trait_.name(db));
+ description.push(MonikerDescriptor {
+ name: trait_.name(db),
+ desc: MonikerDescriptorKind::Type,
+ });
}
}
}
}
if let Definition::Field(it) = def {
- path.push(it.parent_def(db).name(db));
+ description.push(MonikerDescriptor {
+ name: it.parent_def(db).name(db),
+ desc: MonikerDescriptorKind::Type,
+ });
}
- path.push(def.name(db)?);
+ let name_desc = match def {
+ // These are handled by top-level guard (for performance).
+ Definition::GenericParam(_)
+ | Definition::Label(_)
+ | Definition::DeriveHelper(_)
+ | Definition::BuiltinAttr(_)
+ | Definition::ToolModule(_) => return None,
+
+ Definition::Local(local) => {
+ if !local.is_param(db) {
+ return None;
+ }
+
+ MonikerDescriptor { name: local.name(db), desc: MonikerDescriptorKind::Parameter }
+ }
+ Definition::Macro(m) => {
+ MonikerDescriptor { name: m.name(db), desc: MonikerDescriptorKind::Macro }
+ }
+ Definition::Function(f) => {
+ MonikerDescriptor { name: f.name(db), desc: MonikerDescriptorKind::Method }
+ }
+ Definition::Variant(v) => {
+ MonikerDescriptor { name: v.name(db), desc: MonikerDescriptorKind::Type }
+ }
+ Definition::Const(c) => {
+ MonikerDescriptor { name: c.name(db)?, desc: MonikerDescriptorKind::Term }
+ }
+ Definition::Trait(trait_) => {
+ MonikerDescriptor { name: trait_.name(db), desc: MonikerDescriptorKind::Type }
+ }
+ Definition::TypeAlias(ta) => {
+ MonikerDescriptor { name: ta.name(db), desc: MonikerDescriptorKind::TypeParameter }
+ }
+ Definition::Module(m) => {
+ MonikerDescriptor { name: m.name(db)?, desc: MonikerDescriptorKind::Namespace }
+ }
+ Definition::BuiltinType(b) => {
+ MonikerDescriptor { name: b.name(), desc: MonikerDescriptorKind::Type }
+ }
+ Definition::SelfType(imp) => MonikerDescriptor {
+ name: imp.self_ty(db).as_adt()?.name(db),
+ desc: MonikerDescriptorKind::Type,
+ },
+ Definition::Field(it) => {
+ MonikerDescriptor { name: it.name(db), desc: MonikerDescriptorKind::Term }
+ }
+ Definition::Adt(adt) => {
+ MonikerDescriptor { name: adt.name(db), desc: MonikerDescriptorKind::Type }
+ }
+ Definition::Static(s) => {
+ MonikerDescriptor { name: s.name(db), desc: MonikerDescriptorKind::Meta }
+ }
+ };
+
+ description.push(name_desc);
+
Some(MonikerResult {
identifier: MonikerIdentifier {
crate_name: krate.display_name(db)?.crate_name().to_string(),
- path,
+ description,
},
kind: if krate == from_crate { MonikerKind::Export } else { MonikerKind::Import },
package_information: {
- let name = krate.display_name(db)?.to_string();
- let (repo, version) = match krate.origin(db) {
- CrateOrigin::CratesIo { repo } => (repo?, krate.version(db)?),
+ let (name, repo, version) = match krate.origin(db) {
+ CrateOrigin::CratesIo { repo, name } => (
+ name.unwrap_or(krate.display_name(db)?.canonical_name().to_string()),
+ repo?,
+ krate.version(db)?,
+ ),
CrateOrigin::Lang(lang) => (
+ krate.display_name(db)?.canonical_name().to_string(),
"https://github.com/rust-lang/rust/".to_string(),
match lang {
LangCrateOrigin::Other => {
diff --git a/src/tools/rust-analyzer/crates/ide/src/move_item.rs b/src/tools/rust-analyzer/crates/ide/src/move_item.rs
index 02e9fb8b5..ffc4bdd7d 100644
--- a/src/tools/rust-analyzer/crates/ide/src/move_item.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/move_item.rs
@@ -19,8 +19,8 @@ pub enum Direction {
// |===
// | Editor | Action Name
//
-// | VS Code | **Rust Analyzer: Move item up**
-// | VS Code | **Rust Analyzer: Move item down**
+// | VS Code | **rust-analyzer: Move item up**
+// | VS Code | **rust-analyzer: Move item down**
// |===
//
// image::https://user-images.githubusercontent.com/48062697/113065576-04298180-91b1-11eb-91ce-4505e99ed598.gif[]
diff --git a/src/tools/rust-analyzer/crates/ide/src/parent_module.rs b/src/tools/rust-analyzer/crates/ide/src/parent_module.rs
index 9b1f48044..506f9452c 100644
--- a/src/tools/rust-analyzer/crates/ide/src/parent_module.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/parent_module.rs
@@ -1,6 +1,6 @@
-use hir::Semantics;
+use hir::{db::DefDatabase, Semantics};
use ide_db::{
- base_db::{CrateId, FileId, FilePosition},
+ base_db::{CrateId, FileId, FileLoader, FilePosition},
RootDatabase,
};
use itertools::Itertools;
@@ -18,7 +18,7 @@ use crate::NavigationTarget;
// |===
// | Editor | Action Name
//
-// | VS Code | **Rust Analyzer: Locate parent module**
+// | VS Code | **rust-analyzer: Locate parent module**
// |===
//
// image::https://user-images.githubusercontent.com/48062697/113065580-04c21800-91b1-11eb-9a32-00086161c0bd.gif[]
@@ -55,9 +55,13 @@ pub(crate) fn parent_module(db: &RootDatabase, position: FilePosition) -> Vec<Na
}
/// Returns `Vec` for the same reason as `parent_module`
-pub(crate) fn crate_for(db: &RootDatabase, file_id: FileId) -> Vec<CrateId> {
- let sema = Semantics::new(db);
- sema.to_module_defs(file_id).map(|module| module.krate().into()).unique().collect()
+pub(crate) fn crates_for(db: &RootDatabase, file_id: FileId) -> Vec<CrateId> {
+ db.relevant_crates(file_id)
+ .iter()
+ .copied()
+ .filter(|&crate_id| db.crate_def_map(crate_id).modules_for_file(file_id).next().is_some())
+ .sorted()
+ .collect()
}
#[cfg(test)]
@@ -147,7 +151,7 @@ $0
mod foo;
"#,
);
- assert_eq!(analysis.crate_for(file_id).unwrap().len(), 1);
+ assert_eq!(analysis.crates_for(file_id).unwrap().len(), 1);
}
#[test]
@@ -162,6 +166,6 @@ mod baz;
mod baz;
"#,
);
- assert_eq!(analysis.crate_for(file_id).unwrap().len(), 2);
+ assert_eq!(analysis.crates_for(file_id).unwrap().len(), 2);
}
}
diff --git a/src/tools/rust-analyzer/crates/ide/src/prime_caches.rs b/src/tools/rust-analyzer/crates/ide/src/prime_caches.rs
index 296270036..87b3ef380 100644
--- a/src/tools/rust-analyzer/crates/ide/src/prime_caches.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/prime_caches.rs
@@ -12,8 +12,9 @@ use ide_db::{
salsa::{Database, ParallelDatabase, Snapshot},
Cancelled, CrateGraph, CrateId, SourceDatabase, SourceDatabaseExt,
},
- FxHashSet, FxIndexMap,
+ FxIndexMap,
};
+use stdx::hash::NoHashHashSet;
use crate::RootDatabase;
@@ -141,7 +142,7 @@ pub(crate) fn parallel_prime_caches(
}
}
-fn compute_crates_to_prime(db: &RootDatabase, graph: &CrateGraph) -> FxHashSet<CrateId> {
+fn compute_crates_to_prime(db: &RootDatabase, graph: &CrateGraph) -> NoHashHashSet<CrateId> {
// We're only interested in the workspace crates and the `ImportMap`s of their direct
// dependencies, though in practice the latter also compute the `DefMap`s.
// We don't prime transitive dependencies because they're generally not visible in
diff --git a/src/tools/rust-analyzer/crates/ide/src/references.rs b/src/tools/rust-analyzer/crates/ide/src/references.rs
index 1a6beec18..e942413c1 100644
--- a/src/tools/rust-analyzer/crates/ide/src/references.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/references.rs
@@ -14,8 +14,9 @@ use ide_db::{
base_db::FileId,
defs::{Definition, NameClass, NameRefClass},
search::{ReferenceCategory, SearchScope, UsageSearchResult},
- FxHashMap, RootDatabase,
+ RootDatabase,
};
+use stdx::hash::NoHashHashMap;
use syntax::{
algo::find_node_at_offset,
ast::{self, HasName},
@@ -29,7 +30,7 @@ use crate::{FilePosition, NavigationTarget, TryToNav};
#[derive(Debug, Clone)]
pub struct ReferenceSearchResult {
pub declaration: Option<Declaration>,
- pub references: FxHashMap<FileId, Vec<(TextRange, Option<ReferenceCategory>)>>,
+ pub references: NoHashHashMap<FileId, Vec<(TextRange, Option<ReferenceCategory>)>>,
}
#[derive(Debug, Clone)]
@@ -741,7 +742,7 @@ pub struct Foo {
expect![[r#"
foo Module FileId(0) 0..8 4..7
- FileId(0) 14..17
+ FileId(0) 14..17 Import
"#]],
);
}
@@ -759,7 +760,7 @@ use self$0;
expect![[r#"
foo Module FileId(0) 0..8 4..7
- FileId(1) 4..8
+ FileId(1) 4..8 Import
"#]],
);
}
@@ -774,7 +775,7 @@ use self$0;
expect![[r#"
Module FileId(0) 0..10
- FileId(0) 4..8
+ FileId(0) 4..8 Import
"#]],
);
}
@@ -802,7 +803,7 @@ pub(super) struct Foo$0 {
expect![[r#"
Foo Struct FileId(2) 0..41 18..21
- FileId(1) 20..23
+ FileId(1) 20..23 Import
FileId(1) 47..50
"#]],
);
@@ -965,7 +966,7 @@ fn g() { f(); }
expect![[r#"
f Function FileId(0) 22..31 25..26
- FileId(1) 11..12
+ FileId(1) 11..12 Import
FileId(1) 24..25
"#]],
);
@@ -1423,9 +1424,9 @@ pub use level1::Foo;
expect![[r#"
Foo Struct FileId(0) 0..15 11..14
- FileId(1) 16..19
- FileId(2) 16..19
- FileId(3) 16..19
+ FileId(1) 16..19 Import
+ FileId(2) 16..19 Import
+ FileId(3) 16..19 Import
"#]],
);
}
@@ -1453,7 +1454,7 @@ lib::foo!();
expect![[r#"
foo Macro FileId(1) 0..61 29..32
- FileId(0) 46..49
+ FileId(0) 46..49 Import
FileId(2) 0..3
FileId(3) 5..8
"#]],
@@ -1616,7 +1617,7 @@ struct Foo;
expect![[r#"
derive_identity Derive FileId(2) 1..107 45..60
- FileId(0) 17..31
+ FileId(0) 17..31 Import
FileId(0) 56..70
"#]],
);
diff --git a/src/tools/rust-analyzer/crates/ide/src/runnables.rs b/src/tools/rust-analyzer/crates/ide/src/runnables.rs
index bec770ed9..0181c6b8e 100644
--- a/src/tools/rust-analyzer/crates/ide/src/runnables.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/runnables.rs
@@ -116,7 +116,7 @@ impl Runnable {
// |===
// | Editor | Action Name
//
-// | VS Code | **Rust Analyzer: Run**
+// | VS Code | **rust-analyzer: Run**
// |===
// image::https://user-images.githubusercontent.com/48062697/113065583-055aae80-91b1-11eb-958f-d67efcaf6a2f.gif[]
pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> {
@@ -202,7 +202,7 @@ pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> {
// |===
// | Editor | Action Name
//
-// | VS Code | **Rust Analyzer: Peek related tests**
+// | VS Code | **rust-analyzer: Peek related tests**
// |===
pub(crate) fn related_tests(
db: &RootDatabase,
@@ -373,11 +373,13 @@ pub(crate) fn runnable_impl(
let adt_name = ty.as_adt()?.name(sema.db);
let mut ty_args = ty.type_arguments().peekable();
let params = if ty_args.peek().is_some() {
- format!("<{}>", ty_args.format_with(", ", |ty, cb| cb(&ty.display(sema.db))))
+ format!("<{}>", ty_args.format_with(",", |ty, cb| cb(&ty.display(sema.db))))
} else {
String::new()
};
- let test_id = TestId::Path(format!("{}{}", adt_name, params));
+ let mut test_id = format!("{}{}", adt_name, params);
+ test_id.retain(|c| c != ' ');
+ let test_id = TestId::Path(test_id);
Some(Runnable { use_name_in_title: false, nav, kind: RunnableKind::DocTest { test_id }, cfg })
}
@@ -441,10 +443,11 @@ fn module_def_doctest(db: &RootDatabase, def: Definition) -> Option<Runnable> {
format_to!(
path,
"<{}>",
- ty_args.format_with(", ", |ty, cb| cb(&ty.display(db)))
+ ty_args.format_with(",", |ty, cb| cb(&ty.display(db)))
);
}
format_to!(path, "::{}", def_name);
+ path.retain(|c| c != ' ');
return Some(path);
}
}
@@ -2067,13 +2070,23 @@ mod tests {
$0
struct Foo<T, U>;
+/// ```
+/// ```
impl<T, U> Foo<T, U> {
/// ```rust
/// ````
fn t() {}
}
+
+/// ```
+/// ```
+impl Foo<Foo<(), ()>, ()> {
+ /// ```
+ /// ```
+ fn t() {}
+}
"#,
- &[DocTest],
+ &[DocTest, DocTest, DocTest, DocTest],
expect![[r#"
[
Runnable {
@@ -2082,12 +2095,64 @@ impl<T, U> Foo<T, U> {
file_id: FileId(
0,
),
- full_range: 47..85,
+ full_range: 20..103,
+ focus_range: 47..56,
+ name: "impl",
+ kind: Impl,
+ },
+ kind: DocTest {
+ test_id: Path(
+ "Foo<T,U>",
+ ),
+ },
+ cfg: None,
+ },
+ Runnable {
+ use_name_in_title: false,
+ nav: NavigationTarget {
+ file_id: FileId(
+ 0,
+ ),
+ full_range: 63..101,
+ name: "t",
+ },
+ kind: DocTest {
+ test_id: Path(
+ "Foo<T,U>::t",
+ ),
+ },
+ cfg: None,
+ },
+ Runnable {
+ use_name_in_title: false,
+ nav: NavigationTarget {
+ file_id: FileId(
+ 0,
+ ),
+ full_range: 105..188,
+ focus_range: 126..146,
+ name: "impl",
+ kind: Impl,
+ },
+ kind: DocTest {
+ test_id: Path(
+ "Foo<Foo<(),()>,()>",
+ ),
+ },
+ cfg: None,
+ },
+ Runnable {
+ use_name_in_title: false,
+ nav: NavigationTarget {
+ file_id: FileId(
+ 0,
+ ),
+ full_range: 153..186,
name: "t",
},
kind: DocTest {
test_id: Path(
- "Foo<T, U>::t",
+ "Foo<Foo<(),()>,()>::t",
),
},
cfg: None,
@@ -2160,4 +2225,190 @@ macro_rules! foo {
"#]],
);
}
+
+ #[test]
+ fn test_paths_with_raw_ident() {
+ check(
+ r#"
+//- /lib.rs
+$0
+mod r#mod {
+ #[test]
+ fn r#fn() {}
+
+ /// ```
+ /// ```
+ fn r#for() {}
+
+ /// ```
+ /// ```
+ struct r#struct<r#type>(r#type);
+
+ /// ```
+ /// ```
+ impl<r#type> r#struct<r#type> {
+ /// ```
+ /// ```
+ fn r#fn() {}
+ }
+
+ enum r#enum {}
+ impl r#struct<r#enum> {
+ /// ```
+ /// ```
+ fn r#fn() {}
+ }
+
+ trait r#trait {}
+
+ /// ```
+ /// ```
+ impl<T> r#trait for r#struct<T> {}
+}
+"#,
+ &[TestMod, Test, DocTest, DocTest, DocTest, DocTest, DocTest, DocTest],
+ expect![[r#"
+ [
+ Runnable {
+ use_name_in_title: false,
+ nav: NavigationTarget {
+ file_id: FileId(
+ 0,
+ ),
+ full_range: 1..461,
+ focus_range: 5..10,
+ name: "r#mod",
+ kind: Module,
+ description: "mod r#mod",
+ },
+ kind: TestMod {
+ path: "r#mod",
+ },
+ cfg: None,
+ },
+ Runnable {
+ use_name_in_title: false,
+ nav: NavigationTarget {
+ file_id: FileId(
+ 0,
+ ),
+ full_range: 17..41,
+ focus_range: 32..36,
+ name: "r#fn",
+ kind: Function,
+ },
+ kind: Test {
+ test_id: Path(
+ "r#mod::r#fn",
+ ),
+ attr: TestAttr {
+ ignore: false,
+ },
+ },
+ cfg: None,
+ },
+ Runnable {
+ use_name_in_title: false,
+ nav: NavigationTarget {
+ file_id: FileId(
+ 0,
+ ),
+ full_range: 47..84,
+ name: "r#for",
+ },
+ kind: DocTest {
+ test_id: Path(
+ "r#mod::r#for",
+ ),
+ },
+ cfg: None,
+ },
+ Runnable {
+ use_name_in_title: false,
+ nav: NavigationTarget {
+ file_id: FileId(
+ 0,
+ ),
+ full_range: 90..146,
+ name: "r#struct",
+ },
+ kind: DocTest {
+ test_id: Path(
+ "r#mod::r#struct",
+ ),
+ },
+ cfg: None,
+ },
+ Runnable {
+ use_name_in_title: false,
+ nav: NavigationTarget {
+ file_id: FileId(
+ 0,
+ ),
+ full_range: 152..266,
+ focus_range: 189..205,
+ name: "impl",
+ kind: Impl,
+ },
+ kind: DocTest {
+ test_id: Path(
+ "r#struct<r#type>",
+ ),
+ },
+ cfg: None,
+ },
+ Runnable {
+ use_name_in_title: false,
+ nav: NavigationTarget {
+ file_id: FileId(
+ 0,
+ ),
+ full_range: 216..260,
+ name: "r#fn",
+ },
+ kind: DocTest {
+ test_id: Path(
+ "r#mod::r#struct<r#type>::r#fn",
+ ),
+ },
+ cfg: None,
+ },
+ Runnable {
+ use_name_in_title: false,
+ nav: NavigationTarget {
+ file_id: FileId(
+ 0,
+ ),
+ full_range: 323..367,
+ name: "r#fn",
+ },
+ kind: DocTest {
+ test_id: Path(
+ "r#mod::r#struct<r#enum>::r#fn",
+ ),
+ },
+ cfg: None,
+ },
+ Runnable {
+ use_name_in_title: false,
+ nav: NavigationTarget {
+ file_id: FileId(
+ 0,
+ ),
+ full_range: 401..459,
+ focus_range: 445..456,
+ name: "impl",
+ kind: Impl,
+ },
+ kind: DocTest {
+ test_id: Path(
+ "r#struct<T>",
+ ),
+ },
+ cfg: None,
+ },
+ ]
+ "#]],
+ )
+ }
}
diff --git a/src/tools/rust-analyzer/crates/ide/src/shuffle_crate_graph.rs b/src/tools/rust-analyzer/crates/ide/src/shuffle_crate_graph.rs
index 15cb89dcc..2d8662764 100644
--- a/src/tools/rust-analyzer/crates/ide/src/shuffle_crate_graph.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/shuffle_crate_graph.rs
@@ -12,7 +12,7 @@ use ide_db::{
// |===
// | Editor | Action Name
//
-// | VS Code | **Rust Analyzer: Shuffle Crate Graph**
+// | VS Code | **rust-analyzer: Shuffle Crate Graph**
// |===
pub(crate) fn shuffle_crate_graph(db: &mut RootDatabase) {
let crate_graph = db.crate_graph();
diff --git a/src/tools/rust-analyzer/crates/ide/src/static_index.rs b/src/tools/rust-analyzer/crates/ide/src/static_index.rs
index d74b64041..27ad1a948 100644
--- a/src/tools/rust-analyzer/crates/ide/src/static_index.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/static_index.rs
@@ -130,8 +130,11 @@ impl StaticIndex<'_> {
syntax::NodeOrToken::Node(_) => None,
syntax::NodeOrToken::Token(x) => Some(x),
});
- let hover_config =
- HoverConfig { links_in_hover: true, documentation: Some(HoverDocFormat::Markdown) };
+ let hover_config = HoverConfig {
+ links_in_hover: true,
+ documentation: Some(HoverDocFormat::Markdown),
+ keywords: true,
+ };
let tokens = tokens.filter(|token| {
matches!(
token.kind(),
@@ -204,12 +207,10 @@ impl StaticIndex<'_> {
fn get_definition(sema: &Semantics<'_, RootDatabase>, token: SyntaxToken) -> Option<Definition> {
for token in sema.descend_into_macros(token) {
- let def = IdentClass::classify_token(sema, &token).map(IdentClass::definitions);
+ let def = IdentClass::classify_token(sema, &token).map(IdentClass::definitions_no_ops);
if let Some(&[x]) = def.as_deref() {
return Some(x);
- } else {
- continue;
- };
+ }
}
None
}
diff --git a/src/tools/rust-analyzer/crates/ide/src/status.rs b/src/tools/rust-analyzer/crates/ide/src/status.rs
index 3191870eb..20810c25b 100644
--- a/src/tools/rust-analyzer/crates/ide/src/status.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/status.rs
@@ -1,4 +1,4 @@
-use std::{fmt, iter::FromIterator, sync::Arc};
+use std::{fmt, sync::Arc};
use hir::{ExpandResult, MacroFile};
use ide_db::base_db::{
@@ -29,7 +29,7 @@ fn macro_syntax_tree_stats(db: &RootDatabase) -> SyntaxTreeStats {
// |===
// | Editor | Action Name
//
-// | VS Code | **Rust Analyzer: Status**
+// | VS Code | **rust-analyzer: Status**
// |===
// image::https://user-images.githubusercontent.com/48062697/113065584-05f34500-91b1-11eb-98cc-5c196f76be7f.gif[]
pub(crate) fn status(db: &RootDatabase, file_id: Option<FileId>) -> String {
@@ -45,7 +45,7 @@ pub(crate) fn status(db: &RootDatabase, file_id: Option<FileId>) -> String {
if let Some(file_id) = file_id {
format_to!(buf, "\nFile info:\n");
- let crates = crate::parent_module::crate_for(db, file_id);
+ let crates = crate::parent_module::crates_for(db, file_id);
if crates.is_empty() {
format_to!(buf, "Does not belong to any crate");
}
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs
index 3fb49b45d..50371d620 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs
@@ -14,7 +14,7 @@ mod html;
mod tests;
use hir::{Name, Semantics};
-use ide_db::{FxHashMap, RootDatabase};
+use ide_db::{FxHashMap, RootDatabase, SymbolKind};
use syntax::{
ast, AstNode, AstToken, NodeOrToken, SyntaxKind::*, SyntaxNode, TextRange, WalkEvent, T,
};
@@ -24,7 +24,7 @@ use crate::{
escape::highlight_escape_string, format::highlight_format_string, highlights::Highlights,
macro_::MacroHighlighter, tags::Highlight,
},
- FileId, HlMod, HlTag,
+ FileId, HlMod, HlOperator, HlPunct, HlTag,
};
pub(crate) use html::highlight_as_html;
@@ -36,6 +36,26 @@ pub struct HlRange {
pub binding_hash: Option<u64>,
}
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+pub struct HighlightConfig {
+ /// Whether to highlight strings
+ pub strings: bool,
+ /// Whether to highlight punctuation
+ pub punctuation: bool,
+ /// Whether to specialize punctuation highlights
+ pub specialize_punctuation: bool,
+ /// Whether to highlight operator
+ pub operator: bool,
+ /// Whether to specialize operator highlights
+ pub specialize_operator: bool,
+ /// Whether to inject highlights into doc comments
+ pub inject_doc_comment: bool,
+ /// Whether to highlight the macro call bang
+ pub macro_bang: bool,
+ /// Whether to highlight unresolved things be their syntax
+ pub syntactic_name_ref_highlighting: bool,
+}
+
// Feature: Semantic Syntax Highlighting
//
// rust-analyzer highlights the code semantically.
@@ -155,9 +175,9 @@ pub struct HlRange {
// image::https://user-images.githubusercontent.com/48062697/113187625-f7f50100-9250-11eb-825e-91c58f236071.png[]
pub(crate) fn highlight(
db: &RootDatabase,
+ config: HighlightConfig,
file_id: FileId,
range_to_highlight: Option<TextRange>,
- syntactic_name_ref_highlighting: bool,
) -> Vec<HlRange> {
let _p = profile::span("highlight");
let sema = Semantics::new(db);
@@ -183,26 +203,18 @@ pub(crate) fn highlight(
Some(it) => it.krate(),
None => return hl.to_vec(),
};
- traverse(
- &mut hl,
- &sema,
- file_id,
- &root,
- krate,
- range_to_highlight,
- syntactic_name_ref_highlighting,
- );
+ traverse(&mut hl, &sema, config, file_id, &root, krate, range_to_highlight);
hl.to_vec()
}
fn traverse(
hl: &mut Highlights,
sema: &Semantics<'_, RootDatabase>,
+ config: HighlightConfig,
file_id: FileId,
root: &SyntaxNode,
krate: hir::Crate,
range_to_highlight: TextRange,
- syntactic_name_ref_highlighting: bool,
) {
let is_unlinked = sema.to_module_def(file_id).is_none();
let mut bindings_shadow_count: FxHashMap<Name, u32> = FxHashMap::default();
@@ -323,9 +335,11 @@ fn traverse(
Enter(it) => it,
Leave(NodeOrToken::Token(_)) => continue,
Leave(NodeOrToken::Node(node)) => {
- // Doc comment highlighting injection, we do this when leaving the node
- // so that we overwrite the highlighting of the doc comment itself.
- inject::doc_comment(hl, sema, file_id, &node);
+ if config.inject_doc_comment {
+ // Doc comment highlighting injection, we do this when leaving the node
+ // so that we overwrite the highlighting of the doc comment itself.
+ inject::doc_comment(hl, sema, config, file_id, &node);
+ }
continue;
}
};
@@ -400,7 +414,8 @@ fn traverse(
let string_to_highlight = ast::String::cast(descended_token.clone());
if let Some((string, expanded_string)) = string.zip(string_to_highlight) {
if string.is_raw() {
- if inject::ra_fixture(hl, sema, &string, &expanded_string).is_some() {
+ if inject::ra_fixture(hl, sema, config, &string, &expanded_string).is_some()
+ {
continue;
}
}
@@ -421,7 +436,7 @@ fn traverse(
sema,
krate,
&mut bindings_shadow_count,
- syntactic_name_ref_highlighting,
+ config.syntactic_name_ref_highlighting,
name_like,
),
NodeOrToken::Token(token) => highlight::token(sema, token).zip(Some(None)),
@@ -439,6 +454,29 @@ fn traverse(
// something unresolvable. FIXME: There should be a way to prevent that
continue;
}
+
+ // apply config filtering
+ match &mut highlight.tag {
+ HlTag::StringLiteral if !config.strings => continue,
+ // If punctuation is disabled, make the macro bang part of the macro call again.
+ tag @ HlTag::Punctuation(HlPunct::MacroBang) => {
+ if !config.macro_bang {
+ *tag = HlTag::Symbol(SymbolKind::Macro);
+ } else if !config.specialize_punctuation {
+ *tag = HlTag::Punctuation(HlPunct::Other);
+ }
+ }
+ HlTag::Punctuation(_) if !config.punctuation => continue,
+ tag @ HlTag::Punctuation(_) if !config.specialize_punctuation => {
+ *tag = HlTag::Punctuation(HlPunct::Other);
+ }
+ HlTag::Operator(_) if !config.operator && highlight.mods.is_empty() => continue,
+ tag @ HlTag::Operator(_) if !config.specialize_operator => {
+ *tag = HlTag::Operator(HlOperator::Other);
+ }
+ _ => (),
+ }
+
if inside_attribute {
highlight |= HlMod::Attribute
}
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs
index 9395e914c..e7d0a8be7 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs
@@ -87,9 +87,9 @@ fn punctuation(
let parent = token.parent();
let parent_kind = parent.as_ref().map_or(EOF, SyntaxNode::kind);
match (kind, parent_kind) {
- (T![?], _) => HlTag::Operator(HlOperator::Other) | HlMod::ControlFlow,
+ (T![?], TRY_EXPR) => HlTag::Operator(HlOperator::Other) | HlMod::ControlFlow,
(T![&], BIN_EXPR) => HlOperator::Bitwise.into(),
- (T![&], _) => {
+ (T![&], REF_EXPR) => {
let h = HlTag::Operator(HlOperator::Other).into();
let is_unsafe = parent
.and_then(ast::RefExpr::cast)
@@ -100,7 +100,9 @@ fn punctuation(
h
}
}
- (T![::] | T![->] | T![=>] | T![..] | T![=] | T![@] | T![.], _) => HlOperator::Other.into(),
+ (T![::] | T![->] | T![=>] | T![..] | T![..=] | T![=] | T![@] | T![.], _) => {
+ HlOperator::Other.into()
+ }
(T![!], MACRO_CALL | MACRO_RULES) => HlPunct::MacroBang.into(),
(T![!], NEVER_TYPE) => HlTag::BuiltinType.into(),
(T![!], PREFIX_EXPR) => HlOperator::Logical.into(),
@@ -129,7 +131,7 @@ fn punctuation(
(T![+=] | T![-=] | T![*=] | T![/=] | T![%=], BIN_EXPR) => {
Highlight::from(HlOperator::Arithmetic) | HlMod::Mutable
}
- (T![|] | T![&] | T![!] | T![^] | T![>>] | T![<<], BIN_EXPR) => HlOperator::Bitwise.into(),
+ (T![|] | T![&] | T![^] | T![>>] | T![<<], BIN_EXPR) => HlOperator::Bitwise.into(),
(T![|=] | T![&=] | T![^=] | T![>>=] | T![<<=], BIN_EXPR) => {
Highlight::from(HlOperator::Bitwise) | HlMod::Mutable
}
@@ -137,7 +139,6 @@ fn punctuation(
(T![>] | T![<] | T![==] | T![>=] | T![<=] | T![!=], BIN_EXPR) => {
HlOperator::Comparison.into()
}
- (_, PREFIX_EXPR | BIN_EXPR | RANGE_EXPR | RANGE_PAT | REST_PAT) => HlOperator::Other.into(),
(_, ATTR) => HlTag::AttributeBracket.into(),
(kind, _) => match kind {
T!['['] | T![']'] => HlPunct::Bracket,
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/html.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/html.rs
index 9777c014c..e91fd7f12 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/html.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/html.rs
@@ -5,7 +5,10 @@ use oorandom::Rand32;
use stdx::format_to;
use syntax::AstNode;
-use crate::{syntax_highlighting::highlight, FileId, RootDatabase};
+use crate::{
+ syntax_highlighting::{highlight, HighlightConfig},
+ FileId, RootDatabase,
+};
pub(crate) fn highlight_as_html(db: &RootDatabase, file_id: FileId, rainbow: bool) -> String {
let parse = db.parse(file_id);
@@ -20,7 +23,21 @@ pub(crate) fn highlight_as_html(db: &RootDatabase, file_id: FileId, rainbow: boo
)
}
- let hl_ranges = highlight(db, file_id, None, false);
+ let hl_ranges = highlight(
+ db,
+ HighlightConfig {
+ strings: true,
+ punctuation: true,
+ specialize_punctuation: true,
+ specialize_operator: true,
+ operator: true,
+ inject_doc_comment: true,
+ macro_bang: true,
+ syntactic_name_ref_highlighting: false,
+ },
+ file_id,
+ None,
+ );
let text = parse.tree().syntax().to_string();
let mut buf = String::new();
buf.push_str(STYLE);
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/inject.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/inject.rs
index f376f9fda..9139528c7 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/inject.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/inject.rs
@@ -15,13 +15,14 @@ use syntax::{
use crate::{
doc_links::{doc_attributes, extract_definitions_from_docs, resolve_doc_path_for_def},
- syntax_highlighting::{highlights::Highlights, injector::Injector},
+ syntax_highlighting::{highlights::Highlights, injector::Injector, HighlightConfig},
Analysis, HlMod, HlRange, HlTag, RootDatabase,
};
pub(super) fn ra_fixture(
hl: &mut Highlights,
sema: &Semantics<'_, RootDatabase>,
+ config: HighlightConfig,
literal: &ast::String,
expanded: &ast::String,
) -> Option<()> {
@@ -63,7 +64,13 @@ pub(super) fn ra_fixture(
let (analysis, tmp_file_id) = Analysis::from_single_file(inj.take_text());
- for mut hl_range in analysis.highlight(tmp_file_id).unwrap() {
+ for mut hl_range in analysis
+ .highlight(
+ HighlightConfig { syntactic_name_ref_highlighting: false, ..config },
+ tmp_file_id,
+ )
+ .unwrap()
+ {
for range in inj.map_range_up(hl_range.range) {
if let Some(range) = literal.map_range_up(range) {
hl_range.range = range;
@@ -86,6 +93,7 @@ const RUSTDOC_FENCES: [&str; 2] = ["```", "~~~"];
pub(super) fn doc_comment(
hl: &mut Highlights,
sema: &Semantics<'_, RootDatabase>,
+ config: HighlightConfig,
src_file_id: FileId,
node: &SyntaxNode,
) {
@@ -206,7 +214,14 @@ pub(super) fn doc_comment(
let (analysis, tmp_file_id) = Analysis::from_single_file(inj.take_text());
- if let Ok(ranges) = analysis.with_db(|db| super::highlight(db, tmp_file_id, None, true)) {
+ if let Ok(ranges) = analysis.with_db(|db| {
+ super::highlight(
+ db,
+ HighlightConfig { syntactic_name_ref_highlighting: true, ..config },
+ tmp_file_id,
+ None,
+ )
+ }) {
for HlRange { range, highlight, binding_hash } in ranges {
for range in inj.map_range_up(range) {
hl.add(HlRange { range, highlight: highlight | HlMod::Injected, binding_hash });
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tags.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tags.rs
index 5262770f3..3949f1189 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tags.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tags.rs
@@ -199,7 +199,7 @@ impl fmt::Display for HlTag {
}
impl HlMod {
- const ALL: &'static [HlMod; HlMod::Unsafe as u8 as usize + 1] = &[
+ const ALL: &'static [HlMod; 19] = &[
HlMod::Associated,
HlMod::Async,
HlMod::Attribute,
@@ -296,7 +296,7 @@ impl Highlight {
Highlight { tag, mods: HlMods::default() }
}
pub fn is_empty(&self) -> bool {
- self.tag == HlTag::None && self.mods == HlMods::default()
+ self.tag == HlTag::None && self.mods.is_empty()
}
}
@@ -330,6 +330,10 @@ impl ops::BitOr<HlMod> for Highlight {
}
impl HlMods {
+ pub fn is_empty(&self) -> bool {
+ self.0 == 0
+ }
+
pub fn contains(self, m: HlMod) -> bool {
self.0 & m.mask() == m.mask()
}
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_assoc_functions.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_assoc_functions.html
index e07fd3925..9ed65fbc8 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_assoc_functions.html
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_assoc_functions.html
@@ -48,15 +48,15 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
<span class="keyword">impl</span> <span class="struct">foo</span> <span class="brace">{</span>
<span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function associated declaration public static">is_static</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
- <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function associated declaration public reference">is_not_static</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
+ <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function associated declaration public reference">is_not_static</span><span class="parenthesis">(</span><span class="punctuation">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
<span class="brace">}</span>
<span class="keyword">trait</span> <span class="trait declaration">t</span> <span class="brace">{</span>
<span class="keyword">fn</span> <span class="function associated declaration static trait">t_is_static</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
- <span class="keyword">fn</span> <span class="function associated declaration reference trait">t_is_not_static</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
+ <span class="keyword">fn</span> <span class="function associated declaration reference trait">t_is_not_static</span><span class="parenthesis">(</span><span class="punctuation">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
<span class="brace">}</span>
<span class="keyword">impl</span> <span class="trait">t</span> <span class="keyword">for</span> <span class="struct">foo</span> <span class="brace">{</span>
<span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function associated declaration public static trait">is_static</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
- <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function associated declaration public reference trait">is_not_static</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
+ <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function associated declaration public reference trait">is_not_static</span><span class="parenthesis">(</span><span class="punctuation">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
<span class="brace">}</span></code></pre> \ No newline at end of file
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html
index a747b4bc1..18045f1f5 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html
@@ -56,7 +56,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
<span class="field declaration">bar</span><span class="colon">:</span> <span class="builtin_type">bool</span><span class="comma">,</span>
<span class="brace">}</span>
-<span class="comment documentation">/// This is an impl with a code block.</span>
+<span class="comment documentation">/// This is an impl of </span><span class="struct documentation injected intra_doc_link">[`Foo`]</span><span class="comment documentation"> with a code block.</span>
<span class="comment documentation">///</span>
<span class="comment documentation">/// ```</span>
<span class="comment documentation">///</span><span class="comment documentation"> </span><span class="keyword injected">fn</span><span class="none injected"> </span><span class="function declaration injected">foo</span><span class="parenthesis injected">(</span><span class="parenthesis injected">)</span><span class="none injected"> </span><span class="brace injected">{</span>
@@ -125,7 +125,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
<span class="comment documentation">/// ```sh</span>
<span class="comment documentation">/// echo 1</span>
<span class="comment documentation">/// ```</span>
- <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function associated declaration public reference">foo</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">bool</span> <span class="brace">{</span>
+ <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function associated declaration public reference">foo</span><span class="parenthesis">(</span><span class="punctuation">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">bool</span> <span class="brace">{</span>
<span class="bool_literal">true</span>
<span class="brace">}</span>
<span class="brace">}</span>
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_general.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_general.html
index a97802cbb..9f2b1926b 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_general.html
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_general.html
@@ -61,11 +61,11 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
<span class="brace">}</span>
<span class="keyword">trait</span> <span class="trait declaration">Bar</span> <span class="brace">{</span>
- <span class="keyword">fn</span> <span class="function associated declaration reference trait">bar</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">i32</span><span class="semicolon">;</span>
+ <span class="keyword">fn</span> <span class="function associated declaration reference trait">bar</span><span class="parenthesis">(</span><span class="punctuation">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">i32</span><span class="semicolon">;</span>
<span class="brace">}</span>
<span class="keyword">impl</span> <span class="trait">Bar</span> <span class="keyword">for</span> <span class="struct">Foo</span> <span class="brace">{</span>
- <span class="keyword">fn</span> <span class="function associated declaration reference trait">bar</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">i32</span> <span class="brace">{</span>
+ <span class="keyword">fn</span> <span class="function associated declaration reference trait">bar</span><span class="parenthesis">(</span><span class="punctuation">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">i32</span> <span class="brace">{</span>
<span class="self_keyword reference">self</span><span class="operator">.</span><span class="field">x</span>
<span class="brace">}</span>
<span class="brace">}</span>
@@ -75,11 +75,11 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
<span class="value_param">f</span><span class="operator">.</span><span class="function associated consuming">baz</span><span class="parenthesis">(</span><span class="self_keyword consuming mutable">self</span><span class="parenthesis">)</span>
<span class="brace">}</span>
- <span class="keyword">fn</span> <span class="function associated declaration mutable reference">qux</span><span class="parenthesis">(</span><span class="operator">&</span><span class="keyword">mut</span> <span class="self_keyword declaration mutable reference">self</span><span class="parenthesis">)</span> <span class="brace">{</span>
+ <span class="keyword">fn</span> <span class="function associated declaration mutable reference">qux</span><span class="parenthesis">(</span><span class="punctuation">&</span><span class="keyword">mut</span> <span class="self_keyword declaration mutable reference">self</span><span class="parenthesis">)</span> <span class="brace">{</span>
<span class="self_keyword mutable reference">self</span><span class="operator">.</span><span class="field">x</span> <span class="operator">=</span> <span class="numeric_literal">0</span><span class="semicolon">;</span>
<span class="brace">}</span>
- <span class="keyword">fn</span> <span class="function associated declaration reference">quop</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">i32</span> <span class="brace">{</span>
+ <span class="keyword">fn</span> <span class="function associated declaration reference">quop</span><span class="parenthesis">(</span><span class="punctuation">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">i32</span> <span class="brace">{</span>
<span class="self_keyword reference">self</span><span class="operator">.</span><span class="field">x</span>
<span class="brace">}</span>
<span class="brace">}</span>
@@ -96,11 +96,11 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
<span class="value_param">f</span><span class="operator">.</span><span class="function associated">baz</span><span class="parenthesis">(</span><span class="self_keyword">self</span><span class="parenthesis">)</span>
<span class="brace">}</span>
- <span class="keyword">fn</span> <span class="function associated declaration mutable reference">qux</span><span class="parenthesis">(</span><span class="operator">&</span><span class="keyword">mut</span> <span class="self_keyword declaration mutable reference">self</span><span class="parenthesis">)</span> <span class="brace">{</span>
+ <span class="keyword">fn</span> <span class="function associated declaration mutable reference">qux</span><span class="parenthesis">(</span><span class="punctuation">&</span><span class="keyword">mut</span> <span class="self_keyword declaration mutable reference">self</span><span class="parenthesis">)</span> <span class="brace">{</span>
<span class="self_keyword mutable reference">self</span><span class="operator">.</span><span class="field">x</span> <span class="operator">=</span> <span class="numeric_literal">0</span><span class="semicolon">;</span>
<span class="brace">}</span>
- <span class="keyword">fn</span> <span class="function associated declaration reference">quop</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">u32</span> <span class="brace">{</span>
+ <span class="keyword">fn</span> <span class="function associated declaration reference">quop</span><span class="parenthesis">(</span><span class="punctuation">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">u32</span> <span class="brace">{</span>
<span class="self_keyword reference">self</span><span class="operator">.</span><span class="field">x</span>
<span class="brace">}</span>
<span class="brace">}</span>
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html
index ced7d22f0..abcd80c28 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html
@@ -42,7 +42,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
</style>
-<pre><code><span class="keyword">fn</span> <span class="function declaration">fixture</span><span class="parenthesis">(</span><span class="value_param declaration reference">ra_fixture</span><span class="colon">:</span> <span class="operator">&</span><span class="builtin_type">str</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
+<pre><code><span class="keyword">fn</span> <span class="function declaration">fixture</span><span class="parenthesis">(</span><span class="value_param declaration reference">ra_fixture</span><span class="colon">:</span> <span class="punctuation">&</span><span class="builtin_type">str</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
<span class="keyword">fn</span> <span class="function declaration">main</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span>
<span class="function">fixture</span><span class="parenthesis">(</span><span class="string_literal">r#"</span>
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_lifetimes.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_lifetimes.html
index 2d85fc8c9..f98e0b1cd 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_lifetimes.html
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_lifetimes.html
@@ -45,8 +45,8 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
<pre><code>
<span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="attribute attribute default_library library">derive</span><span class="parenthesis attribute">(</span><span class="parenthesis attribute">)</span><span class="attribute_bracket attribute">]</span>
<span class="keyword">struct</span> <span class="struct declaration">Foo</span><span class="angle">&lt;</span><span class="lifetime declaration">'a</span><span class="comma">,</span> <span class="lifetime declaration">'b</span><span class="comma">,</span> <span class="lifetime declaration">'c</span><span class="angle">&gt;</span> <span class="keyword">where</span> <span class="lifetime">'a</span><span class="colon">:</span> <span class="lifetime">'a</span><span class="comma">,</span> <span class="lifetime">'static</span><span class="colon">:</span> <span class="lifetime">'static</span> <span class="brace">{</span>
- <span class="field declaration">field</span><span class="colon">:</span> <span class="operator">&</span><span class="lifetime">'a</span> <span class="parenthesis">(</span><span class="parenthesis">)</span><span class="comma">,</span>
- <span class="field declaration">field2</span><span class="colon">:</span> <span class="operator">&</span><span class="lifetime">'static</span> <span class="parenthesis">(</span><span class="parenthesis">)</span><span class="comma">,</span>
+ <span class="field declaration">field</span><span class="colon">:</span> <span class="punctuation">&</span><span class="lifetime">'a</span> <span class="parenthesis">(</span><span class="parenthesis">)</span><span class="comma">,</span>
+ <span class="field declaration">field2</span><span class="colon">:</span> <span class="punctuation">&</span><span class="lifetime">'static</span> <span class="parenthesis">(</span><span class="parenthesis">)</span><span class="comma">,</span>
<span class="brace">}</span>
<span class="keyword">impl</span><span class="angle">&lt;</span><span class="lifetime declaration">'a</span><span class="angle">&gt;</span> <span class="struct">Foo</span><span class="angle">&lt;</span><span class="lifetime">'_</span><span class="comma">,</span> <span class="lifetime">'a</span><span class="comma">,</span> <span class="lifetime">'static</span><span class="angle">&gt;</span>
<span class="keyword">where</span>
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html
index c627bc9b0..a626cda3f 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html
@@ -62,16 +62,16 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
<span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="operator">=</span><span class="angle">&gt;</span> <span class="parenthesis">(</span>
<span class="punctuation">$</span>crate<span class="colon">:</span><span class="colon">:</span>panicking<span class="colon">:</span><span class="colon">:</span>panic<span class="parenthesis">(</span><span class="string_literal">"explicit panic"</span><span class="parenthesis">)</span>
<span class="parenthesis">)</span><span class="comma">,</span>
- <span class="parenthesis">(</span><span class="punctuation">$</span>msg<span class="colon">:</span>literal <span class="punctuation">$</span><span class="parenthesis">(</span><span class="comma">,</span><span class="parenthesis">)</span><span class="operator control">?</span><span class="parenthesis">)</span> <span class="operator">=</span><span class="angle">&gt;</span> <span class="parenthesis">(</span>
+ <span class="parenthesis">(</span><span class="punctuation">$</span>msg<span class="colon">:</span>literal <span class="punctuation">$</span><span class="parenthesis">(</span><span class="comma">,</span><span class="parenthesis">)</span><span class="punctuation">?</span><span class="parenthesis">)</span> <span class="operator">=</span><span class="angle">&gt;</span> <span class="parenthesis">(</span>
<span class="punctuation">$</span>crate<span class="colon">:</span><span class="colon">:</span>panicking<span class="colon">:</span><span class="colon">:</span>panic<span class="parenthesis">(</span><span class="punctuation">$</span>msg<span class="parenthesis">)</span>
<span class="parenthesis">)</span><span class="comma">,</span>
<span class="comment">// Use `panic_str` instead of `panic_display::&lt;&str&gt;` for non_fmt_panic lint.</span>
- <span class="parenthesis">(</span><span class="punctuation">$</span>msg<span class="colon">:</span>expr <span class="punctuation">$</span><span class="parenthesis">(</span><span class="comma">,</span><span class="parenthesis">)</span><span class="operator control">?</span><span class="parenthesis">)</span> <span class="operator">=</span><span class="angle">&gt;</span> <span class="parenthesis">(</span>
+ <span class="parenthesis">(</span><span class="punctuation">$</span>msg<span class="colon">:</span>expr <span class="punctuation">$</span><span class="parenthesis">(</span><span class="comma">,</span><span class="parenthesis">)</span><span class="punctuation">?</span><span class="parenthesis">)</span> <span class="operator">=</span><span class="angle">&gt;</span> <span class="parenthesis">(</span>
<span class="punctuation">$</span>crate<span class="colon">:</span><span class="colon">:</span>panicking<span class="colon">:</span><span class="colon">:</span>panic_str<span class="parenthesis">(</span><span class="punctuation">$</span>msg<span class="parenthesis">)</span>
<span class="parenthesis">)</span><span class="comma">,</span>
<span class="comment">// Special-case the single-argument case for const_panic.</span>
- <span class="parenthesis">(</span><span class="string_literal">"{}"</span><span class="comma">,</span> <span class="punctuation">$</span>arg<span class="colon">:</span>expr <span class="punctuation">$</span><span class="parenthesis">(</span><span class="comma">,</span><span class="parenthesis">)</span><span class="operator control">?</span><span class="parenthesis">)</span> <span class="operator">=</span><span class="angle">&gt;</span> <span class="parenthesis">(</span>
- <span class="punctuation">$</span>crate<span class="colon">:</span><span class="colon">:</span>panicking<span class="colon">:</span><span class="colon">:</span>panic_display<span class="parenthesis">(</span><span class="operator">&</span><span class="punctuation">$</span>arg<span class="parenthesis">)</span>
+ <span class="parenthesis">(</span><span class="string_literal">"{}"</span><span class="comma">,</span> <span class="punctuation">$</span>arg<span class="colon">:</span>expr <span class="punctuation">$</span><span class="parenthesis">(</span><span class="comma">,</span><span class="parenthesis">)</span><span class="punctuation">?</span><span class="parenthesis">)</span> <span class="operator">=</span><span class="angle">&gt;</span> <span class="parenthesis">(</span>
+ <span class="punctuation">$</span>crate<span class="colon">:</span><span class="colon">:</span>panicking<span class="colon">:</span><span class="colon">:</span>panic_display<span class="parenthesis">(</span><span class="punctuation">&</span><span class="punctuation">$</span>arg<span class="parenthesis">)</span>
<span class="parenthesis">)</span><span class="comma">,</span>
<span class="parenthesis">(</span><span class="punctuation">$</span>fmt<span class="colon">:</span>expr<span class="comma">,</span> <span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>arg<span class="colon">:</span>tt<span class="parenthesis">)</span><span class="punctuation">+</span><span class="parenthesis">)</span> <span class="operator">=</span><span class="angle">&gt;</span> <span class="parenthesis">(</span>
<span class="punctuation">$</span>crate<span class="colon">:</span><span class="colon">:</span>panicking<span class="colon">:</span><span class="colon">:</span>panic_fmt<span class="parenthesis">(</span><span class="punctuation">$</span>crate<span class="colon">:</span><span class="colon">:</span>const_format_args<span class="punctuation">!</span><span class="parenthesis">(</span><span class="punctuation">$</span>fmt<span class="comma">,</span> <span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>arg<span class="parenthesis">)</span><span class="punctuation">+</span><span class="parenthesis">)</span><span class="parenthesis">)</span>
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html
index 0716bae75..1992bdc6a 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html
@@ -49,7 +49,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
<span class="brace">}</span>
<span class="keyword">macro_rules</span><span class="macro_bang">!</span> <span class="macro declaration">unsafe_deref</span> <span class="brace">{</span>
<span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="operator">=</span><span class="angle">&gt;</span> <span class="brace">{</span>
- <span class="punctuation">*</span><span class="parenthesis">(</span><span class="operator">&</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="keyword">as</span> <span class="punctuation">*</span><span class="keyword">const</span> <span class="parenthesis">(</span><span class="parenthesis">)</span><span class="parenthesis">)</span>
+ <span class="punctuation">*</span><span class="parenthesis">(</span><span class="punctuation">&</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="keyword">as</span> <span class="punctuation">*</span><span class="keyword">const</span> <span class="parenthesis">(</span><span class="parenthesis">)</span><span class="parenthesis">)</span>
<span class="brace">}</span><span class="semicolon">;</span>
<span class="brace">}</span>
<span class="keyword">static</span> <span class="keyword">mut</span> <span class="static declaration mutable unsafe">MUT_GLOBAL</span><span class="colon">:</span> <span class="struct">Struct</span> <span class="operator">=</span> <span class="struct">Struct</span> <span class="brace">{</span> <span class="field">field</span><span class="colon">:</span> <span class="numeric_literal">0</span> <span class="brace">}</span><span class="semicolon">;</span>
@@ -63,7 +63,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
<span class="keyword">struct</span> <span class="struct declaration">Struct</span> <span class="brace">{</span> <span class="field declaration">field</span><span class="colon">:</span> <span class="builtin_type">i32</span> <span class="brace">}</span>
<span class="keyword">impl</span> <span class="struct">Struct</span> <span class="brace">{</span>
- <span class="keyword unsafe">unsafe</span> <span class="keyword">fn</span> <span class="function associated declaration reference unsafe">unsafe_method</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
+ <span class="keyword unsafe">unsafe</span> <span class="keyword">fn</span> <span class="function associated declaration reference unsafe">unsafe_method</span><span class="parenthesis">(</span><span class="punctuation">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
<span class="brace">}</span>
<span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="builtin_attr attribute library">repr</span><span class="parenthesis attribute">(</span><span class="none attribute">packed</span><span class="parenthesis attribute">)</span><span class="attribute_bracket attribute">]</span>
@@ -78,11 +78,11 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
<span class="keyword">fn</span> <span class="function declaration">unsafe_trait_bound</span><span class="angle">&lt;</span><span class="type_param declaration">T</span><span class="colon">:</span> <span class="trait">UnsafeTrait</span><span class="angle">&gt;</span><span class="parenthesis">(</span><span class="punctuation">_</span><span class="colon">:</span> <span class="type_param">T</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
<span class="keyword">trait</span> <span class="trait declaration">DoTheAutoref</span> <span class="brace">{</span>
- <span class="keyword">fn</span> <span class="function associated declaration reference trait">calls_autoref</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+ <span class="keyword">fn</span> <span class="function associated declaration reference trait">calls_autoref</span><span class="parenthesis">(</span><span class="punctuation">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span><span class="semicolon">;</span>
<span class="brace">}</span>
<span class="keyword">impl</span> <span class="trait">DoTheAutoref</span> <span class="keyword">for</span> <span class="builtin_type">u16</span> <span class="brace">{</span>
- <span class="keyword">fn</span> <span class="function associated declaration reference trait">calls_autoref</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
+ <span class="keyword">fn</span> <span class="function associated declaration reference trait">calls_autoref</span><span class="parenthesis">(</span><span class="punctuation">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
<span class="brace">}</span>
<span class="keyword">fn</span> <span class="function declaration">main</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span>
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs
index 99be7c664..46cc667fc 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs
@@ -4,7 +4,18 @@ use expect_test::{expect_file, ExpectFile};
use ide_db::SymbolKind;
use test_utils::{bench, bench_fixture, skip_slow_tests, AssertLinear};
-use crate::{fixture, FileRange, HlTag, TextRange};
+use crate::{fixture, FileRange, HighlightConfig, HlTag, TextRange};
+
+const HL_CONFIG: HighlightConfig = HighlightConfig {
+ strings: true,
+ punctuation: true,
+ specialize_punctuation: true,
+ specialize_operator: true,
+ operator: true,
+ inject_doc_comment: true,
+ macro_bang: true,
+ syntactic_name_ref_highlighting: false,
+};
#[test]
fn attributes() {
@@ -613,7 +624,7 @@ struct Foo {
bar: bool,
}
-/// This is an impl with a code block.
+/// This is an impl of [`Foo`] with a code block.
///
/// ```
/// fn foo() {
@@ -958,7 +969,7 @@ pub struct Struct;
#[test]
#[cfg_attr(
- all(unix, not(target_pointer_width = "64")),
+ not(all(unix, target_pointer_width = "64")),
ignore = "depends on `DefaultHasher` outputs"
)]
fn test_rainbow_highlighting() {
@@ -996,7 +1007,10 @@ struct Foo {
// The "x"
let highlights = &analysis
- .highlight_range(FileRange { file_id, range: TextRange::at(45.into(), 1.into()) })
+ .highlight_range(
+ HL_CONFIG,
+ FileRange { file_id, range: TextRange::at(45.into(), 1.into()) },
+ )
.unwrap();
assert_eq!(&highlights[0].highlight.to_string(), "field.declaration.public");
@@ -1011,7 +1025,7 @@ macro_rules! test {}
}"#
.trim(),
);
- let _ = analysis.highlight(file_id).unwrap();
+ let _ = analysis.highlight(HL_CONFIG, file_id).unwrap();
}
/// Highlights the code given by the `ra_fixture` argument, renders the
@@ -1035,7 +1049,7 @@ fn benchmark_syntax_highlighting_long_struct() {
let hash = {
let _pt = bench("syntax highlighting long struct");
analysis
- .highlight(file_id)
+ .highlight(HL_CONFIG, file_id)
.unwrap()
.iter()
.filter(|it| it.highlight.tag == HlTag::Symbol(SymbolKind::Struct))
@@ -1061,7 +1075,7 @@ fn syntax_highlighting_not_quadratic() {
let time = Instant::now();
let hash = analysis
- .highlight(file_id)
+ .highlight(HL_CONFIG, file_id)
.unwrap()
.iter()
.filter(|it| it.highlight.tag == HlTag::Symbol(SymbolKind::Struct))
@@ -1086,7 +1100,7 @@ fn benchmark_syntax_highlighting_parser() {
let hash = {
let _pt = bench("syntax highlighting parser");
analysis
- .highlight(file_id)
+ .highlight(HL_CONFIG, file_id)
.unwrap()
.iter()
.filter(|it| it.highlight.tag == HlTag::Symbol(SymbolKind::Function))
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_tree.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_tree.rs
index 9003e7cd3..4256fea0f 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_tree.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_tree.rs
@@ -12,7 +12,7 @@ use syntax::{
// |===
// | Editor | Action Name
//
-// | VS Code | **Rust Analyzer: Show Syntax Tree**
+// | VS Code | **rust-analyzer: Show Syntax Tree**
// |===
// image::https://user-images.githubusercontent.com/48062697/113065586-068bdb80-91b1-11eb-9507-fee67f9f45a0.gif[]
pub(crate) fn syntax_tree(
diff --git a/src/tools/rust-analyzer/crates/ide/src/view_crate_graph.rs b/src/tools/rust-analyzer/crates/ide/src/view_crate_graph.rs
index 51291a645..17a1e385b 100644
--- a/src/tools/rust-analyzer/crates/ide/src/view_crate_graph.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/view_crate_graph.rs
@@ -3,8 +3,9 @@ use std::sync::Arc;
use dot::{Id, LabelText};
use ide_db::{
base_db::{CrateGraph, CrateId, Dependency, SourceDatabase, SourceDatabaseExt},
- FxHashSet, RootDatabase,
+ RootDatabase,
};
+use stdx::hash::NoHashHashSet;
// Feature: View Crate Graph
//
@@ -16,7 +17,7 @@ use ide_db::{
// |===
// | Editor | Action Name
//
-// | VS Code | **Rust Analyzer: View Crate Graph**
+// | VS Code | **rust-analyzer: View Crate Graph**
// |===
pub(crate) fn view_crate_graph(db: &RootDatabase, full: bool) -> Result<String, String> {
let crate_graph = db.crate_graph();
@@ -41,7 +42,7 @@ pub(crate) fn view_crate_graph(db: &RootDatabase, full: bool) -> Result<String,
struct DotCrateGraph {
graph: Arc<CrateGraph>,
- crates_to_render: FxHashSet<CrateId>,
+ crates_to_render: NoHashHashSet<CrateId>,
}
type Edge<'a> = (CrateId, &'a Dependency);
diff --git a/src/tools/rust-analyzer/crates/ide/src/view_hir.rs b/src/tools/rust-analyzer/crates/ide/src/view_hir.rs
index 7312afe53..d2bbbf6d2 100644
--- a/src/tools/rust-analyzer/crates/ide/src/view_hir.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/view_hir.rs
@@ -1,4 +1,4 @@
-use hir::{Function, Semantics};
+use hir::{DefWithBody, Semantics};
use ide_db::base_db::FilePosition;
use ide_db::RootDatabase;
use syntax::{algo::find_node_at_offset, ast, AstNode};
@@ -8,7 +8,7 @@ use syntax::{algo::find_node_at_offset, ast, AstNode};
// |===
// | Editor | Action Name
//
-// | VS Code | **Rust Analyzer: View Hir**
+// | VS Code | **rust-analyzer: View Hir**
// |===
// image::https://user-images.githubusercontent.com/48062697/113065588-068bdb80-91b1-11eb-9a78-0b4ef1e972fb.gif[]
pub(crate) fn view_hir(db: &RootDatabase, position: FilePosition) -> String {
@@ -19,8 +19,12 @@ fn body_hir(db: &RootDatabase, position: FilePosition) -> Option<String> {
let sema = Semantics::new(db);
let source_file = sema.parse(position.file_id);
- let function = find_node_at_offset::<ast::Fn>(source_file.syntax(), position.offset)?;
-
- let function: Function = sema.to_def(&function)?;
- Some(function.debug_hir(db))
+ let item = find_node_at_offset::<ast::Item>(source_file.syntax(), position.offset)?;
+ let def: DefWithBody = match item {
+ ast::Item::Fn(it) => sema.to_def(&it)?.into(),
+ ast::Item::Const(it) => sema.to_def(&it)?.into(),
+ ast::Item::Static(it) => sema.to_def(&it)?.into(),
+ _ => return None,
+ };
+ Some(def.debug_hir(db))
}
diff --git a/src/tools/rust-analyzer/crates/ide/src/view_item_tree.rs b/src/tools/rust-analyzer/crates/ide/src/view_item_tree.rs
index 3dc03085d..9c1f93356 100644
--- a/src/tools/rust-analyzer/crates/ide/src/view_item_tree.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/view_item_tree.rs
@@ -9,7 +9,7 @@ use ide_db::RootDatabase;
// |===
// | Editor | Action Name
//
-// | VS Code | **Rust Analyzer: Debug ItemTree**
+// | VS Code | **rust-analyzer: Debug ItemTree**
// |===
pub(crate) fn view_item_tree(db: &RootDatabase, file_id: FileId) -> String {
db.file_item_tree(file_id.into()).pretty_print()