aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_hir_ty/Cargo.toml6
-rw-r--r--crates/ra_hir_ty/src/traits/chalk.rs119
-rw-r--r--crates/ra_hir_ty/src/traits/chalk/tls.rs8
-rw-r--r--crates/rust-analyzer/src/bin/main.rs17
-rw-r--r--crates/rust-analyzer/src/caps.rs60
5 files changed, 134 insertions, 76 deletions
diff --git a/crates/ra_hir_ty/Cargo.toml b/crates/ra_hir_ty/Cargo.toml
index 5fc0ec5e3..b2de7fa34 100644
--- a/crates/ra_hir_ty/Cargo.toml
+++ b/crates/ra_hir_ty/Cargo.toml
@@ -27,9 +27,9 @@ test_utils = { path = "../test_utils" }
27 27
28scoped-tls = "1" 28scoped-tls = "1"
29 29
30chalk-solve = { git = "https://github.com/rust-lang/chalk.git", rev = "3e9c2503ae9c5277c2acb74624dc267876dd89b3" } 30chalk-solve = { git = "https://github.com/rust-lang/chalk.git", rev = "eaab84b394007d1bed15f5470409a6ea02900a96" }
31chalk-rust-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "3e9c2503ae9c5277c2acb74624dc267876dd89b3" } 31chalk-rust-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "eaab84b394007d1bed15f5470409a6ea02900a96" }
32chalk-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "3e9c2503ae9c5277c2acb74624dc267876dd89b3" } 32chalk-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "eaab84b394007d1bed15f5470409a6ea02900a96" }
33 33
34[dev-dependencies] 34[dev-dependencies]
35insta = "0.16.0" 35insta = "0.16.0"
diff --git a/crates/ra_hir_ty/src/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs
index 5870618a0..c2d7abd17 100644
--- a/crates/ra_hir_ty/src/traits/chalk.rs
+++ b/crates/ra_hir_ty/src/traits/chalk.rs
@@ -4,7 +4,7 @@ use std::{fmt, sync::Arc};
4use log::debug; 4use log::debug;
5 5
6use chalk_ir::{ 6use chalk_ir::{
7 cast::Cast, fold::shift::Shift, interner::HasInterner, Goal, GoalData, Parameter, 7 cast::Cast, fold::shift::Shift, interner::HasInterner, GenericArg, Goal, GoalData,
8 PlaceholderIndex, TypeName, UniverseIndex, 8 PlaceholderIndex, TypeName, UniverseIndex,
9}; 9};
10 10
@@ -26,24 +26,24 @@ pub(super) mod tls;
26pub struct Interner; 26pub struct Interner;
27 27
28impl chalk_ir::interner::Interner for Interner { 28impl chalk_ir::interner::Interner for Interner {
29 type InternedType = Box<chalk_ir::TyData<Self>>; 29 type InternedType = Box<chalk_ir::TyData<Self>>; // FIXME use Arc?
30 type InternedLifetime = chalk_ir::LifetimeData<Self>; 30 type InternedLifetime = chalk_ir::LifetimeData<Self>;
31 type InternedParameter = chalk_ir::ParameterData<Self>; 31 type InternedConst = Arc<chalk_ir::ConstData<Self>>;
32 type InternedConcreteConst = ();
33 type InternedGenericArg = chalk_ir::GenericArgData<Self>;
32 type InternedGoal = Arc<GoalData<Self>>; 34 type InternedGoal = Arc<GoalData<Self>>;
33 type InternedGoals = Vec<Goal<Self>>; 35 type InternedGoals = Vec<Goal<Self>>;
34 type InternedSubstitution = Vec<Parameter<Self>>; 36 type InternedSubstitution = Vec<GenericArg<Self>>;
35 type InternedProgramClause = chalk_ir::ProgramClauseData<Self>; 37 type InternedProgramClause = chalk_ir::ProgramClauseData<Self>;
36 type InternedProgramClauses = Arc<[chalk_ir::ProgramClause<Self>]>; 38 type InternedProgramClauses = Arc<[chalk_ir::ProgramClause<Self>]>;
37 type InternedQuantifiedWhereClauses = Vec<chalk_ir::QuantifiedWhereClause<Self>>; 39 type InternedQuantifiedWhereClauses = Vec<chalk_ir::QuantifiedWhereClause<Self>>;
38 type InternedParameterKinds = Vec<chalk_ir::ParameterKind<()>>; 40 type InternedVariableKinds = Vec<chalk_ir::VariableKind<Self>>;
39 type InternedCanonicalVarKinds = Vec<chalk_ir::ParameterKind<UniverseIndex>>; 41 type InternedCanonicalVarKinds = Vec<chalk_ir::CanonicalVarKind<Self>>;
40 type Identifier = TypeAliasId;
41 type DefId = InternId; 42 type DefId = InternId;
43 type InternedAdtId = InternId;
44 type Identifier = TypeAliasId;
42 45
43 fn debug_struct_id( 46 fn debug_adt_id(type_kind_id: StructId, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
44 type_kind_id: StructId,
45 fmt: &mut fmt::Formatter<'_>,
46 ) -> Option<fmt::Result> {
47 tls::with_current_program(|prog| Some(prog?.debug_struct_id(type_kind_id, fmt))) 47 tls::with_current_program(|prog| Some(prog?.debug_struct_id(type_kind_id, fmt)))
48 } 48 }
49 49
@@ -94,11 +94,11 @@ impl chalk_ir::interner::Interner for Interner {
94 tls::with_current_program(|prog| Some(prog?.debug_lifetime(lifetime, fmt))) 94 tls::with_current_program(|prog| Some(prog?.debug_lifetime(lifetime, fmt)))
95 } 95 }
96 96
97 fn debug_parameter( 97 fn debug_generic_arg(
98 parameter: &Parameter<Interner>, 98 parameter: &GenericArg<Interner>,
99 fmt: &mut fmt::Formatter<'_>, 99 fmt: &mut fmt::Formatter<'_>,
100 ) -> Option<fmt::Result> { 100 ) -> Option<fmt::Result> {
101 tls::with_current_program(|prog| Some(prog?.debug_parameter(parameter, fmt))) 101 tls::with_current_program(|prog| Some(prog?.debug_generic_arg(parameter, fmt)))
102 } 102 }
103 103
104 fn debug_goal(goal: &Goal<Interner>, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> { 104 fn debug_goal(goal: &Goal<Interner>, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
@@ -164,17 +164,32 @@ impl chalk_ir::interner::Interner for Interner {
164 lifetime 164 lifetime
165 } 165 }
166 166
167 fn intern_parameter( 167 fn intern_const(&self, constant: chalk_ir::ConstData<Self>) -> Arc<chalk_ir::ConstData<Self>> {
168 Arc::new(constant)
169 }
170
171 fn const_data<'a>(
172 &self,
173 constant: &'a Arc<chalk_ir::ConstData<Self>>,
174 ) -> &'a chalk_ir::ConstData<Self> {
175 constant
176 }
177
178 fn const_eq(&self, _ty: &Box<chalk_ir::TyData<Self>>, _c1: &(), _c2: &()) -> bool {
179 true
180 }
181
182 fn intern_generic_arg(
168 &self, 183 &self,
169 parameter: chalk_ir::ParameterData<Self>, 184 parameter: chalk_ir::GenericArgData<Self>,
170 ) -> chalk_ir::ParameterData<Self> { 185 ) -> chalk_ir::GenericArgData<Self> {
171 parameter 186 parameter
172 } 187 }
173 188
174 fn parameter_data<'a>( 189 fn generic_arg_data<'a>(
175 &self, 190 &self,
176 parameter: &'a chalk_ir::ParameterData<Self>, 191 parameter: &'a chalk_ir::GenericArgData<Self>,
177 ) -> &'a chalk_ir::ParameterData<Self> { 192 ) -> &'a chalk_ir::GenericArgData<Self> {
178 parameter 193 parameter
179 } 194 }
180 195
@@ -199,15 +214,15 @@ impl chalk_ir::interner::Interner for Interner {
199 214
200 fn intern_substitution<E>( 215 fn intern_substitution<E>(
201 &self, 216 &self,
202 data: impl IntoIterator<Item = Result<Parameter<Self>, E>>, 217 data: impl IntoIterator<Item = Result<GenericArg<Self>, E>>,
203 ) -> Result<Vec<Parameter<Self>>, E> { 218 ) -> Result<Vec<GenericArg<Self>>, E> {
204 data.into_iter().collect() 219 data.into_iter().collect()
205 } 220 }
206 221
207 fn substitution_data<'a>( 222 fn substitution_data<'a>(
208 &self, 223 &self,
209 substitution: &'a Vec<Parameter<Self>>, 224 substitution: &'a Vec<GenericArg<Self>>,
210 ) -> &'a [Parameter<Self>] { 225 ) -> &'a [GenericArg<Self>] {
211 substitution 226 substitution
212 } 227 }
213 228
@@ -253,23 +268,23 @@ impl chalk_ir::interner::Interner for Interner {
253 clauses 268 clauses
254 } 269 }
255 270
256 fn intern_parameter_kinds<E>( 271 fn intern_generic_arg_kinds<E>(
257 &self, 272 &self,
258 data: impl IntoIterator<Item = Result<chalk_ir::ParameterKind<()>, E>>, 273 data: impl IntoIterator<Item = Result<chalk_ir::VariableKind<Self>, E>>,
259 ) -> Result<Self::InternedParameterKinds, E> { 274 ) -> Result<Self::InternedVariableKinds, E> {
260 data.into_iter().collect() 275 data.into_iter().collect()
261 } 276 }
262 277
263 fn parameter_kinds_data<'a>( 278 fn variable_kinds_data<'a>(
264 &self, 279 &self,
265 parameter_kinds: &'a Self::InternedParameterKinds, 280 parameter_kinds: &'a Self::InternedVariableKinds,
266 ) -> &'a [chalk_ir::ParameterKind<()>] { 281 ) -> &'a [chalk_ir::VariableKind<Self>] {
267 &parameter_kinds 282 &parameter_kinds
268 } 283 }
269 284
270 fn intern_canonical_var_kinds<E>( 285 fn intern_canonical_var_kinds<E>(
271 &self, 286 &self,
272 data: impl IntoIterator<Item = Result<chalk_ir::ParameterKind<UniverseIndex>, E>>, 287 data: impl IntoIterator<Item = Result<chalk_ir::CanonicalVarKind<Self>, E>>,
273 ) -> Result<Self::InternedCanonicalVarKinds, E> { 288 ) -> Result<Self::InternedCanonicalVarKinds, E> {
274 data.into_iter().collect() 289 data.into_iter().collect()
275 } 290 }
@@ -277,7 +292,7 @@ impl chalk_ir::interner::Interner for Interner {
277 fn canonical_var_kinds_data<'a>( 292 fn canonical_var_kinds_data<'a>(
278 &self, 293 &self,
279 canonical_var_kinds: &'a Self::InternedCanonicalVarKinds, 294 canonical_var_kinds: &'a Self::InternedCanonicalVarKinds,
280 ) -> &'a [chalk_ir::ParameterKind<UniverseIndex>] { 295 ) -> &'a [chalk_ir::CanonicalVarKind<Self>] {
281 &canonical_var_kinds 296 &canonical_var_kinds
282 } 297 }
283} 298}
@@ -290,8 +305,8 @@ pub type AssocTypeId = chalk_ir::AssocTypeId<Interner>;
290pub type AssociatedTyDatum = chalk_rust_ir::AssociatedTyDatum<Interner>; 305pub type AssociatedTyDatum = chalk_rust_ir::AssociatedTyDatum<Interner>;
291pub type TraitId = chalk_ir::TraitId<Interner>; 306pub type TraitId = chalk_ir::TraitId<Interner>;
292pub type TraitDatum = chalk_rust_ir::TraitDatum<Interner>; 307pub type TraitDatum = chalk_rust_ir::TraitDatum<Interner>;
293pub type StructId = chalk_ir::StructId<Interner>; 308pub type StructId = chalk_ir::AdtId<Interner>;
294pub type StructDatum = chalk_rust_ir::StructDatum<Interner>; 309pub type StructDatum = chalk_rust_ir::AdtDatum<Interner>;
295pub type ImplId = chalk_ir::ImplId<Interner>; 310pub type ImplId = chalk_ir::ImplId<Interner>;
296pub type ImplDatum = chalk_rust_ir::ImplDatum<Interner>; 311pub type ImplDatum = chalk_rust_ir::ImplDatum<Interner>;
297pub type AssociatedTyValueId = chalk_rust_ir::AssociatedTyValueId<Interner>; 312pub type AssociatedTyValueId = chalk_rust_ir::AssociatedTyValueId<Interner>;
@@ -453,14 +468,14 @@ impl ToChalk for TypeCtor {
453 _ => { 468 _ => {
454 // other TypeCtors get interned and turned into a chalk StructId 469 // other TypeCtors get interned and turned into a chalk StructId
455 let struct_id = db.intern_type_ctor(self).into(); 470 let struct_id = db.intern_type_ctor(self).into();
456 TypeName::Struct(struct_id) 471 TypeName::Adt(struct_id)
457 } 472 }
458 } 473 }
459 } 474 }
460 475
461 fn from_chalk(db: &dyn HirDatabase, type_name: TypeName<Interner>) -> TypeCtor { 476 fn from_chalk(db: &dyn HirDatabase, type_name: TypeName<Interner>) -> TypeCtor {
462 match type_name { 477 match type_name {
463 TypeName::Struct(struct_id) => db.lookup_intern_type_ctor(struct_id.into()), 478 TypeName::Adt(struct_id) => db.lookup_intern_type_ctor(struct_id.into()),
464 TypeName::AssociatedType(type_id) => TypeCtor::AssociatedType(from_chalk(db, type_id)), 479 TypeName::AssociatedType(type_id) => TypeCtor::AssociatedType(from_chalk(db, type_id)),
465 TypeName::OpaqueType(_) => unreachable!(), 480 TypeName::OpaqueType(_) => unreachable!(),
466 481
@@ -471,6 +486,8 @@ impl ToChalk for TypeCtor {
471 TypeName::Ref(_) => unreachable!(), 486 TypeName::Ref(_) => unreachable!(),
472 TypeName::Str => unreachable!(), 487 TypeName::Str => unreachable!(),
473 488
489 TypeName::FnDef(_) => unreachable!(),
490
474 TypeName::Error => { 491 TypeName::Error => {
475 // this should not be reached, since we don't represent TypeName::Error with TypeCtor 492 // this should not be reached, since we don't represent TypeName::Error with TypeCtor
476 unreachable!() 493 unreachable!()
@@ -622,7 +639,10 @@ where
622 type Chalk = chalk_ir::Canonical<T::Chalk>; 639 type Chalk = chalk_ir::Canonical<T::Chalk>;
623 640
624 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Canonical<T::Chalk> { 641 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Canonical<T::Chalk> {
625 let parameter = chalk_ir::ParameterKind::Ty(chalk_ir::UniverseIndex::ROOT); 642 let parameter = chalk_ir::CanonicalVarKind::new(
643 chalk_ir::VariableKind::Ty,
644 chalk_ir::UniverseIndex::ROOT,
645 );
626 let value = self.value.to_chalk(db); 646 let value = self.value.to_chalk(db);
627 chalk_ir::Canonical { 647 chalk_ir::Canonical {
628 value, 648 value,
@@ -738,9 +758,9 @@ where
738 T: HasInterner<Interner = Interner>, 758 T: HasInterner<Interner = Interner>,
739{ 759{
740 chalk_ir::Binders::new( 760 chalk_ir::Binders::new(
741 chalk_ir::ParameterKinds::from( 761 chalk_ir::VariableKinds::from(
742 &Interner, 762 &Interner,
743 std::iter::repeat(chalk_ir::ParameterKind::Ty(())).take(num_vars), 763 std::iter::repeat(chalk_ir::VariableKind::Ty).take(num_vars),
744 ), 764 ),
745 value, 765 value,
746 ) 766 )
@@ -819,16 +839,25 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
819 fn trait_datum(&self, trait_id: TraitId) -> Arc<TraitDatum> { 839 fn trait_datum(&self, trait_id: TraitId) -> Arc<TraitDatum> {
820 self.db.trait_datum(self.krate, trait_id) 840 self.db.trait_datum(self.krate, trait_id)
821 } 841 }
822 fn struct_datum(&self, struct_id: StructId) -> Arc<StructDatum> { 842 fn adt_datum(&self, struct_id: StructId) -> Arc<StructDatum> {
823 self.db.struct_datum(self.krate, struct_id) 843 self.db.struct_datum(self.krate, struct_id)
824 } 844 }
825 fn impl_datum(&self, impl_id: ImplId) -> Arc<ImplDatum> { 845 fn impl_datum(&self, impl_id: ImplId) -> Arc<ImplDatum> {
826 self.db.impl_datum(self.krate, impl_id) 846 self.db.impl_datum(self.krate, impl_id)
827 } 847 }
848
849 fn fn_def_datum(
850 &self,
851 _fn_def_id: chalk_ir::FnDefId<Interner>,
852 ) -> Arc<chalk_rust_ir::FnDefDatum<Interner>> {
853 // We don't yet provide any FnDefs to Chalk
854 unimplemented!()
855 }
856
828 fn impls_for_trait( 857 fn impls_for_trait(
829 &self, 858 &self,
830 trait_id: TraitId, 859 trait_id: TraitId,
831 parameters: &[Parameter<Interner>], 860 parameters: &[GenericArg<Interner>],
832 ) -> Vec<ImplId> { 861 ) -> Vec<ImplId> {
833 debug!("impls_for_trait {:?}", trait_id); 862 debug!("impls_for_trait {:?}", trait_id);
834 let trait_: hir_def::TraitId = from_chalk(self.db, trait_id); 863 let trait_: hir_def::TraitId = from_chalk(self.db, trait_id);
@@ -1000,7 +1029,7 @@ pub(crate) fn struct_datum_query(
1000 struct_id: StructId, 1029 struct_id: StructId,
1001) -> Arc<StructDatum> { 1030) -> Arc<StructDatum> {
1002 debug!("struct_datum {:?}", struct_id); 1031 debug!("struct_datum {:?}", struct_id);
1003 let type_ctor: TypeCtor = from_chalk(db, TypeName::Struct(struct_id)); 1032 let type_ctor: TypeCtor = from_chalk(db, TypeName::Adt(struct_id));
1004 debug!("struct {:?} = {:?}", struct_id, type_ctor); 1033 debug!("struct {:?} = {:?}", struct_id, type_ctor);
1005 let num_params = type_ctor.num_ty_params(db); 1034 let num_params = type_ctor.num_ty_params(db);
1006 let upstream = type_ctor.krate(db) != Some(krate); 1035 let upstream = type_ctor.krate(db) != Some(krate);
@@ -1012,12 +1041,12 @@ pub(crate) fn struct_datum_query(
1012 convert_where_clauses(db, generic_def, &bound_vars) 1041 convert_where_clauses(db, generic_def, &bound_vars)
1013 }) 1042 })
1014 .unwrap_or_else(Vec::new); 1043 .unwrap_or_else(Vec::new);
1015 let flags = chalk_rust_ir::StructFlags { 1044 let flags = chalk_rust_ir::AdtFlags {
1016 upstream, 1045 upstream,
1017 // FIXME set fundamental flag correctly 1046 // FIXME set fundamental flag correctly
1018 fundamental: false, 1047 fundamental: false,
1019 }; 1048 };
1020 let struct_datum_bound = chalk_rust_ir::StructDatumBound { 1049 let struct_datum_bound = chalk_rust_ir::AdtDatumBound {
1021 fields: Vec::new(), // FIXME add fields (only relevant for auto traits) 1050 fields: Vec::new(), // FIXME add fields (only relevant for auto traits)
1022 where_clauses, 1051 where_clauses,
1023 }; 1052 };
@@ -1153,7 +1182,7 @@ impl From<StructId> for crate::TypeCtorId {
1153 1182
1154impl From<crate::TypeCtorId> for StructId { 1183impl From<crate::TypeCtorId> for StructId {
1155 fn from(type_ctor_id: crate::TypeCtorId) -> Self { 1184 fn from(type_ctor_id: crate::TypeCtorId) -> Self {
1156 chalk_ir::StructId(type_ctor_id.as_intern_id()) 1185 chalk_ir::AdtId(type_ctor_id.as_intern_id())
1157 } 1186 }
1158} 1187}
1159 1188
diff --git a/crates/ra_hir_ty/src/traits/chalk/tls.rs b/crates/ra_hir_ty/src/traits/chalk/tls.rs
index 4867cb17e..b7eb49d7b 100644
--- a/crates/ra_hir_ty/src/traits/chalk/tls.rs
+++ b/crates/ra_hir_ty/src/traits/chalk/tls.rs
@@ -1,7 +1,7 @@
1//! Implementation of Chalk debug helper functions using TLS. 1//! Implementation of Chalk debug helper functions using TLS.
2use std::fmt; 2use std::fmt;
3 3
4use chalk_ir::{AliasTy, Goal, Goals, Lifetime, Parameter, ProgramClauseImplication, TypeName}; 4use chalk_ir::{AliasTy, GenericArg, Goal, Goals, Lifetime, ProgramClauseImplication, TypeName};
5use itertools::Itertools; 5use itertools::Itertools;
6 6
7use super::{from_chalk, Interner}; 7use super::{from_chalk, Interner};
@@ -18,7 +18,7 @@ impl DebugContext<'_> {
18 id: super::StructId, 18 id: super::StructId,
19 f: &mut fmt::Formatter<'_>, 19 f: &mut fmt::Formatter<'_>,
20 ) -> Result<(), fmt::Error> { 20 ) -> Result<(), fmt::Error> {
21 let type_ctor: TypeCtor = from_chalk(self.0, TypeName::Struct(id)); 21 let type_ctor: TypeCtor = from_chalk(self.0, TypeName::Adt(id));
22 match type_ctor { 22 match type_ctor {
23 TypeCtor::Bool => write!(f, "bool")?, 23 TypeCtor::Bool => write!(f, "bool")?,
24 TypeCtor::Char => write!(f, "char")?, 24 TypeCtor::Char => write!(f, "char")?,
@@ -188,9 +188,9 @@ impl DebugContext<'_> {
188 write!(fmt, "{:?}", lifetime.data(&Interner)) 188 write!(fmt, "{:?}", lifetime.data(&Interner))
189 } 189 }
190 190
191 pub fn debug_parameter( 191 pub fn debug_generic_arg(
192 &self, 192 &self,
193 parameter: &Parameter<Interner>, 193 parameter: &GenericArg<Interner>,
194 fmt: &mut fmt::Formatter<'_>, 194 fmt: &mut fmt::Formatter<'_>,
195 ) -> Result<(), fmt::Error> { 195 ) -> Result<(), fmt::Error> {
196 write!(fmt, "{:?}", parameter.data(&Interner).inner_debug()) 196 write!(fmt, "{:?}", parameter.data(&Interner).inner_debug())
diff --git a/crates/rust-analyzer/src/bin/main.rs b/crates/rust-analyzer/src/bin/main.rs
index 09908458d..e82fd57de 100644
--- a/crates/rust-analyzer/src/bin/main.rs
+++ b/crates/rust-analyzer/src/bin/main.rs
@@ -74,12 +74,25 @@ fn run_server() -> Result<()> {
74 log::info!("lifecycle: server started"); 74 log::info!("lifecycle: server started");
75 75
76 let (connection, io_threads) = Connection::stdio(); 76 let (connection, io_threads) = Connection::stdio();
77 let server_capabilities = serde_json::to_value(rust_analyzer::server_capabilities()).unwrap();
78 77
79 let initialize_params = connection.initialize(server_capabilities)?; 78 let (initialize_id, initialize_params) = connection.initialize_start()?;
80 let initialize_params = 79 let initialize_params =
81 from_json::<lsp_types::InitializeParams>("InitializeParams", initialize_params)?; 80 from_json::<lsp_types::InitializeParams>("InitializeParams", initialize_params)?;
82 81
82 let server_capabilities = rust_analyzer::server_capabilities(&initialize_params.capabilities);
83
84 let initialize_result = lsp_types::InitializeResult {
85 capabilities: server_capabilities,
86 server_info: Some(lsp_types::ServerInfo {
87 name: String::from("rust-analyzer"),
88 version: Some(String::from(env!("REV"))),
89 }),
90 };
91
92 let initialize_result = serde_json::to_value(initialize_result).unwrap();
93
94 connection.initialize_finish(initialize_id, initialize_result)?;
95
83 if let Some(client_info) = initialize_params.client_info { 96 if let Some(client_info) = initialize_params.client_info {
84 log::info!("Client '{}' {}", client_info.name, client_info.version.unwrap_or_default()); 97 log::info!("Client '{}' {}", client_info.name, client_info.version.unwrap_or_default());
85 } 98 }
diff --git a/crates/rust-analyzer/src/caps.rs b/crates/rust-analyzer/src/caps.rs
index 13af75469..780fc9317 100644
--- a/crates/rust-analyzer/src/caps.rs
+++ b/crates/rust-analyzer/src/caps.rs
@@ -2,19 +2,22 @@
2use std::env; 2use std::env;
3 3
4use lsp_types::{ 4use lsp_types::{
5 CallHierarchyServerCapability, CodeActionOptions, CodeActionProviderCapability, 5 CallHierarchyServerCapability, ClientCapabilities, CodeActionOptions,
6 CodeLensOptions, CompletionOptions, DocumentOnTypeFormattingOptions, 6 CodeActionProviderCapability, CodeLensOptions, CompletionOptions,
7 FoldingRangeProviderCapability, ImplementationProviderCapability, RenameOptions, 7 DocumentOnTypeFormattingOptions, FoldingRangeProviderCapability,
8 RenameProviderCapability, SaveOptions, SelectionRangeProviderCapability, 8 ImplementationProviderCapability, RenameOptions, RenameProviderCapability, SaveOptions,
9 SemanticTokensDocumentProvider, SemanticTokensLegend, SemanticTokensOptions, 9 SelectionRangeProviderCapability, SemanticTokensDocumentProvider, SemanticTokensLegend,
10 ServerCapabilities, SignatureHelpOptions, TextDocumentSyncCapability, TextDocumentSyncKind, 10 SemanticTokensOptions, ServerCapabilities, SignatureHelpOptions, TextDocumentSyncCapability,
11 TextDocumentSyncOptions, TypeDefinitionProviderCapability, WorkDoneProgressOptions, 11 TextDocumentSyncKind, TextDocumentSyncOptions, TypeDefinitionProviderCapability,
12 WorkDoneProgressOptions,
12}; 13};
13use serde_json::json; 14use serde_json::json;
14 15
15use crate::semantic_tokens; 16use crate::semantic_tokens;
16 17
17pub fn server_capabilities() -> ServerCapabilities { 18pub fn server_capabilities(client_caps: &ClientCapabilities) -> ServerCapabilities {
19 let code_action_provider = code_action_capabilities(client_caps);
20
18 ServerCapabilities { 21 ServerCapabilities {
19 text_document_sync: Some(TextDocumentSyncCapability::Options(TextDocumentSyncOptions { 22 text_document_sync: Some(TextDocumentSyncCapability::Options(TextDocumentSyncOptions {
20 open_close: Some(true), 23 open_close: Some(true),
@@ -46,20 +49,7 @@ pub fn server_capabilities() -> ServerCapabilities {
46 document_highlight_provider: Some(true), 49 document_highlight_provider: Some(true),
47 document_symbol_provider: Some(true), 50 document_symbol_provider: Some(true),
48 workspace_symbol_provider: Some(true), 51 workspace_symbol_provider: Some(true),
49 code_action_provider: Some(CodeActionProviderCapability::Options(CodeActionOptions { 52 code_action_provider: Some(code_action_provider),
50 // Advertise support for all built-in CodeActionKinds
51 code_action_kinds: Some(vec![
52 lsp_types::code_action_kind::EMPTY.to_string(),
53 lsp_types::code_action_kind::QUICKFIX.to_string(),
54 lsp_types::code_action_kind::REFACTOR.to_string(),
55 lsp_types::code_action_kind::REFACTOR_EXTRACT.to_string(),
56 lsp_types::code_action_kind::REFACTOR_INLINE.to_string(),
57 lsp_types::code_action_kind::REFACTOR_REWRITE.to_string(),
58 lsp_types::code_action_kind::SOURCE.to_string(),
59 lsp_types::code_action_kind::SOURCE_ORGANIZE_IMPORTS.to_string(),
60 ]),
61 work_done_progress_options: Default::default(),
62 })),
63 code_lens_provider: Some(CodeLensOptions { resolve_provider: Some(true) }), 53 code_lens_provider: Some(CodeLensOptions { resolve_provider: Some(true) }),
64 document_formatting_provider: Some(true), 54 document_formatting_provider: Some(true),
65 document_range_formatting_provider: None, 55 document_range_formatting_provider: None,
@@ -98,3 +88,29 @@ pub fn server_capabilities() -> ServerCapabilities {
98 })), 88 })),
99 } 89 }
100} 90}
91
92fn code_action_capabilities(client_caps: &ClientCapabilities) -> CodeActionProviderCapability {
93 client_caps
94 .text_document
95 .as_ref()
96 .and_then(|it| it.code_action.as_ref())
97 .and_then(|it| it.code_action_literal_support.as_ref())
98 .map_or(CodeActionProviderCapability::Simple(true), |_| {
99 CodeActionProviderCapability::Options(CodeActionOptions {
100 // Advertise support for all built-in CodeActionKinds.
101 // Ideally we would base this off of the client capabilities
102 // but the client is supposed to fall back gracefully for unknown values.
103 code_action_kinds: Some(vec![
104 lsp_types::code_action_kind::EMPTY.to_string(),
105 lsp_types::code_action_kind::QUICKFIX.to_string(),
106 lsp_types::code_action_kind::REFACTOR.to_string(),
107 lsp_types::code_action_kind::REFACTOR_EXTRACT.to_string(),
108 lsp_types::code_action_kind::REFACTOR_INLINE.to_string(),
109 lsp_types::code_action_kind::REFACTOR_REWRITE.to_string(),
110 lsp_types::code_action_kind::SOURCE.to_string(),
111 lsp_types::code_action_kind::SOURCE_ORGANIZE_IMPORTS.to_string(),
112 ]),
113 work_done_progress_options: Default::default(),
114 })
115 })
116}