diff options
Diffstat (limited to 'crates/ra_hir/src/ty/lower.rs')
-rw-r--r-- | crates/ra_hir/src/ty/lower.rs | 164 |
1 files changed, 85 insertions, 79 deletions
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index 2272510e8..27cfe00c1 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs | |||
@@ -14,12 +14,15 @@ 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, AstItemDef, EnumVariantId, FunctionId, GenericDefId, HasModule, LocalStructFieldId, |
18 | Lookup, StructId, VariantId, | ||
18 | }; | 19 | }; |
20 | use ra_arena::map::ArenaMap; | ||
21 | use ra_db::CrateId; | ||
19 | 22 | ||
20 | use super::{ | 23 | use super::{ |
21 | FnSig, GenericPredicate, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, | 24 | FnSig, GenericPredicate, ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, TraitRef, |
22 | TypeWalk, | 25 | Ty, TypeCtor, TypeWalk, |
23 | }; | 26 | }; |
24 | use crate::{ | 27 | use crate::{ |
25 | db::HirDatabase, | 28 | db::HirDatabase, |
@@ -28,8 +31,8 @@ use crate::{ | |||
28 | Adt, | 31 | Adt, |
29 | }, | 32 | }, |
30 | util::make_mut_slice, | 33 | util::make_mut_slice, |
31 | Const, Enum, EnumVariant, Function, GenericDef, ImplBlock, ModuleDef, Path, Static, Struct, | 34 | Const, Enum, EnumVariant, Function, ImplBlock, ModuleDef, Path, Static, Struct, Trait, |
32 | StructField, Trait, TypeAlias, Union, VariantDef, | 35 | TypeAlias, Union, |
33 | }; | 36 | }; |
34 | 37 | ||
35 | // FIXME: this is only really used in `type_for_def`, which contains a bunch of | 38 | // FIXME: this is only really used in `type_for_def`, which contains a bunch of |
@@ -260,8 +263,10 @@ impl Ty { | |||
260 | let traits = traits_from_env.flat_map(|t| t.all_super_traits(db)); | 263 | let traits = traits_from_env.flat_map(|t| t.all_super_traits(db)); |
261 | for t in traits { | 264 | for t in traits { |
262 | if let Some(associated_ty) = t.associated_type_by_name(db, &segment.name) { | 265 | if let Some(associated_ty) = t.associated_type_by_name(db, &segment.name) { |
263 | let substs = | 266 | let substs = Substs::build_for_def(db, t.id) |
264 | Substs::build_for_def(db, t).push(self_ty.clone()).fill_with_unknown().build(); | 267 | .push(self_ty.clone()) |
268 | .fill_with_unknown() | ||
269 | .build(); | ||
265 | // FIXME handle type parameters on the segment | 270 | // FIXME handle type parameters on the segment |
266 | return Ty::Projection(ProjectionTy { associated_ty, parameters: substs }); | 271 | return Ty::Projection(ProjectionTy { associated_ty, parameters: substs }); |
267 | } | 272 | } |
@@ -286,11 +291,11 @@ impl Ty { | |||
286 | segment: &PathSegment, | 291 | segment: &PathSegment, |
287 | resolved: TypableDef, | 292 | resolved: TypableDef, |
288 | ) -> Substs { | 293 | ) -> Substs { |
289 | let def_generic: Option<GenericDef> = match resolved { | 294 | let def_generic: Option<GenericDefId> = match resolved { |
290 | TypableDef::Function(func) => Some(func.into()), | 295 | TypableDef::Function(func) => Some(func.id.into()), |
291 | TypableDef::Adt(adt) => Some(adt.into()), | 296 | TypableDef::Adt(adt) => Some(adt.into()), |
292 | TypableDef::EnumVariant(var) => Some(var.parent_enum(db).into()), | 297 | TypableDef::EnumVariant(var) => Some(var.parent_enum(db).id.into()), |
293 | TypableDef::TypeAlias(t) => Some(t.into()), | 298 | TypableDef::TypeAlias(t) => Some(t.id.into()), |
294 | TypableDef::Const(_) | TypableDef::Static(_) | TypableDef::BuiltinType(_) => None, | 299 | TypableDef::Const(_) | TypableDef::Static(_) | TypableDef::BuiltinType(_) => None, |
295 | }; | 300 | }; |
296 | substs_from_path_segment(db, resolver, segment, def_generic, false) | 301 | substs_from_path_segment(db, resolver, segment, def_generic, false) |
@@ -337,7 +342,7 @@ pub(super) fn substs_from_path_segment( | |||
337 | db: &impl HirDatabase, | 342 | db: &impl HirDatabase, |
338 | resolver: &Resolver, | 343 | resolver: &Resolver, |
339 | segment: &PathSegment, | 344 | segment: &PathSegment, |
340 | def_generic: Option<GenericDef>, | 345 | def_generic: Option<GenericDefId>, |
341 | add_self_param: bool, | 346 | add_self_param: bool, |
342 | ) -> Substs { | 347 | ) -> Substs { |
343 | let mut substs = Vec::new(); | 348 | let mut substs = Vec::new(); |
@@ -375,7 +380,7 @@ pub(super) fn substs_from_path_segment( | |||
375 | 380 | ||
376 | // handle defaults | 381 | // handle defaults |
377 | if let Some(def_generic) = def_generic { | 382 | if let Some(def_generic) = def_generic { |
378 | let default_substs = db.generic_defaults(def_generic); | 383 | let default_substs = db.generic_defaults(def_generic.into()); |
379 | assert_eq!(substs.len(), default_substs.len()); | 384 | assert_eq!(substs.len(), default_substs.len()); |
380 | 385 | ||
381 | for (i, default_ty) in default_substs.iter().enumerate() { | 386 | for (i, default_ty) in default_substs.iter().enumerate() { |
@@ -438,7 +443,7 @@ impl TraitRef { | |||
438 | ) -> Substs { | 443 | ) -> Substs { |
439 | let has_self_param = | 444 | let has_self_param = |
440 | segment.args_and_bindings.as_ref().map(|a| a.has_self_type).unwrap_or(false); | 445 | segment.args_and_bindings.as_ref().map(|a| a.has_self_type).unwrap_or(false); |
441 | substs_from_path_segment(db, resolver, segment, Some(resolved.into()), !has_self_param) | 446 | substs_from_path_segment(db, resolver, segment, Some(resolved.id.into()), !has_self_param) |
442 | } | 447 | } |
443 | 448 | ||
444 | pub(crate) fn for_trait(db: &impl HirDatabase, trait_: Trait) -> TraitRef { | 449 | pub(crate) fn for_trait(db: &impl HirDatabase, trait_: Trait) -> TraitRef { |
@@ -543,22 +548,29 @@ pub(crate) fn type_for_def(db: &impl HirDatabase, def: TypableDef, ns: Namespace | |||
543 | /// Build the signature of a callable item (function, struct or enum variant). | 548 | /// Build the signature of a callable item (function, struct or enum variant). |
544 | pub(crate) fn callable_item_sig(db: &impl HirDatabase, def: CallableDef) -> FnSig { | 549 | pub(crate) fn callable_item_sig(db: &impl HirDatabase, def: CallableDef) -> FnSig { |
545 | match def { | 550 | match def { |
546 | CallableDef::Function(f) => fn_sig_for_fn(db, f), | 551 | CallableDef::FunctionId(f) => fn_sig_for_fn(db, f), |
547 | CallableDef::Struct(s) => fn_sig_for_struct_constructor(db, s), | 552 | CallableDef::StructId(s) => fn_sig_for_struct_constructor(db, s), |
548 | CallableDef::EnumVariant(e) => fn_sig_for_enum_variant_constructor(db, e), | 553 | CallableDef::EnumVariantId(e) => fn_sig_for_enum_variant_constructor(db, e), |
549 | } | 554 | } |
550 | } | 555 | } |
551 | 556 | ||
552 | /// Build the type of a specific field of a struct or enum variant. | 557 | /// 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 { | 558 | pub(crate) fn field_types_query( |
554 | let parent_def = field.parent_def(db); | 559 | db: &impl HirDatabase, |
555 | let resolver = match parent_def { | 560 | variant_id: VariantId, |
556 | VariantDef::Struct(it) => it.id.resolver(db), | 561 | ) -> Arc<ArenaMap<LocalStructFieldId, Ty>> { |
557 | VariantDef::EnumVariant(it) => it.parent.id.resolver(db), | 562 | let (resolver, var_data) = match variant_id { |
563 | VariantId::StructId(it) => (it.resolver(db), db.struct_data(it.0).variant_data.clone()), | ||
564 | VariantId::EnumVariantId(it) => ( | ||
565 | it.parent.resolver(db), | ||
566 | db.enum_data(it.parent).variants[it.local_id].variant_data.clone(), | ||
567 | ), | ||
558 | }; | 568 | }; |
559 | let var_data = parent_def.variant_data(db); | 569 | let mut res = ArenaMap::default(); |
560 | let type_ref = &var_data.fields().unwrap()[field.id].type_ref; | 570 | for (field_id, field_data) in var_data.fields().iter() { |
561 | Ty::from_hir(db, &resolver, type_ref) | 571 | res.insert(field_id, Ty::from_hir(db, &resolver, &field_data.type_ref)) |
572 | } | ||
573 | Arc::new(res) | ||
562 | } | 574 | } |
563 | 575 | ||
564 | /// This query exists only to be used when resolving short-hand associated types | 576 | /// This query exists only to be used when resolving short-hand associated types |
@@ -571,10 +583,10 @@ pub(crate) fn type_for_field(db: &impl HirDatabase, field: StructField) -> Ty { | |||
571 | /// these are fine: `T: Foo<U::Item>, U: Foo<()>`. | 583 | /// these are fine: `T: Foo<U::Item>, U: Foo<()>`. |
572 | pub(crate) fn generic_predicates_for_param_query( | 584 | pub(crate) fn generic_predicates_for_param_query( |
573 | db: &impl HirDatabase, | 585 | db: &impl HirDatabase, |
574 | def: GenericDef, | 586 | def: GenericDefId, |
575 | param_idx: u32, | 587 | param_idx: u32, |
576 | ) -> Arc<[GenericPredicate]> { | 588 | ) -> Arc<[GenericPredicate]> { |
577 | let resolver = GenericDefId::from(def).resolver(db); | 589 | let resolver = def.resolver(db); |
578 | resolver | 590 | resolver |
579 | .where_predicates_in_scope() | 591 | .where_predicates_in_scope() |
580 | // we have to filter out all other predicates *first*, before attempting to lower them | 592 | // we have to filter out all other predicates *first*, before attempting to lower them |
@@ -583,24 +595,23 @@ pub(crate) fn generic_predicates_for_param_query( | |||
583 | .collect() | 595 | .collect() |
584 | } | 596 | } |
585 | 597 | ||
586 | pub(crate) fn trait_env( | 598 | impl TraitEnvironment { |
587 | db: &impl HirDatabase, | 599 | pub(crate) fn lower(db: &impl HirDatabase, resolver: &Resolver) -> Arc<TraitEnvironment> { |
588 | resolver: &Resolver, | 600 | let predicates = resolver |
589 | ) -> Arc<super::TraitEnvironment> { | 601 | .where_predicates_in_scope() |
590 | let predicates = resolver | 602 | .flat_map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred)) |
591 | .where_predicates_in_scope() | 603 | .collect::<Vec<_>>(); |
592 | .flat_map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred)) | ||
593 | .collect::<Vec<_>>(); | ||
594 | 604 | ||
595 | Arc::new(super::TraitEnvironment { predicates }) | 605 | Arc::new(TraitEnvironment { predicates }) |
606 | } | ||
596 | } | 607 | } |
597 | 608 | ||
598 | /// Resolve the where clause(s) of an item with generics. | 609 | /// Resolve the where clause(s) of an item with generics. |
599 | pub(crate) fn generic_predicates_query( | 610 | pub(crate) fn generic_predicates_query( |
600 | db: &impl HirDatabase, | 611 | db: &impl HirDatabase, |
601 | def: GenericDef, | 612 | def: GenericDefId, |
602 | ) -> Arc<[GenericPredicate]> { | 613 | ) -> Arc<[GenericPredicate]> { |
603 | let resolver = GenericDefId::from(def).resolver(db); | 614 | let resolver = def.resolver(db); |
604 | resolver | 615 | resolver |
605 | .where_predicates_in_scope() | 616 | .where_predicates_in_scope() |
606 | .flat_map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred)) | 617 | .flat_map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred)) |
@@ -608,8 +619,8 @@ pub(crate) fn generic_predicates_query( | |||
608 | } | 619 | } |
609 | 620 | ||
610 | /// Resolve the default type params from generics | 621 | /// Resolve the default type params from generics |
611 | pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDef) -> Substs { | 622 | pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDefId) -> Substs { |
612 | let resolver = GenericDefId::from(def).resolver(db); | 623 | let resolver = def.resolver(db); |
613 | let generic_params = db.generic_params(def.into()); | 624 | let generic_params = db.generic_params(def.into()); |
614 | 625 | ||
615 | let defaults = generic_params | 626 | let defaults = generic_params |
@@ -621,9 +632,9 @@ pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDef) -> | |||
621 | Substs(defaults) | 632 | Substs(defaults) |
622 | } | 633 | } |
623 | 634 | ||
624 | fn fn_sig_for_fn(db: &impl HirDatabase, def: Function) -> FnSig { | 635 | fn fn_sig_for_fn(db: &impl HirDatabase, def: FunctionId) -> FnSig { |
625 | let data = db.function_data(def.id); | 636 | let data = db.function_data(def); |
626 | let resolver = def.id.resolver(db); | 637 | let resolver = def.resolver(db); |
627 | let params = data.params.iter().map(|tr| Ty::from_hir(db, &resolver, tr)).collect::<Vec<_>>(); | 638 | 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); | 639 | let ret = Ty::from_hir(db, &resolver, &data.ret_type); |
629 | FnSig::from_params_and_return(params, ret) | 640 | FnSig::from_params_and_return(params, ret) |
@@ -634,7 +645,7 @@ fn fn_sig_for_fn(db: &impl HirDatabase, def: Function) -> FnSig { | |||
634 | fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty { | 645 | fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty { |
635 | let generics = db.generic_params(def.id.into()); | 646 | let generics = db.generic_params(def.id.into()); |
636 | let substs = Substs::identity(&generics); | 647 | let substs = Substs::identity(&generics); |
637 | Ty::apply(TypeCtor::FnDef(def.into()), substs) | 648 | Ty::apply(TypeCtor::FnDef(def.id.into()), substs) |
638 | } | 649 | } |
639 | 650 | ||
640 | /// Build the declared type of a const. | 651 | /// Build the declared type of a const. |
@@ -694,58 +705,53 @@ impl From<Option<BuiltinFloat>> for Uncertain<FloatTy> { | |||
694 | } | 705 | } |
695 | } | 706 | } |
696 | 707 | ||
697 | fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> FnSig { | 708 | fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: StructId) -> FnSig { |
698 | let struct_data = db.struct_data(def.id.into()); | 709 | let struct_data = db.struct_data(def.into()); |
699 | let fields = match struct_data.variant_data.fields() { | 710 | let fields = struct_data.variant_data.fields(); |
700 | Some(fields) => fields, | 711 | let resolver = def.resolver(db); |
701 | None => panic!("fn_sig_for_struct_constructor called on unit struct"), | ||
702 | }; | ||
703 | let resolver = def.id.resolver(db); | ||
704 | let params = fields | 712 | let params = fields |
705 | .iter() | 713 | .iter() |
706 | .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) | 714 | .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) |
707 | .collect::<Vec<_>>(); | 715 | .collect::<Vec<_>>(); |
708 | let ret = type_for_adt(db, def); | 716 | let ret = type_for_adt(db, Struct::from(def)); |
709 | FnSig::from_params_and_return(params, ret) | 717 | FnSig::from_params_and_return(params, ret) |
710 | } | 718 | } |
711 | 719 | ||
712 | /// Build the type of a tuple struct constructor. | 720 | /// Build the type of a tuple struct constructor. |
713 | fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty { | 721 | fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty { |
714 | let struct_data = db.struct_data(def.id.into()); | 722 | let struct_data = db.struct_data(def.id.into()); |
715 | if struct_data.variant_data.fields().is_none() { | 723 | if struct_data.variant_data.is_unit() { |
716 | return type_for_adt(db, def); // Unit struct | 724 | return type_for_adt(db, def); // Unit struct |
717 | } | 725 | } |
718 | let generics = db.generic_params(def.id.into()); | 726 | let generics = db.generic_params(def.id.into()); |
719 | let substs = Substs::identity(&generics); | 727 | let substs = Substs::identity(&generics); |
720 | Ty::apply(TypeCtor::FnDef(def.into()), substs) | 728 | Ty::apply(TypeCtor::FnDef(def.id.into()), substs) |
721 | } | 729 | } |
722 | 730 | ||
723 | fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> FnSig { | 731 | fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariantId) -> FnSig { |
724 | let var_data = def.variant_data(db); | 732 | let enum_data = db.enum_data(def.parent); |
725 | let fields = match var_data.fields() { | 733 | let var_data = &enum_data.variants[def.local_id]; |
726 | Some(fields) => fields, | 734 | let fields = var_data.variant_data.fields(); |
727 | None => panic!("fn_sig_for_enum_variant_constructor called for unit variant"), | 735 | let resolver = def.parent.resolver(db); |
728 | }; | ||
729 | let resolver = def.parent.id.resolver(db); | ||
730 | let params = fields | 736 | let params = fields |
731 | .iter() | 737 | .iter() |
732 | .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) | 738 | .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) |
733 | .collect::<Vec<_>>(); | 739 | .collect::<Vec<_>>(); |
734 | let generics = db.generic_params(def.parent_enum(db).id.into()); | 740 | let generics = db.generic_params(def.parent.into()); |
735 | let substs = Substs::identity(&generics); | 741 | let substs = Substs::identity(&generics); |
736 | let ret = type_for_adt(db, def.parent_enum(db)).subst(&substs); | 742 | let ret = type_for_adt(db, Enum::from(def.parent)).subst(&substs); |
737 | FnSig::from_params_and_return(params, ret) | 743 | FnSig::from_params_and_return(params, ret) |
738 | } | 744 | } |
739 | 745 | ||
740 | /// Build the type of a tuple enum variant constructor. | 746 | /// Build the type of a tuple enum variant constructor. |
741 | fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> Ty { | 747 | fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> Ty { |
742 | let var_data = def.variant_data(db); | 748 | let var_data = def.variant_data(db); |
743 | if var_data.fields().is_none() { | 749 | if var_data.is_unit() { |
744 | return type_for_adt(db, def.parent_enum(db)); // Unit variant | 750 | return type_for_adt(db, def.parent_enum(db)); // Unit variant |
745 | } | 751 | } |
746 | let generics = db.generic_params(def.parent_enum(db).id.into()); | 752 | let generics = db.generic_params(def.parent_enum(db).id.into()); |
747 | let substs = Substs::identity(&generics); | 753 | let substs = Substs::identity(&generics); |
748 | Ty::apply(TypeCtor::FnDef(def.into()), substs) | 754 | Ty::apply(TypeCtor::FnDef(EnumVariantId::from(def).into()), substs) |
749 | } | 755 | } |
750 | 756 | ||
751 | fn type_for_adt(db: &impl HirDatabase, adt: impl Into<Adt>) -> Ty { | 757 | fn type_for_adt(db: &impl HirDatabase, adt: impl Into<Adt>) -> Ty { |
@@ -802,28 +808,28 @@ impl From<ModuleDef> for Option<TypableDef> { | |||
802 | 808 | ||
803 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | 809 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] |
804 | pub enum CallableDef { | 810 | pub enum CallableDef { |
805 | Function(Function), | 811 | FunctionId(FunctionId), |
806 | Struct(Struct), | 812 | StructId(StructId), |
807 | EnumVariant(EnumVariant), | 813 | EnumVariantId(EnumVariantId), |
808 | } | 814 | } |
809 | impl_froms!(CallableDef: Function, Struct, EnumVariant); | 815 | impl_froms!(CallableDef: FunctionId, StructId, EnumVariantId); |
810 | 816 | ||
811 | impl CallableDef { | 817 | impl CallableDef { |
812 | pub fn krate(self, db: &impl HirDatabase) -> Option<crate::Crate> { | 818 | pub fn krate(self, db: &impl HirDatabase) -> CrateId { |
813 | match self { | 819 | match self { |
814 | CallableDef::Function(f) => f.krate(db), | 820 | CallableDef::FunctionId(f) => f.lookup(db).module(db).krate, |
815 | CallableDef::Struct(s) => s.krate(db), | 821 | CallableDef::StructId(s) => s.0.module(db).krate, |
816 | CallableDef::EnumVariant(e) => e.parent_enum(db).krate(db), | 822 | CallableDef::EnumVariantId(e) => e.parent.module(db).krate, |
817 | } | 823 | } |
818 | } | 824 | } |
819 | } | 825 | } |
820 | 826 | ||
821 | impl From<CallableDef> for GenericDef { | 827 | impl From<CallableDef> for GenericDefId { |
822 | fn from(def: CallableDef) -> GenericDef { | 828 | fn from(def: CallableDef) -> GenericDefId { |
823 | match def { | 829 | match def { |
824 | CallableDef::Function(f) => f.into(), | 830 | CallableDef::FunctionId(f) => f.into(), |
825 | CallableDef::Struct(s) => s.into(), | 831 | CallableDef::StructId(s) => s.into(), |
826 | CallableDef::EnumVariant(e) => e.into(), | 832 | CallableDef::EnumVariantId(e) => e.into(), |
827 | } | 833 | } |
828 | } | 834 | } |
829 | } | 835 | } |