aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty/lower.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/ty/lower.rs')
-rw-r--r--crates/ra_hir/src/ty/lower.rs150
1 files changed, 77 insertions, 73 deletions
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs
index c6ad0811b..1ceafd9b1 100644
--- a/crates/ra_hir/src/ty/lower.rs
+++ b/crates/ra_hir/src/ty/lower.rs
@@ -10,27 +10,27 @@ use std::sync::Arc;
10 10
11use hir_def::{ 11use hir_def::{
12 builtin_type::{BuiltinFloat, BuiltinInt, BuiltinType}, 12 builtin_type::{BuiltinFloat, BuiltinInt, BuiltinType},
13 generics::WherePredicate,
13 path::{GenericArg, PathSegment}, 14 path::{GenericArg, PathSegment},
14 resolver::{HasResolver, Resolver, TypeNs}, 15 resolver::{HasResolver, Resolver, TypeNs},
15 type_ref::{TypeBound, TypeRef}, 16 type_ref::{TypeBound, TypeRef},
16 GenericDefId, 17 AdtId, EnumVariantId, GenericDefId, LocalStructFieldId, VariantId,
17}; 18};
19use ra_arena::map::ArenaMap;
18 20
19use super::{ 21use super::{
20 FnSig, GenericPredicate, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, 22 FnSig, GenericPredicate, ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, TraitRef,
21 TypeWalk, 23 Ty, TypeCtor, TypeWalk,
22}; 24};
23use crate::{ 25use crate::{
24 db::HirDatabase, 26 db::HirDatabase,
25 generics::HasGenericParams,
26 generics::{GenericDef, WherePredicate},
27 ty::{ 27 ty::{
28 primitive::{FloatTy, IntTy, Uncertain}, 28 primitive::{FloatTy, IntTy, Uncertain},
29 Adt, 29 Adt,
30 }, 30 },
31 util::make_mut_slice, 31 util::make_mut_slice,
32 Const, Enum, EnumVariant, Function, ImplBlock, ModuleDef, Path, Static, Struct, StructField, 32 Const, Enum, EnumVariant, Function, ImplBlock, ModuleDef, Path, Static, Struct, Trait,
33 Trait, TypeAlias, Union, VariantDef, 33 TypeAlias, Union,
34}; 34};
35 35
36// 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
@@ -261,8 +261,10 @@ impl Ty {
261 let traits = traits_from_env.flat_map(|t| t.all_super_traits(db)); 261 let traits = traits_from_env.flat_map(|t| t.all_super_traits(db));
262 for t in traits { 262 for t in traits {
263 if let Some(associated_ty) = t.associated_type_by_name(db, &segment.name) { 263 if let Some(associated_ty) = t.associated_type_by_name(db, &segment.name) {
264 let substs = 264 let substs = Substs::build_for_def(db, t.id)
265 Substs::build_for_def(db, t).push(self_ty.clone()).fill_with_unknown().build(); 265 .push(self_ty.clone())
266 .fill_with_unknown()
267 .build();
266 // FIXME handle type parameters on the segment 268 // FIXME handle type parameters on the segment
267 return Ty::Projection(ProjectionTy { associated_ty, parameters: substs }); 269 return Ty::Projection(ProjectionTy { associated_ty, parameters: substs });
268 } 270 }
@@ -287,11 +289,11 @@ impl Ty {
287 segment: &PathSegment, 289 segment: &PathSegment,
288 resolved: TypableDef, 290 resolved: TypableDef,
289 ) -> Substs { 291 ) -> Substs {
290 let def_generic: Option<GenericDef> = match resolved { 292 let def_generic: Option<GenericDefId> = match resolved {
291 TypableDef::Function(func) => Some(func.into()), 293 TypableDef::Function(func) => Some(func.id.into()),
292 TypableDef::Adt(adt) => Some(adt.into()), 294 TypableDef::Adt(adt) => Some(adt.into()),
293 TypableDef::EnumVariant(var) => Some(var.parent_enum(db).into()), 295 TypableDef::EnumVariant(var) => Some(var.parent_enum(db).id.into()),
294 TypableDef::TypeAlias(t) => Some(t.into()), 296 TypableDef::TypeAlias(t) => Some(t.id.into()),
295 TypableDef::Const(_) | TypableDef::Static(_) | TypableDef::BuiltinType(_) => None, 297 TypableDef::Const(_) | TypableDef::Static(_) | TypableDef::BuiltinType(_) => None,
296 }; 298 };
297 substs_from_path_segment(db, resolver, segment, def_generic, false) 299 substs_from_path_segment(db, resolver, segment, def_generic, false)
@@ -338,11 +340,11 @@ pub(super) fn substs_from_path_segment(
338 db: &impl HirDatabase, 340 db: &impl HirDatabase,
339 resolver: &Resolver, 341 resolver: &Resolver,
340 segment: &PathSegment, 342 segment: &PathSegment,
341 def_generic: Option<GenericDef>, 343 def_generic: Option<GenericDefId>,
342 add_self_param: bool, 344 add_self_param: bool,
343) -> Substs { 345) -> Substs {
344 let mut substs = Vec::new(); 346 let mut substs = Vec::new();
345 let def_generics = def_generic.map(|def| def.generic_params(db)); 347 let def_generics = def_generic.map(|def| db.generic_params(def.into()));
346 348
347 let (parent_param_count, param_count) = 349 let (parent_param_count, param_count) =
348 def_generics.map_or((0, 0), |g| (g.count_parent_params(), g.params.len())); 350 def_generics.map_or((0, 0), |g| (g.count_parent_params(), g.params.len()));
@@ -376,7 +378,7 @@ pub(super) fn substs_from_path_segment(
376 378
377 // handle defaults 379 // handle defaults
378 if let Some(def_generic) = def_generic { 380 if let Some(def_generic) = def_generic {
379 let default_substs = db.generic_defaults(def_generic); 381 let default_substs = db.generic_defaults(def_generic.into());
380 assert_eq!(substs.len(), default_substs.len()); 382 assert_eq!(substs.len(), default_substs.len());
381 383
382 for (i, default_ty) in default_substs.iter().enumerate() { 384 for (i, default_ty) in default_substs.iter().enumerate() {
@@ -439,11 +441,11 @@ impl TraitRef {
439 ) -> Substs { 441 ) -> Substs {
440 let has_self_param = 442 let has_self_param =
441 segment.args_and_bindings.as_ref().map(|a| a.has_self_type).unwrap_or(false); 443 segment.args_and_bindings.as_ref().map(|a| a.has_self_type).unwrap_or(false);
442 substs_from_path_segment(db, resolver, segment, Some(resolved.into()), !has_self_param) 444 substs_from_path_segment(db, resolver, segment, Some(resolved.id.into()), !has_self_param)
443 } 445 }
444 446
445 pub(crate) fn for_trait(db: &impl HirDatabase, trait_: Trait) -> TraitRef { 447 pub(crate) fn for_trait(db: &impl HirDatabase, trait_: Trait) -> TraitRef {
446 let substs = Substs::identity(&trait_.generic_params(db)); 448 let substs = Substs::identity(&db.generic_params(trait_.id.into()));
447 TraitRef { trait_, substs } 449 TraitRef { trait_, substs }
448 } 450 }
449 451
@@ -550,16 +552,23 @@ pub(crate) fn callable_item_sig(db: &impl HirDatabase, def: CallableDef) -> FnSi
550 } 552 }
551} 553}
552 554
553/// Build the type of a specific field of a struct or enum variant. 555/// Build the type of all specific fields of a struct or enum variant.
554pub(crate) fn type_for_field(db: &impl HirDatabase, field: StructField) -> Ty { 556pub(crate) fn field_types_query(
555 let parent_def = field.parent_def(db); 557 db: &impl HirDatabase,
556 let resolver = match parent_def { 558 variant_id: VariantId,
557 VariantDef::Struct(it) => it.id.resolver(db), 559) -> Arc<ArenaMap<LocalStructFieldId, Ty>> {
558 VariantDef::EnumVariant(it) => it.parent.id.resolver(db), 560 let (resolver, var_data) = match variant_id {
561 VariantId::StructId(it) => (it.resolver(db), db.struct_data(it.0).variant_data.clone()),
562 VariantId::EnumVariantId(it) => (
563 it.parent.resolver(db),
564 db.enum_data(it.parent).variants[it.local_id].variant_data.clone(),
565 ),
559 }; 566 };
560 let var_data = parent_def.variant_data(db); 567 let mut res = ArenaMap::default();
561 let type_ref = &var_data.fields().unwrap()[field.id].type_ref; 568 for (field_id, field_data) in var_data.fields().iter() {
562 Ty::from_hir(db, &resolver, type_ref) 569 res.insert(field_id, Ty::from_hir(db, &resolver, &field_data.type_ref))
570 }
571 Arc::new(res)
563} 572}
564 573
565/// This query exists only to be used when resolving short-hand associated types 574/// This query exists only to be used when resolving short-hand associated types
@@ -572,10 +581,10 @@ pub(crate) fn type_for_field(db: &impl HirDatabase, field: StructField) -> Ty {
572/// these are fine: `T: Foo<U::Item>, U: Foo<()>`. 581/// these are fine: `T: Foo<U::Item>, U: Foo<()>`.
573pub(crate) fn generic_predicates_for_param_query( 582pub(crate) fn generic_predicates_for_param_query(
574 db: &impl HirDatabase, 583 db: &impl HirDatabase,
575 def: GenericDef, 584 def: GenericDefId,
576 param_idx: u32, 585 param_idx: u32,
577) -> Arc<[GenericPredicate]> { 586) -> Arc<[GenericPredicate]> {
578 let resolver = GenericDefId::from(def).resolver(db); 587 let resolver = def.resolver(db);
579 resolver 588 resolver
580 .where_predicates_in_scope() 589 .where_predicates_in_scope()
581 // we have to filter out all other predicates *first*, before attempting to lower them 590 // we have to filter out all other predicates *first*, before attempting to lower them
@@ -584,24 +593,23 @@ pub(crate) fn generic_predicates_for_param_query(
584 .collect() 593 .collect()
585} 594}
586 595
587pub(crate) fn trait_env( 596impl TraitEnvironment {
588 db: &impl HirDatabase, 597 pub(crate) fn lower(db: &impl HirDatabase, resolver: &Resolver) -> Arc<TraitEnvironment> {
589 resolver: &Resolver, 598 let predicates = resolver
590) -> Arc<super::TraitEnvironment> { 599 .where_predicates_in_scope()
591 let predicates = resolver 600 .flat_map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred))
592 .where_predicates_in_scope() 601 .collect::<Vec<_>>();
593 .flat_map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred))
594 .collect::<Vec<_>>();
595 602
596 Arc::new(super::TraitEnvironment { predicates }) 603 Arc::new(TraitEnvironment { predicates })
604 }
597} 605}
598 606
599/// Resolve the where clause(s) of an item with generics. 607/// Resolve the where clause(s) of an item with generics.
600pub(crate) fn generic_predicates_query( 608pub(crate) fn generic_predicates_query(
601 db: &impl HirDatabase, 609 db: &impl HirDatabase,
602 def: GenericDef, 610 def: GenericDefId,
603) -> Arc<[GenericPredicate]> { 611) -> Arc<[GenericPredicate]> {
604 let resolver = GenericDefId::from(def).resolver(db); 612 let resolver = def.resolver(db);
605 resolver 613 resolver
606 .where_predicates_in_scope() 614 .where_predicates_in_scope()
607 .flat_map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred)) 615 .flat_map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred))
@@ -609,9 +617,9 @@ pub(crate) fn generic_predicates_query(
609} 617}
610 618
611/// Resolve the default type params from generics 619/// Resolve the default type params from generics
612pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDef) -> Substs { 620pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDefId) -> Substs {
613 let resolver = GenericDefId::from(def).resolver(db); 621 let resolver = def.resolver(db);
614 let generic_params = def.generic_params(db); 622 let generic_params = db.generic_params(def.into());
615 623
616 let defaults = generic_params 624 let defaults = generic_params
617 .params_including_parent() 625 .params_including_parent()
@@ -623,35 +631,35 @@ pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDef) ->
623} 631}
624 632
625fn fn_sig_for_fn(db: &impl HirDatabase, def: Function) -> FnSig { 633fn fn_sig_for_fn(db: &impl HirDatabase, def: Function) -> FnSig {
626 let data = def.data(db); 634 let data = db.function_data(def.id);
627 let resolver = def.id.resolver(db); 635 let resolver = def.id.resolver(db);
628 let params = data.params().iter().map(|tr| Ty::from_hir(db, &resolver, tr)).collect::<Vec<_>>(); 636 let params = data.params.iter().map(|tr| Ty::from_hir(db, &resolver, tr)).collect::<Vec<_>>();
629 let ret = Ty::from_hir(db, &resolver, data.ret_type()); 637 let ret = Ty::from_hir(db, &resolver, &data.ret_type);
630 FnSig::from_params_and_return(params, ret) 638 FnSig::from_params_and_return(params, ret)
631} 639}
632 640
633/// Build the declared type of a function. This should not need to look at the 641/// Build the declared type of a function. This should not need to look at the
634/// function body. 642/// function body.
635fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty { 643fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty {
636 let generics = def.generic_params(db); 644 let generics = db.generic_params(def.id.into());
637 let substs = Substs::identity(&generics); 645 let substs = Substs::identity(&generics);
638 Ty::apply(TypeCtor::FnDef(def.into()), substs) 646 Ty::apply(TypeCtor::FnDef(def.into()), substs)
639} 647}
640 648
641/// Build the declared type of a const. 649/// Build the declared type of a const.
642fn type_for_const(db: &impl HirDatabase, def: Const) -> Ty { 650fn type_for_const(db: &impl HirDatabase, def: Const) -> Ty {
643 let data = def.data(db); 651 let data = db.const_data(def.id);
644 let resolver = def.id.resolver(db); 652 let resolver = def.id.resolver(db);
645 653
646 Ty::from_hir(db, &resolver, data.type_ref()) 654 Ty::from_hir(db, &resolver, &data.type_ref)
647} 655}
648 656
649/// Build the declared type of a static. 657/// Build the declared type of a static.
650fn type_for_static(db: &impl HirDatabase, def: Static) -> Ty { 658fn type_for_static(db: &impl HirDatabase, def: Static) -> Ty {
651 let data = def.data(db); 659 let data = db.static_data(def.id);
652 let resolver = def.id.resolver(db); 660 let resolver = def.id.resolver(db);
653 661
654 Ty::from_hir(db, &resolver, data.type_ref()) 662 Ty::from_hir(db, &resolver, &data.type_ref)
655} 663}
656 664
657/// Build the declared type of a static. 665/// Build the declared type of a static.
@@ -697,10 +705,7 @@ impl From<Option<BuiltinFloat>> for Uncertain<FloatTy> {
697 705
698fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> FnSig { 706fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> FnSig {
699 let struct_data = db.struct_data(def.id.into()); 707 let struct_data = db.struct_data(def.id.into());
700 let fields = match struct_data.variant_data.fields() { 708 let fields = struct_data.variant_data.fields();
701 Some(fields) => fields,
702 None => panic!("fn_sig_for_struct_constructor called on unit struct"),
703 };
704 let resolver = def.id.resolver(db); 709 let resolver = def.id.resolver(db);
705 let params = fields 710 let params = fields
706 .iter() 711 .iter()
@@ -713,26 +718,23 @@ fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> FnSig {
713/// Build the type of a tuple struct constructor. 718/// Build the type of a tuple struct constructor.
714fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty { 719fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty {
715 let struct_data = db.struct_data(def.id.into()); 720 let struct_data = db.struct_data(def.id.into());
716 if struct_data.variant_data.fields().is_none() { 721 if struct_data.variant_data.is_unit() {
717 return type_for_adt(db, def); // Unit struct 722 return type_for_adt(db, def); // Unit struct
718 } 723 }
719 let generics = def.generic_params(db); 724 let generics = db.generic_params(def.id.into());
720 let substs = Substs::identity(&generics); 725 let substs = Substs::identity(&generics);
721 Ty::apply(TypeCtor::FnDef(def.into()), substs) 726 Ty::apply(TypeCtor::FnDef(def.into()), substs)
722} 727}
723 728
724fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> FnSig { 729fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> FnSig {
725 let var_data = def.variant_data(db); 730 let var_data = def.variant_data(db);
726 let fields = match var_data.fields() { 731 let fields = var_data.fields();
727 Some(fields) => fields,
728 None => panic!("fn_sig_for_enum_variant_constructor called for unit variant"),
729 };
730 let resolver = def.parent.id.resolver(db); 732 let resolver = def.parent.id.resolver(db);
731 let params = fields 733 let params = fields
732 .iter() 734 .iter()
733 .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) 735 .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref))
734 .collect::<Vec<_>>(); 736 .collect::<Vec<_>>();
735 let generics = def.parent_enum(db).generic_params(db); 737 let generics = db.generic_params(def.parent_enum(db).id.into());
736 let substs = Substs::identity(&generics); 738 let substs = Substs::identity(&generics);
737 let ret = type_for_adt(db, def.parent_enum(db)).subst(&substs); 739 let ret = type_for_adt(db, def.parent_enum(db)).subst(&substs);
738 FnSig::from_params_and_return(params, ret) 740 FnSig::from_params_and_return(params, ret)
@@ -741,21 +743,23 @@ fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant)
741/// Build the type of a tuple enum variant constructor. 743/// Build the type of a tuple enum variant constructor.
742fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> Ty { 744fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> Ty {
743 let var_data = def.variant_data(db); 745 let var_data = def.variant_data(db);
744 if var_data.fields().is_none() { 746 if var_data.is_unit() {
745 return type_for_adt(db, def.parent_enum(db)); // Unit variant 747 return type_for_adt(db, def.parent_enum(db)); // Unit variant
746 } 748 }
747 let generics = def.parent_enum(db).generic_params(db); 749 let generics = db.generic_params(def.parent_enum(db).id.into());
748 let substs = Substs::identity(&generics); 750 let substs = Substs::identity(&generics);
749 Ty::apply(TypeCtor::FnDef(def.into()), substs) 751 Ty::apply(TypeCtor::FnDef(def.into()), substs)
750} 752}
751 753
752fn type_for_adt(db: &impl HirDatabase, adt: impl Into<Adt> + HasGenericParams) -> Ty { 754fn type_for_adt(db: &impl HirDatabase, adt: impl Into<Adt>) -> Ty {
753 let generics = adt.generic_params(db); 755 let adt = adt.into();
754 Ty::apply(TypeCtor::Adt(adt.into()), Substs::identity(&generics)) 756 let adt_id: AdtId = adt.into();
757 let generics = db.generic_params(adt_id.into());
758 Ty::apply(TypeCtor::Adt(adt), Substs::identity(&generics))
755} 759}
756 760
757fn type_for_type_alias(db: &impl HirDatabase, t: TypeAlias) -> Ty { 761fn type_for_type_alias(db: &impl HirDatabase, t: TypeAlias) -> Ty {
758 let generics = t.generic_params(db); 762 let generics = db.generic_params(t.id.into());
759 let resolver = t.id.resolver(db); 763 let resolver = t.id.resolver(db);
760 let type_ref = t.type_ref(db); 764 let type_ref = t.type_ref(db);
761 let substs = Substs::identity(&generics); 765 let substs = Substs::identity(&generics);
@@ -817,12 +821,12 @@ impl CallableDef {
817 } 821 }
818} 822}
819 823
820impl From<CallableDef> for GenericDef { 824impl From<CallableDef> for GenericDefId {
821 fn from(def: CallableDef) -> GenericDef { 825 fn from(def: CallableDef) -> GenericDefId {
822 match def { 826 match def {
823 CallableDef::Function(f) => f.into(), 827 CallableDef::Function(f) => f.id.into(),
824 CallableDef::Struct(s) => s.into(), 828 CallableDef::Struct(s) => s.id.into(),
825 CallableDef::EnumVariant(e) => e.into(), 829 CallableDef::EnumVariant(e) => EnumVariantId::from(e).into(),
826 } 830 }
827 } 831 }
828} 832}