#![feature(in_band_lifetimes)]
#![feature(never_type)]
#![feature(specialization)]
#![feature(const_fn)]
#![warn(unused_imports)]
use lark_collections::{IndexVec, Seq};
use lark_debug_derive::DebugWith;
use lark_debug_with::DebugWith;
use lark_entity::Entity;
use lark_error::ErrorReported;
use lark_error::ErrorSentinel;
use lark_string::GlobalIdentifier;
use lark_unify::InferVar;
use std::fmt::{self, Debug};
use std::hash::Hash;
use std::iter::IntoIterator;
use std::sync::Arc;
pub mod base_inferred;
pub mod declaration;
pub mod full_inferred;
pub mod identity;
pub mod map_family;
pub trait TypeFamily: Copy + Clone + Debug + DebugWith + Eq + Hash + 'static {
type InternTables: AsRef<Self::InternTables>;
type Repr: Copy + Clone + Debug + DebugWith + Eq + Hash;
type Perm: Copy + Clone + Debug + DebugWith + Eq + Hash;
type Base: Copy + Clone + Debug + DebugWith + Eq + Hash;
type Placeholder: Copy + Clone + Debug + DebugWith + Eq + Hash;
fn intern_base_data(
tables: &dyn AsRef<Self::InternTables>,
base_data: BaseData<Self>,
) -> Self::Base;
fn own_perm(tables: &dyn AsRef<Self::InternTables>) -> Self::Perm;
fn direct_repr(tables: &dyn AsRef<Self::InternTables>) -> Self::Repr {
Self::known_repr(tables, ReprKind::Direct)
}
fn known_repr(tables: &dyn AsRef<Self::InternTables>, repr_kind: ReprKind) -> Self::Repr;
fn error_type(tables: &dyn AsRef<Self::InternTables>) -> Ty<Self> {
Ty {
repr: Self::direct_repr(tables),
perm: Self::own_perm(tables),
base: Self::error_base_data(tables),
}
}
fn error_base_data(tables: &dyn AsRef<Self::InternTables>) -> Self::Base {
Self::intern_base_data(
tables,
BaseData {
kind: BaseKind::Error,
generics: Generics::empty(),
},
)
}
}
#[derive(Copy, Clone, Debug, DebugWith, PartialEq, Eq, Hash)]
pub struct Ty<F: TypeFamily> {
pub repr: F::Repr,
pub perm: F::Perm,
pub base: F::Base,
}
impl<DB, F> ErrorSentinel<&DB> for Ty<F>
where
DB: AsRef<F::InternTables>,
F: TypeFamily,
{
fn error_sentinel(db: &DB, _report: ErrorReported) -> Self {
F::error_type(db)
}
}
#[derive(Copy, Clone, Debug, DebugWith, PartialEq, Eq, Hash)]
pub struct Erased;
#[derive(Clone, Debug, DebugWith, PartialEq, Eq, Hash)]
pub struct BaseData<F: TypeFamily> {
pub kind: BaseKind<F>,
pub generics: Generics<F>,
}
impl<F: TypeFamily> BaseData<F> {
pub fn from_placeholder(p: F::Placeholder) -> Self {
BaseData {
kind: BaseKind::Placeholder(p),
generics: Generics::empty(),
}
}
}
#[derive(Copy, Clone, Debug, DebugWith, PartialEq, Eq, Hash)]
pub enum BaseKind<F: TypeFamily> {
Named(Entity),
Placeholder(F::Placeholder),
Error,
}
#[derive(Clone, Debug, DebugWith, PartialEq, Eq, Hash)]
pub enum InferVarOr<T> {
InferVar(InferVar),
Known(T),
}
impl<T> InferVarOr<T> {
pub fn assert_known(self) -> T {
match self {
InferVarOr::InferVar(_) => panic!("assert_known invoked on infer var"),
InferVarOr::Known(v) => v,
}
}
}
#[derive(Copy, Clone, Debug, DebugWith, PartialEq, Eq, Hash)]
pub struct Placeholder {
pub universe: Universe,
pub bound_var: BoundVar,
}
lark_collections::index_type! {
pub struct Universe {
debug_name["U"],
..
}
}
lark_debug_with::debug_fallback_impl!(Universe);
impl Universe {
pub const ROOT: Universe = Universe::from_u32(0);
}
#[derive(Clone, Debug, DebugWith, PartialEq, Eq, Hash)]
pub enum BoundVarOr<T> {
BoundVar(BoundVar),
Known(T),
}
impl<T> BoundVarOr<T> {
pub fn assert_known(self) -> T {
match self {
BoundVarOr::BoundVar(_) => panic!("`assert_known` invoked on bound var"),
BoundVarOr::Known(v) => v,
}
}
}
lark_collections::index_type! {
pub struct BoundVar { .. }
}
lark_debug_with::debug_fallback_impl!(BoundVar);
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Generics<F: TypeFamily> {
elements: Seq<Generic<F>>,
}
impl<F: TypeFamily> Generics<F> {
pub fn empty() -> Self {
Generics {
elements: Seq::default(),
}
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn is_not_empty(&self) -> bool {
self.len() != 0
}
pub fn len(&self) -> usize {
self.elements.len()
}
pub fn iter(&self) -> impl Iterator<Item = Generic<F>> + '_ {
self.into_iter()
}
pub fn elements(&self) -> &[Generic<F>] {
&self.elements[..]
}
pub fn push(&mut self, generic: Generic<F>) {
self.extend(std::iter::once(generic));
}
}
impl<F: TypeFamily> DebugWith for Generics<F> {
fn fmt_with<Cx: ?Sized>(&self, cx: &Cx, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_list()
.entries(self.elements().iter().map(|e| e.debug_with(cx)))
.finish()
}
}
impl<F> std::iter::Extend<Generic<F>> for Generics<F>
where
F: TypeFamily,
{
fn extend<T>(&mut self, iter: T)
where
T: IntoIterator<Item = Generic<F>>,
{
self.elements.extend(iter);
}
}
impl<F> std::ops::Index<BoundVar> for Generics<F>
where
F: TypeFamily,
{
type Output = Generic<F>;
fn index(&self, index: BoundVar) -> &Self::Output {
&self.elements()[index.as_usize()]
}
}
impl<F: TypeFamily> std::iter::FromIterator<Generic<F>> for Generics<F> {
fn from_iter<T>(iter: T) -> Self
where
T: IntoIterator<Item = Generic<F>>,
{
Generics {
elements: Seq::from_iter(iter),
}
}
}
impl<F: TypeFamily> IntoIterator for &'iter Generics<F> {
type IntoIter = std::iter::Cloned<std::slice::Iter<'iter, Generic<F>>>;
type Item = Generic<F>;
fn into_iter(self) -> Self::IntoIter {
self.elements().iter().cloned()
}
}
#[allow(type_alias_bounds)]
pub type Generic<F: TypeFamily> = GenericKind<Ty<F>>;
#[derive(Copy, Clone, Debug, DebugWith, PartialEq, Eq, Hash)]
pub enum GenericKind<T> {
Ty(T),
}
impl<T> GenericKind<T> {
pub fn assert_ty(self) -> T {
match self {
GenericKind::Ty(ty) => ty,
}
}
}
#[derive(Clone, Debug, DebugWith, PartialEq, Eq, Hash)]
pub struct Signature<F: TypeFamily> {
pub inputs: Seq<Ty<F>>,
pub output: Ty<F>,
}
impl<F: TypeFamily> Signature<F> {
pub fn error_sentinel(tables: &dyn AsRef<F::InternTables>, num_inputs: usize) -> Signature<F> {
Signature {
inputs: (0..num_inputs).map(|_| F::error_type(tables)).collect(),
output: F::error_type(tables),
}
}
}
#[derive(Clone, Debug, DebugWith, Default, PartialEq, Eq, Hash)]
pub struct GenericDeclarations {
pub parent_item: Option<Entity>,
pub declarations: IndexVec<BoundVar, GenericKind<GenericTyDeclaration>>,
}
impl GenericDeclarations {
pub fn empty(parent_item: Option<Entity>) -> Arc<Self> {
Arc::new(GenericDeclarations {
parent_item,
declarations: IndexVec::default(),
})
}
pub fn is_empty(&self) -> bool {
self.declarations.is_empty() && self.parent_item.is_none()
}
}
#[derive(Clone, Debug, DebugWith, PartialEq, Eq, Hash)]
pub struct GenericTyDeclaration {
pub def_id: Entity,
pub name: GlobalIdentifier,
}
#[derive(Copy, Clone, Debug, DebugWith, PartialEq, Eq, Hash)]
pub enum PermKind {
Own,
Share,
Borrow,
}
#[derive(Copy, Clone, Debug, DebugWith, PartialEq, Eq, Hash)]
pub enum ReprKind {
Direct,
Indirect,
}