Skip to content

Commit

Permalink
Stricter type-check
Browse files Browse the repository at this point in the history
  • Loading branch information
mtshiba committed Aug 17, 2022
1 parent 1e3819b commit ed61bc3
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 15 deletions.
22 changes: 18 additions & 4 deletions compiler/erg_common/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,20 +131,30 @@ impl Constraint {
pub fn sub_type(&self) -> Option<&Type> {
match self {
Self::SupertypeOf(ty) => Some(ty),
Self::Sandwiched { sub, .. } => Some(sub),
_ => None,
}
}

pub fn super_type(&self) -> Option<&Type> {
match self {
Self::SubtypeOf(ty) => Some(ty),
Self::Sandwiched { sup, .. } => Some(sup),
_ => None,
}
}

pub fn sub_sup_type(&self) -> Option<(&Type, &Type)> {
match self {
Self::Sandwiched { sub, sup } => Some((sub, sup)),
_ => None,
}
}

pub fn super_type_mut(&mut self) -> Option<&mut Type> {
match self {
Self::SubtypeOf(ty) => Some(ty),
Self::Sandwiched { sup, .. } => Some(sup),
_ => None,
}
}
Expand Down Expand Up @@ -376,6 +386,14 @@ impl<T: Clone + HasLevel> Free<T> {
)
}

pub fn constraint_is_sandwiched(&self) -> bool {
matches!(
&*self.0.borrow(),
FreeKind::Unbound { constraint, .. }
| FreeKind::NamedUnbound { constraint, .. } if constraint.sub_sup_type().is_some()
)
}

pub fn is_linked(&self) -> bool {
matches!(&*self.0.borrow(), FreeKind::Linked(_))
}
Expand Down Expand Up @@ -1692,10 +1710,6 @@ impl ArgsOwnership {
}

/// NOTE: 連携型変数があるので、比較には`ref_eq`を使うこと
/// Commonが付く型は多相だが中の型をなんでも受け入れるバージョン
/// TODO: MonoArray Int, 3 == PolyArray Int, Int, Int
/// Mut型を作ろうとすると、name() -> &strがうまくいかないので
/// 組み込みMut型は全て書き下す
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Type {
/* Monomorphic (builtin) types */
Expand Down
29 changes: 19 additions & 10 deletions compiler/erg_compiler/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1623,10 +1623,15 @@ impl Context {
}
}

// FIXME:
fn deref_tp(&self, tp: TyParam) -> TyCheckResult<TyParam> {
match tp {
TyParam::FreeVar(fv) if fv.is_linked() => Ok(fv.unwrap_linked()),
TyParam::FreeVar(fv) if fv.is_linked() => {
let inner = fv.unwrap_linked();
self.deref_tp(inner)
},
TyParam::FreeVar(_fv) if self.level == 0 => {
Err(TyCheckError::dummy_infer_error(fn_name!(), line!()))
},
TyParam::Type(t) => Ok(TyParam::t(self.deref_tyvar(*t)?)),
TyParam::App { name, mut args } => {
for param in args.iter_mut() {
Expand All @@ -1637,6 +1642,10 @@ impl Context {
TyParam::BinOp { .. } => todo!(),
TyParam::UnaryOp { .. } => todo!(),
TyParam::Array(_) | TyParam::Tuple(_) => todo!(),
TyParam::MonoProj { .. }
| TyParam::MonoQVar(_)
| TyParam::PolyQVar { .. }
| TyParam::Failure if self.level == 0 => Err(TyCheckError::dummy_infer_error(fn_name!(), line!())),
t => Ok(t),
}
}
Expand Down Expand Up @@ -1666,9 +1675,8 @@ impl Context {
/// ```
fn deref_tyvar(&self, t: Type) -> TyCheckResult<Type> {
match t {
Type::FreeVar(fv) if fv.constraint_is_typeof() => Ok(Type::FreeVar(fv)),
// ?T(<: Int)[n] => Int
Type::FreeVar(fv) if fv.constraint_is_subtypeof() => {
Type::FreeVar(fv) if fv.constraint_is_subtypeof() || fv.constraint_is_sandwiched() => {
if self.level <= fv.level().unwrap() {
Ok(fv.crack_constraint().super_type().unwrap().clone())
} else {
Expand All @@ -1683,7 +1691,7 @@ impl Context {
| Constraint::SubtypeOf(t) => Ok(t.clone()),
Constraint::Sandwiched { sub, .. } => Ok(sub.clone()),
Constraint::TypeOf(_) => {
Err(TyCheckError::unreachable(fn_name!(), line!()))
Err(TyCheckError::dummy_infer_error(fn_name!(), line!()))
},
_ => unreachable!(),
}
Expand All @@ -1698,9 +1706,6 @@ impl Context {
let t = fv.unwrap_linked();
self.deref_tyvar(t)
},
// 未連携型変数が残っているかのチェックはモジュール全体の型検査が終わった後にやる
// Type::FreeVar(_) =>
// Err(TyCheckError::checker_bug(0, Location::Unknown, fn_name!(), line!())),
Type::Poly { name, mut params } => {
for param in params.iter_mut() {
*param = self.deref_tp(mem::take(param))?;
Expand Down Expand Up @@ -1757,8 +1762,12 @@ impl Context {
}
Ok(())
},
hir::Expr::Array(_array) => {
todo!()
hir::Expr::Array(array) => {
array.t = self.deref_tyvar(mem::take(&mut array.t))?;
for elem in array.elems.pos_args.iter_mut() {
self.deref_expr_t(&mut elem.expr)?;
}
Ok(())
},
hir::Expr::Dict(_dict) => {
todo!()
Expand Down
2 changes: 1 addition & 1 deletion compiler/erg_compiler/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,7 @@ impl Accessor {
pub struct Array {
pub l_sqbr: Token,
pub r_sqbr: Token,
t: Type,
pub t: Type,
pub elems: Args,
pub guard: Option<Box<Expr>>,
}
Expand Down
1 change: 1 addition & 0 deletions compiler/erg_compiler/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,7 @@ impl ASTLowerer {
}
}
let hir = HIR::new(ast.name, module);
log!("HIR (not derefed):\n{hir}");
let hir = self.ctx.deref_toplevel(hir)?;
log!(
"[DEBUG] {}() has completed, found errors: {}",
Expand Down

0 comments on commit ed61bc3

Please sign in to comment.