aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/lower.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/lower.rs')
-rw-r--r--crates/hir_ty/src/lower.rs151
1 files changed, 69 insertions, 82 deletions
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs
index c87789d45..214655807 100644
--- a/crates/hir_ty/src/lower.rs
+++ b/crates/hir_ty/src/lower.rs
@@ -15,7 +15,7 @@ use hir_def::{
15 generics::{TypeParamProvenance, WherePredicate, WherePredicateTypeTarget}, 15 generics::{TypeParamProvenance, WherePredicate, WherePredicateTypeTarget},
16 path::{GenericArg, Path, PathSegment, PathSegments}, 16 path::{GenericArg, Path, PathSegment, PathSegments},
17 resolver::{HasResolver, Resolver, TypeNs}, 17 resolver::{HasResolver, Resolver, TypeNs},
18 type_ref::{TypeBound, TypeRef}, 18 type_ref::{TraitRef as HirTraitRef, TypeBound, TypeRef},
19 AdtId, AssocContainerId, AssocItemId, ConstId, ConstParamId, EnumId, EnumVariantId, FunctionId, 19 AdtId, AssocContainerId, AssocItemId, ConstId, ConstParamId, EnumId, EnumVariantId, FunctionId,
20 GenericDefId, HasModule, ImplId, LocalFieldId, Lookup, StaticId, StructId, TraitId, 20 GenericDefId, HasModule, ImplId, LocalFieldId, Lookup, StaticId, StructId, TraitId,
21 TypeAliasId, TypeParamId, UnionId, VariantId, 21 TypeAliasId, TypeParamId, UnionId, VariantId,
@@ -36,7 +36,7 @@ use crate::{
36 AliasEq, AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, DynTy, FnPointer, FnSig, 36 AliasEq, AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, DynTy, FnPointer, FnSig,
37 ImplTraitId, OpaqueTy, PolyFnSig, ProjectionTy, QuantifiedWhereClause, QuantifiedWhereClauses, 37 ImplTraitId, OpaqueTy, PolyFnSig, ProjectionTy, QuantifiedWhereClause, QuantifiedWhereClauses,
38 ReturnTypeImplTrait, ReturnTypeImplTraits, Substitution, TraitEnvironment, TraitRef, Ty, 38 ReturnTypeImplTrait, ReturnTypeImplTraits, Substitution, TraitEnvironment, TraitRef, Ty,
39 TyKind, TypeWalk, WhereClause, 39 TyBuilder, TyKind, TypeWalk, WhereClause,
40}; 40};
41 41
42#[derive(Debug)] 42#[derive(Debug)]
@@ -146,7 +146,7 @@ impl<'a> TyLoweringContext<'a> {
146 self.lower_ty_ext(type_ref).0 146 self.lower_ty_ext(type_ref).0
147 } 147 }
148 148
149 fn lower_ty_ext(&self, type_ref: &TypeRef) -> (Ty, Option<TypeNs>) { 149 pub fn lower_ty_ext(&self, type_ref: &TypeRef) -> (Ty, Option<TypeNs>) {
150 let mut res = None; 150 let mut res = None;
151 let ty = match type_ref { 151 let ty = match type_ref {
152 TypeRef::Never => TyKind::Never.intern(&Interner), 152 TypeRef::Never => TyKind::Never.intern(&Interner),
@@ -178,9 +178,10 @@ impl<'a> TyLoweringContext<'a> {
178 } 178 }
179 TypeRef::Placeholder => TyKind::Unknown.intern(&Interner), 179 TypeRef::Placeholder => TyKind::Unknown.intern(&Interner),
180 TypeRef::Fn(params, is_varargs) => { 180 TypeRef::Fn(params, is_varargs) => {
181 let substs = Substitution(params.iter().map(|tr| self.lower_ty(tr)).collect()); 181 let substs =
182 Substitution::from_iter(&Interner, params.iter().map(|tr| self.lower_ty(tr)));
182 TyKind::Function(FnPointer { 183 TyKind::Function(FnPointer {
183 num_args: substs.len() - 1, 184 num_args: substs.len(&Interner) - 1,
184 sig: FnSig { abi: (), safety: Safety::Safe, variadic: *is_varargs }, 185 sig: FnSig { abi: (), safety: Safety::Safe, variadic: *is_varargs },
185 substs, 186 substs,
186 }) 187 })
@@ -233,7 +234,7 @@ impl<'a> TyLoweringContext<'a> {
233 let impl_trait_id = ImplTraitId::ReturnTypeImplTrait(func, idx); 234 let impl_trait_id = ImplTraitId::ReturnTypeImplTrait(func, idx);
234 let opaque_ty_id = self.db.intern_impl_trait_id(impl_trait_id).into(); 235 let opaque_ty_id = self.db.intern_impl_trait_id(impl_trait_id).into();
235 let generics = generics(self.db.upcast(), func.into()); 236 let generics = generics(self.db.upcast(), func.into());
236 let parameters = Substitution::bound_vars(&generics, self.in_binders); 237 let parameters = generics.bound_vars_subst(self.in_binders);
237 TyKind::Alias(AliasTy::Opaque(OpaqueTy { 238 TyKind::Alias(AliasTy::Opaque(OpaqueTy {
238 opaque_ty_id, 239 opaque_ty_id,
239 substitution: parameters, 240 substitution: parameters,
@@ -410,24 +411,16 @@ impl<'a> TyLoweringContext<'a> {
410 TypeNs::SelfType(impl_id) => { 411 TypeNs::SelfType(impl_id) => {
411 let generics = generics(self.db.upcast(), impl_id.into()); 412 let generics = generics(self.db.upcast(), impl_id.into());
412 let substs = match self.type_param_mode { 413 let substs = match self.type_param_mode {
413 TypeParamLoweringMode::Placeholder => { 414 TypeParamLoweringMode::Placeholder => generics.type_params_subst(self.db),
414 Substitution::type_params_for_generics(self.db, &generics) 415 TypeParamLoweringMode::Variable => generics.bound_vars_subst(self.in_binders),
415 }
416 TypeParamLoweringMode::Variable => {
417 Substitution::bound_vars(&generics, self.in_binders)
418 }
419 }; 416 };
420 self.db.impl_self_ty(impl_id).subst(&substs) 417 self.db.impl_self_ty(impl_id).subst(&substs)
421 } 418 }
422 TypeNs::AdtSelfType(adt) => { 419 TypeNs::AdtSelfType(adt) => {
423 let generics = generics(self.db.upcast(), adt.into()); 420 let generics = generics(self.db.upcast(), adt.into());
424 let substs = match self.type_param_mode { 421 let substs = match self.type_param_mode {
425 TypeParamLoweringMode::Placeholder => { 422 TypeParamLoweringMode::Placeholder => generics.type_params_subst(self.db),
426 Substitution::type_params_for_generics(self.db, &generics) 423 TypeParamLoweringMode::Variable => generics.bound_vars_subst(self.in_binders),
427 }
428 TypeParamLoweringMode::Variable => {
429 Substitution::bound_vars(&generics, self.in_binders)
430 }
431 }; 424 };
432 self.db.ty(adt.into()).subst(&substs) 425 self.db.ty(adt.into()).subst(&substs)
433 } 426 }
@@ -477,12 +470,13 @@ impl<'a> TyLoweringContext<'a> {
477 TypeParamLoweringMode::Placeholder => { 470 TypeParamLoweringMode::Placeholder => {
478 // if we're lowering to placeholders, we have to put 471 // if we're lowering to placeholders, we have to put
479 // them in now 472 // them in now
480 let s = Substitution::type_params( 473 let generics = generics(
481 self.db, 474 self.db.upcast(),
482 self.resolver.generic_def().expect( 475 self.resolver.generic_def().expect(
483 "there should be generics if there's a generic param", 476 "there should be generics if there's a generic param",
484 ), 477 ),
485 ); 478 );
479 let s = generics.type_params_subst(self.db);
486 t.substitution.clone().subst_bound_vars(&s) 480 t.substitution.clone().subst_bound_vars(&s)
487 } 481 }
488 TypeParamLoweringMode::Variable => t.substitution.clone(), 482 TypeParamLoweringMode::Variable => t.substitution.clone(),
@@ -625,7 +619,7 @@ impl<'a> TyLoweringContext<'a> {
625 619
626 for default_ty in defaults.iter().skip(substs.len()) { 620 for default_ty in defaults.iter().skip(substs.len()) {
627 // each default can depend on the previous parameters 621 // each default can depend on the previous parameters
628 let substs_so_far = Substitution(substs.clone().into()); 622 let substs_so_far = Substitution::from_iter(&Interner, substs.clone());
629 substs.push(default_ty.clone().subst(&substs_so_far)); 623 substs.push(default_ty.clone().subst(&substs_so_far));
630 } 624 }
631 } 625 }
@@ -638,7 +632,7 @@ impl<'a> TyLoweringContext<'a> {
638 } 632 }
639 assert_eq!(substs.len(), total_len); 633 assert_eq!(substs.len(), total_len);
640 634
641 Substitution(substs.into()) 635 Substitution::from_iter(&Interner, substs)
642 } 636 }
643 637
644 fn lower_trait_ref_from_path( 638 fn lower_trait_ref_from_path(
@@ -667,14 +661,10 @@ impl<'a> TyLoweringContext<'a> {
667 661
668 fn lower_trait_ref( 662 fn lower_trait_ref(
669 &self, 663 &self,
670 type_ref: &TypeRef, 664 trait_ref: &HirTraitRef,
671 explicit_self_ty: Option<Ty>, 665 explicit_self_ty: Option<Ty>,
672 ) -> Option<TraitRef> { 666 ) -> Option<TraitRef> {
673 let path = match type_ref { 667 self.lower_trait_ref_from_path(&trait_ref.path, explicit_self_ty)
674 TypeRef::Path(path) => path,
675 _ => return None,
676 };
677 self.lower_trait_ref_from_path(path, explicit_self_ty)
678 } 668 }
679 669
680 fn trait_ref_substs_from_path( 670 fn trait_ref_substs_from_path(
@@ -825,58 +815,54 @@ pub fn associated_type_shorthand_candidates<R>(
825 res: TypeNs, 815 res: TypeNs,
826 mut cb: impl FnMut(&Name, &TraitRef, TypeAliasId) -> Option<R>, 816 mut cb: impl FnMut(&Name, &TraitRef, TypeAliasId) -> Option<R>,
827) -> Option<R> { 817) -> Option<R> {
828 let traits_from_env: Vec<_> = match res { 818 let mut search = |t| {
829 TypeNs::SelfType(impl_id) => match db.impl_trait(impl_id) { 819 for t in all_super_trait_refs(db, t) {
830 None => vec![], 820 let data = db.trait_data(t.hir_trait_id());
831 // FIXME: how to correctly handle higher-ranked bounds here? 821
832 Some(trait_ref) => vec![trait_ref.value.shift_bound_vars_out(DebruijnIndex::ONE)], 822 for (name, assoc_id) in &data.items {
833 }, 823 if let AssocItemId::TypeAliasId(alias) = assoc_id {
824 if let Some(result) = cb(name, &t, *alias) {
825 return Some(result);
826 }
827 }
828 }
829 }
830 None
831 };
832
833 match res {
834 // FIXME: how to correctly handle higher-ranked bounds here?
835 TypeNs::SelfType(impl_id) => {
836 search(db.impl_trait(impl_id)?.value.shift_bound_vars_out(DebruijnIndex::ONE))
837 }
834 TypeNs::GenericParam(param_id) => { 838 TypeNs::GenericParam(param_id) => {
835 let predicates = db.generic_predicates_for_param(param_id); 839 let predicates = db.generic_predicates_for_param(param_id);
836 let mut traits_: Vec<_> = predicates 840 let res = predicates.iter().find_map(|pred| match &pred.value.value {
837 .iter() 841 // FIXME: how to correctly handle higher-ranked bounds here?
838 .filter_map(|pred| match &pred.value.value { 842 WhereClause::Implemented(tr) => {
839 // FIXME: how to correctly handle higher-ranked bounds here? 843 search(tr.clone().shift_bound_vars_out(DebruijnIndex::ONE))
840 WhereClause::Implemented(tr) => { 844 }
841 Some(tr.clone().shift_bound_vars_out(DebruijnIndex::ONE)) 845 _ => None,
842 } 846 });
843 _ => None, 847 if let res @ Some(_) = res {
844 }) 848 return res;
845 .collect(); 849 }
846 // Handle `Self::Type` referring to own associated type in trait definitions 850 // Handle `Self::Type` referring to own associated type in trait definitions
847 if let GenericDefId::TraitId(trait_id) = param_id.parent { 851 if let GenericDefId::TraitId(trait_id) = param_id.parent {
848 let generics = generics(db.upcast(), trait_id.into()); 852 let generics = generics(db.upcast(), trait_id.into());
849 if generics.params.types[param_id.local_id].provenance 853 if generics.params.types[param_id.local_id].provenance
850 == TypeParamProvenance::TraitSelf 854 == TypeParamProvenance::TraitSelf
851 { 855 {
852 let trait_ref = TraitRef { 856 let trait_ref = TyBuilder::trait_ref(db, trait_id)
853 trait_id: to_chalk_trait_id(trait_id), 857 .fill_with_bound_vars(DebruijnIndex::INNERMOST, 0)
854 substitution: Substitution::bound_vars(&generics, DebruijnIndex::INNERMOST), 858 .build();
855 }; 859 return search(trait_ref);
856 traits_.push(trait_ref);
857 }
858 }
859 traits_
860 }
861 _ => vec![],
862 };
863
864 for t in traits_from_env.into_iter().flat_map(move |t| all_super_trait_refs(db, t)) {
865 let data = db.trait_data(t.hir_trait_id());
866
867 for (name, assoc_id) in &data.items {
868 match assoc_id {
869 AssocItemId::TypeAliasId(alias) => {
870 if let Some(result) = cb(name, &t, *alias) {
871 return Some(result);
872 }
873 } 860 }
874 AssocItemId::FunctionId(_) | AssocItemId::ConstId(_) => {}
875 } 861 }
862 None
876 } 863 }
864 _ => None,
877 } 865 }
878
879 None
880} 866}
881 867
882/// Build the type of all specific fields of a struct or enum variant. 868/// Build the type of all specific fields of a struct or enum variant.
@@ -978,7 +964,7 @@ pub(crate) fn trait_environment_query(
978 // function default implementations (and hypothetical code 964 // function default implementations (and hypothetical code
979 // inside consts or type aliases) 965 // inside consts or type aliases)
980 cov_mark::hit!(trait_self_implements_self); 966 cov_mark::hit!(trait_self_implements_self);
981 let substs = Substitution::type_params(db, trait_id); 967 let substs = TyBuilder::type_params_subst(db, trait_id);
982 let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_id), substitution: substs }; 968 let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_id), substitution: substs };
983 let pred = WhereClause::Implemented(trait_ref); 969 let pred = WhereClause::Implemented(trait_ref);
984 let program_clause: chalk_ir::ProgramClause<Interner> = pred.to_chalk(db).cast(&Interner); 970 let program_clause: chalk_ir::ProgramClause<Interner> = pred.to_chalk(db).cast(&Interner);
@@ -1060,16 +1046,16 @@ fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig {
1060 let ret = (&ctx_ret).lower_ty(&data.ret_type); 1046 let ret = (&ctx_ret).lower_ty(&data.ret_type);
1061 let generics = generics(db.upcast(), def.into()); 1047 let generics = generics(db.upcast(), def.into());
1062 let num_binders = generics.len(); 1048 let num_binders = generics.len();
1063 Binders::new(num_binders, CallableSig::from_params_and_return(params, ret, data.is_varargs)) 1049 Binders::new(num_binders, CallableSig::from_params_and_return(params, ret, data.is_varargs()))
1064} 1050}
1065 1051
1066/// Build the declared type of a function. This should not need to look at the 1052/// Build the declared type of a function. This should not need to look at the
1067/// function body. 1053/// function body.
1068fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> { 1054fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> {
1069 let generics = generics(db.upcast(), def.into()); 1055 let generics = generics(db.upcast(), def.into());
1070 let substs = Substitution::bound_vars(&generics, DebruijnIndex::INNERMOST); 1056 let substs = generics.bound_vars_subst(DebruijnIndex::INNERMOST);
1071 Binders::new( 1057 Binders::new(
1072 substs.len(), 1058 substs.len(&Interner),
1073 TyKind::FnDef(CallableDefId::FunctionId(def).to_chalk(db), substs).intern(&Interner), 1059 TyKind::FnDef(CallableDefId::FunctionId(def).to_chalk(db), substs).intern(&Interner),
1074 ) 1060 )
1075} 1061}
@@ -1112,9 +1098,9 @@ fn type_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> Binders<T
1112 return type_for_adt(db, def.into()); 1098 return type_for_adt(db, def.into());
1113 } 1099 }
1114 let generics = generics(db.upcast(), def.into()); 1100 let generics = generics(db.upcast(), def.into());
1115 let substs = Substitution::bound_vars(&generics, DebruijnIndex::INNERMOST); 1101 let substs = generics.bound_vars_subst(DebruijnIndex::INNERMOST);
1116 Binders::new( 1102 Binders::new(
1117 substs.len(), 1103 substs.len(&Interner),
1118 TyKind::FnDef(CallableDefId::StructId(def).to_chalk(db), substs).intern(&Interner), 1104 TyKind::FnDef(CallableDefId::StructId(def).to_chalk(db), substs).intern(&Interner),
1119 ) 1105 )
1120} 1106}
@@ -1139,17 +1125,18 @@ fn type_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -
1139 return type_for_adt(db, def.parent.into()); 1125 return type_for_adt(db, def.parent.into());
1140 } 1126 }
1141 let generics = generics(db.upcast(), def.parent.into()); 1127 let generics = generics(db.upcast(), def.parent.into());
1142 let substs = Substitution::bound_vars(&generics, DebruijnIndex::INNERMOST); 1128 let substs = generics.bound_vars_subst(DebruijnIndex::INNERMOST);
1143 Binders::new( 1129 Binders::new(
1144 substs.len(), 1130 substs.len(&Interner),
1145 TyKind::FnDef(CallableDefId::EnumVariantId(def).to_chalk(db), substs).intern(&Interner), 1131 TyKind::FnDef(CallableDefId::EnumVariantId(def).to_chalk(db), substs).intern(&Interner),
1146 ) 1132 )
1147} 1133}
1148 1134
1149fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> { 1135fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> {
1150 let generics = generics(db.upcast(), adt.into()); 1136 let b = TyBuilder::adt(db, adt);
1151 let substs = Substitution::bound_vars(&generics, DebruijnIndex::INNERMOST); 1137 let num_binders = b.remaining();
1152 Binders::new(substs.len(), Ty::adt_ty(adt, substs)) 1138 let ty = b.fill_with_bound_vars(DebruijnIndex::INNERMOST, 0).build();
1139 Binders::new(num_binders, ty)
1153} 1140}
1154 1141
1155fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> { 1142fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> {
@@ -1161,7 +1148,7 @@ fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> {
1161 Binders::new(0, TyKind::ForeignType(crate::to_foreign_def_id(t)).intern(&Interner)) 1148 Binders::new(0, TyKind::ForeignType(crate::to_foreign_def_id(t)).intern(&Interner))
1162 } else { 1149 } else {
1163 let type_ref = &db.type_alias_data(t).type_ref; 1150 let type_ref = &db.type_alias_data(t).type_ref;
1164 let inner = ctx.lower_ty(type_ref.as_ref().unwrap_or(&TypeRef::Error)); 1151 let inner = ctx.lower_ty(type_ref.as_deref().unwrap_or(&TypeRef::Error));
1165 Binders::new(generics.len(), inner) 1152 Binders::new(generics.len(), inner)
1166 } 1153 }
1167} 1154}
@@ -1221,7 +1208,7 @@ impl_from!(FunctionId, StructId, UnionId, EnumVariantId, ConstId, StaticId for V
1221/// namespace. 1208/// namespace.
1222pub(crate) fn ty_query(db: &dyn HirDatabase, def: TyDefId) -> Binders<Ty> { 1209pub(crate) fn ty_query(db: &dyn HirDatabase, def: TyDefId) -> Binders<Ty> {
1223 match def { 1210 match def {
1224 TyDefId::BuiltinType(it) => Binders::new(0, Ty::builtin(it)), 1211 TyDefId::BuiltinType(it) => Binders::new(0, TyBuilder::builtin(it)),
1225 TyDefId::AdtId(it) => type_for_adt(db, it), 1212 TyDefId::AdtId(it) => type_for_adt(db, it),
1226 TyDefId::TypeAliasId(it) => type_for_type_alias(db, it), 1213 TyDefId::TypeAliasId(it) => type_for_type_alias(db, it),
1227 } 1214 }
@@ -1253,7 +1240,7 @@ pub(crate) fn impl_self_ty_query(db: &dyn HirDatabase, impl_id: ImplId) -> Binde
1253 let generics = generics(db.upcast(), impl_id.into()); 1240 let generics = generics(db.upcast(), impl_id.into());
1254 let ctx = 1241 let ctx =
1255 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); 1242 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
1256 Binders::new(generics.len(), ctx.lower_ty(&impl_data.target_type)) 1243 Binders::new(generics.len(), ctx.lower_ty(&impl_data.self_ty))
1257} 1244}
1258 1245
1259pub(crate) fn const_param_ty_query(db: &dyn HirDatabase, def: ConstParamId) -> Ty { 1246pub(crate) fn const_param_ty_query(db: &dyn HirDatabase, def: ConstParamId) -> Ty {