aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/lib.rs')
-rw-r--r--crates/hir_ty/src/lib.rs173
1 files changed, 125 insertions, 48 deletions
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs
index 6f9c698e6..c927ed973 100644
--- a/crates/hir_ty/src/lib.rs
+++ b/crates/hir_ty/src/lib.rs
@@ -24,9 +24,10 @@ mod tests;
24#[cfg(test)] 24#[cfg(test)]
25mod test_db; 25mod test_db;
26 26
27use std::{iter, mem, ops::Deref, sync::Arc}; 27use std::{iter, mem, sync::Arc};
28 28
29use base_db::salsa; 29use base_db::salsa;
30use chalk_ir::cast::{CastTo, Caster};
30use hir_def::{ 31use hir_def::{
31 builtin_type::BuiltinType, expr::ExprId, type_ref::Rawness, AssocContainerId, FunctionId, 32 builtin_type::BuiltinType, expr::ExprId, type_ref::Rawness, AssocContainerId, FunctionId,
32 GenericDefId, HasModule, LifetimeParamId, Lookup, TraitId, TypeAliasId, TypeParamId, 33 GenericDefId, HasModule, LifetimeParamId, Lookup, TraitId, TypeAliasId, TypeParamId,
@@ -109,7 +110,7 @@ impl ProjectionTy {
109 } 110 }
110 111
111 pub fn self_type_parameter(&self) -> &Ty { 112 pub fn self_type_parameter(&self) -> &Ty {
112 &self.substitution[0] 113 &self.substitution.interned(&Interner)[0].assert_ty_ref(&Interner)
113 } 114 }
114 115
115 fn trait_(&self, db: &dyn HirDatabase) -> TraitId { 116 fn trait_(&self, db: &dyn HirDatabase) -> TraitId {
@@ -324,9 +325,72 @@ impl Ty {
324 } 325 }
325} 326}
326 327
328#[derive(Clone, PartialEq, Eq, Debug, Hash)]
329pub struct GenericArg {
330 interned: GenericArgData,
331}
332
333#[derive(Clone, PartialEq, Eq, Debug, Hash)]
334pub enum GenericArgData {
335 Ty(Ty),
336}
337
338impl GenericArg {
339 /// Constructs a generic argument using `GenericArgData`.
340 pub fn new(_interner: &Interner, data: GenericArgData) -> Self {
341 GenericArg { interned: data }
342 }
343
344 /// Gets the interned value.
345 pub fn interned(&self) -> &GenericArgData {
346 &self.interned
347 }
348
349 /// Asserts that this is a type argument.
350 pub fn assert_ty_ref(&self, interner: &Interner) -> &Ty {
351 self.ty(interner).unwrap()
352 }
353
354 /// Checks whether the generic argument is a type.
355 pub fn is_ty(&self, _interner: &Interner) -> bool {
356 match self.interned() {
357 GenericArgData::Ty(_) => true,
358 }
359 }
360
361 /// Returns the type if it is one, `None` otherwise.
362 pub fn ty(&self, _interner: &Interner) -> Option<&Ty> {
363 match self.interned() {
364 GenericArgData::Ty(t) => Some(t),
365 }
366 }
367}
368
369impl TypeWalk for GenericArg {
370 fn walk(&self, f: &mut impl FnMut(&Ty)) {
371 match &self.interned {
372 GenericArgData::Ty(ty) => {
373 ty.walk(f);
374 }
375 }
376 }
377
378 fn walk_mut_binders(
379 &mut self,
380 f: &mut impl FnMut(&mut Ty, DebruijnIndex),
381 binders: DebruijnIndex,
382 ) {
383 match &mut self.interned {
384 GenericArgData::Ty(ty) => {
385 ty.walk_mut_binders(f, binders);
386 }
387 }
388 }
389}
390
327/// A list of substitutions for generic parameters. 391/// A list of substitutions for generic parameters.
328#[derive(Clone, PartialEq, Eq, Debug, Hash)] 392#[derive(Clone, PartialEq, Eq, Debug, Hash)]
329pub struct Substitution(SmallVec<[Ty; 2]>); 393pub struct Substitution(SmallVec<[GenericArg; 2]>);
330 394
331impl TypeWalk for Substitution { 395impl TypeWalk for Substitution {
332 fn walk(&self, f: &mut impl FnMut(&Ty)) { 396 fn walk(&self, f: &mut impl FnMut(&Ty)) {
@@ -347,18 +411,34 @@ impl TypeWalk for Substitution {
347} 411}
348 412
349impl Substitution { 413impl Substitution {
350 pub fn interned(&self, _: &Interner) -> &[Ty] { 414 pub fn interned(&self, _: &Interner) -> &[GenericArg] {
351 &self.0 415 &self.0
352 } 416 }
353 417
354 pub fn empty() -> Substitution { 418 pub fn len(&self, _: &Interner) -> usize {
419 self.0.len()
420 }
421
422 pub fn is_empty(&self, _: &Interner) -> bool {
423 self.0.is_empty()
424 }
425
426 pub fn at(&self, _: &Interner, i: usize) -> &GenericArg {
427 &self.0[i]
428 }
429
430 pub fn empty(_: &Interner) -> Substitution {
355 Substitution(SmallVec::new()) 431 Substitution(SmallVec::new())
356 } 432 }
357 433
434 pub fn iter(&self, _: &Interner) -> std::slice::Iter<'_, GenericArg> {
435 self.0.iter()
436 }
437
358 pub fn single(ty: Ty) -> Substitution { 438 pub fn single(ty: Ty) -> Substitution {
359 Substitution({ 439 Substitution({
360 let mut v = SmallVec::new(); 440 let mut v = SmallVec::new();
361 v.push(ty); 441 v.push(ty.cast(&Interner));
362 v 442 v
363 }) 443 })
364 } 444 }
@@ -371,15 +451,11 @@ impl Substitution {
371 Substitution(self.0[self.0.len() - std::cmp::min(self.0.len(), n)..].into()) 451 Substitution(self.0[self.0.len() - std::cmp::min(self.0.len(), n)..].into())
372 } 452 }
373 453
374 pub fn as_single(&self) -> &Ty { 454 pub fn from_iter(
375 if self.0.len() != 1 { 455 interner: &Interner,
376 panic!("expected substs of len 1, got {:?}", self); 456 elements: impl IntoIterator<Item = impl CastTo<GenericArg>>,
377 } 457 ) -> Self {
378 &self.0[0] 458 Substitution(elements.into_iter().casted(interner).collect())
379 }
380
381 pub fn from_iter(_interner: &Interner, elements: impl IntoIterator<Item = Ty>) -> Self {
382 Substitution(elements.into_iter().collect())
383 } 459 }
384 460
385 /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`). 461 /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`).
@@ -387,11 +463,11 @@ impl Substitution {
387 db: &dyn HirDatabase, 463 db: &dyn HirDatabase,
388 generic_params: &Generics, 464 generic_params: &Generics,
389 ) -> Substitution { 465 ) -> Substitution {
390 Substitution( 466 Substitution::from_iter(
467 &Interner,
391 generic_params 468 generic_params
392 .iter() 469 .iter()
393 .map(|(id, _)| TyKind::Placeholder(to_placeholder_idx(db, id)).intern(&Interner)) 470 .map(|(id, _)| TyKind::Placeholder(to_placeholder_idx(db, id)).intern(&Interner)),
394 .collect(),
395 ) 471 )
396 } 472 }
397 473
@@ -403,12 +479,12 @@ impl Substitution {
403 479
404 /// Return Substs that replace each parameter by a bound variable. 480 /// Return Substs that replace each parameter by a bound variable.
405 pub(crate) fn bound_vars(generic_params: &Generics, debruijn: DebruijnIndex) -> Substitution { 481 pub(crate) fn bound_vars(generic_params: &Generics, debruijn: DebruijnIndex) -> Substitution {
406 Substitution( 482 Substitution::from_iter(
483 &Interner,
407 generic_params 484 generic_params
408 .iter() 485 .iter()
409 .enumerate() 486 .enumerate()
410 .map(|(idx, _)| TyKind::BoundVar(BoundVar::new(debruijn, idx)).intern(&Interner)) 487 .map(|(idx, _)| TyKind::BoundVar(BoundVar::new(debruijn, idx)).intern(&Interner)),
411 .collect(),
412 ) 488 )
413 } 489 }
414 490
@@ -435,18 +511,18 @@ pub fn param_idx(db: &dyn HirDatabase, id: TypeParamId) -> Option<usize> {
435 511
436#[derive(Debug, Clone)] 512#[derive(Debug, Clone)]
437pub struct SubstsBuilder { 513pub struct SubstsBuilder {
438 vec: Vec<Ty>, 514 vec: Vec<GenericArg>,
439 param_count: usize, 515 param_count: usize,
440} 516}
441 517
442impl SubstsBuilder { 518impl SubstsBuilder {
443 pub fn build(self) -> Substitution { 519 pub fn build(self) -> Substitution {
444 assert_eq!(self.vec.len(), self.param_count); 520 assert_eq!(self.vec.len(), self.param_count);
445 Substitution(self.vec.into()) 521 Substitution::from_iter(&Interner, self.vec)
446 } 522 }
447 523
448 pub fn push(mut self, ty: Ty) -> Self { 524 pub fn push(mut self, ty: impl CastTo<GenericArg>) -> Self {
449 self.vec.push(ty); 525 self.vec.push(ty.cast(&Interner));
450 self 526 self
451 } 527 }
452 528
@@ -465,28 +541,20 @@ impl SubstsBuilder {
465 self.fill(iter::repeat(TyKind::Unknown.intern(&Interner))) 541 self.fill(iter::repeat(TyKind::Unknown.intern(&Interner)))
466 } 542 }
467 543
468 pub fn fill(mut self, filler: impl Iterator<Item = Ty>) -> Self { 544 pub fn fill(mut self, filler: impl Iterator<Item = impl CastTo<GenericArg>>) -> Self {
469 self.vec.extend(filler.take(self.remaining())); 545 self.vec.extend(filler.take(self.remaining()).casted(&Interner));
470 assert_eq!(self.remaining(), 0); 546 assert_eq!(self.remaining(), 0);
471 self 547 self
472 } 548 }
473 549
474 pub fn use_parent_substs(mut self, parent_substs: &Substitution) -> Self { 550 pub fn use_parent_substs(mut self, parent_substs: &Substitution) -> Self {
475 assert!(self.vec.is_empty()); 551 assert!(self.vec.is_empty());
476 assert!(parent_substs.len() <= self.param_count); 552 assert!(parent_substs.len(&Interner) <= self.param_count);
477 self.vec.extend(parent_substs.iter().cloned()); 553 self.vec.extend(parent_substs.iter(&Interner).cloned());
478 self 554 self
479 } 555 }
480} 556}
481 557
482impl Deref for Substitution {
483 type Target = [Ty];
484
485 fn deref(&self) -> &[Ty] {
486 &self.0
487 }
488}
489
490#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] 558#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
491pub struct Binders<T> { 559pub struct Binders<T> {
492 pub num_binders: usize, 560 pub num_binders: usize,
@@ -535,7 +603,7 @@ impl<T: Clone> Binders<&T> {
535impl<T: TypeWalk> Binders<T> { 603impl<T: TypeWalk> Binders<T> {
536 /// Substitutes all variables. 604 /// Substitutes all variables.
537 pub fn subst(self, subst: &Substitution) -> T { 605 pub fn subst(self, subst: &Substitution) -> T {
538 assert_eq!(subst.len(), self.num_binders); 606 assert_eq!(subst.len(&Interner), self.num_binders);
539 self.value.subst_bound_vars(subst) 607 self.value.subst_bound_vars(subst)
540 } 608 }
541} 609}
@@ -563,7 +631,7 @@ pub struct TraitRef {
563 631
564impl TraitRef { 632impl TraitRef {
565 pub fn self_type_parameter(&self) -> &Ty { 633 pub fn self_type_parameter(&self) -> &Ty {
566 &self.substitution[0] 634 &self.substitution.at(&Interner, 0).assert_ty_ref(&Interner)
567 } 635 }
568 636
569 pub fn hir_trait_id(&self) -> TraitId { 637 pub fn hir_trait_id(&self) -> TraitId {
@@ -699,14 +767,20 @@ impl CallableSig {
699 .shift_bound_vars_out(DebruijnIndex::ONE) 767 .shift_bound_vars_out(DebruijnIndex::ONE)
700 .interned(&Interner) 768 .interned(&Interner)
701 .iter() 769 .iter()
702 .cloned() 770 .map(|arg| arg.assert_ty_ref(&Interner).clone())
703 .collect(), 771 .collect(),
704 is_varargs: fn_ptr.sig.variadic, 772 is_varargs: fn_ptr.sig.variadic,
705 } 773 }
706 } 774 }
707 775
708 pub fn from_substs(substs: &Substitution) -> CallableSig { 776 pub fn from_substs(substs: &Substitution) -> CallableSig {
709 CallableSig { params_and_return: substs.iter().cloned().collect(), is_varargs: false } 777 CallableSig {
778 params_and_return: substs
779 .iter(&Interner)
780 .map(|arg| arg.assert_ty_ref(&Interner).clone())
781 .collect(),
782 is_varargs: false,
783 }
710 } 784 }
711 785
712 pub fn params(&self) -> &[Ty] { 786 pub fn params(&self) -> &[Ty] {
@@ -738,7 +812,7 @@ impl TypeWalk for CallableSig {
738 812
739impl Ty { 813impl Ty {
740 pub fn unit() -> Self { 814 pub fn unit() -> Self {
741 TyKind::Tuple(0, Substitution::empty()).intern(&Interner) 815 TyKind::Tuple(0, Substitution::empty(&Interner)).intern(&Interner)
742 } 816 }
743 817
744 pub fn adt_ty(adt: hir_def::AdtId, substs: Substitution) -> Ty { 818 pub fn adt_ty(adt: hir_def::AdtId, substs: Substitution) -> Ty {
@@ -908,7 +982,7 @@ impl Ty {
908 Some(sig.subst(&parameters)) 982 Some(sig.subst(&parameters))
909 } 983 }
910 TyKind::Closure(.., substs) => { 984 TyKind::Closure(.., substs) => {
911 let sig_param = &substs[0]; 985 let sig_param = substs.at(&Interner, 0).assert_ty_ref(&Interner);
912 sig_param.callable_sig(db) 986 sig_param.callable_sig(db)
913 } 987 }
914 _ => None, 988 _ => None,
@@ -960,7 +1034,7 @@ impl Ty {
960 0, 1034 0,
961 WhereClause::Implemented(TraitRef { 1035 WhereClause::Implemented(TraitRef {
962 trait_id: to_chalk_trait_id(future_trait), 1036 trait_id: to_chalk_trait_id(future_trait),
963 substitution: Substitution::empty(), 1037 substitution: Substitution::empty(&Interner),
964 }), 1038 }),
965 ); 1039 );
966 Some(vec![impl_bound]) 1040 Some(vec![impl_bound])
@@ -1109,7 +1183,10 @@ pub trait TypeWalk {
1109 &mut |ty, binders| { 1183 &mut |ty, binders| {
1110 if let &mut TyKind::BoundVar(bound) = ty.interned_mut() { 1184 if let &mut TyKind::BoundVar(bound) = ty.interned_mut() {
1111 if bound.debruijn >= binders { 1185 if bound.debruijn >= binders {
1112 *ty = substs.0[bound.index].clone().shift_bound_vars(binders); 1186 *ty = substs.0[bound.index]
1187 .assert_ty_ref(&Interner)
1188 .clone()
1189 .shift_bound_vars(binders);
1113 } 1190 }
1114 } 1191 }
1115 }, 1192 },
@@ -1156,12 +1233,12 @@ impl TypeWalk for Ty {
1156 fn walk(&self, f: &mut impl FnMut(&Ty)) { 1233 fn walk(&self, f: &mut impl FnMut(&Ty)) {
1157 match self.interned(&Interner) { 1234 match self.interned(&Interner) {
1158 TyKind::Alias(AliasTy::Projection(p_ty)) => { 1235 TyKind::Alias(AliasTy::Projection(p_ty)) => {
1159 for t in p_ty.substitution.iter() { 1236 for t in p_ty.substitution.iter(&Interner) {
1160 t.walk(f); 1237 t.walk(f);
1161 } 1238 }
1162 } 1239 }
1163 TyKind::Alias(AliasTy::Opaque(o_ty)) => { 1240 TyKind::Alias(AliasTy::Opaque(o_ty)) => {
1164 for t in o_ty.substitution.iter() { 1241 for t in o_ty.substitution.iter(&Interner) {
1165 t.walk(f); 1242 t.walk(f);
1166 } 1243 }
1167 } 1244 }
@@ -1175,7 +1252,7 @@ impl TypeWalk for Ty {
1175 } 1252 }
1176 _ => { 1253 _ => {
1177 if let Some(substs) = self.substs() { 1254 if let Some(substs) = self.substs() {
1178 for t in substs.iter() { 1255 for t in substs.iter(&Interner) {
1179 t.walk(f); 1256 t.walk(f);
1180 } 1257 }
1181 } 1258 }