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.rs88
1 files changed, 48 insertions, 40 deletions
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs
index 99b0ecf3b..1b5843d48 100644
--- a/crates/hir_ty/src/lower.rs
+++ b/crates/hir_ty/src/lower.rs
@@ -8,6 +8,7 @@
8use std::{iter, sync::Arc}; 8use std::{iter, sync::Arc};
9 9
10use base_db::CrateId; 10use base_db::CrateId;
11use chalk_ir::Mutability;
11use hir_def::{ 12use hir_def::{
12 adt::StructKind, 13 adt::StructKind,
13 builtin_type::BuiltinType, 14 builtin_type::BuiltinType,
@@ -31,9 +32,9 @@ use crate::{
31 all_super_trait_refs, associated_type_by_name_including_super_traits, generics, 32 all_super_trait_refs, associated_type_by_name_including_super_traits, generics,
32 make_mut_slice, variant_data, 33 make_mut_slice, variant_data,
33 }, 34 },
34 Binders, BoundVar, DebruijnIndex, FnSig, GenericPredicate, OpaqueTy, OpaqueTyId, PolyFnSig, 35 AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, FnPointer, FnSig, GenericPredicate,
35 ProjectionPredicate, ProjectionTy, ReturnTypeImplTrait, ReturnTypeImplTraits, Substs, 36 OpaqueTy, OpaqueTyId, PolyFnSig, ProjectionPredicate, ProjectionTy, ReturnTypeImplTrait,
36 TraitEnvironment, TraitRef, Ty, TypeCtor, TypeWalk, 37 ReturnTypeImplTraits, Substs, TraitEnvironment, TraitRef, Ty, TypeWalk,
37}; 38};
38 39
39#[derive(Debug)] 40#[derive(Debug)]
@@ -145,13 +146,10 @@ impl Ty {
145 pub fn from_hir_ext(ctx: &TyLoweringContext<'_>, type_ref: &TypeRef) -> (Self, Option<TypeNs>) { 146 pub fn from_hir_ext(ctx: &TyLoweringContext<'_>, type_ref: &TypeRef) -> (Self, Option<TypeNs>) {
146 let mut res = None; 147 let mut res = None;
147 let ty = match type_ref { 148 let ty = match type_ref {
148 TypeRef::Never => Ty::simple(TypeCtor::Never), 149 TypeRef::Never => Ty::Never,
149 TypeRef::Tuple(inner) => { 150 TypeRef::Tuple(inner) => {
150 let inner_tys: Arc<[Ty]> = inner.iter().map(|tr| Ty::from_hir(ctx, tr)).collect(); 151 let inner_tys: Arc<[Ty]> = inner.iter().map(|tr| Ty::from_hir(ctx, tr)).collect();
151 Ty::apply( 152 Ty::Tuple(inner_tys.len(), Substs(inner_tys))
152 TypeCtor::Tuple { cardinality: inner_tys.len() as u16 },
153 Substs(inner_tys),
154 )
155 } 153 }
156 TypeRef::Path(path) => { 154 TypeRef::Path(path) => {
157 let (ty, res_) = Ty::from_hir_path(ctx, path); 155 let (ty, res_) = Ty::from_hir_path(ctx, path);
@@ -160,30 +158,31 @@ impl Ty {
160 } 158 }
161 TypeRef::RawPtr(inner, mutability) => { 159 TypeRef::RawPtr(inner, mutability) => {
162 let inner_ty = Ty::from_hir(ctx, inner); 160 let inner_ty = Ty::from_hir(ctx, inner);
163 Ty::apply_one(TypeCtor::RawPtr(*mutability), inner_ty) 161 Ty::Raw(lower_to_chalk_mutability(*mutability), Substs::single(inner_ty))
164 } 162 }
165 TypeRef::Array(inner) => { 163 TypeRef::Array(inner) => {
166 let inner_ty = Ty::from_hir(ctx, inner); 164 let inner_ty = Ty::from_hir(ctx, inner);
167 Ty::apply_one(TypeCtor::Array, inner_ty) 165 Ty::Array(Substs::single(inner_ty))
168 } 166 }
169 TypeRef::Slice(inner) => { 167 TypeRef::Slice(inner) => {
170 let inner_ty = Ty::from_hir(ctx, inner); 168 let inner_ty = Ty::from_hir(ctx, inner);
171 Ty::apply_one(TypeCtor::Slice, inner_ty) 169 Ty::Slice(Substs::single(inner_ty))
172 } 170 }
173 TypeRef::Reference(inner, _, mutability) => { 171 TypeRef::Reference(inner, _, mutability) => {
174 let inner_ty = Ty::from_hir(ctx, inner); 172 let inner_ty = Ty::from_hir(ctx, inner);
175 Ty::apply_one(TypeCtor::Ref(*mutability), inner_ty) 173 Ty::Ref(lower_to_chalk_mutability(*mutability), Substs::single(inner_ty))
176 } 174 }
177 TypeRef::Placeholder => Ty::Unknown, 175 TypeRef::Placeholder => Ty::Unknown,
178 TypeRef::Fn(params, is_varargs) => { 176 TypeRef::Fn(params, is_varargs) => {
179 let sig = Substs(params.iter().map(|tr| Ty::from_hir(ctx, tr)).collect()); 177 let substs = Substs(params.iter().map(|tr| Ty::from_hir(ctx, tr)).collect());
180 Ty::apply( 178 Ty::Function(FnPointer {
181 TypeCtor::FnPtr { num_args: sig.len() as u16 - 1, is_varargs: *is_varargs }, 179 num_args: substs.len() - 1,
182 sig, 180 sig: FnSig { variadic: *is_varargs },
183 ) 181 substs,
182 })
184 } 183 }
185 TypeRef::DynTrait(bounds) => { 184 TypeRef::DynTrait(bounds) => {
186 let self_ty = Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0)); 185 let self_ty = Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0));
187 let predicates = ctx.with_shifted_in(DebruijnIndex::ONE, |ctx| { 186 let predicates = ctx.with_shifted_in(DebruijnIndex::ONE, |ctx| {
188 bounds 187 bounds
189 .iter() 188 .iter()
@@ -227,7 +226,10 @@ impl Ty {
227 let impl_trait_id = OpaqueTyId::ReturnTypeImplTrait(func, idx); 226 let impl_trait_id = OpaqueTyId::ReturnTypeImplTrait(func, idx);
228 let generics = generics(ctx.db.upcast(), func.into()); 227 let generics = generics(ctx.db.upcast(), func.into());
229 let parameters = Substs::bound_vars(&generics, ctx.in_binders); 228 let parameters = Substs::bound_vars(&generics, ctx.in_binders);
230 Ty::Opaque(OpaqueTy { opaque_ty_id: impl_trait_id, parameters }) 229 Ty::Alias(AliasTy::Opaque(OpaqueTy {
230 opaque_ty_id: impl_trait_id,
231 parameters,
232 }))
231 } 233 }
232 ImplTraitLoweringMode::Param => { 234 ImplTraitLoweringMode::Param => {
233 let idx = ctx.impl_trait_counter.get(); 235 let idx = ctx.impl_trait_counter.get();
@@ -258,7 +260,7 @@ impl Ty {
258 } else { 260 } else {
259 (0, 0, 0, 0) 261 (0, 0, 0, 0)
260 }; 262 };
261 Ty::Bound(BoundVar::new( 263 Ty::BoundVar(BoundVar::new(
262 ctx.in_binders, 264 ctx.in_binders,
263 idx as usize + parent_params + self_params + list_params, 265 idx as usize + parent_params + self_params + list_params,
264 )) 266 ))
@@ -330,7 +332,7 @@ impl Ty {
330 TypeNs::TraitId(trait_) => { 332 TypeNs::TraitId(trait_) => {
331 // if this is a bare dyn Trait, we'll directly put the required ^0 for the self type in there 333 // if this is a bare dyn Trait, we'll directly put the required ^0 for the self type in there
332 let self_ty = if remaining_segments.len() == 0 { 334 let self_ty = if remaining_segments.len() == 0 {
333 Some(Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0))) 335 Some(Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)))
334 } else { 336 } else {
335 None 337 None
336 }; 338 };
@@ -346,10 +348,10 @@ impl Ty {
346 match found { 348 match found {
347 Some((super_trait_ref, associated_ty)) => { 349 Some((super_trait_ref, associated_ty)) => {
348 // FIXME handle type parameters on the segment 350 // FIXME handle type parameters on the segment
349 Ty::Projection(ProjectionTy { 351 Ty::Alias(AliasTy::Projection(ProjectionTy {
350 associated_ty, 352 associated_ty,
351 parameters: super_trait_ref.substs, 353 parameters: super_trait_ref.substs,
352 }) 354 }))
353 } 355 }
354 None => { 356 None => {
355 // FIXME: report error (associated type not found) 357 // FIXME: report error (associated type not found)
@@ -373,7 +375,7 @@ impl Ty {
373 TypeParamLoweringMode::Placeholder => Ty::Placeholder(param_id), 375 TypeParamLoweringMode::Placeholder => Ty::Placeholder(param_id),
374 TypeParamLoweringMode::Variable => { 376 TypeParamLoweringMode::Variable => {
375 let idx = generics.param_idx(param_id).expect("matching generics"); 377 let idx = generics.param_idx(param_id).expect("matching generics");
376 Ty::Bound(BoundVar::new(ctx.in_binders, idx)) 378 Ty::BoundVar(BoundVar::new(ctx.in_binders, idx))
377 } 379 }
378 } 380 }
379 } 381 }
@@ -414,7 +416,6 @@ impl Ty {
414 // FIXME: report error 416 // FIXME: report error
415 TypeNs::EnumVariantId(_) => return (Ty::Unknown, None), 417 TypeNs::EnumVariantId(_) => return (Ty::Unknown, None),
416 }; 418 };
417
418 Ty::from_type_relative_path(ctx, ty, Some(resolution), remaining_segments) 419 Ty::from_type_relative_path(ctx, ty, Some(resolution), remaining_segments)
419 } 420 }
420 421
@@ -472,10 +473,10 @@ impl Ty {
472 // associated_type_shorthand_candidates does not do that 473 // associated_type_shorthand_candidates does not do that
473 let substs = substs.shift_bound_vars(ctx.in_binders); 474 let substs = substs.shift_bound_vars(ctx.in_binders);
474 // FIXME handle type parameters on the segment 475 // FIXME handle type parameters on the segment
475 return Some(Ty::Projection(ProjectionTy { 476 return Some(Ty::Alias(AliasTy::Projection(ProjectionTy {
476 associated_ty, 477 associated_ty,
477 parameters: substs, 478 parameters: substs,
478 })); 479 })));
479 } 480 }
480 481
481 None 482 None
@@ -676,7 +677,7 @@ impl GenericPredicate {
676 TypeParamLoweringMode::Placeholder => Ty::Placeholder(param_id), 677 TypeParamLoweringMode::Placeholder => Ty::Placeholder(param_id),
677 TypeParamLoweringMode::Variable => { 678 TypeParamLoweringMode::Variable => {
678 let idx = generics.param_idx(param_id).expect("matching generics"); 679 let idx = generics.param_idx(param_id).expect("matching generics");
679 Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, idx)) 680 Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, idx))
680 } 681 }
681 } 682 }
682 } 683 }
@@ -750,7 +751,7 @@ fn assoc_type_bindings_from_type_bound<'a>(
750 preds.extend(GenericPredicate::from_type_bound( 751 preds.extend(GenericPredicate::from_type_bound(
751 ctx, 752 ctx,
752 bound, 753 bound,
753 Ty::Projection(projection_ty.clone()), 754 Ty::Alias(AliasTy::Projection(projection_ty.clone())),
754 )); 755 ));
755 } 756 }
756 preds 757 preds
@@ -760,7 +761,7 @@ fn assoc_type_bindings_from_type_bound<'a>(
760impl ReturnTypeImplTrait { 761impl ReturnTypeImplTrait {
761 fn from_hir(ctx: &TyLoweringContext, bounds: &[TypeBound]) -> Self { 762 fn from_hir(ctx: &TyLoweringContext, bounds: &[TypeBound]) -> Self {
762 mark::hit!(lower_rpit); 763 mark::hit!(lower_rpit);
763 let self_ty = Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0)); 764 let self_ty = Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0));
764 let predicates = ctx.with_shifted_in(DebruijnIndex::ONE, |ctx| { 765 let predicates = ctx.with_shifted_in(DebruijnIndex::ONE, |ctx| {
765 bounds 766 bounds
766 .iter() 767 .iter()
@@ -984,7 +985,7 @@ pub(crate) fn generic_defaults_query(
984 // Each default can only refer to previous parameters. 985 // Each default can only refer to previous parameters.
985 ty.walk_mut_binders( 986 ty.walk_mut_binders(
986 &mut |ty, binders| match ty { 987 &mut |ty, binders| match ty {
987 Ty::Bound(BoundVar { debruijn, index }) if *debruijn == binders => { 988 Ty::BoundVar(BoundVar { debruijn, index }) if *debruijn == binders => {
988 if *index >= idx { 989 if *index >= idx {
989 // type variable default referring to parameter coming 990 // type variable default referring to parameter coming
990 // after it. This is forbidden (FIXME: report 991 // after it. This is forbidden (FIXME: report
@@ -1017,7 +1018,7 @@ fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig {
1017 let ret = Ty::from_hir(&ctx_ret, &data.ret_type); 1018 let ret = Ty::from_hir(&ctx_ret, &data.ret_type);
1018 let generics = generics(db.upcast(), def.into()); 1019 let generics = generics(db.upcast(), def.into());
1019 let num_binders = generics.len(); 1020 let num_binders = generics.len();
1020 Binders::new(num_binders, FnSig::from_params_and_return(params, ret, data.is_varargs)) 1021 Binders::new(num_binders, CallableSig::from_params_and_return(params, ret, data.is_varargs))
1021} 1022}
1022 1023
1023/// Build the declared type of a function. This should not need to look at the 1024/// Build the declared type of a function. This should not need to look at the
@@ -1025,7 +1026,7 @@ fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig {
1025fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> { 1026fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> {
1026 let generics = generics(db.upcast(), def.into()); 1027 let generics = generics(db.upcast(), def.into());
1027 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); 1028 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST);
1028 Binders::new(substs.len(), Ty::apply(TypeCtor::FnDef(def.into()), substs)) 1029 Binders::new(substs.len(), Ty::FnDef(def.into(), substs))
1029} 1030}
1030 1031
1031/// Build the declared type of a const. 1032/// Build the declared type of a const.
@@ -1057,7 +1058,7 @@ fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnS
1057 let params = 1058 let params =
1058 fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>(); 1059 fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>();
1059 let ret = type_for_adt(db, def.into()); 1060 let ret = type_for_adt(db, def.into());
1060 Binders::new(ret.num_binders, FnSig::from_params_and_return(params, ret.value, false)) 1061 Binders::new(ret.num_binders, CallableSig::from_params_and_return(params, ret.value, false))
1061} 1062}
1062 1063
1063/// Build the type of a tuple struct constructor. 1064/// Build the type of a tuple struct constructor.
@@ -1068,7 +1069,7 @@ fn type_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> Binders<T
1068 } 1069 }
1069 let generics = generics(db.upcast(), def.into()); 1070 let generics = generics(db.upcast(), def.into());
1070 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); 1071 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST);
1071 Binders::new(substs.len(), Ty::apply(TypeCtor::FnDef(def.into()), substs)) 1072 Binders::new(substs.len(), Ty::FnDef(def.into(), substs))
1072} 1073}
1073 1074
1074fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> PolyFnSig { 1075fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> PolyFnSig {
@@ -1081,7 +1082,7 @@ fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId)
1081 let params = 1082 let params =
1082 fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>(); 1083 fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>();
1083 let ret = type_for_adt(db, def.parent.into()); 1084 let ret = type_for_adt(db, def.parent.into());
1084 Binders::new(ret.num_binders, FnSig::from_params_and_return(params, ret.value, false)) 1085 Binders::new(ret.num_binders, CallableSig::from_params_and_return(params, ret.value, false))
1085} 1086}
1086 1087
1087/// Build the type of a tuple enum variant constructor. 1088/// Build the type of a tuple enum variant constructor.
@@ -1093,13 +1094,13 @@ fn type_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -
1093 } 1094 }
1094 let generics = generics(db.upcast(), def.parent.into()); 1095 let generics = generics(db.upcast(), def.parent.into());
1095 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); 1096 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST);
1096 Binders::new(substs.len(), Ty::apply(TypeCtor::FnDef(def.into()), substs)) 1097 Binders::new(substs.len(), Ty::FnDef(def.into(), substs))
1097} 1098}
1098 1099
1099fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> { 1100fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> {
1100 let generics = generics(db.upcast(), adt.into()); 1101 let generics = generics(db.upcast(), adt.into());
1101 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); 1102 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST);
1102 Binders::new(substs.len(), Ty::apply(TypeCtor::Adt(adt), substs)) 1103 Binders::new(substs.len(), Ty::Adt(adt, substs))
1103} 1104}
1104 1105
1105fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> { 1106fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> {
@@ -1107,10 +1108,10 @@ fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> {
1107 let resolver = t.resolver(db.upcast()); 1108 let resolver = t.resolver(db.upcast());
1108 let ctx = 1109 let ctx =
1109 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); 1110 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
1110 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST);
1111 if db.type_alias_data(t).is_extern { 1111 if db.type_alias_data(t).is_extern {
1112 Binders::new(substs.len(), Ty::apply(TypeCtor::ForeignType(t), substs)) 1112 Binders::new(0, Ty::ForeignType(t))
1113 } else { 1113 } else {
1114 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST);
1114 let type_ref = &db.type_alias_data(t).type_ref; 1115 let type_ref = &db.type_alias_data(t).type_ref;
1115 let inner = Ty::from_hir(&ctx, type_ref.as_ref().unwrap_or(&TypeRef::Error)); 1116 let inner = Ty::from_hir(&ctx, type_ref.as_ref().unwrap_or(&TypeRef::Error));
1116 Binders::new(substs.len(), inner) 1117 Binders::new(substs.len(), inner)
@@ -1259,3 +1260,10 @@ pub(crate) fn return_type_impl_traits(
1259 Some(Arc::new(Binders::new(num_binders, return_type_impl_traits))) 1260 Some(Arc::new(Binders::new(num_binders, return_type_impl_traits)))
1260 } 1261 }
1261} 1262}
1263
1264pub(crate) fn lower_to_chalk_mutability(m: hir_def::type_ref::Mutability) -> Mutability {
1265 match m {
1266 hir_def::type_ref::Mutability::Shared => Mutability::Not,
1267 hir_def::type_ref::Mutability::Mut => Mutability::Mut,
1268 }
1269}