Fix inferring bugs

This commit is contained in:
Shunsuke Shibayama 2022-09-25 21:32:49 +09:00
parent 93388ddf80
commit d11b05ecff
4 changed files with 13 additions and 4 deletions

View file

@ -606,10 +606,10 @@ impl Context {
self.poly_supertype_of(lhs, lparams, rparams) self.poly_supertype_of(lhs, lparams, rparams)
} }
(MonoQVar(name), r) | (PolyQVar { name, .. }, r) => { (MonoQVar(name), r) | (PolyQVar { name, .. }, r) => {
panic!("Not instantiated type variable: {name}, r: {r}") panic!("internal error: not instantiated type variable: '{name}, r: {r}")
} }
(l, MonoQVar(name)) | (l, PolyQVar { name, .. }) => { (l, MonoQVar(name)) | (l, PolyQVar { name, .. }) => {
panic!("Not instantiated type variable: {name}, l: {l}") panic!("internal error: not instantiated type variable: '{name}, l: {l}")
} }
(MonoProj { .. }, _) => todo!(), (MonoProj { .. }, _) => todo!(),
(_, MonoProj { .. }) => todo!(), (_, MonoProj { .. }) => todo!(),

View file

@ -133,6 +133,7 @@ impl TyVarContext {
params params
.into_iter() .into_iter()
.map(|p| { .map(|p| {
erg_common::log!(err "p: {p}, {:?}", p.tvar_name());
if let Some(name) = p.tvar_name() { if let Some(name) = p.tvar_name() {
let tp = self.instantiate_qtp(p); let tp = self.instantiate_qtp(p);
self.push_or_init_typaram(&name, &tp); self.push_or_init_typaram(&name, &tp);
@ -243,7 +244,7 @@ impl TyVarContext {
} }
} }
TyParam::Type(t) => { TyParam::Type(t) => {
if let Type::MonoQVar(n) = *t { if let Some(n) = t.as_ref().tvar_name() {
if let Some(t) = self.get_typaram(&n) { if let Some(t) = self.get_typaram(&n) {
t.clone() t.clone()
} else if let Some(t) = self.get_tyvar(&n) { } else if let Some(t) = self.get_tyvar(&n) {
@ -254,7 +255,7 @@ impl TyVarContext {
TyParam::t(tv) TyParam::t(tv)
} }
} else { } else {
todo!("{t}") unreachable!("{t}")
} }
} }
TyParam::UnaryOp { op, val } => { TyParam::UnaryOp { op, val } => {
@ -336,6 +337,7 @@ impl TyVarContext {
} }
} }
/// TODO: this struct will be removed when const functions are implemented.
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum ConstTemplate { pub enum ConstTemplate {
Obj(ValueObj), Obj(ValueObj),
@ -766,6 +768,9 @@ impl Context {
let t = Self::instantiate_t(*t, tv_ctx, loc)?; let t = Self::instantiate_t(*t, tv_ctx, loc)?;
Ok(TyParam::t(t)) Ok(TyParam::t(t))
} }
TyParam::FreeVar(fv) if fv.is_linked() => {
Self::instantiate_tp(fv.crack().clone(), tv_ctx, loc)
}
p @ (TyParam::Value(_) | TyParam::Mono(_) | TyParam::FreeVar(_)) => Ok(p), p @ (TyParam::Value(_) | TyParam::Mono(_) | TyParam::FreeVar(_)) => Ok(p),
other => todo!("{other}"), other => todo!("{other}"),
} }
@ -867,6 +872,7 @@ impl Context {
Quantified(_) => { Quantified(_) => {
panic!("a quantified type should not be instantiated, instantiate the inner type") panic!("a quantified type should not be instantiated, instantiate the inner type")
} }
FreeVar(fv) if fv.is_linked() => Self::instantiate_t(fv.crack().clone(), tv_ctx, loc),
other if other.is_monomorphic() => Ok(other), other if other.is_monomorphic() => Ok(other),
other => todo!("{other}"), other => todo!("{other}"),
} }

View file

@ -1817,6 +1817,7 @@ impl Type {
pub fn tvar_name(&self) -> Option<Str> { pub fn tvar_name(&self) -> Option<Str> {
match self { match self {
Self::FreeVar(fv) if fv.is_linked() => fv.crack().tvar_name(),
Self::FreeVar(fv) => fv.unbound_name(), Self::FreeVar(fv) => fv.unbound_name(),
Self::MonoQVar(name) => Some(name.clone()), Self::MonoQVar(name) => Some(name.clone()),
_ => None, _ => None,

View file

@ -509,6 +509,7 @@ impl TyParam {
pub fn name(&self) -> Option<Str> { pub fn name(&self) -> Option<Str> {
match self { match self {
Self::Type(t) => Some(t.name()), Self::Type(t) => Some(t.name()),
Self::FreeVar(fv) if fv.is_linked() => fv.crack().name(),
Self::Mono(name) => Some(name.clone()), Self::Mono(name) => Some(name.clone()),
Self::MonoQVar(name) => Some(name.clone()), Self::MonoQVar(name) => Some(name.clone()),
_ => None, _ => None,
@ -518,6 +519,7 @@ impl TyParam {
pub fn tvar_name(&self) -> Option<Str> { pub fn tvar_name(&self) -> Option<Str> {
match self { match self {
Self::Type(t) => t.tvar_name(), Self::Type(t) => t.tvar_name(),
Self::FreeVar(fv) if fv.is_linked() => fv.crack().tvar_name(),
Self::FreeVar(fv) => fv.unbound_name(), Self::FreeVar(fv) => fv.unbound_name(),
Self::MonoQVar(name) => Some(name.clone()), Self::MonoQVar(name) => Some(name.clone()),
_ => None, _ => None,