aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/code_model.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/code_model.rs')
-rw-r--r--crates/ra_hir/src/code_model.rs179
1 files changed, 134 insertions, 45 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index 8c5e1b746..5d88c5c64 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -1,5 +1,5 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2use std::sync::Arc; 2use std::{iter, sync::Arc};
3 3
4use arrayvec::ArrayVec; 4use arrayvec::ArrayVec;
5use either::Either; 5use either::Either;
@@ -12,6 +12,7 @@ use hir_def::{
12 import_map, 12 import_map,
13 per_ns::PerNs, 13 per_ns::PerNs,
14 resolver::{HasResolver, Resolver}, 14 resolver::{HasResolver, Resolver},
15 src::HasSource as _,
15 type_ref::{Mutability, TypeRef}, 16 type_ref::{Mutability, TypeRef},
16 AdtId, AssocContainerId, ConstId, DefWithBodyId, EnumId, FunctionId, GenericDefId, HasModule, 17 AdtId, AssocContainerId, ConstId, DefWithBodyId, EnumId, FunctionId, GenericDefId, HasModule,
17 ImplId, LocalEnumVariantId, LocalFieldId, LocalModuleId, Lookup, ModuleId, StaticId, StructId, 18 ImplId, LocalEnumVariantId, LocalFieldId, LocalModuleId, Lookup, ModuleId, StaticId, StructId,
@@ -25,21 +26,22 @@ use hir_expand::{
25use hir_ty::{ 26use hir_ty::{
26 autoderef, 27 autoderef,
27 display::{HirDisplayError, HirFormatter}, 28 display::{HirDisplayError, HirFormatter},
28 expr::ExprValidator, 29 method_resolution, ApplicationTy, CallableDefId, Canonical, FnSig, GenericPredicate,
29 method_resolution, 30 InEnvironment, Substs, TraitEnvironment, Ty, TyDefId, TypeCtor,
30 unsafe_validation::UnsafeValidator,
31 ApplicationTy, Canonical, GenericPredicate, InEnvironment, Substs, TraitEnvironment, Ty,
32 TyDefId, TypeCtor,
33}; 31};
34use ra_db::{CrateId, CrateName, Edition, FileId}; 32use ra_db::{CrateId, Edition, FileId};
35use ra_prof::profile; 33use ra_prof::profile;
36use ra_syntax::ast::{self, AttrsOwner, NameOwner}; 34use ra_syntax::{
35 ast::{self, AttrsOwner, NameOwner},
36 AstNode,
37};
37use rustc_hash::FxHashSet; 38use rustc_hash::FxHashSet;
39use stdx::impl_from;
38 40
39use crate::{ 41use crate::{
40 db::{DefDatabase, HirDatabase}, 42 db::{DefDatabase, HirDatabase},
41 has_source::HasSource, 43 has_source::HasSource,
42 CallableDef, HirDisplay, InFile, Name, 44 HirDisplay, InFile, Name,
43}; 45};
44 46
45/// hir::Crate describes a single crate. It's the main interface with which 47/// hir::Crate describes a single crate. It's the main interface with which
@@ -94,8 +96,8 @@ impl Crate {
94 db.crate_graph()[self.id].edition 96 db.crate_graph()[self.id].edition
95 } 97 }
96 98
97 pub fn display_name(self, db: &dyn HirDatabase) -> Option<CrateName> { 99 pub fn display_name(self, db: &dyn HirDatabase) -> Option<String> {
98 db.crate_graph()[self.id].display_name.as_ref().cloned() 100 db.crate_graph()[self.id].display_name.clone()
99 } 101 }
100 102
101 pub fn query_external_importables( 103 pub fn query_external_importables(
@@ -139,8 +141,8 @@ pub enum ModuleDef {
139 TypeAlias(TypeAlias), 141 TypeAlias(TypeAlias),
140 BuiltinType(BuiltinType), 142 BuiltinType(BuiltinType),
141} 143}
142impl_froms!( 144impl_from!(
143 ModuleDef: Module, 145 Module,
144 Function, 146 Function,
145 Adt(Struct, Enum, Union), 147 Adt(Struct, Enum, Union),
146 EnumVariant, 148 EnumVariant,
@@ -149,6 +151,7 @@ impl_froms!(
149 Trait, 151 Trait,
150 TypeAlias, 152 TypeAlias,
151 BuiltinType 153 BuiltinType
154 for ModuleDef
152); 155);
153 156
154impl ModuleDef { 157impl ModuleDef {
@@ -376,8 +379,8 @@ pub struct Field {
376 379
377#[derive(Debug, PartialEq, Eq)] 380#[derive(Debug, PartialEq, Eq)]
378pub enum FieldSource { 381pub enum FieldSource {
379 Named(ast::RecordFieldDef), 382 Named(ast::RecordField),
380 Pos(ast::TupleFieldDef), 383 Pos(ast::TupleField),
381} 384}
382 385
383impl Field { 386impl Field {
@@ -556,7 +559,7 @@ pub enum Adt {
556 Union(Union), 559 Union(Union),
557 Enum(Enum), 560 Enum(Enum),
558} 561}
559impl_froms!(Adt: Struct, Union, Enum); 562impl_from!(Struct, Union, Enum for Adt);
560 563
561impl Adt { 564impl Adt {
562 pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool { 565 pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool {
@@ -599,7 +602,7 @@ pub enum VariantDef {
599 Union(Union), 602 Union(Union),
600 EnumVariant(EnumVariant), 603 EnumVariant(EnumVariant),
601} 604}
602impl_froms!(VariantDef: Struct, Union, EnumVariant); 605impl_from!(Struct, Union, EnumVariant for VariantDef);
603 606
604impl VariantDef { 607impl VariantDef {
605 pub fn fields(self, db: &dyn HirDatabase) -> Vec<Field> { 608 pub fn fields(self, db: &dyn HirDatabase) -> Vec<Field> {
@@ -642,8 +645,7 @@ pub enum DefWithBody {
642 Static(Static), 645 Static(Static),
643 Const(Const), 646 Const(Const),
644} 647}
645 648impl_from!(Function, Const, Static for DefWithBody);
646impl_froms!(DefWithBody: Function, Const, Static);
647 649
648impl DefWithBody { 650impl DefWithBody {
649 pub fn module(self, db: &dyn HirDatabase) -> Module { 651 pub fn module(self, db: &dyn HirDatabase) -> Module {
@@ -694,13 +696,7 @@ impl Function {
694 } 696 }
695 697
696 pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) { 698 pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) {
697 let _p = profile("Function::diagnostics"); 699 hir_ty::diagnostics::validate_body(db, self.id.into(), sink)
698 let infer = db.infer(self.id.into());
699 infer.add_diagnostics(db, self.id, sink);
700 let mut validator = ExprValidator::new(self.id, infer.clone(), sink);
701 validator.validate_body(db);
702 let mut validator = UnsafeValidator::new(self.id, infer, sink);
703 validator.validate_body(db);
704 } 700 }
705} 701}
706 702
@@ -945,14 +941,15 @@ pub enum GenericDef {
945 // consts can have type parameters from their parents (i.e. associated consts of traits) 941 // consts can have type parameters from their parents (i.e. associated consts of traits)
946 Const(Const), 942 Const(Const),
947} 943}
948impl_froms!( 944impl_from!(
949 GenericDef: Function, 945 Function,
950 Adt(Struct, Enum, Union), 946 Adt(Struct, Enum, Union),
951 Trait, 947 Trait,
952 TypeAlias, 948 TypeAlias,
953 ImplDef, 949 ImplDef,
954 EnumVariant, 950 EnumVariant,
955 Const 951 Const
952 for GenericDef
956); 953);
957 954
958impl GenericDef { 955impl GenericDef {
@@ -973,6 +970,16 @@ pub struct Local {
973} 970}
974 971
975impl Local { 972impl Local {
973 pub fn is_param(self, db: &dyn HirDatabase) -> bool {
974 let src = self.source(db);
975 match src.value {
976 Either::Left(bind_pat) => {
977 bind_pat.syntax().ancestors().any(|it| ast::Param::can_cast(it.kind()))
978 }
979 Either::Right(_self_param) => true,
980 }
981 }
982
976 // FIXME: why is this an option? It shouldn't be? 983 // FIXME: why is this an option? It shouldn't be?
977 pub fn name(self, db: &dyn HirDatabase) -> Option<Name> { 984 pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
978 let body = db.body(self.parent.into()); 985 let body = db.body(self.parent.into());
@@ -1071,12 +1078,14 @@ pub struct ImplDef {
1071 1078
1072impl ImplDef { 1079impl ImplDef {
1073 pub fn all_in_crate(db: &dyn HirDatabase, krate: Crate) -> Vec<ImplDef> { 1080 pub fn all_in_crate(db: &dyn HirDatabase, krate: Crate) -> Vec<ImplDef> {
1074 let impls = db.impls_in_crate(krate.id); 1081 let inherent = db.inherent_impls_in_crate(krate.id);
1075 impls.all_impls().map(Self::from).collect() 1082 let trait_ = db.trait_impls_in_crate(krate.id);
1083
1084 inherent.all_impls().chain(trait_.all_impls()).map(Self::from).collect()
1076 } 1085 }
1077 pub fn for_trait(db: &dyn HirDatabase, krate: Crate, trait_: Trait) -> Vec<ImplDef> { 1086 pub fn for_trait(db: &dyn HirDatabase, krate: Crate, trait_: Trait) -> Vec<ImplDef> {
1078 let impls = db.impls_in_crate(krate.id); 1087 let impls = db.trait_impls_in_crate(krate.id);
1079 impls.lookup_impl_defs_for_trait(trait_.id).map(Self::from).collect() 1088 impls.for_trait(trait_.id).map(Self::from).collect()
1080 } 1089 }
1081 1090
1082 pub fn target_trait(self, db: &dyn HirDatabase) -> Option<TypeRef> { 1091 pub fn target_trait(self, db: &dyn HirDatabase) -> Option<TypeRef> {
@@ -1178,6 +1187,12 @@ impl Type {
1178 Type::new(db, krate, def, ty) 1187 Type::new(db, krate, def, ty)
1179 } 1188 }
1180 1189
1190 pub fn is_unit(&self) -> bool {
1191 matches!(
1192 self.ty.value,
1193 Ty::Apply(ApplicationTy { ctor: TypeCtor::Tuple { cardinality: 0 }, .. })
1194 )
1195 }
1181 pub fn is_bool(&self) -> bool { 1196 pub fn is_bool(&self) -> bool {
1182 matches!(self.ty.value, Ty::Apply(ApplicationTy { ctor: TypeCtor::Bool, .. })) 1197 matches!(self.ty.value, Ty::Apply(ApplicationTy { ctor: TypeCtor::Bool, .. }))
1183 } 1198 }
@@ -1205,7 +1220,7 @@ impl Type {
1205 None => return false, 1220 None => return false,
1206 }; 1221 };
1207 1222
1208 let canonical_ty = Canonical { value: self.ty.value.clone(), num_vars: 0 }; 1223 let canonical_ty = Canonical { value: self.ty.value.clone(), kinds: Arc::new([]) };
1209 method_resolution::implements_trait( 1224 method_resolution::implements_trait(
1210 &canonical_ty, 1225 &canonical_ty,
1211 db, 1226 db,
@@ -1229,15 +1244,20 @@ impl Type {
1229 self.ty.environment.clone(), 1244 self.ty.environment.clone(),
1230 hir_ty::Obligation::Trait(trait_ref), 1245 hir_ty::Obligation::Trait(trait_ref),
1231 ), 1246 ),
1232 num_vars: 0, 1247 kinds: Arc::new([]),
1233 }; 1248 };
1234 1249
1235 db.trait_solve(self.krate, goal).is_some() 1250 db.trait_solve(self.krate, goal).is_some()
1236 } 1251 }
1237 1252
1238 // FIXME: this method is broken, as it doesn't take closures into account. 1253 pub fn as_callable(&self, db: &dyn HirDatabase) -> Option<Callable> {
1239 pub fn as_callable(&self) -> Option<CallableDef> { 1254 let def = match self.ty.value {
1240 Some(self.ty.value.as_callable()?.0) 1255 Ty::Apply(ApplicationTy { ctor: TypeCtor::FnDef(def), parameters: _ }) => Some(def),
1256 _ => None,
1257 };
1258
1259 let sig = self.ty.value.callable_sig(db)?;
1260 Some(Callable { ty: self.clone(), sig, def, is_bound_method: false })
1241 } 1261 }
1242 1262
1243 pub fn is_closure(&self) -> bool { 1263 pub fn is_closure(&self) -> bool {
@@ -1304,7 +1324,7 @@ impl Type {
1304 pub fn autoderef<'a>(&'a self, db: &'a dyn HirDatabase) -> impl Iterator<Item = Type> + 'a { 1324 pub fn autoderef<'a>(&'a self, db: &'a dyn HirDatabase) -> impl Iterator<Item = Type> + 'a {
1305 // There should be no inference vars in types passed here 1325 // There should be no inference vars in types passed here
1306 // FIXME check that? 1326 // FIXME check that?
1307 let canonical = Canonical { value: self.ty.value.clone(), num_vars: 0 }; 1327 let canonical = Canonical { value: self.ty.value.clone(), kinds: Arc::new([]) };
1308 let environment = self.ty.environment.clone(); 1328 let environment = self.ty.environment.clone();
1309 let ty = InEnvironment { value: canonical, environment }; 1329 let ty = InEnvironment { value: canonical, environment };
1310 autoderef(db, Some(self.krate), ty) 1330 autoderef(db, Some(self.krate), ty)
@@ -1321,10 +1341,10 @@ impl Type {
1321 mut callback: impl FnMut(AssocItem) -> Option<T>, 1341 mut callback: impl FnMut(AssocItem) -> Option<T>,
1322 ) -> Option<T> { 1342 ) -> Option<T> {
1323 for krate in self.ty.value.def_crates(db, krate.id)? { 1343 for krate in self.ty.value.def_crates(db, krate.id)? {
1324 let impls = db.impls_in_crate(krate); 1344 let impls = db.inherent_impls_in_crate(krate);
1325 1345
1326 for impl_def in impls.lookup_impl_defs(&self.ty.value) { 1346 for impl_def in impls.for_self_ty(&self.ty.value) {
1327 for &item in db.impl_data(impl_def).items.iter() { 1347 for &item in db.impl_data(*impl_def).items.iter() {
1328 if let Some(result) = callback(item.into()) { 1348 if let Some(result) = callback(item.into()) {
1329 return Some(result); 1349 return Some(result);
1330 } 1350 }
@@ -1345,7 +1365,7 @@ impl Type {
1345 // There should be no inference vars in types passed here 1365 // There should be no inference vars in types passed here
1346 // FIXME check that? 1366 // FIXME check that?
1347 // FIXME replace Unknown by bound vars here 1367 // FIXME replace Unknown by bound vars here
1348 let canonical = Canonical { value: self.ty.value.clone(), num_vars: 0 }; 1368 let canonical = Canonical { value: self.ty.value.clone(), kinds: Arc::new([]) };
1349 1369
1350 let env = self.ty.environment.clone(); 1370 let env = self.ty.environment.clone();
1351 let krate = krate.id; 1371 let krate = krate.id;
@@ -1376,7 +1396,7 @@ impl Type {
1376 // There should be no inference vars in types passed here 1396 // There should be no inference vars in types passed here
1377 // FIXME check that? 1397 // FIXME check that?
1378 // FIXME replace Unknown by bound vars here 1398 // FIXME replace Unknown by bound vars here
1379 let canonical = Canonical { value: self.ty.value.clone(), num_vars: 0 }; 1399 let canonical = Canonical { value: self.ty.value.clone(), kinds: Arc::new([]) };
1380 1400
1381 let env = self.ty.environment.clone(); 1401 let env = self.ty.environment.clone();
1382 let krate = krate.id; 1402 let krate = krate.id;
@@ -1522,6 +1542,74 @@ impl HirDisplay for Type {
1522 } 1542 }
1523} 1543}
1524 1544
1545// FIXME: closures
1546#[derive(Debug)]
1547pub struct Callable {
1548 ty: Type,
1549 sig: FnSig,
1550 def: Option<CallableDefId>,
1551 pub(crate) is_bound_method: bool,
1552}
1553
1554pub enum CallableKind {
1555 Function(Function),
1556 TupleStruct(Struct),
1557 TupleEnumVariant(EnumVariant),
1558 Closure,
1559}
1560
1561impl Callable {
1562 pub fn kind(&self) -> CallableKind {
1563 match self.def {
1564 Some(CallableDefId::FunctionId(it)) => CallableKind::Function(it.into()),
1565 Some(CallableDefId::StructId(it)) => CallableKind::TupleStruct(it.into()),
1566 Some(CallableDefId::EnumVariantId(it)) => CallableKind::TupleEnumVariant(it.into()),
1567 None => CallableKind::Closure,
1568 }
1569 }
1570 pub fn receiver_param(&self, db: &dyn HirDatabase) -> Option<ast::SelfParam> {
1571 let func = match self.def {
1572 Some(CallableDefId::FunctionId(it)) if self.is_bound_method => it,
1573 _ => return None,
1574 };
1575 let src = func.lookup(db.upcast()).source(db.upcast());
1576 let param_list = src.value.param_list()?;
1577 param_list.self_param()
1578 }
1579 pub fn n_params(&self) -> usize {
1580 self.sig.params().len() - if self.is_bound_method { 1 } else { 0 }
1581 }
1582 pub fn params(
1583 &self,
1584 db: &dyn HirDatabase,
1585 ) -> Vec<(Option<Either<ast::SelfParam, ast::Pat>>, Type)> {
1586 let types = self
1587 .sig
1588 .params()
1589 .iter()
1590 .skip(if self.is_bound_method { 1 } else { 0 })
1591 .map(|ty| self.ty.derived(ty.clone()));
1592 let patterns = match self.def {
1593 Some(CallableDefId::FunctionId(func)) => {
1594 let src = func.lookup(db.upcast()).source(db.upcast());
1595 src.value.param_list().map(|param_list| {
1596 param_list
1597 .self_param()
1598 .map(|it| Some(Either::Left(it)))
1599 .filter(|_| !self.is_bound_method)
1600 .into_iter()
1601 .chain(param_list.params().map(|it| it.pat().map(Either::Right)))
1602 })
1603 }
1604 _ => None,
1605 };
1606 patterns.into_iter().flatten().chain(iter::repeat(None)).zip(types).collect()
1607 }
1608 pub fn return_type(&self) -> Type {
1609 self.ty.derived(self.sig.ret().clone())
1610 }
1611}
1612
1525/// For IDE only 1613/// For IDE only
1526#[derive(Debug)] 1614#[derive(Debug)]
1527pub enum ScopeDef { 1615pub enum ScopeDef {
@@ -1581,8 +1669,8 @@ pub enum AttrDef {
1581 MacroDef(MacroDef), 1669 MacroDef(MacroDef),
1582} 1670}
1583 1671
1584impl_froms!( 1672impl_from!(
1585 AttrDef: Module, 1673 Module,
1586 Field, 1674 Field,
1587 Adt(Struct, Enum, Union), 1675 Adt(Struct, Enum, Union),
1588 EnumVariant, 1676 EnumVariant,
@@ -1592,6 +1680,7 @@ impl_froms!(
1592 Trait, 1680 Trait,
1593 TypeAlias, 1681 TypeAlias,
1594 MacroDef 1682 MacroDef
1683 for AttrDef
1595); 1684);
1596 1685
1597pub trait HasAttrs { 1686pub trait HasAttrs {