diff options
Diffstat (limited to 'crates')
42 files changed, 675 insertions, 420 deletions
diff --git a/crates/ra_assists/src/assists/add_explicit_type.rs b/crates/ra_assists/src/assists/add_explicit_type.rs index 562a09685..eeb4ff39f 100644 --- a/crates/ra_assists/src/assists/add_explicit_type.rs +++ b/crates/ra_assists/src/assists/add_explicit_type.rs | |||
@@ -1,4 +1,4 @@ | |||
1 | use hir::{db::HirDatabase, HirDisplay, Ty}; | 1 | use hir::{db::HirDatabase, HirDisplay}; |
2 | use ra_syntax::{ | 2 | use ra_syntax::{ |
3 | ast::{self, AstNode, LetStmt, NameOwner}, | 3 | ast::{self, AstNode, LetStmt, NameOwner}, |
4 | T, | 4 | T, |
@@ -43,7 +43,7 @@ pub(crate) fn add_explicit_type(ctx: AssistCtx<impl HirDatabase>) -> Option<Assi | |||
43 | let analyzer = ctx.source_analyzer(stmt.syntax(), None); | 43 | let analyzer = ctx.source_analyzer(stmt.syntax(), None); |
44 | let ty = analyzer.type_of(db, &expr)?; | 44 | let ty = analyzer.type_of(db, &expr)?; |
45 | // Assist not applicable if the type is unknown | 45 | // Assist not applicable if the type is unknown |
46 | if is_unknown(&ty) { | 46 | if ty.contains_unknown() { |
47 | return None; | 47 | return None; |
48 | } | 48 | } |
49 | 49 | ||
@@ -53,15 +53,6 @@ pub(crate) fn add_explicit_type(ctx: AssistCtx<impl HirDatabase>) -> Option<Assi | |||
53 | }) | 53 | }) |
54 | } | 54 | } |
55 | 55 | ||
56 | /// Returns true if any type parameter is unknown | ||
57 | fn is_unknown(ty: &Ty) -> bool { | ||
58 | match ty { | ||
59 | Ty::Unknown => true, | ||
60 | Ty::Apply(a_ty) => a_ty.parameters.iter().any(is_unknown), | ||
61 | _ => false, | ||
62 | } | ||
63 | } | ||
64 | |||
65 | #[cfg(test)] | 56 | #[cfg(test)] |
66 | mod tests { | 57 | mod tests { |
67 | use super::*; | 58 | use super::*; |
diff --git a/crates/ra_assists/src/assists/fill_match_arms.rs b/crates/ra_assists/src/assists/fill_match_arms.rs index 8482897c5..b75bd44eb 100644 --- a/crates/ra_assists/src/assists/fill_match_arms.rs +++ b/crates/ra_assists/src/assists/fill_match_arms.rs | |||
@@ -83,10 +83,11 @@ fn resolve_enum_def( | |||
83 | ) -> Option<ast::EnumDef> { | 83 | ) -> Option<ast::EnumDef> { |
84 | let expr_ty = analyzer.type_of(db, &expr)?; | 84 | let expr_ty = analyzer.type_of(db, &expr)?; |
85 | 85 | ||
86 | analyzer.autoderef(db, expr_ty).find_map(|ty| match ty.as_adt() { | 86 | let res = expr_ty.autoderef(db).find_map(|ty| match ty.as_adt() { |
87 | Some((Adt::Enum(e), _)) => Some(e.source(db).value), | 87 | Some(Adt::Enum(e)) => Some(e.source(db).value), |
88 | _ => None, | 88 | _ => None, |
89 | }) | 89 | }); |
90 | res | ||
90 | } | 91 | } |
91 | 92 | ||
92 | fn build_pat(var: ast::EnumVariant) -> Option<ast::Pat> { | 93 | fn build_pat(var: ast::EnumVariant) -> Option<ast::Pat> { |
diff --git a/crates/ra_assists/src/test_db.rs b/crates/ra_assists/src/test_db.rs index 5f96c974b..523259fd4 100644 --- a/crates/ra_assists/src/test_db.rs +++ b/crates/ra_assists/src/test_db.rs | |||
@@ -21,6 +21,9 @@ impl salsa::Database for TestDB { | |||
21 | fn salsa_runtime(&self) -> &salsa::Runtime<Self> { | 21 | fn salsa_runtime(&self) -> &salsa::Runtime<Self> { |
22 | &self.runtime | 22 | &self.runtime |
23 | } | 23 | } |
24 | fn salsa_runtime_mut(&mut self) -> &mut salsa::Runtime<Self> { | ||
25 | &mut self.runtime | ||
26 | } | ||
24 | } | 27 | } |
25 | 28 | ||
26 | impl std::panic::RefUnwindSafe for TestDB {} | 29 | impl std::panic::RefUnwindSafe for TestDB {} |
diff --git a/crates/ra_cli/src/analysis_bench.rs b/crates/ra_cli/src/analysis_bench.rs index 8bbe5d9e8..34105af57 100644 --- a/crates/ra_cli/src/analysis_bench.rs +++ b/crates/ra_cli/src/analysis_bench.rs | |||
@@ -91,7 +91,7 @@ fn do_work<F: Fn(&Analysis) -> T, T>(host: &mut AnalysisHost, file_id: FileId, w | |||
91 | { | 91 | { |
92 | let start = Instant::now(); | 92 | let start = Instant::now(); |
93 | eprint!("trivial change: "); | 93 | eprint!("trivial change: "); |
94 | host.raw_database().salsa_runtime().synthetic_write(Durability::LOW); | 94 | host.raw_database_mut().salsa_runtime_mut().synthetic_write(Durability::LOW); |
95 | work(&host.analysis()); | 95 | work(&host.analysis()); |
96 | eprintln!("{:?}", start.elapsed()); | 96 | eprintln!("{:?}", start.elapsed()); |
97 | } | 97 | } |
@@ -111,7 +111,7 @@ fn do_work<F: Fn(&Analysis) -> T, T>(host: &mut AnalysisHost, file_id: FileId, w | |||
111 | { | 111 | { |
112 | let start = Instant::now(); | 112 | let start = Instant::now(); |
113 | eprint!("const change: "); | 113 | eprint!("const change: "); |
114 | host.raw_database().salsa_runtime().synthetic_write(Durability::HIGH); | 114 | host.raw_database_mut().salsa_runtime_mut().synthetic_write(Durability::HIGH); |
115 | let res = work(&host.analysis()); | 115 | let res = work(&host.analysis()); |
116 | eprintln!("{:?}", start.elapsed()); | 116 | eprintln!("{:?}", start.elapsed()); |
117 | res | 117 | res |
diff --git a/crates/ra_db/Cargo.toml b/crates/ra_db/Cargo.toml index 4ec09b6d9..7afa5d8fc 100644 --- a/crates/ra_db/Cargo.toml +++ b/crates/ra_db/Cargo.toml | |||
@@ -8,7 +8,7 @@ authors = ["rust-analyzer developers"] | |||
8 | doctest = false | 8 | doctest = false |
9 | 9 | ||
10 | [dependencies] | 10 | [dependencies] |
11 | salsa = "0.13.0" | 11 | salsa = "0.14.1" |
12 | relative-path = "1.0.0" | 12 | relative-path = "1.0.0" |
13 | rustc-hash = "1.0" | 13 | rustc-hash = "1.0" |
14 | 14 | ||
diff --git a/crates/ra_hir/Cargo.toml b/crates/ra_hir/Cargo.toml index 42ddfecc9..caba85a4f 100644 --- a/crates/ra_hir/Cargo.toml +++ b/crates/ra_hir/Cargo.toml | |||
@@ -11,7 +11,7 @@ doctest = false | |||
11 | arrayvec = "0.5.1" | 11 | arrayvec = "0.5.1" |
12 | log = "0.4.5" | 12 | log = "0.4.5" |
13 | rustc-hash = "1.0" | 13 | rustc-hash = "1.0" |
14 | parking_lot = "0.9.0" | 14 | parking_lot = "0.10.0" |
15 | ena = "0.13" | 15 | ena = "0.13" |
16 | once_cell = "1.0.1" | 16 | once_cell = "1.0.1" |
17 | 17 | ||
@@ -23,12 +23,15 @@ mbe = { path = "../ra_mbe", package = "ra_mbe" } | |||
23 | tt = { path = "../ra_tt", package = "ra_tt" } | 23 | tt = { path = "../ra_tt", package = "ra_tt" } |
24 | hir_expand = { path = "../ra_hir_expand", package = "ra_hir_expand" } | 24 | hir_expand = { path = "../ra_hir_expand", package = "ra_hir_expand" } |
25 | hir_def = { path = "../ra_hir_def", package = "ra_hir_def" } | 25 | hir_def = { path = "../ra_hir_def", package = "ra_hir_def" } |
26 | hir_ty = { path = "../ra_hir_ty", package = "ra_hir_ty" } | ||
26 | test_utils = { path = "../test_utils" } | 27 | test_utils = { path = "../test_utils" } |
27 | ra_prof = { path = "../ra_prof" } | 28 | ra_prof = { path = "../ra_prof" } |
28 | 29 | ||
29 | chalk-solve = { git = "https://github.com/rust-lang/chalk.git", rev = "a88cad7f0a69e05ba8f40b74c58a1c229c1b2478" } | 30 | # https://github.com/rust-lang/chalk/pull/294 |
30 | chalk-rust-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "a88cad7f0a69e05ba8f40b74c58a1c229c1b2478" } | 31 | chalk-solve = { git = "https://github.com/jackh726/chalk.git", rev = "095cd38a4f16337913bba487f2055b9ca0179f30" } |
31 | chalk-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "a88cad7f0a69e05ba8f40b74c58a1c229c1b2478" } | 32 | chalk-rust-ir = { git = "https://github.com/jackh726/chalk.git", rev = "095cd38a4f16337913bba487f2055b9ca0179f30" } |
33 | chalk-ir = { git = "https://github.com/jackh726/chalk.git", rev = "095cd38a4f16337913bba487f2055b9ca0179f30" } | ||
34 | |||
32 | lalrpop-intern = "0.15.1" | 35 | lalrpop-intern = "0.15.1" |
33 | 36 | ||
34 | [dev-dependencies] | 37 | [dev-dependencies] |
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index f7fc80d4e..821f919d4 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs | |||
@@ -10,10 +10,10 @@ use hir_def::{ | |||
10 | docs::Documentation, | 10 | docs::Documentation, |
11 | per_ns::PerNs, | 11 | per_ns::PerNs, |
12 | resolver::{HasResolver, TypeNs}, | 12 | resolver::{HasResolver, TypeNs}, |
13 | type_ref::TypeRef, | 13 | type_ref::{Mutability, TypeRef}, |
14 | AstItemDef, ConstId, ContainerId, EnumId, FunctionId, GenericDefId, HasModule, ImplId, | 14 | AdtId, AstItemDef, ConstId, ContainerId, DefWithBodyId, EnumId, FunctionId, GenericDefId, |
15 | LocalEnumVariantId, LocalImportId, LocalModuleId, LocalStructFieldId, Lookup, ModuleId, | 15 | HasModule, ImplId, LocalEnumVariantId, LocalImportId, LocalModuleId, LocalStructFieldId, |
16 | StaticId, StructId, TraitId, TypeAliasId, UnionId, | 16 | Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId, UnionId, |
17 | }; | 17 | }; |
18 | use hir_expand::{ | 18 | use hir_expand::{ |
19 | diagnostics::DiagnosticSink, | 19 | diagnostics::DiagnosticSink, |
@@ -26,8 +26,12 @@ use ra_syntax::{ast, AstNode, SyntaxNode}; | |||
26 | use crate::{ | 26 | use crate::{ |
27 | db::{DefDatabase, HirDatabase}, | 27 | db::{DefDatabase, HirDatabase}, |
28 | expr::{BindingAnnotation, Body, BodySourceMap, ExprValidator, Pat, PatId}, | 28 | expr::{BindingAnnotation, Body, BodySourceMap, ExprValidator, Pat, PatId}, |
29 | ty::{InferenceResult, Namespace, TraitRef}, | 29 | ty::display::HirFormatter, |
30 | Either, Name, Source, Ty, | 30 | ty::{ |
31 | self, InEnvironment, InferenceResult, Namespace, TraitEnvironment, TraitRef, Ty, TypeCtor, | ||
32 | TypeWalk, | ||
33 | }, | ||
34 | CallableDef, Either, HirDisplay, Name, Source, | ||
31 | }; | 35 | }; |
32 | 36 | ||
33 | /// hir::Crate describes a single crate. It's the main interface with which | 37 | /// hir::Crate describes a single crate. It's the main interface with which |
@@ -379,6 +383,28 @@ impl Union { | |||
379 | pub fn ty(self, db: &impl HirDatabase) -> Ty { | 383 | pub fn ty(self, db: &impl HirDatabase) -> Ty { |
380 | db.type_for_def(self.into(), Namespace::Types) | 384 | db.type_for_def(self.into(), Namespace::Types) |
381 | } | 385 | } |
386 | |||
387 | pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> { | ||
388 | db.union_data(self.id) | ||
389 | .variant_data | ||
390 | .fields() | ||
391 | .iter() | ||
392 | .map(|(id, _)| StructField { parent: self.into(), id }) | ||
393 | .collect() | ||
394 | } | ||
395 | |||
396 | pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> { | ||
397 | db.union_data(self.id) | ||
398 | .variant_data | ||
399 | .fields() | ||
400 | .iter() | ||
401 | .find(|(_id, data)| data.name == *name) | ||
402 | .map(|(id, _)| StructField { parent: self.into(), id }) | ||
403 | } | ||
404 | |||
405 | fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> { | ||
406 | db.union_data(self.id).variant_data.clone() | ||
407 | } | ||
382 | } | 408 | } |
383 | 409 | ||
384 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 410 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
@@ -469,6 +495,10 @@ pub enum Adt { | |||
469 | impl_froms!(Adt: Struct, Union, Enum); | 495 | impl_froms!(Adt: Struct, Union, Enum); |
470 | 496 | ||
471 | impl Adt { | 497 | impl Adt { |
498 | pub fn has_non_default_type_params(self, db: &impl HirDatabase) -> bool { | ||
499 | let subst = db.generic_defaults(self.into()); | ||
500 | subst.iter().any(|ty| ty == &Ty::Unknown) | ||
501 | } | ||
472 | pub fn ty(self, db: &impl HirDatabase) -> Ty { | 502 | pub fn ty(self, db: &impl HirDatabase) -> Ty { |
473 | match self { | 503 | match self { |
474 | Adt::Struct(it) => it.ty(db), | 504 | Adt::Struct(it) => it.ty(db), |
@@ -493,14 +523,16 @@ impl Adt { | |||
493 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | 523 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] |
494 | pub enum VariantDef { | 524 | pub enum VariantDef { |
495 | Struct(Struct), | 525 | Struct(Struct), |
526 | Union(Union), | ||
496 | EnumVariant(EnumVariant), | 527 | EnumVariant(EnumVariant), |
497 | } | 528 | } |
498 | impl_froms!(VariantDef: Struct, EnumVariant); | 529 | impl_froms!(VariantDef: Struct, Union, EnumVariant); |
499 | 530 | ||
500 | impl VariantDef { | 531 | impl VariantDef { |
501 | pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> { | 532 | pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> { |
502 | match self { | 533 | match self { |
503 | VariantDef::Struct(it) => it.fields(db), | 534 | VariantDef::Struct(it) => it.fields(db), |
535 | VariantDef::Union(it) => it.fields(db), | ||
504 | VariantDef::EnumVariant(it) => it.fields(db), | 536 | VariantDef::EnumVariant(it) => it.fields(db), |
505 | } | 537 | } |
506 | } | 538 | } |
@@ -508,6 +540,7 @@ impl VariantDef { | |||
508 | pub(crate) fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> { | 540 | pub(crate) fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> { |
509 | match self { | 541 | match self { |
510 | VariantDef::Struct(it) => it.field(db, name), | 542 | VariantDef::Struct(it) => it.field(db, name), |
543 | VariantDef::Union(it) => it.field(db, name), | ||
511 | VariantDef::EnumVariant(it) => it.field(db, name), | 544 | VariantDef::EnumVariant(it) => it.field(db, name), |
512 | } | 545 | } |
513 | } | 546 | } |
@@ -515,6 +548,7 @@ impl VariantDef { | |||
515 | pub fn module(self, db: &impl HirDatabase) -> Module { | 548 | pub fn module(self, db: &impl HirDatabase) -> Module { |
516 | match self { | 549 | match self { |
517 | VariantDef::Struct(it) => it.module(db), | 550 | VariantDef::Struct(it) => it.module(db), |
551 | VariantDef::Union(it) => it.module(db), | ||
518 | VariantDef::EnumVariant(it) => it.module(db), | 552 | VariantDef::EnumVariant(it) => it.module(db), |
519 | } | 553 | } |
520 | } | 554 | } |
@@ -522,6 +556,7 @@ impl VariantDef { | |||
522 | pub(crate) fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> { | 556 | pub(crate) fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> { |
523 | match self { | 557 | match self { |
524 | VariantDef::Struct(it) => it.variant_data(db), | 558 | VariantDef::Struct(it) => it.variant_data(db), |
559 | VariantDef::Union(it) => it.variant_data(db), | ||
525 | VariantDef::EnumVariant(it) => it.variant_data(db), | 560 | VariantDef::EnumVariant(it) => it.variant_data(db), |
526 | } | 561 | } |
527 | } | 562 | } |
@@ -777,6 +812,11 @@ pub struct TypeAlias { | |||
777 | } | 812 | } |
778 | 813 | ||
779 | impl TypeAlias { | 814 | impl TypeAlias { |
815 | pub fn has_non_default_type_params(self, db: &impl HirDatabase) -> bool { | ||
816 | let subst = db.generic_defaults(self.id.into()); | ||
817 | subst.iter().any(|ty| ty == &Ty::Unknown) | ||
818 | } | ||
819 | |||
780 | pub fn module(self, db: &impl DefDatabase) -> Module { | 820 | pub fn module(self, db: &impl DefDatabase) -> Module { |
781 | Module { id: self.id.lookup(db).module(db) } | 821 | Module { id: self.id.lookup(db).module(db) } |
782 | } | 822 | } |
@@ -927,9 +967,14 @@ impl Local { | |||
927 | self.parent.module(db) | 967 | self.parent.module(db) |
928 | } | 968 | } |
929 | 969 | ||
930 | pub fn ty(self, db: &impl HirDatabase) -> Ty { | 970 | pub fn ty(self, db: &impl HirDatabase) -> Type { |
931 | let infer = db.infer(self.parent); | 971 | let infer = db.infer(self.parent); |
932 | infer[self.pat_id].clone() | 972 | let ty = infer[self.pat_id].clone(); |
973 | let def = DefWithBodyId::from(self.parent); | ||
974 | let resolver = def.resolver(db); | ||
975 | let krate = def.module(db).krate; | ||
976 | let environment = TraitEnvironment::lower(db, &resolver); | ||
977 | Type { krate, ty: InEnvironment { value: ty, environment } } | ||
933 | } | 978 | } |
934 | 979 | ||
935 | pub fn source(self, db: &impl HirDatabase) -> Source<Either<ast::BindPat, ast::SelfParam>> { | 980 | pub fn source(self, db: &impl HirDatabase) -> Source<Either<ast::BindPat, ast::SelfParam>> { |
@@ -952,6 +997,15 @@ pub struct ImplBlock { | |||
952 | } | 997 | } |
953 | 998 | ||
954 | impl ImplBlock { | 999 | impl ImplBlock { |
1000 | pub fn all_in_crate(db: &impl HirDatabase, krate: Crate) -> Vec<ImplBlock> { | ||
1001 | let impls = db.impls_in_crate(krate.crate_id); | ||
1002 | impls.all_impls().map(Self::from).collect() | ||
1003 | } | ||
1004 | pub fn for_trait(db: &impl HirDatabase, krate: Crate, trait_: Trait) -> Vec<ImplBlock> { | ||
1005 | let impls = db.impls_in_crate(krate.crate_id); | ||
1006 | impls.lookup_impl_blocks_for_trait(trait_).map(Self::from).collect() | ||
1007 | } | ||
1008 | |||
955 | pub fn target_trait(&self, db: &impl DefDatabase) -> Option<TypeRef> { | 1009 | pub fn target_trait(&self, db: &impl DefDatabase) -> Option<TypeRef> { |
956 | db.impl_data(self.id).target_trait.clone() | 1010 | db.impl_data(self.id).target_trait.clone() |
957 | } | 1011 | } |
@@ -986,6 +1040,145 @@ impl ImplBlock { | |||
986 | } | 1040 | } |
987 | } | 1041 | } |
988 | 1042 | ||
1043 | #[derive(Clone, PartialEq, Eq)] | ||
1044 | pub struct Type { | ||
1045 | pub(crate) krate: CrateId, | ||
1046 | pub(crate) ty: InEnvironment<Ty>, | ||
1047 | } | ||
1048 | |||
1049 | impl Type { | ||
1050 | pub fn is_bool(&self) -> bool { | ||
1051 | match &self.ty.value { | ||
1052 | Ty::Apply(a_ty) => match a_ty.ctor { | ||
1053 | TypeCtor::Bool => true, | ||
1054 | _ => false, | ||
1055 | }, | ||
1056 | _ => false, | ||
1057 | } | ||
1058 | } | ||
1059 | |||
1060 | pub fn is_mutable_reference(&self) -> bool { | ||
1061 | match &self.ty.value { | ||
1062 | Ty::Apply(a_ty) => match a_ty.ctor { | ||
1063 | TypeCtor::Ref(Mutability::Mut) => true, | ||
1064 | _ => false, | ||
1065 | }, | ||
1066 | _ => false, | ||
1067 | } | ||
1068 | } | ||
1069 | |||
1070 | pub fn is_unknown(&self) -> bool { | ||
1071 | match &self.ty.value { | ||
1072 | Ty::Unknown => true, | ||
1073 | _ => false, | ||
1074 | } | ||
1075 | } | ||
1076 | |||
1077 | // FIXME: this method is broken, as it doesn't take closures into account. | ||
1078 | pub fn as_callable(&self) -> Option<CallableDef> { | ||
1079 | Some(self.ty.value.as_callable()?.0) | ||
1080 | } | ||
1081 | |||
1082 | pub fn contains_unknown(&self) -> bool { | ||
1083 | return go(&self.ty.value); | ||
1084 | |||
1085 | fn go(ty: &Ty) -> bool { | ||
1086 | match ty { | ||
1087 | Ty::Unknown => true, | ||
1088 | Ty::Apply(a_ty) => a_ty.parameters.iter().any(go), | ||
1089 | _ => false, | ||
1090 | } | ||
1091 | } | ||
1092 | } | ||
1093 | |||
1094 | pub fn fields(&self, db: &impl HirDatabase) -> Vec<(StructField, Type)> { | ||
1095 | if let Ty::Apply(a_ty) = &self.ty.value { | ||
1096 | match a_ty.ctor { | ||
1097 | ty::TypeCtor::Adt(AdtId::StructId(s)) => { | ||
1098 | let var_def = s.into(); | ||
1099 | return db | ||
1100 | .field_types(var_def) | ||
1101 | .iter() | ||
1102 | .map(|(local_id, ty)| { | ||
1103 | let def = StructField { parent: var_def.into(), id: local_id }; | ||
1104 | let ty = ty.clone().subst(&a_ty.parameters); | ||
1105 | (def, self.derived(ty)) | ||
1106 | }) | ||
1107 | .collect(); | ||
1108 | } | ||
1109 | _ => {} | ||
1110 | } | ||
1111 | }; | ||
1112 | Vec::new() | ||
1113 | } | ||
1114 | |||
1115 | pub fn tuple_fields(&self, _db: &impl HirDatabase) -> Vec<Type> { | ||
1116 | let mut res = Vec::new(); | ||
1117 | if let Ty::Apply(a_ty) = &self.ty.value { | ||
1118 | match a_ty.ctor { | ||
1119 | ty::TypeCtor::Tuple { .. } => { | ||
1120 | for ty in a_ty.parameters.iter() { | ||
1121 | let ty = ty.clone().subst(&a_ty.parameters); | ||
1122 | res.push(self.derived(ty)); | ||
1123 | } | ||
1124 | } | ||
1125 | _ => {} | ||
1126 | } | ||
1127 | }; | ||
1128 | res | ||
1129 | } | ||
1130 | |||
1131 | pub fn variant_fields( | ||
1132 | &self, | ||
1133 | db: &impl HirDatabase, | ||
1134 | def: VariantDef, | ||
1135 | ) -> Vec<(StructField, Type)> { | ||
1136 | // FIXME: check that ty and def match | ||
1137 | match &self.ty.value { | ||
1138 | Ty::Apply(a_ty) => def | ||
1139 | .fields(db) | ||
1140 | .into_iter() | ||
1141 | .map(|it| (it, self.derived(it.ty(db).subst(&a_ty.parameters)))) | ||
1142 | .collect(), | ||
1143 | _ => Vec::new(), | ||
1144 | } | ||
1145 | } | ||
1146 | |||
1147 | pub fn autoderef<'a>(&'a self, db: &'a impl HirDatabase) -> impl Iterator<Item = Type> + 'a { | ||
1148 | // There should be no inference vars in types passed here | ||
1149 | // FIXME check that? | ||
1150 | let canonical = crate::ty::Canonical { value: self.ty.value.clone(), num_vars: 0 }; | ||
1151 | let environment = self.ty.environment.clone(); | ||
1152 | let ty = InEnvironment { value: canonical, environment: environment.clone() }; | ||
1153 | ty::autoderef(db, Some(self.krate), ty) | ||
1154 | .map(|canonical| canonical.value) | ||
1155 | .map(move |ty| self.derived(ty)) | ||
1156 | } | ||
1157 | |||
1158 | // FIXME: remove | ||
1159 | pub fn into_ty(self) -> Ty { | ||
1160 | self.ty.value | ||
1161 | } | ||
1162 | |||
1163 | pub fn as_adt(&self) -> Option<Adt> { | ||
1164 | let (adt, _subst) = self.ty.value.as_adt()?; | ||
1165 | Some(adt) | ||
1166 | } | ||
1167 | |||
1168 | fn derived(&self, ty: Ty) -> Type { | ||
1169 | Type { | ||
1170 | krate: self.krate, | ||
1171 | ty: InEnvironment { value: ty, environment: self.ty.environment.clone() }, | ||
1172 | } | ||
1173 | } | ||
1174 | } | ||
1175 | |||
1176 | impl HirDisplay for Type { | ||
1177 | fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> std::fmt::Result { | ||
1178 | self.ty.value.hir_fmt(f) | ||
1179 | } | ||
1180 | } | ||
1181 | |||
989 | /// For IDE only | 1182 | /// For IDE only |
990 | pub enum ScopeDef { | 1183 | pub enum ScopeDef { |
991 | ModuleDef(ModuleDef), | 1184 | ModuleDef(ModuleDef), |
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index b034d4e44..32f05a4d8 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs | |||
@@ -3,7 +3,7 @@ | |||
3 | use std::sync::Arc; | 3 | use std::sync::Arc; |
4 | 4 | ||
5 | use ra_arena::map::ArenaMap; | 5 | use ra_arena::map::ArenaMap; |
6 | use ra_db::salsa; | 6 | use ra_db::{salsa, CrateId}; |
7 | 7 | ||
8 | use crate::{ | 8 | use crate::{ |
9 | ty::{ | 9 | ty::{ |
@@ -60,7 +60,7 @@ pub trait HirDatabase: DefDatabase { | |||
60 | fn generic_defaults(&self, def: GenericDefId) -> Substs; | 60 | fn generic_defaults(&self, def: GenericDefId) -> Substs; |
61 | 61 | ||
62 | #[salsa::invoke(crate::ty::method_resolution::CrateImplBlocks::impls_in_crate_query)] | 62 | #[salsa::invoke(crate::ty::method_resolution::CrateImplBlocks::impls_in_crate_query)] |
63 | fn impls_in_crate(&self, krate: Crate) -> Arc<CrateImplBlocks>; | 63 | fn impls_in_crate(&self, krate: CrateId) -> Arc<CrateImplBlocks>; |
64 | 64 | ||
65 | #[salsa::invoke(crate::ty::traits::impls_for_trait_query)] | 65 | #[salsa::invoke(crate::ty::traits::impls_for_trait_query)] |
66 | fn impls_for_trait(&self, krate: Crate, trait_: Trait) -> Arc<[ImplBlock]>; | 66 | fn impls_for_trait(&self, krate: Crate, trait_: Trait) -> Arc<[ImplBlock]>; |
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index 43fedde7a..adb9805ab 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs | |||
@@ -2,7 +2,7 @@ | |||
2 | 2 | ||
3 | use std::sync::Arc; | 3 | use std::sync::Arc; |
4 | 4 | ||
5 | use hir_def::{path::known, resolver::HasResolver}; | 5 | use hir_def::{path::known, resolver::HasResolver, AdtId}; |
6 | use hir_expand::diagnostics::DiagnosticSink; | 6 | use hir_expand::diagnostics::DiagnosticSink; |
7 | use ra_syntax::ast; | 7 | use ra_syntax::ast; |
8 | use ra_syntax::AstPtr; | 8 | use ra_syntax::AstPtr; |
@@ -127,7 +127,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> { | |||
127 | _ => return, | 127 | _ => return, |
128 | }; | 128 | }; |
129 | 129 | ||
130 | let std_result_ctor = TypeCtor::Adt(Adt::Enum(std_result_enum.into())); | 130 | let std_result_ctor = TypeCtor::Adt(AdtId::EnumId(std_result_enum)); |
131 | let params = match &mismatch.expected { | 131 | let params = match &mismatch.expected { |
132 | Ty::Apply(ApplicationTy { ctor, parameters }) if ctor == &std_result_ctor => parameters, | 132 | Ty::Apply(ApplicationTy { ctor, parameters }) if ctor == &std_result_ctor => parameters, |
133 | _ => return, | 133 | _ => return, |
diff --git a/crates/ra_hir/src/from_id.rs b/crates/ra_hir/src/from_id.rs index 619f6055e..38daa5e59 100644 --- a/crates/ra_hir/src/from_id.rs +++ b/crates/ra_hir/src/from_id.rs | |||
@@ -199,11 +199,22 @@ impl From<Adt> for GenericDefId { | |||
199 | } | 199 | } |
200 | } | 200 | } |
201 | 201 | ||
202 | impl From<VariantId> for VariantDef { | ||
203 | fn from(def: VariantId) -> Self { | ||
204 | match def { | ||
205 | VariantId::StructId(it) => VariantDef::Struct(it.into()), | ||
206 | VariantId::EnumVariantId(it) => VariantDef::EnumVariant(it.into()), | ||
207 | VariantId::UnionId(it) => VariantDef::Union(it.into()), | ||
208 | } | ||
209 | } | ||
210 | } | ||
211 | |||
202 | impl From<VariantDef> for VariantId { | 212 | impl From<VariantDef> for VariantId { |
203 | fn from(def: VariantDef) -> Self { | 213 | fn from(def: VariantDef) -> Self { |
204 | match def { | 214 | match def { |
205 | VariantDef::Struct(it) => VariantId::StructId(it.id), | 215 | VariantDef::Struct(it) => VariantId::StructId(it.id), |
206 | VariantDef::EnumVariant(it) => VariantId::EnumVariantId(it.into()), | 216 | VariantDef::EnumVariant(it) => VariantId::EnumVariantId(it.into()), |
217 | VariantDef::Union(it) => VariantId::UnionId(it.id), | ||
207 | } | 218 | } |
208 | } | 219 | } |
209 | } | 220 | } |
@@ -214,6 +225,12 @@ impl From<StructField> for StructFieldId { | |||
214 | } | 225 | } |
215 | } | 226 | } |
216 | 227 | ||
228 | impl From<StructFieldId> for StructField { | ||
229 | fn from(def: StructFieldId) -> Self { | ||
230 | StructField { parent: def.parent.into(), id: def.local_id } | ||
231 | } | ||
232 | } | ||
233 | |||
217 | impl From<AttrDef> for AttrDefId { | 234 | impl From<AttrDef> for AttrDefId { |
218 | fn from(def: AttrDef) -> Self { | 235 | fn from(def: AttrDef) -> Self { |
219 | match def { | 236 | match def { |
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index 843ce6a88..b88e4c745 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs | |||
@@ -51,7 +51,7 @@ pub use crate::{ | |||
51 | src::HasSource, Adt, AssocItem, AttrDef, Const, Container, Crate, CrateDependency, | 51 | src::HasSource, Adt, AssocItem, AttrDef, Const, Container, Crate, CrateDependency, |
52 | DefWithBody, Docs, Enum, EnumVariant, FieldSource, Function, GenericDef, GenericParam, | 52 | DefWithBody, Docs, Enum, EnumVariant, FieldSource, Function, GenericDef, GenericParam, |
53 | HasAttrs, ImplBlock, Import, Local, MacroDef, Module, ModuleDef, ModuleSource, ScopeDef, | 53 | HasAttrs, ImplBlock, Import, Local, MacroDef, Module, ModuleDef, ModuleSource, ScopeDef, |
54 | Static, Struct, StructField, Trait, TypeAlias, Union, VariantDef, | 54 | Static, Struct, StructField, Trait, Type, TypeAlias, Union, VariantDef, |
55 | }, | 55 | }, |
56 | expr::ExprScopes, | 56 | expr::ExprScopes, |
57 | from_source::FromSource, | 57 | from_source::FromSource, |
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 144e144bb..82cb66583 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -29,10 +29,10 @@ use crate::{ | |||
29 | expr::{BodySourceMap, ExprScopes, ScopeId}, | 29 | expr::{BodySourceMap, ExprScopes, ScopeId}, |
30 | ty::{ | 30 | ty::{ |
31 | method_resolution::{self, implements_trait}, | 31 | method_resolution::{self, implements_trait}, |
32 | TraitEnvironment, | 32 | InEnvironment, TraitEnvironment, Ty, |
33 | }, | 33 | }, |
34 | Adt, AssocItem, Const, DefWithBody, Either, Enum, EnumVariant, FromSource, Function, | 34 | Adt, AssocItem, Const, DefWithBody, Either, Enum, EnumVariant, FromSource, Function, |
35 | GenericParam, Local, MacroDef, Name, Path, ScopeDef, Static, Struct, Trait, Ty, TypeAlias, | 35 | GenericParam, Local, MacroDef, Name, Path, ScopeDef, Static, Struct, Trait, Type, TypeAlias, |
36 | }; | 36 | }; |
37 | 37 | ||
38 | fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) -> Option<Resolver> { | 38 | fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) -> Option<Resolver> { |
@@ -199,14 +199,18 @@ impl SourceAnalyzer { | |||
199 | self.body_source_map.as_ref()?.node_pat(src) | 199 | self.body_source_map.as_ref()?.node_pat(src) |
200 | } | 200 | } |
201 | 201 | ||
202 | pub fn type_of(&self, _db: &impl HirDatabase, expr: &ast::Expr) -> Option<crate::Ty> { | 202 | pub fn type_of(&self, db: &impl HirDatabase, expr: &ast::Expr) -> Option<Type> { |
203 | let expr_id = self.expr_id(expr)?; | 203 | let expr_id = self.expr_id(expr)?; |
204 | Some(self.infer.as_ref()?[expr_id].clone()) | 204 | let ty = self.infer.as_ref()?[expr_id].clone(); |
205 | let environment = TraitEnvironment::lower(db, &self.resolver); | ||
206 | Some(Type { krate: self.resolver.krate()?, ty: InEnvironment { value: ty, environment } }) | ||
205 | } | 207 | } |
206 | 208 | ||
207 | pub fn type_of_pat(&self, _db: &impl HirDatabase, pat: &ast::Pat) -> Option<crate::Ty> { | 209 | pub fn type_of_pat(&self, db: &impl HirDatabase, pat: &ast::Pat) -> Option<Type> { |
208 | let pat_id = self.pat_id(pat)?; | 210 | let pat_id = self.pat_id(pat)?; |
209 | Some(self.infer.as_ref()?[pat_id].clone()) | 211 | let ty = self.infer.as_ref()?[pat_id].clone(); |
212 | let environment = TraitEnvironment::lower(db, &self.resolver); | ||
213 | Some(Type { krate: self.resolver.krate()?, ty: InEnvironment { value: ty, environment } }) | ||
210 | } | 214 | } |
211 | 215 | ||
212 | pub fn resolve_method_call(&self, call: &ast::MethodCallExpr) -> Option<Function> { | 216 | pub fn resolve_method_call(&self, call: &ast::MethodCallExpr) -> Option<Function> { |
@@ -362,14 +366,14 @@ impl SourceAnalyzer { | |||
362 | pub fn iterate_method_candidates<T>( | 366 | pub fn iterate_method_candidates<T>( |
363 | &self, | 367 | &self, |
364 | db: &impl HirDatabase, | 368 | db: &impl HirDatabase, |
365 | ty: Ty, | 369 | ty: &Type, |
366 | name: Option<&Name>, | 370 | name: Option<&Name>, |
367 | mut callback: impl FnMut(&Ty, Function) -> Option<T>, | 371 | mut callback: impl FnMut(&Ty, Function) -> Option<T>, |
368 | ) -> Option<T> { | 372 | ) -> Option<T> { |
369 | // There should be no inference vars in types passed here | 373 | // There should be no inference vars in types passed here |
370 | // FIXME check that? | 374 | // FIXME check that? |
371 | // FIXME replace Unknown by bound vars here | 375 | // FIXME replace Unknown by bound vars here |
372 | let canonical = crate::ty::Canonical { value: ty, num_vars: 0 }; | 376 | let canonical = crate::ty::Canonical { value: ty.ty.value.clone(), num_vars: 0 }; |
373 | method_resolution::iterate_method_candidates( | 377 | method_resolution::iterate_method_candidates( |
374 | &canonical, | 378 | &canonical, |
375 | db, | 379 | db, |
@@ -404,19 +408,19 @@ impl SourceAnalyzer { | |||
404 | ) | 408 | ) |
405 | } | 409 | } |
406 | 410 | ||
407 | pub fn autoderef<'a>( | 411 | // pub fn autoderef<'a>( |
408 | &'a self, | 412 | // &'a self, |
409 | db: &'a impl HirDatabase, | 413 | // db: &'a impl HirDatabase, |
410 | ty: Ty, | 414 | // ty: Ty, |
411 | ) -> impl Iterator<Item = Ty> + 'a { | 415 | // ) -> impl Iterator<Item = Ty> + 'a { |
412 | // There should be no inference vars in types passed here | 416 | // // There should be no inference vars in types passed here |
413 | // FIXME check that? | 417 | // // FIXME check that? |
414 | let canonical = crate::ty::Canonical { value: ty, num_vars: 0 }; | 418 | // let canonical = crate::ty::Canonical { value: ty, num_vars: 0 }; |
415 | let krate = self.resolver.krate(); | 419 | // let krate = self.resolver.krate(); |
416 | let environment = TraitEnvironment::lower(db, &self.resolver); | 420 | // let environment = TraitEnvironment::lower(db, &self.resolver); |
417 | let ty = crate::ty::InEnvironment { value: canonical, environment }; | 421 | // let ty = crate::ty::InEnvironment { value: canonical, environment }; |
418 | crate::ty::autoderef(db, krate, ty).map(|canonical| canonical.value) | 422 | // crate::ty::autoderef(db, krate, ty).map(|canonical| canonical.value) |
419 | } | 423 | // } |
420 | 424 | ||
421 | /// Checks that particular type `ty` implements `std::future::Future`. | 425 | /// Checks that particular type `ty` implements `std::future::Future`. |
422 | /// This function is used in `.await` syntax completion. | 426 | /// This function is used in `.await` syntax completion. |
diff --git a/crates/ra_hir/src/test_db.rs b/crates/ra_hir/src/test_db.rs index efee2f658..a2071f71c 100644 --- a/crates/ra_hir/src/test_db.rs +++ b/crates/ra_hir/src/test_db.rs | |||
@@ -28,6 +28,10 @@ impl salsa::Database for TestDB { | |||
28 | &self.runtime | 28 | &self.runtime |
29 | } | 29 | } |
30 | 30 | ||
31 | fn salsa_runtime_mut(&mut self) -> &mut salsa::Runtime<Self> { | ||
32 | &mut self.runtime | ||
33 | } | ||
34 | |||
31 | fn salsa_event(&self, event: impl Fn() -> salsa::Event<TestDB>) { | 35 | fn salsa_event(&self, event: impl Fn() -> salsa::Event<TestDB>) { |
32 | let mut events = self.events.lock(); | 36 | let mut events = self.events.lock(); |
33 | if let Some(events) = &mut *events { | 37 | if let Some(events) = &mut *events { |
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 388530f31..bd03055b9 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -58,7 +58,7 @@ pub enum TypeCtor { | |||
58 | Float(Uncertain<FloatTy>), | 58 | Float(Uncertain<FloatTy>), |
59 | 59 | ||
60 | /// Structures, enumerations and unions. | 60 | /// Structures, enumerations and unions. |
61 | Adt(Adt), | 61 | Adt(AdtId), |
62 | 62 | ||
63 | /// The pointee of a string slice. Written as `str`. | 63 | /// The pointee of a string slice. Written as `str`. |
64 | Str, | 64 | Str, |
@@ -174,7 +174,7 @@ impl TypeCtor { | |||
174 | | TypeCtor::Tuple { .. } => None, | 174 | | TypeCtor::Tuple { .. } => None, |
175 | // Closure's krate is irrelevant for coherence I would think? | 175 | // Closure's krate is irrelevant for coherence I would think? |
176 | TypeCtor::Closure { .. } => None, | 176 | TypeCtor::Closure { .. } => None, |
177 | TypeCtor::Adt(adt) => adt.krate(db), | 177 | TypeCtor::Adt(adt) => Some(adt.module(db).krate.into()), |
178 | TypeCtor::FnDef(callable) => Some(callable.krate(db).into()), | 178 | TypeCtor::FnDef(callable) => Some(callable.krate(db).into()), |
179 | TypeCtor::AssociatedType(type_alias) => { | 179 | TypeCtor::AssociatedType(type_alias) => { |
180 | Some(type_alias.lookup(db).module(db).krate.into()) | 180 | Some(type_alias.lookup(db).module(db).krate.into()) |
@@ -598,7 +598,7 @@ impl Ty { | |||
598 | pub fn as_adt(&self) -> Option<(Adt, &Substs)> { | 598 | pub fn as_adt(&self) -> Option<(Adt, &Substs)> { |
599 | match self { | 599 | match self { |
600 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(adt_def), parameters }) => { | 600 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(adt_def), parameters }) => { |
601 | Some((*adt_def, parameters)) | 601 | Some(((*adt_def).into(), parameters)) |
602 | } | 602 | } |
603 | _ => None, | 603 | _ => None, |
604 | } | 604 | } |
@@ -889,9 +889,9 @@ impl HirDisplay for ApplicationTy { | |||
889 | } | 889 | } |
890 | TypeCtor::Adt(def_id) => { | 890 | TypeCtor::Adt(def_id) => { |
891 | let name = match def_id { | 891 | let name = match def_id { |
892 | Adt::Struct(s) => s.name(f.db), | 892 | AdtId::StructId(it) => f.db.struct_data(it).name.clone(), |
893 | Adt::Union(u) => u.name(f.db), | 893 | AdtId::UnionId(it) => f.db.union_data(it).name.clone(), |
894 | Adt::Enum(e) => e.name(f.db), | 894 | AdtId::EnumId(it) => f.db.enum_data(it).name.clone(), |
895 | } | 895 | } |
896 | .unwrap_or_else(Name::missing); | 896 | .unwrap_or_else(Name::missing); |
897 | write!(f, "{}", name)?; | 897 | write!(f, "{}", name)?; |
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index 6fd00d457..fce45321d 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs | |||
@@ -598,10 +598,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
598 | trait_.associated_type_by_name(self.db, &name::OUTPUT_TYPE) | 598 | trait_.associated_type_by_name(self.db, &name::OUTPUT_TYPE) |
599 | } | 599 | } |
600 | 600 | ||
601 | fn resolve_boxed_box(&self) -> Option<Adt> { | 601 | fn resolve_boxed_box(&self) -> Option<AdtId> { |
602 | let path = known::std_boxed_box(); | 602 | let path = known::std_boxed_box(); |
603 | let struct_ = self.resolver.resolve_known_struct(self.db, &path)?; | 603 | let struct_ = self.resolver.resolve_known_struct(self.db, &path)?; |
604 | Some(Adt::Struct(struct_.into())) | 604 | Some(struct_.into()) |
605 | } | 605 | } |
606 | } | 606 | } |
607 | 607 | ||
diff --git a/crates/ra_hir/src/ty/infer/coerce.rs b/crates/ra_hir/src/ty/infer/coerce.rs index bb9a2e427..5ed4470af 100644 --- a/crates/ra_hir/src/ty/infer/coerce.rs +++ b/crates/ra_hir/src/ty/infer/coerce.rs | |||
@@ -4,14 +4,14 @@ | |||
4 | //! | 4 | //! |
5 | //! See: https://doc.rust-lang.org/nomicon/coercions.html | 5 | //! See: https://doc.rust-lang.org/nomicon/coercions.html |
6 | 6 | ||
7 | use hir_def::{lang_item::LangItemTarget, resolver::Resolver}; | 7 | use hir_def::{lang_item::LangItemTarget, resolver::Resolver, AdtId}; |
8 | use rustc_hash::FxHashMap; | 8 | use rustc_hash::FxHashMap; |
9 | use test_utils::tested_by; | 9 | use test_utils::tested_by; |
10 | 10 | ||
11 | use crate::{ | 11 | use crate::{ |
12 | db::HirDatabase, | 12 | db::HirDatabase, |
13 | ty::{autoderef, Substs, Ty, TypeCtor, TypeWalk}, | 13 | ty::{autoderef, Substs, Ty, TypeCtor, TypeWalk}, |
14 | Adt, Mutability, | 14 | Mutability, |
15 | }; | 15 | }; |
16 | 16 | ||
17 | use super::{InEnvironment, InferTy, InferenceContext, TypeVarValue}; | 17 | use super::{InEnvironment, InferTy, InferenceContext, TypeVarValue}; |
@@ -242,11 +242,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
242 | // - T is not part of the type of any other fields | 242 | // - T is not part of the type of any other fields |
243 | // - Bar<T>: Unsize<Bar<U>>, if the last field of Foo has type Bar<T> | 243 | // - Bar<T>: Unsize<Bar<U>>, if the last field of Foo has type Bar<T> |
244 | ( | 244 | ( |
245 | ty_app!(TypeCtor::Adt(Adt::Struct(struct1)), st1), | 245 | ty_app!(TypeCtor::Adt(AdtId::StructId(struct1)), st1), |
246 | ty_app!(TypeCtor::Adt(Adt::Struct(struct2)), st2), | 246 | ty_app!(TypeCtor::Adt(AdtId::StructId(struct2)), st2), |
247 | ) if struct1 == struct2 => { | 247 | ) if struct1 == struct2 => { |
248 | let field_tys = self.db.field_types(struct1.id.into()); | 248 | let field_tys = self.db.field_types((*struct1).into()); |
249 | let struct_data = self.db.struct_data(struct1.id); | 249 | let struct_data = self.db.struct_data(*struct1); |
250 | 250 | ||
251 | let mut fields = struct_data.variant_data.fields().iter(); | 251 | let mut fields = struct_data.variant_data.fields().iter(); |
252 | let (last_field_id, _data) = fields.next_back()?; | 252 | let (last_field_id, _data) = fields.next_back()?; |
diff --git a/crates/ra_hir/src/ty/infer/expr.rs b/crates/ra_hir/src/ty/infer/expr.rs index 316cdc880..3d0895dc6 100644 --- a/crates/ra_hir/src/ty/infer/expr.rs +++ b/crates/ra_hir/src/ty/infer/expr.rs | |||
@@ -8,7 +8,7 @@ use hir_def::{ | |||
8 | generics::GenericParams, | 8 | generics::GenericParams, |
9 | path::{GenericArg, GenericArgs}, | 9 | path::{GenericArg, GenericArgs}, |
10 | resolver::resolver_for_expr, | 10 | resolver::resolver_for_expr, |
11 | ContainerId, Lookup, | 11 | AdtId, ContainerId, Lookup, StructFieldId, |
12 | }; | 12 | }; |
13 | use hir_expand::name; | 13 | use hir_expand::name; |
14 | 14 | ||
@@ -20,7 +20,7 @@ use crate::{ | |||
20 | Mutability, Namespace, Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, | 20 | Mutability, Namespace, Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, |
21 | TypeCtor, TypeWalk, Uncertain, | 21 | TypeCtor, TypeWalk, Uncertain, |
22 | }, | 22 | }, |
23 | Adt, Name, | 23 | Name, |
24 | }; | 24 | }; |
25 | 25 | ||
26 | use super::{BindingMode, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch}; | 26 | use super::{BindingMode, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch}; |
@@ -259,14 +259,17 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
259 | TypeCtor::Tuple { .. } => name | 259 | TypeCtor::Tuple { .. } => name |
260 | .as_tuple_index() | 260 | .as_tuple_index() |
261 | .and_then(|idx| a_ty.parameters.0.get(idx).cloned()), | 261 | .and_then(|idx| a_ty.parameters.0.get(idx).cloned()), |
262 | TypeCtor::Adt(Adt::Struct(s)) => s.field(self.db, name).map(|field| { | 262 | TypeCtor::Adt(AdtId::StructId(s)) => { |
263 | self.write_field_resolution(tgt_expr, field); | 263 | self.db.struct_data(s).variant_data.field(name).map(|local_id| { |
264 | self.db.field_types(s.id.into())[field.id] | 264 | let field = StructFieldId { parent: s.into(), local_id }.into(); |
265 | .clone() | 265 | self.write_field_resolution(tgt_expr, field); |
266 | .subst(&a_ty.parameters) | 266 | self.db.field_types(s.into())[field.id] |
267 | }), | 267 | .clone() |
268 | .subst(&a_ty.parameters) | ||
269 | }) | ||
270 | } | ||
268 | // FIXME: | 271 | // FIXME: |
269 | TypeCtor::Adt(Adt::Union(_)) => None, | 272 | TypeCtor::Adt(AdtId::UnionId(_)) => None, |
270 | _ => None, | 273 | _ => None, |
271 | }, | 274 | }, |
272 | _ => None, | 275 | _ => None, |
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index d7d4bb0d6..2d23890a5 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs | |||
@@ -9,7 +9,7 @@ use std::iter; | |||
9 | use std::sync::Arc; | 9 | use std::sync::Arc; |
10 | 10 | ||
11 | use hir_def::{ | 11 | use hir_def::{ |
12 | builtin_type::{BuiltinFloat, BuiltinInt, BuiltinType}, | 12 | builtin_type::BuiltinType, |
13 | generics::WherePredicate, | 13 | generics::WherePredicate, |
14 | path::{GenericArg, PathSegment}, | 14 | path::{GenericArg, PathSegment}, |
15 | resolver::{HasResolver, Resolver, TypeNs}, | 15 | resolver::{HasResolver, Resolver, TypeNs}, |
@@ -27,7 +27,7 @@ use super::{ | |||
27 | use crate::{ | 27 | use crate::{ |
28 | db::HirDatabase, | 28 | db::HirDatabase, |
29 | ty::{ | 29 | ty::{ |
30 | primitive::{FloatTy, IntTy, Uncertain}, | 30 | primitive::{FloatTy, IntTy}, |
31 | Adt, | 31 | Adt, |
32 | }, | 32 | }, |
33 | util::make_mut_slice, | 33 | util::make_mut_slice, |
@@ -679,36 +679,6 @@ fn type_for_builtin(def: BuiltinType) -> Ty { | |||
679 | }) | 679 | }) |
680 | } | 680 | } |
681 | 681 | ||
682 | impl From<BuiltinInt> for IntTy { | ||
683 | fn from(t: BuiltinInt) -> Self { | ||
684 | IntTy { signedness: t.signedness, bitness: t.bitness } | ||
685 | } | ||
686 | } | ||
687 | |||
688 | impl From<BuiltinFloat> for FloatTy { | ||
689 | fn from(t: BuiltinFloat) -> Self { | ||
690 | FloatTy { bitness: t.bitness } | ||
691 | } | ||
692 | } | ||
693 | |||
694 | impl From<Option<BuiltinInt>> for Uncertain<IntTy> { | ||
695 | fn from(t: Option<BuiltinInt>) -> Self { | ||
696 | match t { | ||
697 | None => Uncertain::Unknown, | ||
698 | Some(t) => Uncertain::Known(t.into()), | ||
699 | } | ||
700 | } | ||
701 | } | ||
702 | |||
703 | impl From<Option<BuiltinFloat>> for Uncertain<FloatTy> { | ||
704 | fn from(t: Option<BuiltinFloat>) -> Self { | ||
705 | match t { | ||
706 | None => Uncertain::Unknown, | ||
707 | Some(t) => Uncertain::Known(t.into()), | ||
708 | } | ||
709 | } | ||
710 | } | ||
711 | |||
712 | fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: StructId) -> FnSig { | 682 | fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: StructId) -> FnSig { |
713 | let struct_data = db.struct_data(def.into()); | 683 | let struct_data = db.struct_data(def.into()); |
714 | let fields = struct_data.variant_data.fields(); | 684 | let fields = struct_data.variant_data.fields(); |
@@ -762,7 +732,7 @@ fn type_for_adt(db: &impl HirDatabase, adt: impl Into<Adt>) -> Ty { | |||
762 | let adt = adt.into(); | 732 | let adt = adt.into(); |
763 | let adt_id: AdtId = adt.into(); | 733 | let adt_id: AdtId = adt.into(); |
764 | let generics = db.generic_params(adt_id.into()); | 734 | let generics = db.generic_params(adt_id.into()); |
765 | Ty::apply(TypeCtor::Adt(adt), Substs::identity(&generics)) | 735 | Ty::apply(TypeCtor::Adt(adt_id), Substs::identity(&generics)) |
766 | } | 736 | } |
767 | 737 | ||
768 | fn type_for_type_alias(db: &impl HirDatabase, t: TypeAlias) -> Ty { | 738 | fn type_for_type_alias(db: &impl HirDatabase, t: TypeAlias) -> Ty { |
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index c5ab690eb..489fcd64b 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs | |||
@@ -5,14 +5,19 @@ | |||
5 | use std::sync::Arc; | 5 | use std::sync::Arc; |
6 | 6 | ||
7 | use arrayvec::ArrayVec; | 7 | use arrayvec::ArrayVec; |
8 | use hir_def::{lang_item::LangItemTarget, resolver::Resolver, AstItemDef}; | 8 | use hir_def::{ |
9 | lang_item::LangItemTarget, resolver::HasResolver, resolver::Resolver, AssocItemId, AstItemDef, | ||
10 | HasModule, ImplId, TraitId, | ||
11 | }; | ||
12 | use ra_db::CrateId; | ||
13 | use ra_prof::profile; | ||
9 | use rustc_hash::FxHashMap; | 14 | use rustc_hash::FxHashMap; |
10 | 15 | ||
11 | use crate::{ | 16 | use crate::{ |
12 | db::HirDatabase, | 17 | db::HirDatabase, |
13 | ty::primitive::{FloatBitness, Uncertain}, | 18 | ty::primitive::{FloatBitness, Uncertain}, |
14 | ty::{Ty, TypeCtor}, | 19 | ty::{Ty, TypeCtor}, |
15 | AssocItem, Crate, Function, ImplBlock, Module, Mutability, Name, Trait, | 20 | AssocItem, Crate, Function, Mutability, Name, Trait, |
16 | }; | 21 | }; |
17 | 22 | ||
18 | use super::{autoderef, Canonical, InEnvironment, TraitEnvironment, TraitRef}; | 23 | use super::{autoderef, Canonical, InEnvironment, TraitEnvironment, TraitRef}; |
@@ -37,54 +42,58 @@ impl TyFingerprint { | |||
37 | 42 | ||
38 | #[derive(Debug, PartialEq, Eq)] | 43 | #[derive(Debug, PartialEq, Eq)] |
39 | pub struct CrateImplBlocks { | 44 | pub struct CrateImplBlocks { |
40 | impls: FxHashMap<TyFingerprint, Vec<ImplBlock>>, | 45 | impls: FxHashMap<TyFingerprint, Vec<ImplId>>, |
41 | impls_by_trait: FxHashMap<Trait, Vec<ImplBlock>>, | 46 | impls_by_trait: FxHashMap<TraitId, Vec<ImplId>>, |
42 | } | 47 | } |
43 | 48 | ||
44 | impl CrateImplBlocks { | 49 | impl CrateImplBlocks { |
45 | pub(crate) fn impls_in_crate_query( | 50 | pub(crate) fn impls_in_crate_query( |
46 | db: &impl HirDatabase, | 51 | db: &impl HirDatabase, |
47 | krate: Crate, | 52 | krate: CrateId, |
48 | ) -> Arc<CrateImplBlocks> { | 53 | ) -> Arc<CrateImplBlocks> { |
49 | let mut crate_impl_blocks = | 54 | let _p = profile("impls_in_crate_query"); |
55 | let mut res = | ||
50 | CrateImplBlocks { impls: FxHashMap::default(), impls_by_trait: FxHashMap::default() }; | 56 | CrateImplBlocks { impls: FxHashMap::default(), impls_by_trait: FxHashMap::default() }; |
51 | if let Some(module) = krate.root_module(db) { | 57 | |
52 | crate_impl_blocks.collect_recursive(db, module); | 58 | let crate_def_map = db.crate_def_map(krate); |
59 | for (_module_id, module_data) in crate_def_map.modules.iter() { | ||
60 | for &impl_id in module_data.impls.iter() { | ||
61 | let impl_data = db.impl_data(impl_id); | ||
62 | let resolver = impl_id.resolver(db); | ||
63 | |||
64 | let target_ty = { Ty::from_hir(db, &resolver, &impl_data.target_type) }; | ||
65 | |||
66 | match &impl_data.target_trait { | ||
67 | Some(trait_ref) => { | ||
68 | if let Some(tr) = | ||
69 | TraitRef::from_hir(db, &resolver, &trait_ref, Some(target_ty)) | ||
70 | { | ||
71 | res.impls_by_trait.entry(tr.trait_.id).or_default().push(impl_id); | ||
72 | } | ||
73 | } | ||
74 | None => { | ||
75 | if let Some(target_ty_fp) = TyFingerprint::for_impl(&target_ty) { | ||
76 | res.impls.entry(target_ty_fp).or_default().push(impl_id); | ||
77 | } | ||
78 | } | ||
79 | } | ||
80 | } | ||
53 | } | 81 | } |
54 | Arc::new(crate_impl_blocks) | 82 | |
83 | Arc::new(res) | ||
55 | } | 84 | } |
56 | pub fn lookup_impl_blocks(&self, ty: &Ty) -> impl Iterator<Item = ImplBlock> + '_ { | 85 | pub fn lookup_impl_blocks(&self, ty: &Ty) -> impl Iterator<Item = ImplId> + '_ { |
57 | let fingerprint = TyFingerprint::for_impl(ty); | 86 | let fingerprint = TyFingerprint::for_impl(ty); |
58 | fingerprint.and_then(|f| self.impls.get(&f)).into_iter().flatten().copied() | 87 | fingerprint.and_then(|f| self.impls.get(&f)).into_iter().flatten().copied() |
59 | } | 88 | } |
60 | 89 | ||
61 | pub fn lookup_impl_blocks_for_trait(&self, tr: Trait) -> impl Iterator<Item = ImplBlock> + '_ { | 90 | pub fn lookup_impl_blocks_for_trait(&self, tr: Trait) -> impl Iterator<Item = ImplId> + '_ { |
62 | self.impls_by_trait.get(&tr).into_iter().flatten().copied() | 91 | self.impls_by_trait.get(&tr.id).into_iter().flatten().copied() |
63 | } | 92 | } |
64 | 93 | ||
65 | pub fn all_impls<'a>(&'a self) -> impl Iterator<Item = ImplBlock> + 'a { | 94 | pub fn all_impls<'a>(&'a self) -> impl Iterator<Item = ImplId> + 'a { |
66 | self.impls.values().chain(self.impls_by_trait.values()).flatten().copied() | 95 | self.impls.values().chain(self.impls_by_trait.values()).flatten().copied() |
67 | } | 96 | } |
68 | |||
69 | fn collect_recursive(&mut self, db: &impl HirDatabase, module: Module) { | ||
70 | for impl_block in module.impl_blocks(db) { | ||
71 | let target_ty = impl_block.target_ty(db); | ||
72 | |||
73 | if impl_block.target_trait(db).is_some() { | ||
74 | if let Some(tr) = impl_block.target_trait_ref(db) { | ||
75 | self.impls_by_trait.entry(tr.trait_).or_default().push(impl_block); | ||
76 | } | ||
77 | } else { | ||
78 | if let Some(target_ty_fp) = TyFingerprint::for_impl(&target_ty) { | ||
79 | self.impls.entry(target_ty_fp).or_default().push(impl_block); | ||
80 | } | ||
81 | } | ||
82 | } | ||
83 | |||
84 | for child in module.children(db) { | ||
85 | self.collect_recursive(db, child); | ||
86 | } | ||
87 | } | ||
88 | } | 97 | } |
89 | 98 | ||
90 | fn def_crates(db: &impl HirDatabase, cur_crate: Crate, ty: &Ty) -> Option<ArrayVec<[Crate; 2]>> { | 99 | fn def_crates(db: &impl HirDatabase, cur_crate: Crate, ty: &Ty) -> Option<ArrayVec<[Crate; 2]>> { |
@@ -102,7 +111,9 @@ fn def_crates(db: &impl HirDatabase, cur_crate: Crate, ty: &Ty) -> Option<ArrayV | |||
102 | 111 | ||
103 | let lang_item_targets = match ty { | 112 | let lang_item_targets = match ty { |
104 | Ty::Apply(a_ty) => match a_ty.ctor { | 113 | Ty::Apply(a_ty) => match a_ty.ctor { |
105 | TypeCtor::Adt(def_id) => return Some(std::iter::once(def_id.krate(db)?).collect()), | 114 | TypeCtor::Adt(def_id) => { |
115 | return Some(std::iter::once(def_id.module(db).krate.into()).collect()) | ||
116 | } | ||
106 | TypeCtor::Bool => lang_item_crate!("bool"), | 117 | TypeCtor::Bool => lang_item_crate!("bool"), |
107 | TypeCtor::Char => lang_item_crate!("char"), | 118 | TypeCtor::Char => lang_item_crate!("char"), |
108 | TypeCtor::Float(Uncertain::Known(f)) => match f.bitness { | 119 | TypeCtor::Float(Uncertain::Known(f)) => match f.bitness { |
@@ -277,14 +288,14 @@ fn iterate_inherent_methods<T>( | |||
277 | mut callback: impl FnMut(&Ty, AssocItem) -> Option<T>, | 288 | mut callback: impl FnMut(&Ty, AssocItem) -> Option<T>, |
278 | ) -> Option<T> { | 289 | ) -> Option<T> { |
279 | for krate in def_crates(db, krate, &ty.value)? { | 290 | for krate in def_crates(db, krate, &ty.value)? { |
280 | let impls = db.impls_in_crate(krate); | 291 | let impls = db.impls_in_crate(krate.crate_id); |
281 | 292 | ||
282 | for impl_block in impls.lookup_impl_blocks(&ty.value) { | 293 | for impl_block in impls.lookup_impl_blocks(&ty.value) { |
283 | for item in impl_block.items(db) { | 294 | for &item in db.impl_data(impl_block).items.iter() { |
284 | if !is_valid_candidate(db, name, mode, item) { | 295 | if !is_valid_candidate(db, name, mode, item) { |
285 | continue; | 296 | continue; |
286 | } | 297 | } |
287 | if let Some(result) = callback(&ty.value, item) { | 298 | if let Some(result) = callback(&ty.value, item.into()) { |
288 | return Some(result); | 299 | return Some(result); |
289 | } | 300 | } |
290 | } | 301 | } |
@@ -297,17 +308,17 @@ fn is_valid_candidate( | |||
297 | db: &impl HirDatabase, | 308 | db: &impl HirDatabase, |
298 | name: Option<&Name>, | 309 | name: Option<&Name>, |
299 | mode: LookupMode, | 310 | mode: LookupMode, |
300 | item: AssocItem, | 311 | item: AssocItemId, |
301 | ) -> bool { | 312 | ) -> bool { |
302 | match item { | 313 | match item { |
303 | AssocItem::Function(m) => { | 314 | AssocItemId::FunctionId(m) => { |
304 | let data = db.function_data(m.id); | 315 | let data = db.function_data(m); |
305 | name.map_or(true, |name| data.name == *name) | 316 | name.map_or(true, |name| &data.name == name) |
306 | && (data.has_self_param || mode == LookupMode::Path) | 317 | && (data.has_self_param || mode == LookupMode::Path) |
307 | } | 318 | } |
308 | AssocItem::Const(c) => { | 319 | AssocItemId::ConstId(c) => { |
309 | name.map_or(true, |name| Some(name) == c.name(db).as_ref()) | 320 | let data = db.const_data(c); |
310 | && (mode == LookupMode::Path) | 321 | name.map_or(true, |name| data.name.as_ref() == Some(name)) && (mode == LookupMode::Path) |
311 | } | 322 | } |
312 | _ => false, | 323 | _ => false, |
313 | } | 324 | } |
@@ -342,11 +353,11 @@ impl Ty { | |||
342 | mut callback: impl FnMut(AssocItem) -> Option<T>, | 353 | mut callback: impl FnMut(AssocItem) -> Option<T>, |
343 | ) -> Option<T> { | 354 | ) -> Option<T> { |
344 | for krate in def_crates(db, krate, &self)? { | 355 | for krate in def_crates(db, krate, &self)? { |
345 | let impls = db.impls_in_crate(krate); | 356 | let impls = db.impls_in_crate(krate.crate_id); |
346 | 357 | ||
347 | for impl_block in impls.lookup_impl_blocks(&self) { | 358 | for impl_block in impls.lookup_impl_blocks(&self) { |
348 | for item in impl_block.items(db) { | 359 | for &item in db.impl_data(impl_block).items.iter() { |
349 | if let Some(result) = callback(item) { | 360 | if let Some(result) = callback(item.into()) { |
350 | return Some(result); | 361 | return Some(result); |
351 | } | 362 | } |
352 | } | 363 | } |
diff --git a/crates/ra_hir/src/ty/primitive.rs b/crates/ra_hir/src/ty/primitive.rs index 47789db87..12dc96572 100644 --- a/crates/ra_hir/src/ty/primitive.rs +++ b/crates/ra_hir/src/ty/primitive.rs | |||
@@ -1,160 +1,3 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use std::fmt; | 3 | pub use hir_ty::primitive::{FloatBitness, FloatTy, IntBitness, IntTy, Signedness, Uncertain}; |
4 | |||
5 | pub use hir_def::builtin_type::{FloatBitness, IntBitness, Signedness}; | ||
6 | |||
7 | #[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)] | ||
8 | pub enum Uncertain<T> { | ||
9 | Unknown, | ||
10 | Known(T), | ||
11 | } | ||
12 | |||
13 | impl From<IntTy> for Uncertain<IntTy> { | ||
14 | fn from(ty: IntTy) -> Self { | ||
15 | Uncertain::Known(ty) | ||
16 | } | ||
17 | } | ||
18 | |||
19 | impl fmt::Display for Uncertain<IntTy> { | ||
20 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
21 | match *self { | ||
22 | Uncertain::Unknown => write!(f, "{{integer}}"), | ||
23 | Uncertain::Known(ty) => write!(f, "{}", ty), | ||
24 | } | ||
25 | } | ||
26 | } | ||
27 | |||
28 | impl From<FloatTy> for Uncertain<FloatTy> { | ||
29 | fn from(ty: FloatTy) -> Self { | ||
30 | Uncertain::Known(ty) | ||
31 | } | ||
32 | } | ||
33 | |||
34 | impl fmt::Display for Uncertain<FloatTy> { | ||
35 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
36 | match *self { | ||
37 | Uncertain::Unknown => write!(f, "{{float}}"), | ||
38 | Uncertain::Known(ty) => write!(f, "{}", ty), | ||
39 | } | ||
40 | } | ||
41 | } | ||
42 | |||
43 | #[derive(Copy, Clone, Eq, PartialEq, Hash)] | ||
44 | pub struct IntTy { | ||
45 | pub signedness: Signedness, | ||
46 | pub bitness: IntBitness, | ||
47 | } | ||
48 | |||
49 | impl fmt::Debug for IntTy { | ||
50 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
51 | fmt::Display::fmt(self, f) | ||
52 | } | ||
53 | } | ||
54 | |||
55 | impl fmt::Display for IntTy { | ||
56 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
57 | write!(f, "{}", self.ty_to_string()) | ||
58 | } | ||
59 | } | ||
60 | |||
61 | impl IntTy { | ||
62 | pub fn isize() -> IntTy { | ||
63 | IntTy { signedness: Signedness::Signed, bitness: IntBitness::Xsize } | ||
64 | } | ||
65 | |||
66 | pub fn i8() -> IntTy { | ||
67 | IntTy { signedness: Signedness::Signed, bitness: IntBitness::X8 } | ||
68 | } | ||
69 | |||
70 | pub fn i16() -> IntTy { | ||
71 | IntTy { signedness: Signedness::Signed, bitness: IntBitness::X16 } | ||
72 | } | ||
73 | |||
74 | pub fn i32() -> IntTy { | ||
75 | IntTy { signedness: Signedness::Signed, bitness: IntBitness::X32 } | ||
76 | } | ||
77 | |||
78 | pub fn i64() -> IntTy { | ||
79 | IntTy { signedness: Signedness::Signed, bitness: IntBitness::X64 } | ||
80 | } | ||
81 | |||
82 | pub fn i128() -> IntTy { | ||
83 | IntTy { signedness: Signedness::Signed, bitness: IntBitness::X128 } | ||
84 | } | ||
85 | |||
86 | pub fn usize() -> IntTy { | ||
87 | IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::Xsize } | ||
88 | } | ||
89 | |||
90 | pub fn u8() -> IntTy { | ||
91 | IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X8 } | ||
92 | } | ||
93 | |||
94 | pub fn u16() -> IntTy { | ||
95 | IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X16 } | ||
96 | } | ||
97 | |||
98 | pub fn u32() -> IntTy { | ||
99 | IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X32 } | ||
100 | } | ||
101 | |||
102 | pub fn u64() -> IntTy { | ||
103 | IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X64 } | ||
104 | } | ||
105 | |||
106 | pub fn u128() -> IntTy { | ||
107 | IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X128 } | ||
108 | } | ||
109 | |||
110 | pub(crate) fn ty_to_string(self) -> &'static str { | ||
111 | match (self.signedness, self.bitness) { | ||
112 | (Signedness::Signed, IntBitness::Xsize) => "isize", | ||
113 | (Signedness::Signed, IntBitness::X8) => "i8", | ||
114 | (Signedness::Signed, IntBitness::X16) => "i16", | ||
115 | (Signedness::Signed, IntBitness::X32) => "i32", | ||
116 | (Signedness::Signed, IntBitness::X64) => "i64", | ||
117 | (Signedness::Signed, IntBitness::X128) => "i128", | ||
118 | (Signedness::Unsigned, IntBitness::Xsize) => "usize", | ||
119 | (Signedness::Unsigned, IntBitness::X8) => "u8", | ||
120 | (Signedness::Unsigned, IntBitness::X16) => "u16", | ||
121 | (Signedness::Unsigned, IntBitness::X32) => "u32", | ||
122 | (Signedness::Unsigned, IntBitness::X64) => "u64", | ||
123 | (Signedness::Unsigned, IntBitness::X128) => "u128", | ||
124 | } | ||
125 | } | ||
126 | } | ||
127 | |||
128 | #[derive(Copy, Clone, PartialEq, Eq, Hash)] | ||
129 | pub struct FloatTy { | ||
130 | pub bitness: FloatBitness, | ||
131 | } | ||
132 | |||
133 | impl fmt::Debug for FloatTy { | ||
134 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
135 | fmt::Display::fmt(self, f) | ||
136 | } | ||
137 | } | ||
138 | |||
139 | impl fmt::Display for FloatTy { | ||
140 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
141 | write!(f, "{}", self.ty_to_string()) | ||
142 | } | ||
143 | } | ||
144 | |||
145 | impl FloatTy { | ||
146 | pub fn f32() -> FloatTy { | ||
147 | FloatTy { bitness: FloatBitness::X32 } | ||
148 | } | ||
149 | |||
150 | pub fn f64() -> FloatTy { | ||
151 | FloatTy { bitness: FloatBitness::X64 } | ||
152 | } | ||
153 | |||
154 | pub(crate) fn ty_to_string(self) -> &'static str { | ||
155 | match self.bitness { | ||
156 | FloatBitness::X32 => "f32", | ||
157 | FloatBitness::X64 => "f64", | ||
158 | } | ||
159 | } | ||
160 | } | ||
diff --git a/crates/ra_hir/src/ty/traits.rs b/crates/ra_hir/src/ty/traits.rs index b9a5d651f..2eeb03099 100644 --- a/crates/ra_hir/src/ty/traits.rs +++ b/crates/ra_hir/src/ty/traits.rs | |||
@@ -88,8 +88,8 @@ pub(crate) fn impls_for_trait_query( | |||
88 | for dep in krate.dependencies(db) { | 88 | for dep in krate.dependencies(db) { |
89 | impls.extend(db.impls_for_trait(dep.krate, trait_).iter()); | 89 | impls.extend(db.impls_for_trait(dep.krate, trait_).iter()); |
90 | } | 90 | } |
91 | let crate_impl_blocks = db.impls_in_crate(krate); | 91 | let crate_impl_blocks = db.impls_in_crate(krate.crate_id); |
92 | impls.extend(crate_impl_blocks.lookup_impl_blocks_for_trait(trait_)); | 92 | impls.extend(crate_impl_blocks.lookup_impl_blocks_for_trait(trait_).map(ImplBlock::from)); |
93 | impls.into_iter().collect() | 93 | impls.into_iter().collect() |
94 | } | 94 | } |
95 | 95 | ||
diff --git a/crates/ra_hir_def/src/adt.rs b/crates/ra_hir_def/src/adt.rs index 0091bfbc3..0cf418d30 100644 --- a/crates/ra_hir_def/src/adt.rs +++ b/crates/ra_hir_def/src/adt.rs | |||
@@ -129,6 +129,10 @@ impl VariantData { | |||
129 | } | 129 | } |
130 | } | 130 | } |
131 | 131 | ||
132 | pub fn field(&self, name: &Name) -> Option<LocalStructFieldId> { | ||
133 | self.fields().iter().find_map(|(id, data)| if &data.name == name { Some(id) } else { None }) | ||
134 | } | ||
135 | |||
132 | pub fn is_unit(&self) -> bool { | 136 | pub fn is_unit(&self) -> bool { |
133 | match self { | 137 | match self { |
134 | VariantData::Unit => true, | 138 | VariantData::Unit => true, |
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index a88a78b38..274dd1467 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs | |||
@@ -489,6 +489,16 @@ impl HasModule for AdtId { | |||
489 | } | 489 | } |
490 | } | 490 | } |
491 | 491 | ||
492 | impl HasModule for DefWithBodyId { | ||
493 | fn module(&self, db: &impl db::DefDatabase) -> ModuleId { | ||
494 | match self { | ||
495 | DefWithBodyId::FunctionId(it) => it.lookup(db).module(db), | ||
496 | DefWithBodyId::StaticId(it) => it.lookup(db).module(db), | ||
497 | DefWithBodyId::ConstId(it) => it.lookup(db).module(db), | ||
498 | } | ||
499 | } | ||
500 | } | ||
501 | |||
492 | impl HasModule for StaticLoc { | 502 | impl HasModule for StaticLoc { |
493 | fn module(&self, _db: &impl db::DefDatabase) -> ModuleId { | 503 | fn module(&self, _db: &impl db::DefDatabase) -> ModuleId { |
494 | self.container | 504 | self.container |
diff --git a/crates/ra_hir_def/src/test_db.rs b/crates/ra_hir_def/src/test_db.rs index 439e8a412..54e3a84bd 100644 --- a/crates/ra_hir_def/src/test_db.rs +++ b/crates/ra_hir_def/src/test_db.rs | |||
@@ -24,7 +24,9 @@ impl salsa::Database for TestDB { | |||
24 | fn salsa_runtime(&self) -> &salsa::Runtime<Self> { | 24 | fn salsa_runtime(&self) -> &salsa::Runtime<Self> { |
25 | &self.runtime | 25 | &self.runtime |
26 | } | 26 | } |
27 | 27 | fn salsa_runtime_mut(&mut self) -> &mut salsa::Runtime<Self> { | |
28 | &mut self.runtime | ||
29 | } | ||
28 | fn salsa_event(&self, event: impl Fn() -> salsa::Event<TestDB>) { | 30 | fn salsa_event(&self, event: impl Fn() -> salsa::Event<TestDB>) { |
29 | let mut events = self.events.lock().unwrap(); | 31 | let mut events = self.events.lock().unwrap(); |
30 | if let Some(events) = &mut *events { | 32 | if let Some(events) = &mut *events { |
diff --git a/crates/ra_hir_expand/src/test_db.rs b/crates/ra_hir_expand/src/test_db.rs index d23e75d9e..918736e2a 100644 --- a/crates/ra_hir_expand/src/test_db.rs +++ b/crates/ra_hir_expand/src/test_db.rs | |||
@@ -23,6 +23,10 @@ impl salsa::Database for TestDB { | |||
23 | &self.runtime | 23 | &self.runtime |
24 | } | 24 | } |
25 | 25 | ||
26 | fn salsa_runtime_mut(&mut self) -> &mut salsa::Runtime<Self> { | ||
27 | &mut self.runtime | ||
28 | } | ||
29 | |||
26 | fn salsa_event(&self, event: impl Fn() -> salsa::Event<TestDB>) { | 30 | fn salsa_event(&self, event: impl Fn() -> salsa::Event<TestDB>) { |
27 | let mut events = self.events.lock().unwrap(); | 31 | let mut events = self.events.lock().unwrap(); |
28 | if let Some(events) = &mut *events { | 32 | if let Some(events) = &mut *events { |
diff --git a/crates/ra_hir_ty/Cargo.toml b/crates/ra_hir_ty/Cargo.toml new file mode 100644 index 000000000..70216ab24 --- /dev/null +++ b/crates/ra_hir_ty/Cargo.toml | |||
@@ -0,0 +1,32 @@ | |||
1 | [package] | ||
2 | edition = "2018" | ||
3 | name = "ra_hir_ty" | ||
4 | version = "0.1.0" | ||
5 | authors = ["rust-analyzer developers"] | ||
6 | |||
7 | [lib] | ||
8 | doctest = false | ||
9 | |||
10 | [dependencies] | ||
11 | log = "0.4.5" | ||
12 | rustc-hash = "1.0" | ||
13 | parking_lot = "0.9.0" | ||
14 | ena = "0.13" | ||
15 | |||
16 | ra_syntax = { path = "../ra_syntax" } | ||
17 | ra_arena = { path = "../ra_arena" } | ||
18 | ra_db = { path = "../ra_db" } | ||
19 | hir_expand = { path = "../ra_hir_expand", package = "ra_hir_expand" } | ||
20 | hir_def = { path = "../ra_hir_def", package = "ra_hir_def" } | ||
21 | test_utils = { path = "../test_utils" } | ||
22 | ra_prof = { path = "../ra_prof" } | ||
23 | |||
24 | # https://github.com/rust-lang/chalk/pull/294 | ||
25 | chalk-solve = { git = "https://github.com/jackh726/chalk.git", rev = "095cd38a4f16337913bba487f2055b9ca0179f30" } | ||
26 | chalk-rust-ir = { git = "https://github.com/jackh726/chalk.git", rev = "095cd38a4f16337913bba487f2055b9ca0179f30" } | ||
27 | chalk-ir = { git = "https://github.com/jackh726/chalk.git", rev = "095cd38a4f16337913bba487f2055b9ca0179f30" } | ||
28 | |||
29 | lalrpop-intern = "0.15.1" | ||
30 | |||
31 | [dev-dependencies] | ||
32 | insta = "0.12.0" | ||
diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs new file mode 100644 index 000000000..28859ba63 --- /dev/null +++ b/crates/ra_hir_ty/src/lib.rs | |||
@@ -0,0 +1,4 @@ | |||
1 | //! Work in Progress: everything related to types, type inference and trait | ||
2 | //! solving. | ||
3 | |||
4 | pub mod primitive; | ||
diff --git a/crates/ra_hir_ty/src/primitive.rs b/crates/ra_hir_ty/src/primitive.rs new file mode 100644 index 000000000..02a8179d9 --- /dev/null +++ b/crates/ra_hir_ty/src/primitive.rs | |||
@@ -0,0 +1,193 @@ | |||
1 | //! Defines primitive types, which have a couple of peculiarities: | ||
2 | //! | ||
3 | //! * during type inference, they can be uncertain (ie, `let x = 92;`) | ||
4 | //! * they don't belong to any particular crate. | ||
5 | |||
6 | use std::fmt; | ||
7 | |||
8 | pub use hir_def::builtin_type::{BuiltinFloat, BuiltinInt, FloatBitness, IntBitness, Signedness}; | ||
9 | |||
10 | #[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)] | ||
11 | pub enum Uncertain<T> { | ||
12 | Unknown, | ||
13 | Known(T), | ||
14 | } | ||
15 | |||
16 | impl From<IntTy> for Uncertain<IntTy> { | ||
17 | fn from(ty: IntTy) -> Self { | ||
18 | Uncertain::Known(ty) | ||
19 | } | ||
20 | } | ||
21 | |||
22 | impl fmt::Display for Uncertain<IntTy> { | ||
23 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
24 | match *self { | ||
25 | Uncertain::Unknown => write!(f, "{{integer}}"), | ||
26 | Uncertain::Known(ty) => write!(f, "{}", ty), | ||
27 | } | ||
28 | } | ||
29 | } | ||
30 | |||
31 | impl From<FloatTy> for Uncertain<FloatTy> { | ||
32 | fn from(ty: FloatTy) -> Self { | ||
33 | Uncertain::Known(ty) | ||
34 | } | ||
35 | } | ||
36 | |||
37 | impl fmt::Display for Uncertain<FloatTy> { | ||
38 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
39 | match *self { | ||
40 | Uncertain::Unknown => write!(f, "{{float}}"), | ||
41 | Uncertain::Known(ty) => write!(f, "{}", ty), | ||
42 | } | ||
43 | } | ||
44 | } | ||
45 | |||
46 | #[derive(Copy, Clone, Eq, PartialEq, Hash)] | ||
47 | pub struct IntTy { | ||
48 | pub signedness: Signedness, | ||
49 | pub bitness: IntBitness, | ||
50 | } | ||
51 | |||
52 | impl fmt::Debug for IntTy { | ||
53 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
54 | fmt::Display::fmt(self, f) | ||
55 | } | ||
56 | } | ||
57 | |||
58 | impl fmt::Display for IntTy { | ||
59 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
60 | write!(f, "{}", self.ty_to_string()) | ||
61 | } | ||
62 | } | ||
63 | |||
64 | impl IntTy { | ||
65 | pub fn isize() -> IntTy { | ||
66 | IntTy { signedness: Signedness::Signed, bitness: IntBitness::Xsize } | ||
67 | } | ||
68 | |||
69 | pub fn i8() -> IntTy { | ||
70 | IntTy { signedness: Signedness::Signed, bitness: IntBitness::X8 } | ||
71 | } | ||
72 | |||
73 | pub fn i16() -> IntTy { | ||
74 | IntTy { signedness: Signedness::Signed, bitness: IntBitness::X16 } | ||
75 | } | ||
76 | |||
77 | pub fn i32() -> IntTy { | ||
78 | IntTy { signedness: Signedness::Signed, bitness: IntBitness::X32 } | ||
79 | } | ||
80 | |||
81 | pub fn i64() -> IntTy { | ||
82 | IntTy { signedness: Signedness::Signed, bitness: IntBitness::X64 } | ||
83 | } | ||
84 | |||
85 | pub fn i128() -> IntTy { | ||
86 | IntTy { signedness: Signedness::Signed, bitness: IntBitness::X128 } | ||
87 | } | ||
88 | |||
89 | pub fn usize() -> IntTy { | ||
90 | IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::Xsize } | ||
91 | } | ||
92 | |||
93 | pub fn u8() -> IntTy { | ||
94 | IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X8 } | ||
95 | } | ||
96 | |||
97 | pub fn u16() -> IntTy { | ||
98 | IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X16 } | ||
99 | } | ||
100 | |||
101 | pub fn u32() -> IntTy { | ||
102 | IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X32 } | ||
103 | } | ||
104 | |||
105 | pub fn u64() -> IntTy { | ||
106 | IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X64 } | ||
107 | } | ||
108 | |||
109 | pub fn u128() -> IntTy { | ||
110 | IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X128 } | ||
111 | } | ||
112 | |||
113 | pub fn ty_to_string(self) -> &'static str { | ||
114 | match (self.signedness, self.bitness) { | ||
115 | (Signedness::Signed, IntBitness::Xsize) => "isize", | ||
116 | (Signedness::Signed, IntBitness::X8) => "i8", | ||
117 | (Signedness::Signed, IntBitness::X16) => "i16", | ||
118 | (Signedness::Signed, IntBitness::X32) => "i32", | ||
119 | (Signedness::Signed, IntBitness::X64) => "i64", | ||
120 | (Signedness::Signed, IntBitness::X128) => "i128", | ||
121 | (Signedness::Unsigned, IntBitness::Xsize) => "usize", | ||
122 | (Signedness::Unsigned, IntBitness::X8) => "u8", | ||
123 | (Signedness::Unsigned, IntBitness::X16) => "u16", | ||
124 | (Signedness::Unsigned, IntBitness::X32) => "u32", | ||
125 | (Signedness::Unsigned, IntBitness::X64) => "u64", | ||
126 | (Signedness::Unsigned, IntBitness::X128) => "u128", | ||
127 | } | ||
128 | } | ||
129 | } | ||
130 | |||
131 | #[derive(Copy, Clone, PartialEq, Eq, Hash)] | ||
132 | pub struct FloatTy { | ||
133 | pub bitness: FloatBitness, | ||
134 | } | ||
135 | |||
136 | impl fmt::Debug for FloatTy { | ||
137 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
138 | fmt::Display::fmt(self, f) | ||
139 | } | ||
140 | } | ||
141 | |||
142 | impl fmt::Display for FloatTy { | ||
143 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
144 | write!(f, "{}", self.ty_to_string()) | ||
145 | } | ||
146 | } | ||
147 | |||
148 | impl FloatTy { | ||
149 | pub fn f32() -> FloatTy { | ||
150 | FloatTy { bitness: FloatBitness::X32 } | ||
151 | } | ||
152 | |||
153 | pub fn f64() -> FloatTy { | ||
154 | FloatTy { bitness: FloatBitness::X64 } | ||
155 | } | ||
156 | |||
157 | pub fn ty_to_string(self) -> &'static str { | ||
158 | match self.bitness { | ||
159 | FloatBitness::X32 => "f32", | ||
160 | FloatBitness::X64 => "f64", | ||
161 | } | ||
162 | } | ||
163 | } | ||
164 | |||
165 | impl From<BuiltinInt> for IntTy { | ||
166 | fn from(t: BuiltinInt) -> Self { | ||
167 | IntTy { signedness: t.signedness, bitness: t.bitness } | ||
168 | } | ||
169 | } | ||
170 | |||
171 | impl From<BuiltinFloat> for FloatTy { | ||
172 | fn from(t: BuiltinFloat) -> Self { | ||
173 | FloatTy { bitness: t.bitness } | ||
174 | } | ||
175 | } | ||
176 | |||
177 | impl From<Option<BuiltinInt>> for Uncertain<IntTy> { | ||
178 | fn from(t: Option<BuiltinInt>) -> Self { | ||
179 | match t { | ||
180 | None => Uncertain::Unknown, | ||
181 | Some(t) => Uncertain::Known(t.into()), | ||
182 | } | ||
183 | } | ||
184 | } | ||
185 | |||
186 | impl From<Option<BuiltinFloat>> for Uncertain<FloatTy> { | ||
187 | fn from(t: Option<BuiltinFloat>) -> Self { | ||
188 | match t { | ||
189 | None => Uncertain::Unknown, | ||
190 | Some(t) => Uncertain::Known(t.into()), | ||
191 | } | ||
192 | } | ||
193 | } | ||
diff --git a/crates/ra_ide_api/src/call_info.rs b/crates/ra_ide_api/src/call_info.rs index 7ebdfc585..d559dc4d0 100644 --- a/crates/ra_ide_api/src/call_info.rs +++ b/crates/ra_ide_api/src/call_info.rs | |||
@@ -23,8 +23,8 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<Cal | |||
23 | let analyzer = hir::SourceAnalyzer::new(db, name_ref, None); | 23 | let analyzer = hir::SourceAnalyzer::new(db, name_ref, None); |
24 | let (mut call_info, has_self) = match &calling_node { | 24 | let (mut call_info, has_self) = match &calling_node { |
25 | FnCallNode::CallExpr(expr) => { | 25 | FnCallNode::CallExpr(expr) => { |
26 | //FIXME: don't poke into Ty | 26 | //FIXME: Type::as_callable is broken |
27 | let (callable_def, _subst) = analyzer.type_of(db, &expr.expr()?)?.as_callable()?; | 27 | let callable_def = analyzer.type_of(db, &expr.expr()?)?.as_callable()?; |
28 | match callable_def { | 28 | match callable_def { |
29 | hir::CallableDef::FunctionId(it) => { | 29 | hir::CallableDef::FunctionId(it) => { |
30 | let fn_def = it.into(); | 30 | let fn_def = it.into(); |
diff --git a/crates/ra_ide_api/src/change.rs b/crates/ra_ide_api/src/change.rs index 0f692460d..84340aff8 100644 --- a/crates/ra_ide_api/src/change.rs +++ b/crates/ra_ide_api/src/change.rs | |||
@@ -171,7 +171,7 @@ impl RootDatabase { | |||
171 | log::info!("apply_change {:?}", change); | 171 | log::info!("apply_change {:?}", change); |
172 | { | 172 | { |
173 | let _p = profile("RootDatabase::apply_change/cancellation"); | 173 | let _p = profile("RootDatabase::apply_change/cancellation"); |
174 | self.salsa_runtime().synthetic_write(Durability::LOW); | 174 | self.salsa_runtime_mut().synthetic_write(Durability::LOW); |
175 | } | 175 | } |
176 | if !change.new_roots.is_empty() { | 176 | if !change.new_roots.is_empty() { |
177 | let mut local_roots = Vec::clone(&self.local_roots()); | 177 | let mut local_roots = Vec::clone(&self.local_roots()); |
diff --git a/crates/ra_ide_api/src/completion/complete_dot.rs b/crates/ra_ide_api/src/completion/complete_dot.rs index 5a3f9b5f6..b6fe48627 100644 --- a/crates/ra_ide_api/src/completion/complete_dot.rs +++ b/crates/ra_ide_api/src/completion/complete_dot.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use hir::{Adt, Ty, TypeCtor}; | 3 | use hir::Type; |
4 | 4 | ||
5 | use crate::completion::completion_item::CompletionKind; | 5 | use crate::completion::completion_item::CompletionKind; |
6 | use crate::{ | 6 | use crate::{ |
@@ -22,12 +22,12 @@ pub(super) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) { | |||
22 | }; | 22 | }; |
23 | 23 | ||
24 | if !ctx.is_call { | 24 | if !ctx.is_call { |
25 | complete_fields(acc, ctx, receiver_ty.clone()); | 25 | complete_fields(acc, ctx, &receiver_ty); |
26 | } | 26 | } |
27 | complete_methods(acc, ctx, receiver_ty.clone()); | 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 ctx.analyzer.impls_future(ctx.db, receiver_ty.into_ty()) { |
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") |
@@ -35,28 +35,18 @@ pub(super) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) { | |||
35 | } | 35 | } |
36 | } | 36 | } |
37 | 37 | ||
38 | fn complete_fields(acc: &mut Completions, ctx: &CompletionContext, receiver: Ty) { | 38 | fn complete_fields(acc: &mut Completions, ctx: &CompletionContext, receiver: &Type) { |
39 | for receiver in ctx.analyzer.autoderef(ctx.db, receiver) { | 39 | for receiver in receiver.autoderef(ctx.db) { |
40 | if let Ty::Apply(a_ty) = receiver { | 40 | for (field, ty) in receiver.fields(ctx.db) { |
41 | match a_ty.ctor { | 41 | acc.add_field(ctx, field, &ty); |
42 | TypeCtor::Adt(Adt::Struct(s)) => { | 42 | } |
43 | for field in s.fields(ctx.db) { | 43 | for (i, ty) in receiver.tuple_fields(ctx.db).into_iter().enumerate() { |
44 | acc.add_field(ctx, field, &a_ty.parameters); | 44 | acc.add_tuple_field(ctx, i, &ty); |
45 | } | 45 | } |
46 | } | ||
47 | // FIXME unions | ||
48 | TypeCtor::Tuple { .. } => { | ||
49 | for (i, ty) in a_ty.parameters.iter().enumerate() { | ||
50 | acc.add_tuple_field(ctx, i, ty); | ||
51 | } | ||
52 | } | ||
53 | _ => {} | ||
54 | } | ||
55 | }; | ||
56 | } | 46 | } |
57 | } | 47 | } |
58 | 48 | ||
59 | fn complete_methods(acc: &mut Completions, ctx: &CompletionContext, receiver: Ty) { | 49 | fn complete_methods(acc: &mut Completions, ctx: &CompletionContext, receiver: &Type) { |
60 | let mut seen_methods = FxHashSet::default(); | 50 | let mut seen_methods = FxHashSet::default(); |
61 | ctx.analyzer.iterate_method_candidates(ctx.db, receiver, None, |_ty, func| { | 51 | ctx.analyzer.iterate_method_candidates(ctx.db, receiver, None, |_ty, func| { |
62 | if func.has_self_param(ctx.db) && seen_methods.insert(func.name(ctx.db)) { | 52 | if func.has_self_param(ctx.db) && seen_methods.insert(func.name(ctx.db)) { |
diff --git a/crates/ra_ide_api/src/completion/complete_postfix.rs b/crates/ra_ide_api/src/completion/complete_postfix.rs index 17b75cf7e..646a30c76 100644 --- a/crates/ra_ide_api/src/completion/complete_postfix.rs +++ b/crates/ra_ide_api/src/completion/complete_postfix.rs | |||
@@ -1,6 +1,5 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use hir::{Ty, TypeCtor}; | ||
4 | use ra_syntax::{ast::AstNode, TextRange, TextUnit}; | 3 | use ra_syntax::{ast::AstNode, TextRange, TextUnit}; |
5 | use ra_text_edit::TextEdit; | 4 | use ra_text_edit::TextEdit; |
6 | 5 | ||
@@ -30,9 +29,12 @@ pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) { | |||
30 | dot_receiver.syntax().text().to_string() | 29 | dot_receiver.syntax().text().to_string() |
31 | }; | 30 | }; |
32 | 31 | ||
33 | let receiver_ty = ctx.analyzer.type_of(ctx.db, &dot_receiver); | 32 | let receiver_ty = match ctx.analyzer.type_of(ctx.db, &dot_receiver) { |
33 | Some(it) => it, | ||
34 | None => return, | ||
35 | }; | ||
34 | 36 | ||
35 | if is_bool_or_unknown(receiver_ty) { | 37 | if receiver_ty.is_bool() || receiver_ty.is_unknown() { |
36 | postfix_snippet(ctx, "if", "if expr {}", &format!("if {} {{$0}}", receiver_text)) | 38 | postfix_snippet(ctx, "if", "if expr {}", &format!("if {} {{$0}}", receiver_text)) |
37 | .add_to(acc); | 39 | .add_to(acc); |
38 | postfix_snippet( | 40 | postfix_snippet( |
@@ -75,14 +77,6 @@ fn postfix_snippet(ctx: &CompletionContext, label: &str, detail: &str, snippet: | |||
75 | .snippet_edit(edit) | 77 | .snippet_edit(edit) |
76 | } | 78 | } |
77 | 79 | ||
78 | fn is_bool_or_unknown(ty: Option<Ty>) -> bool { | ||
79 | match &ty { | ||
80 | Some(Ty::Apply(app)) if app.ctor == TypeCtor::Bool => true, | ||
81 | Some(Ty::Unknown) | None => true, | ||
82 | Some(_) => false, | ||
83 | } | ||
84 | } | ||
85 | |||
86 | #[cfg(test)] | 80 | #[cfg(test)] |
87 | mod tests { | 81 | mod tests { |
88 | use insta::assert_debug_snapshot; | 82 | use insta::assert_debug_snapshot; |
diff --git a/crates/ra_ide_api/src/completion/complete_record_literal.rs b/crates/ra_ide_api/src/completion/complete_record_literal.rs index 45a4a9738..577c394d2 100644 --- a/crates/ra_ide_api/src/completion/complete_record_literal.rs +++ b/crates/ra_ide_api/src/completion/complete_record_literal.rs | |||
@@ -1,7 +1,5 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use hir::Substs; | ||
4 | |||
5 | use crate::completion::{CompletionContext, Completions}; | 3 | use crate::completion::{CompletionContext, Completions}; |
6 | 4 | ||
7 | /// Complete fields in fields literals. | 5 | /// Complete fields in fields literals. |
@@ -15,10 +13,9 @@ pub(super) fn complete_record_literal(acc: &mut Completions, ctx: &CompletionCon | |||
15 | Some(it) => it, | 13 | Some(it) => it, |
16 | _ => return, | 14 | _ => return, |
17 | }; | 15 | }; |
18 | let substs = &ty.substs().unwrap_or_else(Substs::empty); | ||
19 | 16 | ||
20 | for field in variant.fields(ctx.db) { | 17 | for (field, field_ty) in ty.variant_fields(ctx.db, variant) { |
21 | acc.add_field(ctx, field, substs); | 18 | acc.add_field(ctx, field, &field_ty); |
22 | } | 19 | } |
23 | } | 20 | } |
24 | 21 | ||
diff --git a/crates/ra_ide_api/src/completion/complete_record_pattern.rs b/crates/ra_ide_api/src/completion/complete_record_pattern.rs index aa0fd6d24..a56c7e3a1 100644 --- a/crates/ra_ide_api/src/completion/complete_record_pattern.rs +++ b/crates/ra_ide_api/src/completion/complete_record_pattern.rs | |||
@@ -1,7 +1,5 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use hir::Substs; | ||
4 | |||
5 | use crate::completion::{CompletionContext, Completions}; | 3 | use crate::completion::{CompletionContext, Completions}; |
6 | 4 | ||
7 | pub(super) fn complete_record_pattern(acc: &mut Completions, ctx: &CompletionContext) { | 5 | pub(super) fn complete_record_pattern(acc: &mut Completions, ctx: &CompletionContext) { |
@@ -14,10 +12,9 @@ pub(super) fn complete_record_pattern(acc: &mut Completions, ctx: &CompletionCon | |||
14 | Some(it) => it, | 12 | Some(it) => it, |
15 | _ => return, | 13 | _ => return, |
16 | }; | 14 | }; |
17 | let substs = &ty.substs().unwrap_or_else(Substs::empty); | ||
18 | 15 | ||
19 | for field in variant.fields(ctx.db) { | 16 | for (field, field_ty) in ty.variant_fields(ctx.db, variant) { |
20 | acc.add_field(ctx, field, substs); | 17 | acc.add_field(ctx, field, &field_ty); |
21 | } | 18 | } |
22 | } | 19 | } |
23 | 20 | ||
diff --git a/crates/ra_ide_api/src/completion/presentation.rs b/crates/ra_ide_api/src/completion/presentation.rs index 85b053a6e..5f056730a 100644 --- a/crates/ra_ide_api/src/completion/presentation.rs +++ b/crates/ra_ide_api/src/completion/presentation.rs | |||
@@ -1,12 +1,12 @@ | |||
1 | //! This modules takes care of rendering various definitions as completion items. | 1 | //! This modules takes care of rendering various definitions as completion items. |
2 | 2 | ||
3 | use hir::{db::HirDatabase, Docs, HasAttrs, HasSource, HirDisplay, ScopeDef, Ty, TypeWalk}; | 3 | use hir::{db::HirDatabase, Docs, HasAttrs, HasSource, HirDisplay, ScopeDef, Type}; |
4 | use join_to_string::join; | 4 | use join_to_string::join; |
5 | use ra_syntax::ast::NameOwner; | 5 | use ra_syntax::ast::NameOwner; |
6 | use test_utils::tested_by; | 6 | use test_utils::tested_by; |
7 | 7 | ||
8 | use crate::completion::{ | 8 | use crate::completion::{ |
9 | db, CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, Completions, | 9 | CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, Completions, |
10 | }; | 10 | }; |
11 | 11 | ||
12 | use crate::display::{const_label, function_label, macro_label, type_label}; | 12 | use crate::display::{const_label, function_label, macro_label, type_label}; |
@@ -16,7 +16,7 @@ impl Completions { | |||
16 | &mut self, | 16 | &mut self, |
17 | ctx: &CompletionContext, | 17 | ctx: &CompletionContext, |
18 | field: hir::StructField, | 18 | field: hir::StructField, |
19 | substs: &hir::Substs, | 19 | ty: &Type, |
20 | ) { | 20 | ) { |
21 | let is_deprecated = is_deprecated(field, ctx.db); | 21 | let is_deprecated = is_deprecated(field, ctx.db); |
22 | CompletionItem::new( | 22 | CompletionItem::new( |
@@ -25,13 +25,13 @@ impl Completions { | |||
25 | field.name(ctx.db).to_string(), | 25 | field.name(ctx.db).to_string(), |
26 | ) | 26 | ) |
27 | .kind(CompletionItemKind::Field) | 27 | .kind(CompletionItemKind::Field) |
28 | .detail(field.ty(ctx.db).subst(substs).display(ctx.db).to_string()) | 28 | .detail(ty.display(ctx.db).to_string()) |
29 | .set_documentation(field.docs(ctx.db)) | 29 | .set_documentation(field.docs(ctx.db)) |
30 | .set_deprecated(is_deprecated) | 30 | .set_deprecated(is_deprecated) |
31 | .add_to(self); | 31 | .add_to(self); |
32 | } | 32 | } |
33 | 33 | ||
34 | pub(crate) fn add_tuple_field(&mut self, ctx: &CompletionContext, field: usize, ty: &hir::Ty) { | 34 | pub(crate) fn add_tuple_field(&mut self, ctx: &CompletionContext, field: usize, ty: &Type) { |
35 | CompletionItem::new(CompletionKind::Reference, ctx.source_range(), field.to_string()) | 35 | CompletionItem::new(CompletionKind::Reference, ctx.source_range(), field.to_string()) |
36 | .kind(CompletionItemKind::Field) | 36 | .kind(CompletionItemKind::Field) |
37 | .detail(ty.display(ctx.db).to_string()) | 37 | .detail(ty.display(ctx.db).to_string()) |
@@ -98,7 +98,7 @@ impl Completions { | |||
98 | CompletionItem::new(completion_kind, ctx.source_range(), local_name.clone()); | 98 | CompletionItem::new(completion_kind, ctx.source_range(), local_name.clone()); |
99 | if let ScopeDef::Local(local) = resolution { | 99 | if let ScopeDef::Local(local) = resolution { |
100 | let ty = local.ty(ctx.db); | 100 | let ty = local.ty(ctx.db); |
101 | if ty != Ty::Unknown { | 101 | if !ty.is_unknown() { |
102 | completion_item = completion_item.detail(ty.display(ctx.db).to_string()); | 102 | completion_item = completion_item.detail(ty.display(ctx.db).to_string()); |
103 | } | 103 | } |
104 | }; | 104 | }; |
@@ -108,19 +108,17 @@ impl Completions { | |||
108 | && !ctx.has_type_args | 108 | && !ctx.has_type_args |
109 | && ctx.db.feature_flags.get("completion.insertion.add-call-parenthesis") | 109 | && ctx.db.feature_flags.get("completion.insertion.add-call-parenthesis") |
110 | { | 110 | { |
111 | let generic_def: Option<hir::GenericDef> = match resolution { | 111 | let has_non_default_type_params = match resolution { |
112 | ScopeDef::ModuleDef(Adt(it)) => Some((*it).into()), | 112 | ScopeDef::ModuleDef(Adt(it)) => it.has_non_default_type_params(ctx.db), |
113 | ScopeDef::ModuleDef(TypeAlias(it)) => Some((*it).into()), | 113 | ScopeDef::ModuleDef(TypeAlias(it)) => it.has_non_default_type_params(ctx.db), |
114 | _ => None, | 114 | _ => false, |
115 | }; | 115 | }; |
116 | if let Some(def) = generic_def { | 116 | if has_non_default_type_params { |
117 | if has_non_default_type_params(def, ctx.db) { | 117 | tested_by!(inserts_angle_brackets_for_generics); |
118 | tested_by!(inserts_angle_brackets_for_generics); | 118 | completion_item = completion_item |
119 | completion_item = completion_item | 119 | .lookup_by(local_name.clone()) |
120 | .lookup_by(local_name.clone()) | 120 | .label(format!("{}<…>", local_name)) |
121 | .label(format!("{}<…>", local_name)) | 121 | .insert_snippet(format!("{}<$0>", local_name)); |
122 | .insert_snippet(format!("{}<$0>", local_name)); | ||
123 | } | ||
124 | } | 122 | } |
125 | } | 123 | } |
126 | 124 | ||
@@ -291,11 +289,6 @@ fn is_deprecated(node: impl HasAttrs, db: &impl HirDatabase) -> bool { | |||
291 | node.attrs(db).by_key("deprecated").exists() | 289 | node.attrs(db).by_key("deprecated").exists() |
292 | } | 290 | } |
293 | 291 | ||
294 | fn has_non_default_type_params(def: hir::GenericDef, db: &db::RootDatabase) -> bool { | ||
295 | let subst = db.generic_defaults(def.into()); | ||
296 | subst.iter().any(|ty| ty == &Ty::Unknown) | ||
297 | } | ||
298 | |||
299 | #[cfg(test)] | 292 | #[cfg(test)] |
300 | mod tests { | 293 | mod tests { |
301 | use insta::assert_debug_snapshot; | 294 | use insta::assert_debug_snapshot; |
diff --git a/crates/ra_ide_api/src/db.rs b/crates/ra_ide_api/src/db.rs index c2a9dcdd1..f739ebecd 100644 --- a/crates/ra_ide_api/src/db.rs +++ b/crates/ra_ide_api/src/db.rs | |||
@@ -65,6 +65,9 @@ impl salsa::Database for RootDatabase { | |||
65 | fn salsa_runtime(&self) -> &salsa::Runtime<RootDatabase> { | 65 | fn salsa_runtime(&self) -> &salsa::Runtime<RootDatabase> { |
66 | &self.runtime | 66 | &self.runtime |
67 | } | 67 | } |
68 | fn salsa_runtime_mut(&mut self) -> &mut salsa::Runtime<Self> { | ||
69 | &mut self.runtime | ||
70 | } | ||
68 | fn on_propagated_panic(&self) -> ! { | 71 | fn on_propagated_panic(&self) -> ! { |
69 | Canceled::throw() | 72 | Canceled::throw() |
70 | } | 73 | } |
diff --git a/crates/ra_ide_api/src/goto_type_definition.rs b/crates/ra_ide_api/src/goto_type_definition.rs index 28a83a3e2..992a08809 100644 --- a/crates/ra_ide_api/src/goto_type_definition.rs +++ b/crates/ra_ide_api/src/goto_type_definition.rs | |||
@@ -24,7 +24,7 @@ pub(crate) fn goto_type_definition( | |||
24 | 24 | ||
25 | let analyzer = hir::SourceAnalyzer::new(db, token.with_value(&node), None); | 25 | let analyzer = hir::SourceAnalyzer::new(db, token.with_value(&node), None); |
26 | 26 | ||
27 | let ty: hir::Ty = if let Some(ty) = | 27 | let ty: hir::Type = if let Some(ty) = |
28 | ast::Expr::cast(node.clone()).and_then(|e| analyzer.type_of(db, &e)) | 28 | ast::Expr::cast(node.clone()).and_then(|e| analyzer.type_of(db, &e)) |
29 | { | 29 | { |
30 | ty | 30 | ty |
@@ -35,7 +35,7 @@ pub(crate) fn goto_type_definition( | |||
35 | return None; | 35 | return None; |
36 | }; | 36 | }; |
37 | 37 | ||
38 | let adt_def = analyzer.autoderef(db, ty).find_map(|ty| ty.as_adt().map(|adt| adt.0))?; | 38 | let adt_def = ty.autoderef(db).find_map(|ty| ty.as_adt())?; |
39 | 39 | ||
40 | let nav = adt_def.to_nav(db); | 40 | let nav = adt_def.to_nav(db); |
41 | Some(RangeInfo::new(node.text_range(), vec![nav])) | 41 | Some(RangeInfo::new(node.text_range(), vec![nav])) |
diff --git a/crates/ra_ide_api/src/impls.rs b/crates/ra_ide_api/src/impls.rs index 2b3100fc3..b3ebd9145 100644 --- a/crates/ra_ide_api/src/impls.rs +++ b/crates/ra_ide_api/src/impls.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use hir::{db::HirDatabase, ApplicationTy, FromSource, Ty, TypeCtor}; | 3 | use hir::{ApplicationTy, FromSource, ImplBlock, Ty, TypeCtor}; |
4 | use ra_db::SourceDatabase; | 4 | use ra_db::SourceDatabase; |
5 | use ra_syntax::{algo::find_node_at_offset, ast, AstNode}; | 5 | use ra_syntax::{algo::find_node_at_offset, ast, AstNode}; |
6 | 6 | ||
@@ -56,11 +56,11 @@ fn impls_for_def( | |||
56 | }; | 56 | }; |
57 | 57 | ||
58 | let krate = module.krate(); | 58 | let krate = module.krate(); |
59 | let impls = db.impls_in_crate(krate); | 59 | let impls = ImplBlock::all_in_crate(db, krate); |
60 | 60 | ||
61 | Some( | 61 | Some( |
62 | impls | 62 | impls |
63 | .all_impls() | 63 | .into_iter() |
64 | .filter(|impl_block| is_equal_for_find_impls(&ty, &impl_block.target_ty(db))) | 64 | .filter(|impl_block| is_equal_for_find_impls(&ty, &impl_block.target_ty(db))) |
65 | .map(|imp| imp.to_nav(db)) | 65 | .map(|imp| imp.to_nav(db)) |
66 | .collect(), | 66 | .collect(), |
@@ -77,9 +77,9 @@ fn impls_for_trait( | |||
77 | let tr = hir::Trait::from_source(db, src)?; | 77 | let tr = hir::Trait::from_source(db, src)?; |
78 | 78 | ||
79 | let krate = module.krate(); | 79 | let krate = module.krate(); |
80 | let impls = db.impls_in_crate(krate); | 80 | let impls = ImplBlock::for_trait(db, krate, tr); |
81 | 81 | ||
82 | Some(impls.lookup_impl_blocks_for_trait(tr).map(|imp| imp.to_nav(db)).collect()) | 82 | Some(impls.into_iter().map(|imp| imp.to_nav(db)).collect()) |
83 | } | 83 | } |
84 | 84 | ||
85 | fn is_equal_for_find_impls(original_ty: &Ty, impl_ty: &Ty) -> bool { | 85 | fn is_equal_for_find_impls(original_ty: &Ty, impl_ty: &Ty) -> bool { |
diff --git a/crates/ra_ide_api/src/inlay_hints.rs b/crates/ra_ide_api/src/inlay_hints.rs index 24a7ca5e7..45149bf0c 100644 --- a/crates/ra_ide_api/src/inlay_hints.rs +++ b/crates/ra_ide_api/src/inlay_hints.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use crate::{db::RootDatabase, FileId}; | 3 | use crate::{db::RootDatabase, FileId}; |
4 | use hir::{HirDisplay, SourceAnalyzer, Ty}; | 4 | use hir::{HirDisplay, SourceAnalyzer}; |
5 | use ra_syntax::{ | 5 | use ra_syntax::{ |
6 | ast::{self, AstNode, TypeAscriptionOwner}, | 6 | ast::{self, AstNode, TypeAscriptionOwner}, |
7 | match_ast, SmolStr, SourceFile, SyntaxKind, SyntaxNode, TextRange, | 7 | match_ast, SmolStr, SourceFile, SyntaxKind, SyntaxNode, TextRange, |
@@ -100,8 +100,11 @@ fn get_pat_type_hints( | |||
100 | .into_iter() | 100 | .into_iter() |
101 | .filter(|pat| !skip_root_pat_hint || pat != original_pat) | 101 | .filter(|pat| !skip_root_pat_hint || pat != original_pat) |
102 | .filter_map(|pat| { | 102 | .filter_map(|pat| { |
103 | get_node_displayable_type(db, &analyzer, &pat) | 103 | let ty = analyzer.type_of_pat(db, &pat)?; |
104 | .map(|pat_type| (pat.syntax().text_range(), pat_type)) | 104 | if ty.is_unknown() { |
105 | return None; | ||
106 | } | ||
107 | Some((pat.syntax().text_range(), ty)) | ||
105 | }) | 108 | }) |
106 | .map(|(range, pat_type)| InlayHint { | 109 | .map(|(range, pat_type)| InlayHint { |
107 | range, | 110 | range, |
@@ -158,20 +161,6 @@ fn get_leaf_pats(root_pat: ast::Pat) -> Vec<ast::Pat> { | |||
158 | leaf_pats | 161 | leaf_pats |
159 | } | 162 | } |
160 | 163 | ||
161 | fn get_node_displayable_type( | ||
162 | db: &RootDatabase, | ||
163 | analyzer: &SourceAnalyzer, | ||
164 | node_pat: &ast::Pat, | ||
165 | ) -> Option<Ty> { | ||
166 | analyzer.type_of_pat(db, node_pat).and_then(|resolved_type| { | ||
167 | if let Ty::Apply(_) = resolved_type { | ||
168 | Some(resolved_type) | ||
169 | } else { | ||
170 | None | ||
171 | } | ||
172 | }) | ||
173 | } | ||
174 | |||
175 | #[cfg(test)] | 164 | #[cfg(test)] |
176 | mod tests { | 165 | mod tests { |
177 | use crate::mock_analysis::single_file; | 166 | use crate::mock_analysis::single_file; |
diff --git a/crates/ra_ide_api/src/references/name_definition.rs b/crates/ra_ide_api/src/references/name_definition.rs index aca23f79e..cf12db066 100644 --- a/crates/ra_ide_api/src/references/name_definition.rs +++ b/crates/ra_ide_api/src/references/name_definition.rs | |||
@@ -46,6 +46,7 @@ pub(super) fn from_struct_field(db: &RootDatabase, field: StructField) -> NameDe | |||
46 | let container = parent.module(db); | 46 | let container = parent.module(db); |
47 | let visibility = match parent { | 47 | let visibility = match parent { |
48 | VariantDef::Struct(s) => s.source(db).value.visibility(), | 48 | VariantDef::Struct(s) => s.source(db).value.visibility(), |
49 | VariantDef::Union(e) => e.source(db).value.visibility(), | ||
49 | VariantDef::EnumVariant(e) => e.source(db).value.parent_enum().visibility(), | 50 | VariantDef::EnumVariant(e) => e.source(db).value.parent_enum().visibility(), |
50 | }; | 51 | }; |
51 | NameDefinition { kind, container, visibility } | 52 | NameDefinition { kind, container, visibility } |
diff --git a/crates/ra_ide_api/src/syntax_highlighting.rs b/crates/ra_ide_api/src/syntax_highlighting.rs index 2b653fe8f..10165a9bb 100644 --- a/crates/ra_ide_api/src/syntax_highlighting.rs +++ b/crates/ra_ide_api/src/syntax_highlighting.rs | |||
@@ -2,7 +2,7 @@ | |||
2 | 2 | ||
3 | use rustc_hash::{FxHashMap, FxHashSet}; | 3 | use rustc_hash::{FxHashMap, FxHashSet}; |
4 | 4 | ||
5 | use hir::{Mutability, Name, Source}; | 5 | use hir::{Name, Source}; |
6 | use ra_db::SourceDatabase; | 6 | use ra_db::SourceDatabase; |
7 | use ra_prof::profile; | 7 | use ra_prof::profile; |
8 | use ra_syntax::{ast, AstNode, Direction, SyntaxElement, SyntaxKind, SyntaxKind::*, TextRange, T}; | 8 | use ra_syntax::{ast, AstNode, Direction, SyntaxElement, SyntaxKind, SyntaxKind::*, TextRange, T}; |
@@ -230,11 +230,10 @@ fn highlight_name(db: &RootDatabase, name_kind: NameKind) -> &'static str { | |||
230 | Local(local) => { | 230 | Local(local) => { |
231 | if local.is_mut(db) { | 231 | if local.is_mut(db) { |
232 | "variable.mut" | 232 | "variable.mut" |
233 | } else if local.ty(db).is_mutable_reference() { | ||
234 | "variable.mut" | ||
233 | } else { | 235 | } else { |
234 | match local.ty(db).as_reference() { | 236 | "variable" |
235 | Some((_, Mutability::Mut)) => "variable.mut", | ||
236 | _ => "variable", | ||
237 | } | ||
238 | } | 237 | } |
239 | } | 238 | } |
240 | } | 239 | } |
diff --git a/crates/ra_lsp_server/Cargo.toml b/crates/ra_lsp_server/Cargo.toml index 72dbe06dc..58b9cfaa0 100644 --- a/crates/ra_lsp_server/Cargo.toml +++ b/crates/ra_lsp_server/Cargo.toml | |||
@@ -17,7 +17,7 @@ flexi_logger = "0.14.0" | |||
17 | log = "0.4.3" | 17 | log = "0.4.3" |
18 | lsp-types = { version = "0.61.0", features = ["proposed"] } | 18 | lsp-types = { version = "0.61.0", features = ["proposed"] } |
19 | rustc-hash = "1.0" | 19 | rustc-hash = "1.0" |
20 | parking_lot = "0.9.0" | 20 | parking_lot = "0.10.0" |
21 | jod-thread = "0.1.0" | 21 | jod-thread = "0.1.0" |
22 | ra_vfs = "0.5.0" | 22 | ra_vfs = "0.5.0" |
23 | ra_syntax = { path = "../ra_syntax" } | 23 | ra_syntax = { path = "../ra_syntax" } |