diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-04-04 12:30:07 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2021-04-04 12:30:07 +0100 |
commit | 082996032054031bd1b68ee45ab04293f4877e91 (patch) | |
tree | ccf4586bbb70ef9ebf429a2c79a5f409549ebf73 /crates/hir_ty/src/lib.rs | |
parent | c9bcbf9a43eb0bf1a5255f704080305e568f0a36 (diff) | |
parent | cde3857897955558ed0e60cf8158e18d5c75d188 (diff) |
Merge #8327
8327: Move `Ty` creation methods out of `Ty` (Chalk move preparation) r=flodiebold a=flodiebold
When we'll move to using `chalk_ir::Ty` (#8313), we won't be able to have our own inherent methods on `Ty` anymore, so we need to move the helpers elsewhere.
This adds a `TyBuilder` that allows easily constructing `Ty` and related types (`TraitRef`, `ProjectionTy`, `Substitution`). It also replaces `SubstsBuilder`. `TyBuilder` can construct different things based on its type parameter; e.g. if it has an `AdtId`, we're constructing an ADT type, but if it has a `TraitId`, we're constructing a `TraitRef`. The common thing for all of them is that we need to build a `Substitution`, so the API stays the same for all of them except at the beginning and end.
We also use `TyBuilder` to house various one-shot methods for constructing types, e.g. `TyBuilder::unit()`.
Co-authored-by: Florian Diebold <[email protected]>
Diffstat (limited to 'crates/hir_ty/src/lib.rs')
-rw-r--r-- | crates/hir_ty/src/lib.rs | 158 |
1 files changed, 14 insertions, 144 deletions
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index 4c3d904bf..a8c87eadf 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs | |||
@@ -14,6 +14,8 @@ mod lower; | |||
14 | pub(crate) mod infer; | 14 | pub(crate) mod infer; |
15 | pub(crate) mod utils; | 15 | pub(crate) mod utils; |
16 | mod chalk_cast; | 16 | mod chalk_cast; |
17 | mod chalk_ext; | ||
18 | mod builder; | ||
17 | 19 | ||
18 | pub mod display; | 20 | pub mod display; |
19 | pub mod db; | 21 | pub mod db; |
@@ -24,24 +26,27 @@ mod tests; | |||
24 | #[cfg(test)] | 26 | #[cfg(test)] |
25 | mod test_db; | 27 | mod test_db; |
26 | 28 | ||
27 | use std::{iter, mem, sync::Arc}; | 29 | use std::{mem, sync::Arc}; |
28 | 30 | ||
29 | use base_db::salsa; | ||
30 | use chalk_ir::cast::{CastTo, Caster}; | 31 | use chalk_ir::cast::{CastTo, Caster}; |
31 | use hir_def::{ | ||
32 | builtin_type::BuiltinType, expr::ExprId, type_ref::Rawness, AssocContainerId, FunctionId, | ||
33 | GenericDefId, HasModule, LifetimeParamId, Lookup, TraitId, TypeAliasId, TypeParamId, | ||
34 | }; | ||
35 | use itertools::Itertools; | 32 | use itertools::Itertools; |
36 | use smallvec::SmallVec; | 33 | use smallvec::SmallVec; |
37 | 34 | ||
35 | use base_db::salsa; | ||
36 | use hir_def::{ | ||
37 | expr::ExprId, type_ref::Rawness, AssocContainerId, FunctionId, GenericDefId, HasModule, | ||
38 | LifetimeParamId, Lookup, TraitId, TypeAliasId, TypeParamId, | ||
39 | }; | ||
40 | |||
38 | use crate::{ | 41 | use crate::{ |
39 | db::HirDatabase, | 42 | db::HirDatabase, |
40 | display::HirDisplay, | 43 | display::HirDisplay, |
41 | utils::{generics, make_mut_slice, Generics}, | 44 | utils::{generics, make_mut_slice}, |
42 | }; | 45 | }; |
43 | 46 | ||
44 | pub use autoderef::autoderef; | 47 | pub use autoderef::autoderef; |
48 | pub use builder::TyBuilder; | ||
49 | pub use chalk_ext::TyExt; | ||
45 | pub use infer::{could_unify, InferenceResult, InferenceVar}; | 50 | pub use infer::{could_unify, InferenceResult, InferenceVar}; |
46 | pub use lower::{ | 51 | pub use lower::{ |
47 | associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode, | 52 | associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode, |
@@ -457,51 +462,6 @@ impl Substitution { | |||
457 | ) -> Self { | 462 | ) -> Self { |
458 | Substitution(elements.into_iter().casted(interner).collect()) | 463 | Substitution(elements.into_iter().casted(interner).collect()) |
459 | } | 464 | } |
460 | |||
461 | /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`). | ||
462 | pub(crate) fn type_params_for_generics( | ||
463 | db: &dyn HirDatabase, | ||
464 | generic_params: &Generics, | ||
465 | ) -> Substitution { | ||
466 | Substitution::from_iter( | ||
467 | &Interner, | ||
468 | generic_params | ||
469 | .iter() | ||
470 | .map(|(id, _)| TyKind::Placeholder(to_placeholder_idx(db, id)).intern(&Interner)), | ||
471 | ) | ||
472 | } | ||
473 | |||
474 | /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`). | ||
475 | pub fn type_params(db: &dyn HirDatabase, def: impl Into<GenericDefId>) -> Substitution { | ||
476 | let params = generics(db.upcast(), def.into()); | ||
477 | Substitution::type_params_for_generics(db, ¶ms) | ||
478 | } | ||
479 | |||
480 | /// Return Substs that replace each parameter by a bound variable. | ||
481 | pub(crate) fn bound_vars(generic_params: &Generics, debruijn: DebruijnIndex) -> Substitution { | ||
482 | Substitution::from_iter( | ||
483 | &Interner, | ||
484 | generic_params | ||
485 | .iter() | ||
486 | .enumerate() | ||
487 | .map(|(idx, _)| TyKind::BoundVar(BoundVar::new(debruijn, idx)).intern(&Interner)), | ||
488 | ) | ||
489 | } | ||
490 | |||
491 | pub fn build_for_def(db: &dyn HirDatabase, def: impl Into<GenericDefId>) -> SubstsBuilder { | ||
492 | let def = def.into(); | ||
493 | let params = generics(db.upcast(), def); | ||
494 | let param_count = params.len(); | ||
495 | Substitution::builder(param_count) | ||
496 | } | ||
497 | |||
498 | pub(crate) fn build_for_generics(generic_params: &Generics) -> SubstsBuilder { | ||
499 | Substitution::builder(generic_params.len()) | ||
500 | } | ||
501 | |||
502 | fn builder(param_count: usize) -> SubstsBuilder { | ||
503 | SubstsBuilder { vec: Vec::with_capacity(param_count), param_count } | ||
504 | } | ||
505 | } | 465 | } |
506 | 466 | ||
507 | /// Return an index of a parameter in the generic type parameter list by it's id. | 467 | /// Return an index of a parameter in the generic type parameter list by it's id. |
@@ -509,52 +469,6 @@ pub fn param_idx(db: &dyn HirDatabase, id: TypeParamId) -> Option<usize> { | |||
509 | generics(db.upcast(), id.parent).param_idx(id) | 469 | generics(db.upcast(), id.parent).param_idx(id) |
510 | } | 470 | } |
511 | 471 | ||
512 | #[derive(Debug, Clone)] | ||
513 | pub struct SubstsBuilder { | ||
514 | vec: Vec<GenericArg>, | ||
515 | param_count: usize, | ||
516 | } | ||
517 | |||
518 | impl SubstsBuilder { | ||
519 | pub fn build(self) -> Substitution { | ||
520 | assert_eq!(self.vec.len(), self.param_count); | ||
521 | Substitution::from_iter(&Interner, self.vec) | ||
522 | } | ||
523 | |||
524 | pub fn push(mut self, ty: impl CastTo<GenericArg>) -> Self { | ||
525 | self.vec.push(ty.cast(&Interner)); | ||
526 | self | ||
527 | } | ||
528 | |||
529 | fn remaining(&self) -> usize { | ||
530 | self.param_count - self.vec.len() | ||
531 | } | ||
532 | |||
533 | pub fn fill_with_bound_vars(self, debruijn: DebruijnIndex, starting_from: usize) -> Self { | ||
534 | self.fill( | ||
535 | (starting_from..) | ||
536 | .map(|idx| TyKind::BoundVar(BoundVar::new(debruijn, idx)).intern(&Interner)), | ||
537 | ) | ||
538 | } | ||
539 | |||
540 | pub fn fill_with_unknown(self) -> Self { | ||
541 | self.fill(iter::repeat(TyKind::Unknown.intern(&Interner))) | ||
542 | } | ||
543 | |||
544 | pub fn fill(mut self, filler: impl Iterator<Item = impl CastTo<GenericArg>>) -> Self { | ||
545 | self.vec.extend(filler.take(self.remaining()).casted(&Interner)); | ||
546 | assert_eq!(self.remaining(), 0); | ||
547 | self | ||
548 | } | ||
549 | |||
550 | pub fn use_parent_substs(mut self, parent_substs: &Substitution) -> Self { | ||
551 | assert!(self.vec.is_empty()); | ||
552 | assert!(parent_substs.len(&Interner) <= self.param_count); | ||
553 | self.vec.extend(parent_substs.iter(&Interner).cloned()); | ||
554 | self | ||
555 | } | ||
556 | } | ||
557 | |||
558 | #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] | 472 | #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] |
559 | pub struct Binders<T> { | 473 | pub struct Binders<T> { |
560 | pub num_binders: usize, | 474 | pub num_binders: usize, |
@@ -760,7 +674,7 @@ impl CallableSig { | |||
760 | 674 | ||
761 | pub fn from_fn_ptr(fn_ptr: &FnPointer) -> CallableSig { | 675 | pub fn from_fn_ptr(fn_ptr: &FnPointer) -> CallableSig { |
762 | CallableSig { | 676 | CallableSig { |
763 | // FIXME: what to do about lifetime params? | 677 | // FIXME: what to do about lifetime params? -> return PolyFnSig |
764 | params_and_return: fn_ptr | 678 | params_and_return: fn_ptr |
765 | .substs | 679 | .substs |
766 | .clone() | 680 | .clone() |
@@ -773,16 +687,6 @@ impl CallableSig { | |||
773 | } | 687 | } |
774 | } | 688 | } |
775 | 689 | ||
776 | pub fn from_substs(substs: &Substitution) -> CallableSig { | ||
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 | } | ||
784 | } | ||
785 | |||
786 | pub fn params(&self) -> &[Ty] { | 690 | pub fn params(&self) -> &[Ty] { |
787 | &self.params_and_return[0..self.params_and_return.len() - 1] | 691 | &self.params_and_return[0..self.params_and_return.len() - 1] |
788 | } | 692 | } |
@@ -811,40 +715,6 @@ impl TypeWalk for CallableSig { | |||
811 | } | 715 | } |
812 | 716 | ||
813 | impl Ty { | 717 | impl Ty { |
814 | pub fn unit() -> Self { | ||
815 | TyKind::Tuple(0, Substitution::empty(&Interner)).intern(&Interner) | ||
816 | } | ||
817 | |||
818 | pub fn adt_ty(adt: hir_def::AdtId, substs: Substitution) -> Ty { | ||
819 | TyKind::Adt(AdtId(adt), substs).intern(&Interner) | ||
820 | } | ||
821 | |||
822 | pub fn fn_ptr(sig: CallableSig) -> Self { | ||
823 | TyKind::Function(FnPointer { | ||
824 | num_args: sig.params().len(), | ||
825 | sig: FnSig { abi: (), safety: Safety::Safe, variadic: sig.is_varargs }, | ||
826 | substs: Substitution::from_iter(&Interner, sig.params_and_return.iter().cloned()), | ||
827 | }) | ||
828 | .intern(&Interner) | ||
829 | } | ||
830 | |||
831 | pub fn builtin(builtin: BuiltinType) -> Self { | ||
832 | match builtin { | ||
833 | BuiltinType::Char => TyKind::Scalar(Scalar::Char).intern(&Interner), | ||
834 | BuiltinType::Bool => TyKind::Scalar(Scalar::Bool).intern(&Interner), | ||
835 | BuiltinType::Str => TyKind::Str.intern(&Interner), | ||
836 | BuiltinType::Int(t) => { | ||
837 | TyKind::Scalar(Scalar::Int(primitive::int_ty_from_builtin(t))).intern(&Interner) | ||
838 | } | ||
839 | BuiltinType::Uint(t) => { | ||
840 | TyKind::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(t))).intern(&Interner) | ||
841 | } | ||
842 | BuiltinType::Float(t) => { | ||
843 | TyKind::Scalar(Scalar::Float(primitive::float_ty_from_builtin(t))).intern(&Interner) | ||
844 | } | ||
845 | } | ||
846 | } | ||
847 | |||
848 | pub fn as_reference(&self) -> Option<(&Ty, Mutability)> { | 718 | pub fn as_reference(&self) -> Option<(&Ty, Mutability)> { |
849 | match self.kind(&Interner) { | 719 | match self.kind(&Interner) { |
850 | TyKind::Ref(mutability, ty) => Some((ty, *mutability)), | 720 | TyKind::Ref(mutability, ty) => Some((ty, *mutability)), |
@@ -1068,7 +938,7 @@ impl Ty { | |||
1068 | let param_data = &generic_params.types[id.local_id]; | 938 | let param_data = &generic_params.types[id.local_id]; |
1069 | match param_data.provenance { | 939 | match param_data.provenance { |
1070 | hir_def::generics::TypeParamProvenance::ArgumentImplTrait => { | 940 | hir_def::generics::TypeParamProvenance::ArgumentImplTrait => { |
1071 | let substs = Substitution::type_params(db, id.parent); | 941 | let substs = TyBuilder::type_params_subst(db, id.parent); |
1072 | let predicates = db | 942 | let predicates = db |
1073 | .generic_predicates(id.parent) | 943 | .generic_predicates(id.parent) |
1074 | .into_iter() | 944 | .into_iter() |