diff options
author | Seivan Heidari <[email protected]> | 2019-11-25 00:54:54 +0000 |
---|---|---|
committer | Seivan Heidari <[email protected]> | 2019-11-25 00:54:54 +0000 |
commit | 15ea338ac991707d330288ba4d1bf5daa0fc75d9 (patch) | |
tree | 16aeab28bcdb07d36aae28e3fb4a385614865a48 /crates/ra_hir/src/ty/lower.rs | |
parent | eb7363d167c7a9f7c73cb950b621eb1dce493318 (diff) | |
parent | f7f9757b6b144385ab8ce57b15764473b1f57331 (diff) |
Merge branch 'master' of https://github.com/rust-analyzer/rust-analyzer into feature/themes
Diffstat (limited to 'crates/ra_hir/src/ty/lower.rs')
-rw-r--r-- | crates/ra_hir/src/ty/lower.rs | 58 |
1 files changed, 30 insertions, 28 deletions
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index 75c552569..a39beb2a0 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs | |||
@@ -14,8 +14,9 @@ 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, GenericDefId, | 17 | AdtId, GenericDefId, LocalStructFieldId, VariantId, |
18 | }; | 18 | }; |
19 | use ra_arena::map::ArenaMap; | ||
19 | 20 | ||
20 | use super::{ | 21 | use super::{ |
21 | FnSig, GenericPredicate, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, | 22 | FnSig, GenericPredicate, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, |
@@ -29,7 +30,7 @@ use crate::{ | |||
29 | }, | 30 | }, |
30 | util::make_mut_slice, | 31 | util::make_mut_slice, |
31 | Const, Enum, EnumVariant, Function, GenericDef, ImplBlock, ModuleDef, Path, Static, Struct, | 32 | Const, Enum, EnumVariant, Function, GenericDef, ImplBlock, ModuleDef, Path, Static, Struct, |
32 | StructField, Trait, TypeAlias, Union, VariantDef, | 33 | Trait, TypeAlias, Union, |
33 | }; | 34 | }; |
34 | 35 | ||
35 | // FIXME: this is only really used in `type_for_def`, which contains a bunch of | 36 | // FIXME: this is only really used in `type_for_def`, which contains a bunch of |
@@ -549,16 +550,23 @@ pub(crate) fn callable_item_sig(db: &impl HirDatabase, def: CallableDef) -> FnSi | |||
549 | } | 550 | } |
550 | } | 551 | } |
551 | 552 | ||
552 | /// Build the type of a specific field of a struct or enum variant. | 553 | /// Build the type of all specific fields of a struct or enum variant. |
553 | pub(crate) fn type_for_field(db: &impl HirDatabase, field: StructField) -> Ty { | 554 | pub(crate) fn field_types_query( |
554 | let parent_def = field.parent_def(db); | 555 | db: &impl HirDatabase, |
555 | let resolver = match parent_def { | 556 | variant_id: VariantId, |
556 | VariantDef::Struct(it) => it.id.resolver(db), | 557 | ) -> Arc<ArenaMap<LocalStructFieldId, Ty>> { |
557 | VariantDef::EnumVariant(it) => it.parent.id.resolver(db), | 558 | let (resolver, var_data) = match variant_id { |
559 | VariantId::StructId(it) => (it.resolver(db), db.struct_data(it.0).variant_data.clone()), | ||
560 | VariantId::EnumVariantId(it) => ( | ||
561 | it.parent.resolver(db), | ||
562 | db.enum_data(it.parent).variants[it.local_id].variant_data.clone(), | ||
563 | ), | ||
558 | }; | 564 | }; |
559 | let var_data = parent_def.variant_data(db); | 565 | let mut res = ArenaMap::default(); |
560 | let type_ref = &var_data.fields().unwrap()[field.id].type_ref; | 566 | for (field_id, field_data) in var_data.fields().iter() { |
561 | Ty::from_hir(db, &resolver, type_ref) | 567 | res.insert(field_id, Ty::from_hir(db, &resolver, &field_data.type_ref)) |
568 | } | ||
569 | Arc::new(res) | ||
562 | } | 570 | } |
563 | 571 | ||
564 | /// This query exists only to be used when resolving short-hand associated types | 572 | /// This query exists only to be used when resolving short-hand associated types |
@@ -622,10 +630,10 @@ pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDef) -> | |||
622 | } | 630 | } |
623 | 631 | ||
624 | fn fn_sig_for_fn(db: &impl HirDatabase, def: Function) -> FnSig { | 632 | fn fn_sig_for_fn(db: &impl HirDatabase, def: Function) -> FnSig { |
625 | let data = def.data(db); | 633 | let data = db.function_data(def.id); |
626 | let resolver = def.id.resolver(db); | 634 | let resolver = def.id.resolver(db); |
627 | let params = data.params().iter().map(|tr| Ty::from_hir(db, &resolver, tr)).collect::<Vec<_>>(); | 635 | let params = data.params.iter().map(|tr| Ty::from_hir(db, &resolver, tr)).collect::<Vec<_>>(); |
628 | let ret = Ty::from_hir(db, &resolver, data.ret_type()); | 636 | let ret = Ty::from_hir(db, &resolver, &data.ret_type); |
629 | FnSig::from_params_and_return(params, ret) | 637 | FnSig::from_params_and_return(params, ret) |
630 | } | 638 | } |
631 | 639 | ||
@@ -639,18 +647,18 @@ fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty { | |||
639 | 647 | ||
640 | /// Build the declared type of a const. | 648 | /// Build the declared type of a const. |
641 | fn type_for_const(db: &impl HirDatabase, def: Const) -> Ty { | 649 | fn type_for_const(db: &impl HirDatabase, def: Const) -> Ty { |
642 | let data = def.data(db); | 650 | let data = db.const_data(def.id); |
643 | let resolver = def.id.resolver(db); | 651 | let resolver = def.id.resolver(db); |
644 | 652 | ||
645 | Ty::from_hir(db, &resolver, data.type_ref()) | 653 | Ty::from_hir(db, &resolver, &data.type_ref) |
646 | } | 654 | } |
647 | 655 | ||
648 | /// Build the declared type of a static. | 656 | /// Build the declared type of a static. |
649 | fn type_for_static(db: &impl HirDatabase, def: Static) -> Ty { | 657 | fn type_for_static(db: &impl HirDatabase, def: Static) -> Ty { |
650 | let data = def.data(db); | 658 | let data = db.static_data(def.id); |
651 | let resolver = def.id.resolver(db); | 659 | let resolver = def.id.resolver(db); |
652 | 660 | ||
653 | Ty::from_hir(db, &resolver, data.type_ref()) | 661 | Ty::from_hir(db, &resolver, &data.type_ref) |
654 | } | 662 | } |
655 | 663 | ||
656 | /// Build the declared type of a static. | 664 | /// Build the declared type of a static. |
@@ -696,10 +704,7 @@ impl From<Option<BuiltinFloat>> for Uncertain<FloatTy> { | |||
696 | 704 | ||
697 | fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> FnSig { | 705 | fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> FnSig { |
698 | let struct_data = db.struct_data(def.id.into()); | 706 | let struct_data = db.struct_data(def.id.into()); |
699 | let fields = match struct_data.variant_data.fields() { | 707 | let fields = struct_data.variant_data.fields(); |
700 | Some(fields) => fields, | ||
701 | None => panic!("fn_sig_for_struct_constructor called on unit struct"), | ||
702 | }; | ||
703 | let resolver = def.id.resolver(db); | 708 | let resolver = def.id.resolver(db); |
704 | let params = fields | 709 | let params = fields |
705 | .iter() | 710 | .iter() |
@@ -712,7 +717,7 @@ fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> FnSig { | |||
712 | /// Build the type of a tuple struct constructor. | 717 | /// Build the type of a tuple struct constructor. |
713 | fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty { | 718 | fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty { |
714 | let struct_data = db.struct_data(def.id.into()); | 719 | let struct_data = db.struct_data(def.id.into()); |
715 | if struct_data.variant_data.fields().is_none() { | 720 | if struct_data.variant_data.is_unit() { |
716 | return type_for_adt(db, def); // Unit struct | 721 | return type_for_adt(db, def); // Unit struct |
717 | } | 722 | } |
718 | let generics = db.generic_params(def.id.into()); | 723 | let generics = db.generic_params(def.id.into()); |
@@ -722,10 +727,7 @@ fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty { | |||
722 | 727 | ||
723 | fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> FnSig { | 728 | fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> FnSig { |
724 | let var_data = def.variant_data(db); | 729 | let var_data = def.variant_data(db); |
725 | let fields = match var_data.fields() { | 730 | let fields = var_data.fields(); |
726 | Some(fields) => fields, | ||
727 | None => panic!("fn_sig_for_enum_variant_constructor called for unit variant"), | ||
728 | }; | ||
729 | let resolver = def.parent.id.resolver(db); | 731 | let resolver = def.parent.id.resolver(db); |
730 | let params = fields | 732 | let params = fields |
731 | .iter() | 733 | .iter() |
@@ -740,7 +742,7 @@ fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) | |||
740 | /// Build the type of a tuple enum variant constructor. | 742 | /// Build the type of a tuple enum variant constructor. |
741 | fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> Ty { | 743 | fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> Ty { |
742 | let var_data = def.variant_data(db); | 744 | let var_data = def.variant_data(db); |
743 | if var_data.fields().is_none() { | 745 | if var_data.is_unit() { |
744 | return type_for_adt(db, def.parent_enum(db)); // Unit variant | 746 | return type_for_adt(db, def.parent_enum(db)); // Unit variant |
745 | } | 747 | } |
746 | let generics = db.generic_params(def.parent_enum(db).id.into()); | 748 | let generics = db.generic_params(def.parent_enum(db).id.into()); |