use std::borrow::Cow; use std::rc::Rc; use dhall_syntax::context::Context as SimpleContext; use dhall_syntax::{Label, V}; use crate::core::thunk::Thunk; use crate::core::value::Value; use crate::core::var::{AlphaVar, Shift, Subst}; use crate::error::TypeError; use crate::phase::{Type, Typed}; #[derive(Debug, Clone)] pub(crate) enum CtxItem { Kept(AlphaVar, T), Replaced(Thunk, T), } #[derive(Debug, Clone)] pub(crate) struct Context(Rc>>); #[derive(Debug, Clone)] pub(crate) struct NormalizationContext(Context<()>); #[derive(Debug, Clone)] pub(crate) struct TypecheckContext(Context); impl CtxItem { fn forget(&self) -> CtxItem<()> { match self { CtxItem::Kept(var, _) => CtxItem::Kept(var.clone(), ()), CtxItem::Replaced(e, _) => CtxItem::Replaced(e.clone(), ()), } } } impl Context { pub(crate) fn new() -> Self { Context(Rc::new(SimpleContext::new())) } pub(crate) fn forget(&self) -> Context<()> { let mut ctx = SimpleContext::new(); for (k, vs) in self.0.iter_keys() { for v in vs.iter() { ctx = ctx.insert(k.clone(), v.forget()); } } Context(Rc::new(ctx)) } pub(crate) fn insert_kept(&self, x: &Label, t: T) -> Self where T: Shift + Clone, { Context(Rc::new(self.0.map(|_, e| e.shift(1, &x.into())).insert( x.clone(), CtxItem::Kept(x.into(), t.shift(1, &x.into())), ))) } pub(crate) fn insert_replaced(&self, x: &Label, e: Thunk, t: T) -> Self where T: Clone, { Context(Rc::new(self.0.insert(x.clone(), CtxItem::Replaced(e, t)))) } pub(crate) fn lookup(&self, var: &V