mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-30 22:01:37 +00:00
⬆️ rust-analyzer
This commit is contained in:
parent
459bbb4222
commit
f5fde4df43
76 changed files with 1613 additions and 654 deletions
|
@ -41,6 +41,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(
|
||||
|
@ -65,10 +71,10 @@ pub(crate) fn annotations(
|
|||
visit_file_defs(&Semantics::new(db), file_id, &mut |def| {
|
||||
let range = match def {
|
||||
Definition::Const(konst) if config.annotate_references => {
|
||||
konst.source(db).and_then(|node| name_range(db, node, file_id))
|
||||
konst.source(db).and_then(|node| name_range(db, config, node, file_id))
|
||||
}
|
||||
Definition::Trait(trait_) if config.annotate_references || config.annotate_impls => {
|
||||
trait_.source(db).and_then(|node| name_range(db, node, file_id))
|
||||
trait_.source(db).and_then(|node| name_range(db, config, node, file_id))
|
||||
}
|
||||
Definition::Adt(adt) => match adt {
|
||||
hir::Adt::Enum(enum_) => {
|
||||
|
@ -77,7 +83,9 @@ pub(crate) fn annotations(
|
|||
.variants(db)
|
||||
.into_iter()
|
||||
.map(|variant| {
|
||||
variant.source(db).and_then(|node| name_range(db, node, file_id))
|
||||
variant
|
||||
.source(db)
|
||||
.and_then(|node| name_range(db, config, node, file_id))
|
||||
})
|
||||
.flatten()
|
||||
.for_each(|range| {
|
||||
|
@ -88,14 +96,14 @@ pub(crate) fn annotations(
|
|||
})
|
||||
}
|
||||
if config.annotate_references || config.annotate_impls {
|
||||
enum_.source(db).and_then(|node| name_range(db, node, file_id))
|
||||
enum_.source(db).and_then(|node| name_range(db, config, node, file_id))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
if config.annotate_references || config.annotate_impls {
|
||||
adt.source(db).and_then(|node| name_range(db, node, file_id))
|
||||
adt.source(db).and_then(|node| name_range(db, config, node, file_id))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
@ -113,6 +121,7 @@ pub(crate) fn annotations(
|
|||
annotations
|
||||
.push(Annotation { range, kind: AnnotationKind::HasImpls { file_id, data: None } });
|
||||
}
|
||||
|
||||
if config.annotate_references {
|
||||
annotations.push(Annotation {
|
||||
range,
|
||||
|
@ -122,12 +131,18 @@ pub(crate) fn annotations(
|
|||
|
||||
fn name_range<T: HasName>(
|
||||
db: &RootDatabase,
|
||||
config: &AnnotationConfig,
|
||||
node: InFile<T>,
|
||||
source_file_id: FileId,
|
||||
) -> 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 match config.location {
|
||||
AnnotationLocation::AboveName => {
|
||||
value.name().map(|name| name.syntax().text_range())
|
||||
}
|
||||
AnnotationLocation::AboveWholeItem => Some(value.syntax().text_range()),
|
||||
};
|
||||
}
|
||||
}
|
||||
None
|
||||
|
@ -188,21 +203,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 +228,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(
|
||||
|
@ -786,4 +807,40 @@ 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 {
|
||||
file_id: FileId(
|
||||
0,
|
||||
),
|
||||
data: Some(
|
||||
[],
|
||||
),
|
||||
},
|
||||
},
|
||||
Annotation {
|
||||
range: 0..71,
|
||||
kind: HasReferences {
|
||||
file_id: FileId(
|
||||
0,
|
||||
),
|
||||
data: None,
|
||||
},
|
||||
},
|
||||
]
|
||||
"#]],
|
||||
&AnnotationConfig { location: AnnotationLocation::AboveWholeItem, ..DEFAULT_CONFIG },
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -377,6 +377,7 @@ mod tests {
|
|||
match it {
|
||||
ReferenceCategory::Read => "read",
|
||||
ReferenceCategory::Write => "write",
|
||||
ReferenceCategory::Import => "import",
|
||||
}
|
||||
.to_string()
|
||||
}),
|
||||
|
@ -423,12 +424,12 @@ struct Foo;
|
|||
check(
|
||||
r#"
|
||||
use crate$0;
|
||||
//^^^^^
|
||||
//^^^^^ import
|
||||
use self;
|
||||
//^^^^
|
||||
//^^^^ import
|
||||
mod __ {
|
||||
use super;
|
||||
//^^^^^
|
||||
//^^^^^ import
|
||||
}
|
||||
"#,
|
||||
);
|
||||
|
@ -436,7 +437,7 @@ mod __ {
|
|||
r#"
|
||||
//- /main.rs crate:main deps:lib
|
||||
use lib$0;
|
||||
//^^^
|
||||
//^^^ import
|
||||
//- /lib.rs crate:lib
|
||||
"#,
|
||||
);
|
||||
|
@ -450,7 +451,7 @@ use lib$0;
|
|||
mod foo;
|
||||
//- /foo.rs
|
||||
use self$0;
|
||||
// ^^^^
|
||||
// ^^^^ import
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1687,6 +1687,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(
|
||||
|
|
|
@ -74,7 +74,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},
|
||||
|
|
|
@ -742,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
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
@ -760,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
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
@ -775,7 +775,7 @@ use self$0;
|
|||
expect![[r#"
|
||||
Module FileId(0) 0..10
|
||||
|
||||
FileId(0) 4..8
|
||||
FileId(0) 4..8 Import
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
@ -803,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
|
||||
"#]],
|
||||
);
|
||||
|
@ -966,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
|
||||
"#]],
|
||||
);
|
||||
|
@ -1424,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
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
@ -1454,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
|
||||
"#]],
|
||||
|
@ -1617,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
|
||||
"#]],
|
||||
);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue