diff options
author | Aleksey Kladov <[email protected]> | 2019-11-26 18:04:24 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2019-11-26 18:04:24 +0000 |
commit | 4e415a269e2d821f31963c05843517c6fde0132d (patch) | |
tree | 9acc9b8f635405f8c194cfd807927c45ee3fbb02 /crates/ra_hir/src/ty | |
parent | 475367d08a0b5e8ed4d6c7c7d43947fd11b26bb7 (diff) |
Remove ns-polymorphic type_for_def
Diffstat (limited to 'crates/ra_hir/src/ty')
-rw-r--r-- | crates/ra_hir/src/ty/infer.rs | 53 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/infer/expr.rs | 10 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/infer/path.rs | 7 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/lower.rs | 189 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/traits/chalk.rs | 2 |
5 files changed, 111 insertions, 150 deletions
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index b023ae690..beb2efb7a 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs | |||
@@ -35,15 +35,15 @@ use test_utils::tested_by; | |||
35 | 35 | ||
36 | use super::{ | 36 | use super::{ |
37 | traits::{Guidance, Obligation, ProjectionPredicate, Solution}, | 37 | traits::{Guidance, Obligation, ProjectionPredicate, Solution}, |
38 | ApplicationTy, InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypableDef, | 38 | ApplicationTy, InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeCtor, |
39 | TypeCtor, TypeWalk, Uncertain, | 39 | TypeWalk, Uncertain, |
40 | }; | 40 | }; |
41 | use crate::{ | 41 | use crate::{ |
42 | code_model::TypeAlias, | 42 | code_model::TypeAlias, |
43 | db::HirDatabase, | 43 | db::HirDatabase, |
44 | expr::{BindingAnnotation, Body, ExprId, PatId}, | 44 | expr::{BindingAnnotation, Body, ExprId, PatId}, |
45 | ty::infer::diagnostics::InferenceDiagnostic, | 45 | ty::infer::diagnostics::InferenceDiagnostic, |
46 | Adt, AssocItem, DefWithBody, FloatTy, Function, IntTy, Path, StructField, VariantDef, | 46 | AssocItem, DefWithBody, FloatTy, Function, IntTy, Path, StructField, VariantDef, |
47 | }; | 47 | }; |
48 | 48 | ||
49 | macro_rules! ty_app { | 49 | macro_rules! ty_app { |
@@ -520,45 +520,22 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
520 | None => return (Ty::Unknown, None), | 520 | None => return (Ty::Unknown, None), |
521 | }; | 521 | }; |
522 | let resolver = &self.resolver; | 522 | let resolver = &self.resolver; |
523 | let def: TypableDef = | 523 | // FIXME: this should resolve assoc items as well, see this example: |
524 | // FIXME: this should resolve assoc items as well, see this example: | 524 | // https://play.rust-lang.org/?gist=087992e9e22495446c01c0d4e2d69521 |
525 | // https://play.rust-lang.org/?gist=087992e9e22495446c01c0d4e2d69521 | 525 | match resolver.resolve_path_in_type_ns_fully(self.db, &path) { |
526 | match resolver.resolve_path_in_type_ns_fully(self.db, &path) { | 526 | Some(TypeNs::AdtId(AdtId::StructId(strukt))) => { |
527 | Some(TypeNs::AdtId(AdtId::StructId(it))) => it.into(), | 527 | let substs = Ty::substs_from_path(self.db, resolver, path, strukt.into()); |
528 | Some(TypeNs::AdtId(AdtId::UnionId(it))) => it.into(), | 528 | let ty = self.db.ty(strukt.into()); |
529 | Some(TypeNs::AdtSelfType(adt)) => adt.into(), | ||
530 | Some(TypeNs::EnumVariantId(it)) => it.into(), | ||
531 | Some(TypeNs::TypeAliasId(it)) => it.into(), | ||
532 | |||
533 | Some(TypeNs::SelfType(_)) | | ||
534 | Some(TypeNs::GenericParam(_)) | | ||
535 | Some(TypeNs::BuiltinType(_)) | | ||
536 | Some(TypeNs::TraitId(_)) | | ||
537 | Some(TypeNs::AdtId(AdtId::EnumId(_))) | | ||
538 | None => { | ||
539 | return (Ty::Unknown, None) | ||
540 | } | ||
541 | }; | ||
542 | // FIXME remove the duplication between here and `Ty::from_path`? | ||
543 | let substs = Ty::substs_from_path(self.db, resolver, path, def); | ||
544 | match def { | ||
545 | TypableDef::Adt(Adt::Struct(s)) => { | ||
546 | let ty = s.ty(self.db); | ||
547 | let ty = self.insert_type_vars(ty.apply_substs(substs)); | 529 | let ty = self.insert_type_vars(ty.apply_substs(substs)); |
548 | (ty, Some(s.into())) | 530 | (ty, Some(VariantDef::Struct(strukt.into()))) |
549 | } | 531 | } |
550 | TypableDef::EnumVariant(var) => { | 532 | Some(TypeNs::EnumVariantId(var)) => { |
551 | let ty = var.parent_enum(self.db).ty(self.db); | 533 | let substs = Ty::substs_from_path(self.db, resolver, path, var.into()); |
534 | let ty = self.db.ty(var.parent.into()); | ||
552 | let ty = self.insert_type_vars(ty.apply_substs(substs)); | 535 | let ty = self.insert_type_vars(ty.apply_substs(substs)); |
553 | (ty, Some(var.into())) | 536 | (ty, Some(VariantDef::EnumVariant(var.into()))) |
554 | } | 537 | } |
555 | TypableDef::Adt(Adt::Enum(_)) | 538 | Some(_) | None => (Ty::Unknown, None), |
556 | | TypableDef::Adt(Adt::Union(_)) | ||
557 | | TypableDef::TypeAlias(_) | ||
558 | | TypableDef::Function(_) | ||
559 | | TypableDef::Const(_) | ||
560 | | TypableDef::Static(_) | ||
561 | | TypableDef::BuiltinType(_) => (Ty::Unknown, None), | ||
562 | } | 539 | } |
563 | } | 540 | } |
564 | 541 | ||
diff --git a/crates/ra_hir/src/ty/infer/expr.rs b/crates/ra_hir/src/ty/infer/expr.rs index 3d0895dc6..eb221d6bc 100644 --- a/crates/ra_hir/src/ty/infer/expr.rs +++ b/crates/ra_hir/src/ty/infer/expr.rs | |||
@@ -17,8 +17,8 @@ use crate::{ | |||
17 | expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, | 17 | expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, |
18 | ty::{ | 18 | ty::{ |
19 | autoderef, method_resolution, op, traits::InEnvironment, CallableDef, InferTy, IntTy, | 19 | autoderef, method_resolution, op, traits::InEnvironment, CallableDef, InferTy, IntTy, |
20 | Mutability, Namespace, Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, | 20 | Mutability, Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, |
21 | TypeCtor, TypeWalk, Uncertain, | 21 | TypeWalk, Uncertain, |
22 | }, | 22 | }, |
23 | Name, | 23 | Name, |
24 | }; | 24 | }; |
@@ -558,11 +558,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
558 | Some((ty, func)) => { | 558 | Some((ty, func)) => { |
559 | let ty = canonicalized_receiver.decanonicalize_ty(ty); | 559 | let ty = canonicalized_receiver.decanonicalize_ty(ty); |
560 | self.write_method_resolution(tgt_expr, func); | 560 | self.write_method_resolution(tgt_expr, func); |
561 | ( | 561 | (ty, self.db.value_ty(func.id.into()), Some(self.db.generic_params(func.id.into()))) |
562 | ty, | ||
563 | self.db.type_for_def(func.into(), Namespace::Values), | ||
564 | Some(self.db.generic_params(func.id.into())), | ||
565 | ) | ||
566 | } | 562 | } |
567 | None => (receiver_ty, Ty::Unknown, None), | 563 | None => (receiver_ty, Ty::Unknown, None), |
568 | }; | 564 | }; |
diff --git a/crates/ra_hir/src/ty/infer/path.rs b/crates/ra_hir/src/ty/infer/path.rs index 202fff4f3..be2067dd4 100644 --- a/crates/ra_hir/src/ty/infer/path.rs +++ b/crates/ra_hir/src/ty/infer/path.rs | |||
@@ -7,7 +7,7 @@ use hir_def::{ | |||
7 | 7 | ||
8 | use crate::{ | 8 | use crate::{ |
9 | db::HirDatabase, | 9 | db::HirDatabase, |
10 | ty::{method_resolution, Namespace, Substs, Ty, TypableDef, TypeWalk}, | 10 | ty::{method_resolution, Substs, Ty, TypeWalk, ValueTyDefId}, |
11 | AssocItem, Container, Function, Name, Path, | 11 | AssocItem, Container, Function, Name, Path, |
12 | }; | 12 | }; |
13 | 13 | ||
@@ -56,7 +56,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
56 | } | 56 | } |
57 | }; | 57 | }; |
58 | 58 | ||
59 | let typable: TypableDef = match value { | 59 | let typable: ValueTyDefId = match value { |
60 | ValueNs::LocalBinding(pat) => { | 60 | ValueNs::LocalBinding(pat) => { |
61 | let ty = self.result.type_of_pat.get(pat)?.clone(); | 61 | let ty = self.result.type_of_pat.get(pat)?.clone(); |
62 | let ty = self.resolve_ty_as_possible(&mut vec![], ty); | 62 | let ty = self.resolve_ty_as_possible(&mut vec![], ty); |
@@ -69,11 +69,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
69 | ValueNs::EnumVariantId(it) => it.into(), | 69 | ValueNs::EnumVariantId(it) => it.into(), |
70 | }; | 70 | }; |
71 | 71 | ||
72 | let mut ty = self.db.type_for_def(typable, Namespace::Values); | 72 | let mut ty = self.db.value_ty(typable); |
73 | if let Some(self_subst) = self_subst { | 73 | if let Some(self_subst) = self_subst { |
74 | ty = ty.subst(&self_subst); | 74 | ty = ty.subst(&self_subst); |
75 | } | 75 | } |
76 | |||
77 | let substs = Ty::substs_from_path(self.db, &self.resolver, path, typable); | 76 | let substs = Ty::substs_from_path(self.db, &self.resolver, path, typable); |
78 | let ty = ty.subst(&substs); | 77 | let ty = ty.subst(&substs); |
79 | Some(ty) | 78 | Some(ty) |
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index c3c47a576..709492d21 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs | |||
@@ -14,8 +14,8 @@ use hir_def::{ | |||
14 | path::{GenericArg, PathSegment}, | 14 | path::{GenericArg, PathSegment}, |
15 | resolver::{HasResolver, Resolver, TypeNs}, | 15 | resolver::{HasResolver, Resolver, TypeNs}, |
16 | type_ref::{TypeBound, TypeRef}, | 16 | type_ref::{TypeBound, TypeRef}, |
17 | AdtId, AstItemDef, EnumVariantId, FunctionId, GenericDefId, HasModule, LocalStructFieldId, | 17 | AdtId, AstItemDef, ConstId, EnumId, EnumVariantId, FunctionId, GenericDefId, HasModule, |
18 | Lookup, StructId, TraitId, VariantId, | 18 | LocalStructFieldId, Lookup, StaticId, StructId, TraitId, TypeAliasId, UnionId, VariantId, |
19 | }; | 19 | }; |
20 | use ra_arena::map::ArenaMap; | 20 | use ra_arena::map::ArenaMap; |
21 | use ra_db::CrateId; | 21 | use ra_db::CrateId; |
@@ -35,17 +35,6 @@ use crate::{ | |||
35 | TypeAlias, Union, | 35 | TypeAlias, Union, |
36 | }; | 36 | }; |
37 | 37 | ||
38 | // FIXME: this is only really used in `type_for_def`, which contains a bunch of | ||
39 | // impossible cases. Perhaps we should recombine `TypeableDef` and `Namespace` | ||
40 | // into a `AsTypeDef`, `AsValueDef` enums? | ||
41 | #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] | ||
42 | pub enum Namespace { | ||
43 | Types, | ||
44 | Values, | ||
45 | // Note that only type inference uses this enum, and it doesn't care about macros. | ||
46 | // Macro, | ||
47 | } | ||
48 | |||
49 | impl Ty { | 38 | impl Ty { |
50 | pub(crate) fn from_hir(db: &impl HirDatabase, resolver: &Resolver, type_ref: &TypeRef) -> Self { | 39 | pub(crate) fn from_hir(db: &impl HirDatabase, resolver: &Resolver, type_ref: &TypeRef) -> Self { |
51 | match type_ref { | 40 | match type_ref { |
@@ -281,27 +270,15 @@ impl Ty { | |||
281 | db: &impl HirDatabase, | 270 | db: &impl HirDatabase, |
282 | resolver: &Resolver, | 271 | resolver: &Resolver, |
283 | segment: &PathSegment, | 272 | segment: &PathSegment, |
284 | typable: TypableDef, | 273 | typable: TyDefId, |
285 | ) -> Ty { | 274 | ) -> Ty { |
286 | let ty = db.type_for_def(typable, Namespace::Types); | 275 | let generic_def = match typable { |
287 | let substs = Ty::substs_from_path_segment(db, resolver, segment, typable); | 276 | TyDefId::BuiltinType(_) => None, |
288 | ty.subst(&substs) | 277 | TyDefId::AdtId(it) => Some(it.into()), |
289 | } | 278 | TyDefId::TypeAliasId(it) => Some(it.into()), |
290 | |||
291 | pub(super) fn substs_from_path_segment( | ||
292 | db: &impl HirDatabase, | ||
293 | resolver: &Resolver, | ||
294 | segment: &PathSegment, | ||
295 | resolved: TypableDef, | ||
296 | ) -> Substs { | ||
297 | let def_generic: Option<GenericDefId> = match resolved { | ||
298 | TypableDef::Function(func) => Some(func.id.into()), | ||
299 | TypableDef::Adt(adt) => Some(adt.into()), | ||
300 | TypableDef::EnumVariant(var) => Some(var.parent_enum(db).id.into()), | ||
301 | TypableDef::TypeAlias(t) => Some(t.id.into()), | ||
302 | TypableDef::Const(_) | TypableDef::Static(_) | TypableDef::BuiltinType(_) => None, | ||
303 | }; | 279 | }; |
304 | substs_from_path_segment(db, resolver, segment, def_generic, false) | 280 | let substs = substs_from_path_segment(db, resolver, segment, generic_def, false); |
281 | db.ty(typable).subst(&substs) | ||
305 | } | 282 | } |
306 | 283 | ||
307 | /// Collect generic arguments from a path into a `Substs`. See also | 284 | /// Collect generic arguments from a path into a `Substs`. See also |
@@ -310,17 +287,18 @@ impl Ty { | |||
310 | db: &impl HirDatabase, | 287 | db: &impl HirDatabase, |
311 | resolver: &Resolver, | 288 | resolver: &Resolver, |
312 | path: &Path, | 289 | path: &Path, |
313 | resolved: TypableDef, | 290 | // Note that we don't call `db.value_type(resolved)` here, |
291 | // `ValueTyDefId` is just a convenient way to pass generics and | ||
292 | // special-case enum variants | ||
293 | resolved: ValueTyDefId, | ||
314 | ) -> Substs { | 294 | ) -> Substs { |
315 | let last = path.segments.last().expect("path should have at least one segment"); | 295 | let last = path.segments.last().expect("path should have at least one segment"); |
316 | let segment = match resolved { | 296 | let (segment, generic_def) = match resolved { |
317 | TypableDef::Function(_) | 297 | ValueTyDefId::FunctionId(it) => (last, Some(it.into())), |
318 | | TypableDef::Adt(_) | 298 | ValueTyDefId::StructId(it) => (last, Some(it.into())), |
319 | | TypableDef::Const(_) | 299 | ValueTyDefId::ConstId(it) => (last, Some(it.into())), |
320 | | TypableDef::Static(_) | 300 | ValueTyDefId::StaticId(_) => (last, None), |
321 | | TypableDef::TypeAlias(_) | 301 | ValueTyDefId::EnumVariantId(var) => { |
322 | | TypableDef::BuiltinType(_) => last, | ||
323 | TypableDef::EnumVariant(_) => { | ||
324 | // the generic args for an enum variant may be either specified | 302 | // the generic args for an enum variant may be either specified |
325 | // on the segment referring to the enum, or on the segment | 303 | // on the segment referring to the enum, or on the segment |
326 | // referring to the variant. So `Option::<T>::None` and | 304 | // referring to the variant. So `Option::<T>::None` and |
@@ -334,10 +312,10 @@ impl Ty { | |||
334 | // Option::None::<T> | 312 | // Option::None::<T> |
335 | last | 313 | last |
336 | }; | 314 | }; |
337 | segment | 315 | (segment, Some(var.parent.into())) |
338 | } | 316 | } |
339 | }; | 317 | }; |
340 | Ty::substs_from_path_segment(db, resolver, segment, resolved) | 318 | substs_from_path_segment(db, resolver, segment, generic_def, false) |
341 | } | 319 | } |
342 | } | 320 | } |
343 | 321 | ||
@@ -522,33 +500,6 @@ fn assoc_type_bindings_from_type_bound<'a>( | |||
522 | }) | 500 | }) |
523 | } | 501 | } |
524 | 502 | ||
525 | /// Build the declared type of an item. This depends on the namespace; e.g. for | ||
526 | /// `struct Foo(usize)`, we have two types: The type of the struct itself, and | ||
527 | /// the constructor function `(usize) -> Foo` which lives in the values | ||
528 | /// namespace. | ||
529 | pub(crate) fn type_for_def(db: &impl HirDatabase, def: TypableDef, ns: Namespace) -> Ty { | ||
530 | match (def, ns) { | ||
531 | (TypableDef::Function(f), Namespace::Values) => type_for_fn(db, f), | ||
532 | (TypableDef::Adt(Adt::Struct(s)), Namespace::Values) => type_for_struct_constructor(db, s), | ||
533 | (TypableDef::Adt(adt), Namespace::Types) => type_for_adt(db, adt), | ||
534 | (TypableDef::EnumVariant(v), Namespace::Values) => type_for_enum_variant_constructor(db, v), | ||
535 | (TypableDef::TypeAlias(t), Namespace::Types) => type_for_type_alias(db, t), | ||
536 | (TypableDef::Const(c), Namespace::Values) => type_for_const(db, c), | ||
537 | (TypableDef::Static(c), Namespace::Values) => type_for_static(db, c), | ||
538 | (TypableDef::BuiltinType(t), Namespace::Types) => type_for_builtin(t), | ||
539 | |||
540 | // 'error' cases: | ||
541 | (TypableDef::Function(_), Namespace::Types) => Ty::Unknown, | ||
542 | (TypableDef::Adt(Adt::Union(_)), Namespace::Values) => Ty::Unknown, | ||
543 | (TypableDef::Adt(Adt::Enum(_)), Namespace::Values) => Ty::Unknown, | ||
544 | (TypableDef::EnumVariant(_), Namespace::Types) => Ty::Unknown, | ||
545 | (TypableDef::TypeAlias(_), Namespace::Values) => Ty::Unknown, | ||
546 | (TypableDef::Const(_), Namespace::Types) => Ty::Unknown, | ||
547 | (TypableDef::Static(_), Namespace::Types) => Ty::Unknown, | ||
548 | (TypableDef::BuiltinType(_), Namespace::Values) => Ty::Unknown, | ||
549 | } | ||
550 | } | ||
551 | |||
552 | /// Build the signature of a callable item (function, struct or enum variant). | 503 | /// Build the signature of a callable item (function, struct or enum variant). |
553 | pub(crate) fn callable_item_sig(db: &impl HirDatabase, def: CallableDef) -> FnSig { | 504 | pub(crate) fn callable_item_sig(db: &impl HirDatabase, def: CallableDef) -> FnSig { |
554 | match def { | 505 | match def { |
@@ -647,24 +598,24 @@ fn fn_sig_for_fn(db: &impl HirDatabase, def: FunctionId) -> FnSig { | |||
647 | 598 | ||
648 | /// Build the declared type of a function. This should not need to look at the | 599 | /// Build the declared type of a function. This should not need to look at the |
649 | /// function body. | 600 | /// function body. |
650 | fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty { | 601 | fn type_for_fn(db: &impl HirDatabase, def: FunctionId) -> Ty { |
651 | let generics = db.generic_params(def.id.into()); | 602 | let generics = db.generic_params(def.into()); |
652 | let substs = Substs::identity(&generics); | 603 | let substs = Substs::identity(&generics); |
653 | Ty::apply(TypeCtor::FnDef(def.id.into()), substs) | 604 | Ty::apply(TypeCtor::FnDef(def.into()), substs) |
654 | } | 605 | } |
655 | 606 | ||
656 | /// Build the declared type of a const. | 607 | /// Build the declared type of a const. |
657 | fn type_for_const(db: &impl HirDatabase, def: Const) -> Ty { | 608 | fn type_for_const(db: &impl HirDatabase, def: ConstId) -> Ty { |
658 | let data = db.const_data(def.id); | 609 | let data = db.const_data(def); |
659 | let resolver = def.id.resolver(db); | 610 | let resolver = def.resolver(db); |
660 | 611 | ||
661 | Ty::from_hir(db, &resolver, &data.type_ref) | 612 | Ty::from_hir(db, &resolver, &data.type_ref) |
662 | } | 613 | } |
663 | 614 | ||
664 | /// Build the declared type of a static. | 615 | /// Build the declared type of a static. |
665 | fn type_for_static(db: &impl HirDatabase, def: Static) -> Ty { | 616 | fn type_for_static(db: &impl HirDatabase, def: StaticId) -> Ty { |
666 | let data = db.static_data(def.id); | 617 | let data = db.static_data(def); |
667 | let resolver = def.id.resolver(db); | 618 | let resolver = def.resolver(db); |
668 | 619 | ||
669 | Ty::from_hir(db, &resolver, &data.type_ref) | 620 | Ty::from_hir(db, &resolver, &data.type_ref) |
670 | } | 621 | } |
@@ -688,19 +639,19 @@ fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: StructId) -> FnSig | |||
688 | .iter() | 639 | .iter() |
689 | .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) | 640 | .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) |
690 | .collect::<Vec<_>>(); | 641 | .collect::<Vec<_>>(); |
691 | let ret = type_for_adt(db, Struct::from(def)); | 642 | let ret = type_for_adt(db, def.into()); |
692 | FnSig::from_params_and_return(params, ret) | 643 | FnSig::from_params_and_return(params, ret) |
693 | } | 644 | } |
694 | 645 | ||
695 | /// Build the type of a tuple struct constructor. | 646 | /// Build the type of a tuple struct constructor. |
696 | fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty { | 647 | fn type_for_struct_constructor(db: &impl HirDatabase, def: StructId) -> Ty { |
697 | let struct_data = db.struct_data(def.id.into()); | 648 | let struct_data = db.struct_data(def.into()); |
698 | if struct_data.variant_data.is_unit() { | 649 | if struct_data.variant_data.is_unit() { |
699 | return type_for_adt(db, def); // Unit struct | 650 | return type_for_adt(db, def.into()); // Unit struct |
700 | } | 651 | } |
701 | let generics = db.generic_params(def.id.into()); | 652 | let generics = db.generic_params(def.into()); |
702 | let substs = Substs::identity(&generics); | 653 | let substs = Substs::identity(&generics); |
703 | Ty::apply(TypeCtor::FnDef(def.id.into()), substs) | 654 | Ty::apply(TypeCtor::FnDef(def.into()), substs) |
704 | } | 655 | } |
705 | 656 | ||
706 | fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariantId) -> FnSig { | 657 | fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariantId) -> FnSig { |
@@ -714,34 +665,33 @@ fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariantId | |||
714 | .collect::<Vec<_>>(); | 665 | .collect::<Vec<_>>(); |
715 | let generics = db.generic_params(def.parent.into()); | 666 | let generics = db.generic_params(def.parent.into()); |
716 | let substs = Substs::identity(&generics); | 667 | let substs = Substs::identity(&generics); |
717 | let ret = type_for_adt(db, Enum::from(def.parent)).subst(&substs); | 668 | let ret = type_for_adt(db, def.parent.into()).subst(&substs); |
718 | FnSig::from_params_and_return(params, ret) | 669 | FnSig::from_params_and_return(params, ret) |
719 | } | 670 | } |
720 | 671 | ||
721 | /// Build the type of a tuple enum variant constructor. | 672 | /// Build the type of a tuple enum variant constructor. |
722 | fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> Ty { | 673 | fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariantId) -> Ty { |
723 | let var_data = def.variant_data(db); | 674 | let enum_data = db.enum_data(def.parent); |
675 | let var_data = &enum_data.variants[def.local_id].variant_data; | ||
724 | if var_data.is_unit() { | 676 | if var_data.is_unit() { |
725 | return type_for_adt(db, def.parent_enum(db)); // Unit variant | 677 | return type_for_adt(db, def.parent.into()); // Unit variant |
726 | } | 678 | } |
727 | let generics = db.generic_params(def.parent_enum(db).id.into()); | 679 | let generics = db.generic_params(def.parent.into()); |
728 | let substs = Substs::identity(&generics); | 680 | let substs = Substs::identity(&generics); |
729 | Ty::apply(TypeCtor::FnDef(EnumVariantId::from(def).into()), substs) | 681 | Ty::apply(TypeCtor::FnDef(EnumVariantId::from(def).into()), substs) |
730 | } | 682 | } |
731 | 683 | ||
732 | fn type_for_adt(db: &impl HirDatabase, adt: impl Into<Adt>) -> Ty { | 684 | fn type_for_adt(db: &impl HirDatabase, adt: AdtId) -> Ty { |
733 | let adt = adt.into(); | 685 | let generics = db.generic_params(adt.into()); |
734 | let adt_id: AdtId = adt.into(); | 686 | Ty::apply(TypeCtor::Adt(adt), Substs::identity(&generics)) |
735 | let generics = db.generic_params(adt_id.into()); | ||
736 | Ty::apply(TypeCtor::Adt(adt_id), Substs::identity(&generics)) | ||
737 | } | 687 | } |
738 | 688 | ||
739 | fn type_for_type_alias(db: &impl HirDatabase, t: TypeAlias) -> Ty { | 689 | fn type_for_type_alias(db: &impl HirDatabase, t: TypeAliasId) -> Ty { |
740 | let generics = db.generic_params(t.id.into()); | 690 | let generics = db.generic_params(t.into()); |
741 | let resolver = t.id.resolver(db); | 691 | let resolver = t.resolver(db); |
742 | let type_ref = t.type_ref(db); | 692 | let type_ref = &db.type_alias_data(t).type_ref; |
743 | let substs = Substs::identity(&generics); | 693 | let substs = Substs::identity(&generics); |
744 | let inner = Ty::from_hir(db, &resolver, &type_ref.unwrap_or(TypeRef::Error)); | 694 | let inner = Ty::from_hir(db, &resolver, type_ref.as_ref().unwrap_or(&TypeRef::Error)); |
745 | inner.subst(&substs) | 695 | inner.subst(&substs) |
746 | } | 696 | } |
747 | 697 | ||
@@ -808,3 +758,42 @@ impl From<CallableDef> for GenericDefId { | |||
808 | } | 758 | } |
809 | } | 759 | } |
810 | } | 760 | } |
761 | |||
762 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
763 | pub enum TyDefId { | ||
764 | BuiltinType(BuiltinType), | ||
765 | AdtId(AdtId), | ||
766 | TypeAliasId(TypeAliasId), | ||
767 | } | ||
768 | impl_froms!(TyDefId: BuiltinType, AdtId(StructId, EnumId, UnionId), TypeAliasId); | ||
769 | |||
770 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
771 | pub enum ValueTyDefId { | ||
772 | FunctionId(FunctionId), | ||
773 | StructId(StructId), | ||
774 | EnumVariantId(EnumVariantId), | ||
775 | ConstId(ConstId), | ||
776 | StaticId(StaticId), | ||
777 | } | ||
778 | impl_froms!(ValueTyDefId: FunctionId, StructId, EnumVariantId, ConstId, StaticId); | ||
779 | |||
780 | /// Build the declared type of an item. This depends on the namespace; e.g. for | ||
781 | /// `struct Foo(usize)`, we have two types: The type of the struct itself, and | ||
782 | /// the constructor function `(usize) -> Foo` which lives in the values | ||
783 | /// namespace. | ||
784 | pub(crate) fn ty_query(db: &impl HirDatabase, def: TyDefId) -> Ty { | ||
785 | match def { | ||
786 | TyDefId::BuiltinType(it) => type_for_builtin(it), | ||
787 | TyDefId::AdtId(it) => type_for_adt(db, it), | ||
788 | TyDefId::TypeAliasId(it) => type_for_type_alias(db, it), | ||
789 | } | ||
790 | } | ||
791 | pub(crate) fn value_ty_query(db: &impl HirDatabase, def: ValueTyDefId) -> Ty { | ||
792 | match def { | ||
793 | ValueTyDefId::FunctionId(it) => type_for_fn(db, it), | ||
794 | ValueTyDefId::StructId(it) => type_for_struct_constructor(db, it), | ||
795 | ValueTyDefId::EnumVariantId(it) => type_for_enum_variant_constructor(db, it), | ||
796 | ValueTyDefId::ConstId(it) => type_for_const(db, it), | ||
797 | ValueTyDefId::StaticId(it) => type_for_static(db, it), | ||
798 | } | ||
799 | } | ||
diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs index 02d37dead..4b0f4f56c 100644 --- a/crates/ra_hir/src/ty/traits/chalk.rs +++ b/crates/ra_hir/src/ty/traits/chalk.rs | |||
@@ -786,7 +786,7 @@ fn type_alias_associated_ty_value( | |||
786 | .expect("assoc ty value should not exist"); // validated when building the impl data as well | 786 | .expect("assoc ty value should not exist"); // validated when building the impl data as well |
787 | let generic_params = db.generic_params(impl_block.id.into()); | 787 | let generic_params = db.generic_params(impl_block.id.into()); |
788 | let bound_vars = Substs::bound_vars(&generic_params); | 788 | let bound_vars = Substs::bound_vars(&generic_params); |
789 | let ty = db.type_for_def(type_alias.into(), crate::ty::Namespace::Types).subst(&bound_vars); | 789 | let ty = db.ty(type_alias.id.into()).subst(&bound_vars); |
790 | let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: ty.to_chalk(db) }; | 790 | let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: ty.to_chalk(db) }; |
791 | let value = chalk_rust_ir::AssociatedTyValue { | 791 | let value = chalk_rust_ir::AssociatedTyValue { |
792 | impl_id, | 792 | impl_id, |