diff options
author | bors[bot] <bors[bot]@users.noreply.github.com> | 2018-12-24 14:40:11 +0000 |
---|---|---|
committer | bors[bot] <bors[bot]@users.noreply.github.com> | 2018-12-24 14:40:11 +0000 |
commit | 67e768466ff2e2611eead0f30b2e9c4083c80c20 (patch) | |
tree | 8984028019837c91131fc30f60eecf8c2a457368 /crates/ra_analysis/src | |
parent | abe09eb5edfe8f4c58baa16140acbd414635836f (diff) | |
parent | 4befde1eee5b1e2b7ddc9bf764b77f82b792c318 (diff) |
Merge #327
327: Beginnings of type inference r=flodiebold a=flodiebold
I was a bit bored, so I thought I'd try to start implementing the type system and see how far I come :wink: This is obviously still extremely WIP, only very basic stuff working, but I thought I'd post this now to get some feedback as to whether this approach makes sense at all.
There's no user-visible effect yet, but the type inference has tests similar to the ones for the parser. My next step will probably be to implement struct types, after which this could probably be used to complete fields.
I realize this may all get thrown away when/if the compiler query system gets usable, but I feel like there are lots of IDE features that could be implemented with somewhat working type inference in the meantime :smile:
Co-authored-by: Florian Diebold <[email protected]>
Diffstat (limited to 'crates/ra_analysis/src')
-rw-r--r-- | crates/ra_analysis/src/db.rs | 2 | ||||
-rw-r--r-- | crates/ra_analysis/src/imp.rs | 20 | ||||
-rw-r--r-- | crates/ra_analysis/src/lib.rs | 3 |
3 files changed, 24 insertions, 1 deletions
diff --git a/crates/ra_analysis/src/db.rs b/crates/ra_analysis/src/db.rs index 94729d296..780a84291 100644 --- a/crates/ra_analysis/src/db.rs +++ b/crates/ra_analysis/src/db.rs | |||
@@ -93,6 +93,8 @@ salsa::database_storage! { | |||
93 | fn item_map() for hir::db::ItemMapQuery; | 93 | fn item_map() for hir::db::ItemMapQuery; |
94 | fn fn_syntax() for hir::db::FnSyntaxQuery; | 94 | fn fn_syntax() for hir::db::FnSyntaxQuery; |
95 | fn submodules() for hir::db::SubmodulesQuery; | 95 | fn submodules() for hir::db::SubmodulesQuery; |
96 | fn infer() for hir::db::InferQuery; | ||
97 | fn type_for_def() for hir::db::TypeForDefQuery; | ||
96 | } | 98 | } |
97 | } | 99 | } |
98 | } | 100 | } |
diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs index b01382808..40996bfd7 100644 --- a/crates/ra_analysis/src/imp.rs +++ b/crates/ra_analysis/src/imp.rs | |||
@@ -5,7 +5,8 @@ use std::{ | |||
5 | 5 | ||
6 | use ra_editor::{self, find_node_at_offset, FileSymbol, LineIndex, LocalEdit}; | 6 | use ra_editor::{self, find_node_at_offset, FileSymbol, LineIndex, LocalEdit}; |
7 | use ra_syntax::{ | 7 | use ra_syntax::{ |
8 | ast::{self, ArgListOwner, Expr, NameOwner}, | 8 | ast::{self, ArgListOwner, Expr, NameOwner, FnDef}, |
9 | algo::find_covering_node, | ||
9 | AstNode, SourceFileNode, | 10 | AstNode, SourceFileNode, |
10 | SyntaxKind::*, | 11 | SyntaxKind::*, |
11 | SyntaxNodeRef, TextRange, TextUnit, | 12 | SyntaxNodeRef, TextRange, TextUnit, |
@@ -510,6 +511,23 @@ impl AnalysisImpl { | |||
510 | Ok(None) | 511 | Ok(None) |
511 | } | 512 | } |
512 | 513 | ||
514 | pub fn type_of(&self, file_id: FileId, range: TextRange) -> Cancelable<Option<String>> { | ||
515 | let file = self.db.source_file(file_id); | ||
516 | let syntax = file.syntax(); | ||
517 | let node = find_covering_node(syntax, range); | ||
518 | let parent_fn = node.ancestors().filter_map(FnDef::cast).next(); | ||
519 | let parent_fn = if let Some(p) = parent_fn { | ||
520 | p | ||
521 | } else { | ||
522 | return Ok(None); | ||
523 | }; | ||
524 | let function = ctry!(source_binder::function_from_source( | ||
525 | &*self.db, file_id, parent_fn | ||
526 | )?); | ||
527 | let infer = function.infer(&*self.db)?; | ||
528 | Ok(infer.type_of_node(node).map(|t| t.to_string())) | ||
529 | } | ||
530 | |||
513 | fn index_resolve(&self, name_ref: ast::NameRef) -> Cancelable<Vec<(FileId, FileSymbol)>> { | 531 | fn index_resolve(&self, name_ref: ast::NameRef) -> Cancelable<Vec<(FileId, FileSymbol)>> { |
514 | let name = name_ref.text(); | 532 | let name = name_ref.text(); |
515 | let mut query = Query::new(name.to_string()); | 533 | let mut query = Query::new(name.to_string()); |
diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs index 85df9c089..830898140 100644 --- a/crates/ra_analysis/src/lib.rs +++ b/crates/ra_analysis/src/lib.rs | |||
@@ -366,6 +366,9 @@ impl Analysis { | |||
366 | ) -> Cancelable<Option<(FnSignatureInfo, Option<usize>)>> { | 366 | ) -> Cancelable<Option<(FnSignatureInfo, Option<usize>)>> { |
367 | self.imp.resolve_callable(position) | 367 | self.imp.resolve_callable(position) |
368 | } | 368 | } |
369 | pub fn type_of(&self, file_id: FileId, range: TextRange) -> Cancelable<Option<String>> { | ||
370 | self.imp.type_of(file_id, range) | ||
371 | } | ||
369 | } | 372 | } |
370 | 373 | ||
371 | pub struct LibraryData { | 374 | pub struct LibraryData { |