aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock6
-rw-r--r--bors.toml2
-rw-r--r--crates/ra_hir/src/code_model.rs20
-rw-r--r--crates/ra_hir/src/lib.rs4
-rw-r--r--crates/ra_hir/src/source_analyzer.rs (renamed from crates/ra_hir/src/source_binder.rs)141
-rw-r--r--crates/ra_hir_ty/src/method_resolution.rs3
-rw-r--r--crates/ra_ide/src/completion/complete_dot.rs3
-rw-r--r--crates/ra_lsp_server/src/main.rs4
8 files changed, 90 insertions, 93 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 12a8896a3..29e70d8fc 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -45,7 +45,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
45 45
46[[package]] 46[[package]]
47name = "backtrace" 47name = "backtrace"
48version = "0.3.40" 48version = "0.3.41"
49source = "registry+https://github.com/rust-lang/crates.io-index" 49source = "registry+https://github.com/rust-lang/crates.io-index"
50dependencies = [ 50dependencies = [
51 "backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", 51 "backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1113,7 +1113,7 @@ dependencies = [
1113name = "ra_prof" 1113name = "ra_prof"
1114version = "0.1.0" 1114version = "0.1.0"
1115dependencies = [ 1115dependencies = [
1116 "backtrace 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)", 1116 "backtrace 0.3.41 (registry+https://github.com/rust-lang/crates.io-index)",
1117 "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", 1117 "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
1118 "jemalloc-ctl 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 1118 "jemalloc-ctl 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
1119 "jemallocator 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 1119 "jemallocator 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1780,7 +1780,7 @@ dependencies = [
1780"checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" 1780"checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
1781"checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" 1781"checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
1782"checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" 1782"checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
1783"checksum backtrace 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)" = "924c76597f0d9ca25d762c25a4d369d51267536465dc5064bdf0eb073ed477ea" 1783"checksum backtrace 0.3.41 (registry+https://github.com/rust-lang/crates.io-index)" = "a4ed64ae6d9ebfd9893193c4b2532b1292ec97bd8271c9d7d0fa90cd78a34cba"
1784"checksum backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6575f128516de27e3ce99689419835fce9643a9b215a14d2b5b685be018491" 1784"checksum backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6575f128516de27e3ce99689419835fce9643a9b215a14d2b5b685be018491"
1785"checksum base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" 1785"checksum base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
1786"checksum bit-set 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e84c238982c4b1e1ee668d136c510c67a13465279c0cb367ea6baf6310620a80" 1786"checksum bit-set 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e84c238982c4b1e1ee668d136c510c67a13465279c0cb367ea6baf6310620a80"
diff --git a/bors.toml b/bors.toml
index 0bc71860f..bf5553df4 100644
--- a/bors.toml
+++ b/bors.toml
@@ -1,6 +1,6 @@
1status = [ 1status = [
2 "Rust (ubuntu-latest)", 2 "Rust (ubuntu-latest)",
3 "Rust (windows-latest)", 3 # "Rust (windows-latest)",
4 "Rust (macos-latest)", 4 "Rust (macos-latest)",
5 "TypeScript" 5 "TypeScript"
6] 6]
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index a177cebca..346118350 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -21,8 +21,8 @@ use hir_expand::{
21 MacroDefId, 21 MacroDefId,
22}; 22};
23use hir_ty::{ 23use hir_ty::{
24 autoderef, display::HirFormatter, expr::ExprValidator, ApplicationTy, Canonical, InEnvironment, 24 autoderef, display::HirFormatter, expr::ExprValidator, method_resolution::implements_trait,
25 TraitEnvironment, Ty, TyDefId, TypeCtor, TypeWalk, 25 ApplicationTy, Canonical, InEnvironment, TraitEnvironment, Ty, TyDefId, TypeCtor, TypeWalk,
26}; 26};
27use ra_db::{CrateId, Edition, FileId}; 27use ra_db::{CrateId, Edition, FileId};
28use ra_prof::profile; 28use ra_prof::profile;
@@ -878,6 +878,22 @@ impl Type {
878 } 878 }
879 } 879 }
880 880
881 /// Checks that particular type `ty` implements `std::future::Future`.
882 /// This function is used in `.await` syntax completion.
883 pub fn impls_future(&self, db: &impl HirDatabase) -> bool {
884 let krate = self.krate;
885
886 let std_future_trait =
887 db.lang_item(krate, "future_trait".into()).and_then(|it| it.as_trait());
888 let std_future_trait = match std_future_trait {
889 Some(it) => it,
890 None => return false,
891 };
892
893 let canonical_ty = Canonical { value: self.ty.value.clone(), num_vars: 0 };
894 implements_trait(&canonical_ty, db, self.ty.environment.clone(), krate, std_future_trait)
895 }
896
881 // FIXME: this method is broken, as it doesn't take closures into account. 897 // FIXME: this method is broken, as it doesn't take closures into account.
882 pub fn as_callable(&self) -> Option<CallableDef> { 898 pub fn as_callable(&self) -> Option<CallableDef> {
883 Some(self.ty.value.as_callable()?.0) 899 Some(self.ty.value.as_callable()?.0)
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs
index 3d13978d4..a1cf89010 100644
--- a/crates/ra_hir/src/lib.rs
+++ b/crates/ra_hir/src/lib.rs
@@ -27,7 +27,7 @@ macro_rules! impl_froms {
27} 27}
28 28
29pub mod db; 29pub mod db;
30pub mod source_binder; 30pub mod source_analyzer;
31 31
32pub mod diagnostics; 32pub mod diagnostics;
33 33
@@ -46,7 +46,7 @@ pub use crate::{
46 }, 46 },
47 from_source::FromSource, 47 from_source::FromSource,
48 has_source::HasSource, 48 has_source::HasSource,
49 source_binder::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer}, 49 source_analyzer::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer},
50}; 50};
51 51
52pub use hir_def::{ 52pub use hir_def::{
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_analyzer.rs
index a2a9d968c..3df48842d 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_analyzer.rs
@@ -15,17 +15,13 @@ use hir_def::{
15 }, 15 },
16 expr::{ExprId, PatId}, 16 expr::{ExprId, PatId},
17 nameres::ModuleSource, 17 nameres::ModuleSource,
18 path::path,
19 resolver::{self, resolver_for_scope, HasResolver, Resolver, TypeNs, ValueNs}, 18 resolver::{self, resolver_for_scope, HasResolver, Resolver, TypeNs, ValueNs},
20 AssocItemId, DefWithBodyId, 19 AssocItemId, DefWithBodyId,
21}; 20};
22use hir_expand::{ 21use hir_expand::{
23 hygiene::Hygiene, name::AsName, AstId, HirFileId, InFile, MacroCallId, MacroCallKind, 22 hygiene::Hygiene, name::AsName, AstId, HirFileId, InFile, MacroCallId, MacroCallKind,
24}; 23};
25use hir_ty::{ 24use hir_ty::{method_resolution, Canonical, InEnvironment, InferenceResult, TraitEnvironment, Ty};
26 method_resolution::{self, implements_trait},
27 Canonical, InEnvironment, InferenceResult, TraitEnvironment, Ty,
28};
29use ra_prof::profile; 25use ra_prof::profile;
30use ra_syntax::{ 26use ra_syntax::{
31 ast::{self, AstNode}, 27 ast::{self, AstNode},
@@ -40,64 +36,6 @@ use crate::{
40 TypeParam, 36 TypeParam,
41}; 37};
42 38
43fn try_get_resolver_for_node(db: &impl HirDatabase, node: InFile<&SyntaxNode>) -> Option<Resolver> {
44 match_ast! {
45 match (node.value) {
46 ast::Module(it) => {
47 let src = node.with_value(it);
48 Some(crate::Module::from_declaration(db, src)?.id.resolver(db))
49 },
50 ast::SourceFile(it) => {
51 let src = node.with_value(ModuleSource::SourceFile(it));
52 Some(crate::Module::from_definition(db, src)?.id.resolver(db))
53 },
54 ast::StructDef(it) => {
55 let src = node.with_value(it);
56 Some(Struct::from_source(db, src)?.id.resolver(db))
57 },
58 ast::EnumDef(it) => {
59 let src = node.with_value(it);
60 Some(Enum::from_source(db, src)?.id.resolver(db))
61 },
62 ast::ImplBlock(it) => {
63 let src = node.with_value(it);
64 Some(ImplBlock::from_source(db, src)?.id.resolver(db))
65 },
66 ast::TraitDef(it) => {
67 let src = node.with_value(it);
68 Some(Trait::from_source(db, src)?.id.resolver(db))
69 },
70 _ => match node.value.kind() {
71 FN_DEF | CONST_DEF | STATIC_DEF => {
72 let def = def_with_body_from_child_node(db, node)?;
73 let def = DefWithBodyId::from(def);
74 Some(def.resolver(db))
75 }
76 // FIXME add missing cases
77 _ => None
78 }
79 }
80 }
81}
82
83fn def_with_body_from_child_node(
84 db: &impl HirDatabase,
85 child: InFile<&SyntaxNode>,
86) -> Option<DefWithBody> {
87 let _p = profile("def_with_body_from_child_node");
88 child.cloned().ancestors_with_macros(db).find_map(|node| {
89 let n = &node.value;
90 match_ast! {
91 match n {
92 ast::FnDef(def) => { return Function::from_source(db, node.with_value(def)).map(DefWithBody::from); },
93 ast::ConstDef(def) => { return Const::from_source(db, node.with_value(def)).map(DefWithBody::from); },
94 ast::StaticDef(def) => { return Static::from_source(db, node.with_value(def)).map(DefWithBody::from); },
95 _ => { None },
96 }
97 }
98 })
99}
100
101/// `SourceAnalyzer` is a convenience wrapper which exposes HIR API in terms of 39/// `SourceAnalyzer` is a convenience wrapper which exposes HIR API in terms of
102/// original source files. It should not be used inside the HIR itself. 40/// original source files. It should not be used inside the HIR itself.
103#[derive(Debug)] 41#[derive(Debug)]
@@ -454,25 +392,6 @@ impl SourceAnalyzer {
454 ) 392 )
455 } 393 }
456 394
457 /// Checks that particular type `ty` implements `std::future::Future`.
458 /// This function is used in `.await` syntax completion.
459 pub fn impls_future(&self, db: &impl HirDatabase, ty: Type) -> bool {
460 let std_future_path = path![std::future::Future];
461
462 let std_future_trait = match self.resolver.resolve_known_trait(db, &std_future_path) {
463 Some(it) => it.into(),
464 _ => return false,
465 };
466
467 let krate = match self.resolver.krate() {
468 Some(krate) => krate,
469 _ => return false,
470 };
471
472 let canonical_ty = Canonical { value: ty.ty.value, num_vars: 0 };
473 implements_trait(&canonical_ty, db, &self.resolver, krate.into(), std_future_trait)
474 }
475
476 pub fn expand( 395 pub fn expand(
477 &self, 396 &self,
478 db: &impl HirDatabase, 397 db: &impl HirDatabase,
@@ -487,6 +406,64 @@ impl SourceAnalyzer {
487 } 406 }
488} 407}
489 408
409fn try_get_resolver_for_node(db: &impl HirDatabase, node: InFile<&SyntaxNode>) -> Option<Resolver> {
410 match_ast! {
411 match (node.value) {
412 ast::Module(it) => {
413 let src = node.with_value(it);
414 Some(crate::Module::from_declaration(db, src)?.id.resolver(db))
415 },
416 ast::SourceFile(it) => {
417 let src = node.with_value(ModuleSource::SourceFile(it));
418 Some(crate::Module::from_definition(db, src)?.id.resolver(db))
419 },
420 ast::StructDef(it) => {
421 let src = node.with_value(it);
422 Some(Struct::from_source(db, src)?.id.resolver(db))
423 },
424 ast::EnumDef(it) => {
425 let src = node.with_value(it);
426 Some(Enum::from_source(db, src)?.id.resolver(db))
427 },
428 ast::ImplBlock(it) => {
429 let src = node.with_value(it);
430 Some(ImplBlock::from_source(db, src)?.id.resolver(db))
431 },
432 ast::TraitDef(it) => {
433 let src = node.with_value(it);
434 Some(Trait::from_source(db, src)?.id.resolver(db))
435 },
436 _ => match node.value.kind() {
437 FN_DEF | CONST_DEF | STATIC_DEF => {
438 let def = def_with_body_from_child_node(db, node)?;
439 let def = DefWithBodyId::from(def);
440 Some(def.resolver(db))
441 }
442 // FIXME add missing cases
443 _ => None
444 }
445 }
446 }
447}
448
449fn def_with_body_from_child_node(
450 db: &impl HirDatabase,
451 child: InFile<&SyntaxNode>,
452) -> Option<DefWithBody> {
453 let _p = profile("def_with_body_from_child_node");
454 child.cloned().ancestors_with_macros(db).find_map(|node| {
455 let n = &node.value;
456 match_ast! {
457 match n {
458 ast::FnDef(def) => { return Function::from_source(db, node.with_value(def)).map(DefWithBody::from); },
459 ast::ConstDef(def) => { return Const::from_source(db, node.with_value(def)).map(DefWithBody::from); },
460 ast::StaticDef(def) => { return Static::from_source(db, node.with_value(def)).map(DefWithBody::from); },
461 _ => { None },
462 }
463 }
464 })
465}
466
490fn scope_for( 467fn scope_for(
491 scopes: &ExprScopes, 468 scopes: &ExprScopes,
492 source_map: &BodySourceMap, 469 source_map: &BodySourceMap,
diff --git a/crates/ra_hir_ty/src/method_resolution.rs b/crates/ra_hir_ty/src/method_resolution.rs
index 888dc3116..55435e6ea 100644
--- a/crates/ra_hir_ty/src/method_resolution.rs
+++ b/crates/ra_hir_ty/src/method_resolution.rs
@@ -465,7 +465,7 @@ fn transform_receiver_ty(
465pub fn implements_trait( 465pub fn implements_trait(
466 ty: &Canonical<Ty>, 466 ty: &Canonical<Ty>,
467 db: &impl HirDatabase, 467 db: &impl HirDatabase,
468 resolver: &Resolver, 468 env: Arc<TraitEnvironment>,
469 krate: CrateId, 469 krate: CrateId,
470 trait_: TraitId, 470 trait_: TraitId,
471) -> bool { 471) -> bool {
@@ -474,7 +474,6 @@ pub fn implements_trait(
474 // anyway, but currently Chalk doesn't implement `dyn/impl Trait` yet 474 // anyway, but currently Chalk doesn't implement `dyn/impl Trait` yet
475 return true; 475 return true;
476 } 476 }
477 let env = TraitEnvironment::lower(db, resolver);
478 let goal = generic_implements_goal(db, env, trait_, ty.clone()); 477 let goal = generic_implements_goal(db, env, trait_, ty.clone());
479 let solution = db.trait_solve(krate.into(), goal); 478 let solution = db.trait_solve(krate.into(), goal);
480 479
diff --git a/crates/ra_ide/src/completion/complete_dot.rs b/crates/ra_ide/src/completion/complete_dot.rs
index 210a685e4..9ab43644e 100644
--- a/crates/ra_ide/src/completion/complete_dot.rs
+++ b/crates/ra_ide/src/completion/complete_dot.rs
@@ -27,7 +27,7 @@ pub(super) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) {
27 complete_methods(acc, ctx, &receiver_ty); 27 complete_methods(acc, ctx, &receiver_ty);
28 28
29 // Suggest .await syntax for types that implement Future trait 29 // Suggest .await syntax for types that implement Future trait
30 if ctx.analyzer.impls_future(ctx.db, receiver_ty) { 30 if receiver_ty.impls_future(ctx.db) {
31 CompletionItem::new(CompletionKind::Keyword, ctx.source_range(), "await") 31 CompletionItem::new(CompletionKind::Keyword, ctx.source_range(), "await")
32 .detail("expr.await") 32 .detail("expr.await")
33 .insert_text("await") 33 .insert_text("await")
@@ -525,6 +525,7 @@ mod tests {
525 525
526 //- /std/lib.rs 526 //- /std/lib.rs
527 pub mod future { 527 pub mod future {
528 #[lang = "future_trait"]
528 pub trait Future {} 529 pub trait Future {}
529 } 530 }
530 "###, CompletionKind::Keyword), 531 "###, CompletionKind::Keyword),
diff --git a/crates/ra_lsp_server/src/main.rs b/crates/ra_lsp_server/src/main.rs
index cdd925c9f..3879eeff2 100644
--- a/crates/ra_lsp_server/src/main.rs
+++ b/crates/ra_lsp_server/src/main.rs
@@ -47,6 +47,10 @@ fn run_server() -> Result<()> {
47 let initialize_params = connection.initialize(server_capabilities)?; 47 let initialize_params = connection.initialize(server_capabilities)?;
48 let initialize_params: lsp_types::InitializeParams = serde_json::from_value(initialize_params)?; 48 let initialize_params: lsp_types::InitializeParams = serde_json::from_value(initialize_params)?;
49 49
50 if let Some(client_info) = initialize_params.client_info {
51 log::info!("Client '{}' {}", client_info.name, client_info.version.unwrap_or_default());
52 }
53
50 let cwd = std::env::current_dir()?; 54 let cwd = std::env::current_dir()?;
51 let root = initialize_params.root_uri.and_then(|it| it.to_file_path().ok()).unwrap_or(cwd); 55 let root = initialize_params.root_uri.and_then(|it| it.to_file_path().ok()).unwrap_or(cwd);
52 56