diff options
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 18 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/raw.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir_expand/src/proc_macro.rs | 2 | ||||
-rw-r--r-- | crates/ra_ide/src/completion/complete_trait_impl.rs | 61 | ||||
-rw-r--r-- | docs/dev/lsp-extensions.md | 63 | ||||
-rw-r--r-- | editors/code/src/util.ts | 9 |
6 files changed, 108 insertions, 47 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 840cfdfc8..8d7937d94 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs | |||
@@ -532,7 +532,7 @@ impl Adt { | |||
532 | Some(self.module(db).krate()) | 532 | Some(self.module(db).krate()) |
533 | } | 533 | } |
534 | 534 | ||
535 | pub fn name(&self, db: &dyn HirDatabase) -> Name { | 535 | pub fn name(self, db: &dyn HirDatabase) -> Name { |
536 | match self { | 536 | match self { |
537 | Adt::Struct(s) => s.name(db), | 537 | Adt::Struct(s) => s.name(db), |
538 | Adt::Union(u) => u.name(db), | 538 | Adt::Union(u) => u.name(db), |
@@ -1018,15 +1018,15 @@ impl ImplDef { | |||
1018 | impls.lookup_impl_defs_for_trait(trait_.id).map(Self::from).collect() | 1018 | impls.lookup_impl_defs_for_trait(trait_.id).map(Self::from).collect() |
1019 | } | 1019 | } |
1020 | 1020 | ||
1021 | pub fn target_trait(&self, db: &dyn HirDatabase) -> Option<TypeRef> { | 1021 | pub fn target_trait(self, db: &dyn HirDatabase) -> Option<TypeRef> { |
1022 | db.impl_data(self.id).target_trait.clone() | 1022 | db.impl_data(self.id).target_trait.clone() |
1023 | } | 1023 | } |
1024 | 1024 | ||
1025 | pub fn target_type(&self, db: &dyn HirDatabase) -> TypeRef { | 1025 | pub fn target_type(self, db: &dyn HirDatabase) -> TypeRef { |
1026 | db.impl_data(self.id).target_type.clone() | 1026 | db.impl_data(self.id).target_type.clone() |
1027 | } | 1027 | } |
1028 | 1028 | ||
1029 | pub fn target_ty(&self, db: &dyn HirDatabase) -> Type { | 1029 | pub fn target_ty(self, db: &dyn HirDatabase) -> Type { |
1030 | let impl_data = db.impl_data(self.id); | 1030 | let impl_data = db.impl_data(self.id); |
1031 | let resolver = self.id.resolver(db.upcast()); | 1031 | let resolver = self.id.resolver(db.upcast()); |
1032 | let ctx = hir_ty::TyLoweringContext::new(db, &resolver); | 1032 | let ctx = hir_ty::TyLoweringContext::new(db, &resolver); |
@@ -1038,23 +1038,23 @@ impl ImplDef { | |||
1038 | } | 1038 | } |
1039 | } | 1039 | } |
1040 | 1040 | ||
1041 | pub fn items(&self, db: &dyn HirDatabase) -> Vec<AssocItem> { | 1041 | pub fn items(self, db: &dyn HirDatabase) -> Vec<AssocItem> { |
1042 | db.impl_data(self.id).items.iter().map(|it| (*it).into()).collect() | 1042 | db.impl_data(self.id).items.iter().map(|it| (*it).into()).collect() |
1043 | } | 1043 | } |
1044 | 1044 | ||
1045 | pub fn is_negative(&self, db: &dyn HirDatabase) -> bool { | 1045 | pub fn is_negative(self, db: &dyn HirDatabase) -> bool { |
1046 | db.impl_data(self.id).is_negative | 1046 | db.impl_data(self.id).is_negative |
1047 | } | 1047 | } |
1048 | 1048 | ||
1049 | pub fn module(&self, db: &dyn HirDatabase) -> Module { | 1049 | pub fn module(self, db: &dyn HirDatabase) -> Module { |
1050 | self.id.lookup(db.upcast()).container.module(db.upcast()).into() | 1050 | self.id.lookup(db.upcast()).container.module(db.upcast()).into() |
1051 | } | 1051 | } |
1052 | 1052 | ||
1053 | pub fn krate(&self, db: &dyn HirDatabase) -> Crate { | 1053 | pub fn krate(self, db: &dyn HirDatabase) -> Crate { |
1054 | Crate { id: self.module(db).id.krate } | 1054 | Crate { id: self.module(db).id.krate } |
1055 | } | 1055 | } |
1056 | 1056 | ||
1057 | pub fn is_builtin_derive(&self, db: &dyn HirDatabase) -> Option<InFile<ast::Attr>> { | 1057 | pub fn is_builtin_derive(self, db: &dyn HirDatabase) -> Option<InFile<ast::Attr>> { |
1058 | let src = self.source(db); | 1058 | let src = self.source(db); |
1059 | let item = src.file_id.is_builtin_derive(db.upcast())?; | 1059 | let item = src.file_id.is_builtin_derive(db.upcast())?; |
1060 | let hygenic = hir_expand::hygiene::Hygiene::new(db.upcast(), item.file_id); | 1060 | let hygenic = hir_expand::hygiene::Hygiene::new(db.upcast(), item.file_id); |
diff --git a/crates/ra_hir_def/src/nameres/raw.rs b/crates/ra_hir_def/src/nameres/raw.rs index 4e628b14d..f44baa579 100644 --- a/crates/ra_hir_def/src/nameres/raw.rs +++ b/crates/ra_hir_def/src/nameres/raw.rs | |||
@@ -175,7 +175,7 @@ pub(super) enum DefKind { | |||
175 | } | 175 | } |
176 | 176 | ||
177 | impl DefKind { | 177 | impl DefKind { |
178 | pub fn ast_id(&self) -> FileAstId<ast::ModuleItem> { | 178 | pub fn ast_id(self) -> FileAstId<ast::ModuleItem> { |
179 | match self { | 179 | match self { |
180 | DefKind::Function(it) => it.upcast(), | 180 | DefKind::Function(it) => it.upcast(), |
181 | DefKind::Struct(it, _) => it.upcast(), | 181 | DefKind::Struct(it, _) => it.upcast(), |
diff --git a/crates/ra_hir_expand/src/proc_macro.rs b/crates/ra_hir_expand/src/proc_macro.rs index 4e0e069c8..04c026004 100644 --- a/crates/ra_hir_expand/src/proc_macro.rs +++ b/crates/ra_hir_expand/src/proc_macro.rs | |||
@@ -25,7 +25,7 @@ impl ProcMacroExpander { | |||
25 | } | 25 | } |
26 | 26 | ||
27 | pub fn expand( | 27 | pub fn expand( |
28 | &self, | 28 | self, |
29 | db: &dyn AstDatabase, | 29 | db: &dyn AstDatabase, |
30 | _id: LazyMacroId, | 30 | _id: LazyMacroId, |
31 | tt: &tt::Subtree, | 31 | tt: &tt::Subtree, |
diff --git a/crates/ra_ide/src/completion/complete_trait_impl.rs b/crates/ra_ide/src/completion/complete_trait_impl.rs index 039df03e0..21c9316e6 100644 --- a/crates/ra_ide/src/completion/complete_trait_impl.rs +++ b/crates/ra_ide/src/completion/complete_trait_impl.rs | |||
@@ -49,56 +49,53 @@ use crate::{ | |||
49 | pub(crate) fn complete_trait_impl(acc: &mut Completions, ctx: &CompletionContext) { | 49 | pub(crate) fn complete_trait_impl(acc: &mut Completions, ctx: &CompletionContext) { |
50 | if let Some((trigger, impl_def)) = completion_match(ctx) { | 50 | if let Some((trigger, impl_def)) = completion_match(ctx) { |
51 | match trigger.kind() { | 51 | match trigger.kind() { |
52 | SyntaxKind::NAME_REF => { | 52 | SyntaxKind::NAME_REF => get_missing_assoc_items(&ctx.sema, &impl_def) |
53 | get_missing_assoc_items(&ctx.sema, &impl_def).iter().for_each(|item| match item { | 53 | .into_iter() |
54 | .for_each(|item| match item { | ||
54 | hir::AssocItem::Function(fn_item) => { | 55 | hir::AssocItem::Function(fn_item) => { |
55 | add_function_impl(&trigger, acc, ctx, &fn_item) | 56 | add_function_impl(&trigger, acc, ctx, fn_item) |
56 | } | 57 | } |
57 | hir::AssocItem::TypeAlias(type_item) => { | 58 | hir::AssocItem::TypeAlias(type_item) => { |
58 | add_type_alias_impl(&trigger, acc, ctx, &type_item) | 59 | add_type_alias_impl(&trigger, acc, ctx, type_item) |
59 | } | 60 | } |
60 | hir::AssocItem::Const(const_item) => { | 61 | hir::AssocItem::Const(const_item) => { |
61 | add_const_impl(&trigger, acc, ctx, &const_item) | 62 | add_const_impl(&trigger, acc, ctx, const_item) |
62 | } | 63 | } |
63 | }) | 64 | }), |
64 | } | ||
65 | 65 | ||
66 | SyntaxKind::FN_DEF => { | 66 | SyntaxKind::FN_DEF => { |
67 | for missing_fn in | 67 | for missing_fn in get_missing_assoc_items(&ctx.sema, &impl_def) |
68 | get_missing_assoc_items(&ctx.sema, &impl_def).iter().filter_map(|item| { | 68 | .into_iter() |
69 | match item { | 69 | .filter_map(|item| match item { |
70 | hir::AssocItem::Function(fn_item) => Some(fn_item), | 70 | hir::AssocItem::Function(fn_item) => Some(fn_item), |
71 | _ => None, | 71 | _ => None, |
72 | } | ||
73 | }) | 72 | }) |
74 | { | 73 | { |
75 | add_function_impl(&trigger, acc, ctx, &missing_fn); | 74 | add_function_impl(&trigger, acc, ctx, missing_fn); |
76 | } | 75 | } |
77 | } | 76 | } |
78 | 77 | ||
79 | SyntaxKind::TYPE_ALIAS_DEF => { | 78 | SyntaxKind::TYPE_ALIAS_DEF => { |
80 | for missing_fn in | 79 | for missing_fn in get_missing_assoc_items(&ctx.sema, &impl_def) |
81 | get_missing_assoc_items(&ctx.sema, &impl_def).iter().filter_map(|item| { | 80 | .into_iter() |
82 | match item { | 81 | .filter_map(|item| match item { |
83 | hir::AssocItem::TypeAlias(type_item) => Some(type_item), | 82 | hir::AssocItem::TypeAlias(type_item) => Some(type_item), |
84 | _ => None, | 83 | _ => None, |
85 | } | ||
86 | }) | 84 | }) |
87 | { | 85 | { |
88 | add_type_alias_impl(&trigger, acc, ctx, &missing_fn); | 86 | add_type_alias_impl(&trigger, acc, ctx, missing_fn); |
89 | } | 87 | } |
90 | } | 88 | } |
91 | 89 | ||
92 | SyntaxKind::CONST_DEF => { | 90 | SyntaxKind::CONST_DEF => { |
93 | for missing_fn in | 91 | for missing_fn in get_missing_assoc_items(&ctx.sema, &impl_def) |
94 | get_missing_assoc_items(&ctx.sema, &impl_def).iter().filter_map(|item| { | 92 | .into_iter() |
95 | match item { | 93 | .filter_map(|item| match item { |
96 | hir::AssocItem::Const(const_item) => Some(const_item), | 94 | hir::AssocItem::Const(const_item) => Some(const_item), |
97 | _ => None, | 95 | _ => None, |
98 | } | ||
99 | }) | 96 | }) |
100 | { | 97 | { |
101 | add_const_impl(&trigger, acc, ctx, &missing_fn); | 98 | add_const_impl(&trigger, acc, ctx, missing_fn); |
102 | } | 99 | } |
103 | } | 100 | } |
104 | 101 | ||
@@ -126,9 +123,9 @@ fn add_function_impl( | |||
126 | fn_def_node: &SyntaxNode, | 123 | fn_def_node: &SyntaxNode, |
127 | acc: &mut Completions, | 124 | acc: &mut Completions, |
128 | ctx: &CompletionContext, | 125 | ctx: &CompletionContext, |
129 | func: &hir::Function, | 126 | func: hir::Function, |
130 | ) { | 127 | ) { |
131 | let signature = FunctionSignature::from_hir(ctx.db, *func); | 128 | let signature = FunctionSignature::from_hir(ctx.db, func); |
132 | 129 | ||
133 | let fn_name = func.name(ctx.db).to_string(); | 130 | let fn_name = func.name(ctx.db).to_string(); |
134 | 131 | ||
@@ -167,7 +164,7 @@ fn add_type_alias_impl( | |||
167 | type_def_node: &SyntaxNode, | 164 | type_def_node: &SyntaxNode, |
168 | acc: &mut Completions, | 165 | acc: &mut Completions, |
169 | ctx: &CompletionContext, | 166 | ctx: &CompletionContext, |
170 | type_alias: &hir::TypeAlias, | 167 | type_alias: hir::TypeAlias, |
171 | ) { | 168 | ) { |
172 | let alias_name = type_alias.name(ctx.db).to_string(); | 169 | let alias_name = type_alias.name(ctx.db).to_string(); |
173 | 170 | ||
@@ -187,7 +184,7 @@ fn add_const_impl( | |||
187 | const_def_node: &SyntaxNode, | 184 | const_def_node: &SyntaxNode, |
188 | acc: &mut Completions, | 185 | acc: &mut Completions, |
189 | ctx: &CompletionContext, | 186 | ctx: &CompletionContext, |
190 | const_: &hir::Const, | 187 | const_: hir::Const, |
191 | ) { | 188 | ) { |
192 | let const_name = const_.name(ctx.db).map(|n| n.to_string()); | 189 | let const_name = const_.name(ctx.db).map(|n| n.to_string()); |
193 | 190 | ||
diff --git a/docs/dev/lsp-extensions.md b/docs/dev/lsp-extensions.md index 209f470eb..68a5df27e 100644 --- a/docs/dev/lsp-extensions.md +++ b/docs/dev/lsp-extensions.md | |||
@@ -362,3 +362,66 @@ interface ExpandedMacro { | |||
362 | ``` | 362 | ``` |
363 | 363 | ||
364 | Expands macro call at a given position. | 364 | Expands macro call at a given position. |
365 | |||
366 | ## Inlay Hints | ||
367 | |||
368 | **Method:** `rust-analyzer/inlayHints` | ||
369 | |||
370 | This request is send from client to server to render "inlay hints" -- virtual text inserted into editor to show things like inferred types. | ||
371 | Generally, the client should re-query inlay hints after every modification. | ||
372 | Note that we plan to move this request to `experimental/inlayHints`, as it is not really Rust-specific, but the current API is not necessary the right one. | ||
373 | Upstream issue: https://github.com/microsoft/language-server-protocol/issues/956 | ||
374 | |||
375 | **Request:** | ||
376 | |||
377 | ```typescript | ||
378 | interface InlayHintsParams { | ||
379 | textDocument: TextDocumentIdentifier, | ||
380 | } | ||
381 | ``` | ||
382 | |||
383 | **Response:** `InlayHint[]` | ||
384 | |||
385 | ```typescript | ||
386 | interface InlayHint { | ||
387 | kind: "TypeHint" | "ParameterHint" | "ChainingHint", | ||
388 | range: Range, | ||
389 | label: string, | ||
390 | } | ||
391 | ``` | ||
392 | |||
393 | ## Runnables | ||
394 | |||
395 | **Method:** `rust-analyzer/runnables` | ||
396 | |||
397 | This request is send from client to server to get the list of things that can be run (tests, binaries, `cargo check -p`). | ||
398 | Note that we plan to move this request to `experimental/runnables`, as it is not really Rust-specific, but the current API is not necessary the right one. | ||
399 | Upstream issue: https://github.com/microsoft/language-server-protocol/issues/944 | ||
400 | |||
401 | **Request:** | ||
402 | |||
403 | ```typescript | ||
404 | interface RunnablesParams { | ||
405 | textDocument: TextDocumentIdentifier; | ||
406 | /// If null, compute runnables for the whole file. | ||
407 | position?: Position; | ||
408 | } | ||
409 | ``` | ||
410 | |||
411 | **Response:** `Runnable[]` | ||
412 | |||
413 | ```typescript | ||
414 | interface Runnable { | ||
415 | /// The range this runnable is applicable for. | ||
416 | range: lc.Range; | ||
417 | /// The label to show in the UI. | ||
418 | label: string; | ||
419 | /// The following fields describe a process to spawn. | ||
420 | bin: string; | ||
421 | args: string[]; | ||
422 | /// Args for cargo after `--`. | ||
423 | extraArgs: string[]; | ||
424 | env: { [key: string]: string }; | ||
425 | cwd: string | null; | ||
426 | } | ||
427 | ``` | ||
diff --git a/editors/code/src/util.ts b/editors/code/src/util.ts index 127a9e911..793c481fb 100644 --- a/editors/code/src/util.ts +++ b/editors/code/src/util.ts | |||
@@ -74,10 +74,11 @@ export type RustDocument = vscode.TextDocument & { languageId: "rust" }; | |||
74 | export type RustEditor = vscode.TextEditor & { document: RustDocument }; | 74 | export type RustEditor = vscode.TextEditor & { document: RustDocument }; |
75 | 75 | ||
76 | export function isRustDocument(document: vscode.TextDocument): document is RustDocument { | 76 | export function isRustDocument(document: vscode.TextDocument): document is RustDocument { |
77 | return document.languageId === 'rust' | 77 | // Prevent corrupted text (particularly via inlay hints) in diff views |
78 | // SCM diff views have the same URI as the on-disk document but not the same content | 78 | // by allowing only `file` schemes |
79 | && document.uri.scheme !== 'git' | 79 | // unfortunately extensions that use diff views not always set this |
80 | && document.uri.scheme !== 'svn'; | 80 | // to something different than 'file' (see ongoing bug: #4608) |
81 | return document.languageId === 'rust' && document.uri.scheme === 'file'; | ||
81 | } | 82 | } |
82 | 83 | ||
83 | export function isRustEditor(editor: vscode.TextEditor): editor is RustEditor { | 84 | export function isRustEditor(editor: vscode.TextEditor): editor is RustEditor { |