cargo fmt

This commit is contained in:
ShantanuKumar 2022-08-17 11:21:09 +02:00
parent 98a2586f6f
commit 4e7be1400b
9 changed files with 300 additions and 203 deletions

View file

@ -298,9 +298,7 @@ pub trait ImmutableStream<T>: Sized {
// for Runnable::run // for Runnable::run
fn expect_block(src: &str) -> bool { fn expect_block(src: &str) -> bool {
src.ends_with(&['=', ':']) src.ends_with(&['=', ':']) || src.ends_with("->") || src.ends_with("=>")
|| src.ends_with("->")
|| src.ends_with("=>")
} }
/// This trait implements REPL (Read-Eval-Print-Loop) automatically /// This trait implements REPL (Read-Eval-Print-Loop) automatically
@ -331,9 +329,7 @@ pub trait Runnable: Sized {
fn run(cfg: ErgConfig) { fn run(cfg: ErgConfig) {
let mut instance = Self::new(cfg); let mut instance = Self::new(cfg);
let res = match instance.input() { let res = match instance.input() {
Input::File(_) | Input::Pipe(_) | Input::Str(_) => { Input::File(_) | Input::Pipe(_) | Input::Str(_) => instance.exec(),
instance.exec()
}
Input::REPL => { Input::REPL => {
let output = stdout(); let output = stdout();
let mut output = BufWriter::new(output.lock()); let mut output = BufWriter::new(output.lock());

View file

@ -42,7 +42,12 @@ fn reorder_by_key<T: Eq, U>(mut g: Graph<T, U>, idx: Vec<T>) -> Graph<T, U> {
g g
} }
fn dfs<T: Eq + Hash + Clone, U>(g: &Graph<T, U>, v: T, used: &mut Set<T>, idx: &mut Vec<T>) -> Result<(), ()> { fn dfs<T: Eq + Hash + Clone, U>(
g: &Graph<T, U>,
v: T,
used: &mut Set<T>,
idx: &mut Vec<T>,
) -> Result<(), ()> {
used.insert(v.clone()); used.insert(v.clone());
for node_id in g.iter().find(|n| n.id == v).unwrap().depends_on.iter() { for node_id in g.iter().find(|n| n.id == v).unwrap().depends_on.iter() {
// detecting cycles // detecting cycles

View file

@ -94,7 +94,10 @@ pub enum Constraint {
/// <: T /// <: T
SubtypeOf(Type), SubtypeOf(Type),
/// :> Sub, <: Sup /// :> Sub, <: Sup
Sandwiched { sub: Type, sup: Type }, Sandwiched {
sub: Type,
sup: Type,
},
/// : T /// : T
TypeOf(Type), TypeOf(Type),
Uninited, Uninited,
@ -311,8 +314,14 @@ impl<T: Clone + HasLevel> Free<T> {
pub fn unwrap_unbound(self) -> (Option<Str>, usize, Constraint) { pub fn unwrap_unbound(self) -> (Option<Str>, usize, Constraint) {
match self.0.clone_inner() { match self.0.clone_inner() {
FreeKind::Linked(_) => panic!("the value is linked"), FreeKind::Linked(_) => panic!("the value is linked"),
FreeKind::Unbound { constraint, lev, .. } => (None, lev, constraint), FreeKind::Unbound {
| FreeKind::NamedUnbound { name, lev, constraint } => (Some(name), lev, constraint), constraint, lev, ..
} => (None, lev, constraint),
FreeKind::NamedUnbound {
name,
lev,
constraint,
} => (Some(name), lev, constraint),
} }
} }
@ -339,8 +348,9 @@ impl<T: Clone + HasLevel> Free<T> {
pub fn crack_constraint(&self) -> Ref<'_, Constraint> { pub fn crack_constraint(&self) -> Ref<'_, Constraint> {
Ref::map(self.0.borrow(), |f| match f { Ref::map(self.0.borrow(), |f| match f {
FreeKind::Linked(_) => panic!("the value is linked"), FreeKind::Linked(_) => panic!("the value is linked"),
FreeKind::Unbound { constraint, .. } FreeKind::Unbound { constraint, .. } | FreeKind::NamedUnbound { constraint, .. } => {
| FreeKind::NamedUnbound { constraint, .. } => constraint, constraint
}
}) })
} }
@ -902,7 +912,7 @@ impl TyParam {
pub fn update_constraint(&self, new_constraint: Constraint) { pub fn update_constraint(&self, new_constraint: Constraint) {
match self { match self {
Self::Type(t) => { t.update_constraint(new_constraint) }, Self::Type(t) => t.update_constraint(new_constraint),
_ => {} _ => {}
} }
} }
@ -2861,8 +2871,10 @@ impl Type {
pub fn update_constraint(&self, new_constraint: Constraint) { pub fn update_constraint(&self, new_constraint: Constraint) {
match self { match self {
Self::FreeVar(fv) => { fv.update_constraint(new_constraint); }, Self::FreeVar(fv) => {
_ => {}, fv.update_constraint(new_constraint);
}
_ => {}
} }
} }
} }

View file

@ -55,16 +55,16 @@ pub enum TyParamIdx {
impl TyParamIdx { impl TyParamIdx {
pub fn search(search_from: &Type, target: &Type) -> Option<Self> { pub fn search(search_from: &Type, target: &Type) -> Option<Self> {
match search_from { match search_from {
Type::Poly{ params, .. } => { Type::Poly { params, .. } => {
for (i, tp) in params.iter().enumerate() { for (i, tp) in params.iter().enumerate() {
match tp { match tp {
TyParam::Type(t) if t.rec_eq(target) => { return Some(Self::Nth(i)) }, TyParam::Type(t) if t.rec_eq(target) => return Some(Self::Nth(i)),
TyParam::Type(t) if t.is_monomorphic() => {}, TyParam::Type(t) if t.is_monomorphic() => {}
other => todo!("{other:?}"), other => todo!("{other:?}"),
} }
} }
None None
}, }
_ => todo!(), _ => todo!(),
} }
} }
@ -81,7 +81,7 @@ impl TyParamIdx {
TyParam::Type(t) => *t.clone(), TyParam::Type(t) => *t.clone(),
_ => todo!(), _ => todo!(),
} }
}, }
Self::Nested(_, _) => todo!(), Self::Nested(_, _) => todo!(),
} }
} }
@ -192,23 +192,26 @@ impl TyVarContext {
self_ self_
} }
fn instantiate_const_template(&mut self, var_name: &str, _callee_name: &Str, ct: &ConstTemplate) -> TyParam { fn instantiate_const_template(
&mut self,
var_name: &str,
_callee_name: &Str,
ct: &ConstTemplate,
) -> TyParam {
match ct { match ct {
ConstTemplate::Obj(o) => { ConstTemplate::Obj(o) => match o {
match o { ConstObj::Type(t) if t.is_mono_q() => {
ConstObj::Type(t) if t.is_mono_q() => { if t.name() == "Self" {
if t.name() == "Self" { let constraint = Constraint::TypeOf(Type);
let constraint = Constraint::TypeOf(Type); let t = Type::named_free_var(Str::rc(var_name), self.level, constraint);
let t = Type::named_free_var(Str::rc(var_name), self.level, constraint); TyParam::t(t)
TyParam::t(t) } else {
} else { todo!()
todo!() }
}
},
ConstObj::Type(t) => TyParam::t(*t.clone()),
v @ ConstObj::Value(_) => TyParam::ConstObj(v.clone()),
other => todo!("{other}"),
} }
ConstObj::Type(t) => TyParam::t(*t.clone()),
v @ ConstObj::Value(_) => TyParam::ConstObj(v.clone()),
other => todo!("{other}"),
}, },
ConstTemplate::App { .. } => { ConstTemplate::App { .. } => {
todo!() todo!()
@ -216,22 +219,32 @@ impl TyVarContext {
} }
} }
fn instantiate_poly(&mut self, tvar_name: &str, name: &Str, params: Vec<TyParam>, ctx: &Context) -> Type { fn instantiate_poly(
&mut self,
tvar_name: &str,
name: &Str,
params: Vec<TyParam>,
ctx: &Context,
) -> Type {
if let Some(temp_defaults) = ctx.rec_get_const_param_defaults(&name) { if let Some(temp_defaults) = ctx.rec_get_const_param_defaults(&name) {
let c = ctx.rec_type_ctx_by_name(name).unwrap_or_else(|| panic!("{} not found", name)); let c = ctx
.rec_type_ctx_by_name(name)
.unwrap_or_else(|| panic!("{} not found", name));
let defined_params_len = c.params.len(); let defined_params_len = c.params.len();
let given_params_len = params.len(); let given_params_len = params.len();
if defined_params_len < given_params_len { panic!() } if defined_params_len < given_params_len {
panic!()
}
let inst_non_defaults = params.into_iter().map(|p| self.instantiate_tp(p)).collect(); let inst_non_defaults = params.into_iter().map(|p| self.instantiate_tp(p)).collect();
let mut inst_defaults = vec![]; let mut inst_defaults = vec![];
for c in temp_defaults.into_iter().take(defined_params_len - given_params_len) { for c in temp_defaults
.into_iter()
.take(defined_params_len - given_params_len)
{
let c = self.instantiate_const_template(tvar_name, name, c); let c = self.instantiate_const_template(tvar_name, name, c);
inst_defaults.push(c); inst_defaults.push(c);
} }
Type::poly( Type::poly(name, [inst_non_defaults, inst_defaults].concat())
name,
[inst_non_defaults, inst_defaults].concat(),
)
} else { } else {
Type::poly( Type::poly(
name, name,
@ -257,7 +270,10 @@ impl TyVarContext {
tp.update_constraint(constraint); tp.update_constraint(constraint);
} else { } else {
let name = Str::rc(sub.name()); let name = Str::rc(sub.name());
self.push_tyvar(name.clone(), Type::named_free_var(name, self.level, constraint)); self.push_tyvar(
name.clone(),
Type::named_free_var(name, self.level, constraint),
);
} }
} }
TyBound::Supertype { sup, sub } => { TyBound::Supertype { sup, sub } => {
@ -275,7 +291,10 @@ impl TyVarContext {
tp.update_constraint(constraint); tp.update_constraint(constraint);
} else { } else {
let name = Str::rc(sup.name()); let name = Str::rc(sup.name());
self.push_tyvar(name.clone(), Type::named_free_var(name, self.level, constraint)); self.push_tyvar(
name.clone(),
Type::named_free_var(name, self.level, constraint),
);
} }
} }
TyBound::Sandwiched { sub, mid, sup } => { TyBound::Sandwiched { sub, mid, sup } => {
@ -300,7 +319,10 @@ impl TyVarContext {
tp.update_constraint(constraint); tp.update_constraint(constraint);
} else { } else {
let name = Str::rc(mid.name()); let name = Str::rc(mid.name());
self.push_tyvar(name.clone(), Type::named_free_var(name, self.level, constraint)); self.push_tyvar(
name.clone(),
Type::named_free_var(name, self.level, constraint),
);
} }
} }
TyBound::Instance { name, t } => { TyBound::Instance { name, t } => {
@ -327,7 +349,10 @@ impl TyVarContext {
if let Some(tp) = self.typaram_instances.get(&name) { if let Some(tp) = self.typaram_instances.get(&name) {
tp.update_constraint(constraint); tp.update_constraint(constraint);
} else { } else {
self.push_typaram(name.clone(), TyParam::named_free_var(name, self.level, t)); self.push_typaram(
name.clone(),
TyParam::named_free_var(name, self.level, t),
);
} }
} }
} }
@ -421,11 +446,19 @@ impl TyVarContext {
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum ConstTemplate { pub enum ConstTemplate {
Obj(ConstObj), Obj(ConstObj),
App{ name: Str, non_default_args: Vec<Type>, default_args: Vec<ConstTemplate> }, App {
name: Str,
non_default_args: Vec<Type>,
default_args: Vec<ConstTemplate>,
},
} }
impl ConstTemplate { impl ConstTemplate {
pub const fn app(name: &'static str, non_default_args: Vec<Type>, default_args: Vec<ConstTemplate>) -> Self { pub const fn app(
name: &'static str,
non_default_args: Vec<Type>,
default_args: Vec<ConstTemplate>,
) -> Self {
ConstTemplate::App { ConstTemplate::App {
name: Str::ever(name), name: Str::ever(name),
non_default_args, non_default_args,
@ -1564,25 +1597,25 @@ impl Context {
for (param_ty, pos_arg) in params.clone().zip(pos_args) { for (param_ty, pos_arg) in params.clone().zip(pos_args) {
let arg_t = pos_arg.expr.ref_t(); let arg_t = pos_arg.expr.ref_t();
let param_t = &param_ty.ty; let param_t = &param_ty.ty;
self.sub_unify( self.sub_unify(arg_t, param_t, None, Some(pos_arg.loc()))
arg_t, .map_err(|e| {
param_t, // REVIEW:
None, let name = callee.var_full_name().unwrap_or_else(|| "".to_string());
Some(pos_arg.loc()), let name = name
) + "::"
.map_err(|e| { + param_ty
// REVIEW: .name
let name = callee.var_full_name().unwrap_or_else(|| "".to_string()); .as_ref()
let name = .map(|s| readable_name(&s[..]))
name + "::" + param_ty.name.as_ref().map(|s| readable_name(&s[..])).unwrap_or(""); .unwrap_or("");
TyCheckError::type_mismatch_error( TyCheckError::type_mismatch_error(
e.core.loc, e.core.loc,
e.caused_by, e.caused_by,
&name[..], &name[..],
param_t, param_t,
arg_t, arg_t,
) )
})?; })?;
if let Some(name) = &param_ty.name { if let Some(name) = &param_ty.name {
if passed_params.contains(name) { if passed_params.contains(name) {
return Err(TyCheckError::multiple_args_error( return Err(TyCheckError::multiple_args_error(
@ -1628,10 +1661,10 @@ impl Context {
TyParam::FreeVar(fv) if fv.is_linked() => { TyParam::FreeVar(fv) if fv.is_linked() => {
let inner = fv.unwrap_linked(); let inner = fv.unwrap_linked();
self.deref_tp(inner) self.deref_tp(inner)
}, }
TyParam::FreeVar(_fv) if self.level == 0 => { TyParam::FreeVar(_fv) if self.level == 0 => {
Err(TyCheckError::dummy_infer_error(fn_name!(), line!())) Err(TyCheckError::dummy_infer_error(fn_name!(), line!()))
}, }
TyParam::Type(t) => Ok(TyParam::t(self.deref_tyvar(*t)?)), TyParam::Type(t) => Ok(TyParam::t(self.deref_tyvar(*t)?)),
TyParam::App { name, mut args } => { TyParam::App { name, mut args } => {
for param in args.iter_mut() { for param in args.iter_mut() {
@ -1645,25 +1678,24 @@ impl Context {
TyParam::MonoProj { .. } TyParam::MonoProj { .. }
| TyParam::MonoQVar(_) | TyParam::MonoQVar(_)
| TyParam::PolyQVar { .. } | TyParam::PolyQVar { .. }
| TyParam::Failure if self.level == 0 => Err(TyCheckError::dummy_infer_error(fn_name!(), line!())), | TyParam::Failure
if self.level == 0 =>
{
Err(TyCheckError::dummy_infer_error(fn_name!(), line!()))
}
t => Ok(t), t => Ok(t),
} }
} }
fn deref_constraint(&self, constraint: Constraint) -> TyCheckResult<Constraint> { fn deref_constraint(&self, constraint: Constraint) -> TyCheckResult<Constraint> {
match constraint { match constraint {
Constraint::SubtypeOf(sup) => { Constraint::SubtypeOf(sup) => Ok(Constraint::SubtypeOf(self.deref_tyvar(sup)?)),
Ok(Constraint::SubtypeOf(self.deref_tyvar(sup)?)) Constraint::Sandwiched { sub, sup } => Ok(Constraint::sandwiched(
}, self.deref_tyvar(sub)?,
Constraint::Sandwiched { sub, sup } => { self.deref_tyvar(sup)?,
Ok(Constraint::sandwiched(self.deref_tyvar(sub)?, self.deref_tyvar(sup)?)) )),
}, Constraint::SupertypeOf(sub) => Ok(Constraint::SupertypeOf(self.deref_tyvar(sub)?)),
Constraint::SupertypeOf(sub) => { Constraint::TypeOf(t) => Ok(Constraint::TypeOf(self.deref_tyvar(t)?)),
Ok(Constraint::SupertypeOf(self.deref_tyvar(sub)?))
},
Constraint::TypeOf(t) => {
Ok(Constraint::TypeOf(self.deref_tyvar(t)?))
},
_ => unreachable!(), _ => unreachable!(),
} }
} }
@ -1682,17 +1714,16 @@ impl Context {
} else { } else {
Ok(Type::FreeVar(fv)) Ok(Type::FreeVar(fv))
} }
}, }
// ?T(<: Add(?R(<: T), ?O(<: U)) => ?T(<: Add(T, U)) // ?T(<: Add(?R(<: T), ?O(<: U)) => ?T(<: Add(T, U))
Type::FreeVar(fv) if fv.is_unbound() => { Type::FreeVar(fv) if fv.is_unbound() => {
if self.level == 0 { if self.level == 0 {
match &*fv.crack_constraint() { match &*fv.crack_constraint() {
Constraint::SupertypeOf(t) Constraint::SupertypeOf(t) | Constraint::SubtypeOf(t) => Ok(t.clone()),
| Constraint::SubtypeOf(t) => Ok(t.clone()),
Constraint::Sandwiched { sub, .. } => Ok(sub.clone()), Constraint::Sandwiched { sub, .. } => Ok(sub.clone()),
Constraint::TypeOf(_) => { Constraint::TypeOf(_) => {
Err(TyCheckError::dummy_infer_error(fn_name!(), line!())) Err(TyCheckError::dummy_infer_error(fn_name!(), line!()))
}, }
_ => unreachable!(), _ => unreachable!(),
} }
} else { } else {
@ -1701,11 +1732,11 @@ impl Context {
fv.update_constraint(new_constraint); fv.update_constraint(new_constraint);
Ok(Type::FreeVar(fv)) Ok(Type::FreeVar(fv))
} }
}, }
Type::FreeVar(fv) if fv.is_linked() => { Type::FreeVar(fv) if fv.is_linked() => {
let t = fv.unwrap_linked(); let t = fv.unwrap_linked();
self.deref_tyvar(t) self.deref_tyvar(t)
}, }
Type::Poly { name, mut params } => { Type::Poly { name, mut params } => {
for param in params.iter_mut() { for param in params.iter_mut() {
*param = self.deref_tp(mem::take(param))?; *param = self.deref_tp(mem::take(param))?;
@ -1761,14 +1792,14 @@ impl Context {
_ => todo!(), _ => todo!(),
} }
Ok(()) Ok(())
}, }
hir::Expr::Array(array) => { hir::Expr::Array(array) => {
array.t = self.deref_tyvar(mem::take(&mut array.t))?; array.t = self.deref_tyvar(mem::take(&mut array.t))?;
for elem in array.elems.pos_args.iter_mut() { for elem in array.elems.pos_args.iter_mut() {
self.deref_expr_t(&mut elem.expr)?; self.deref_expr_t(&mut elem.expr)?;
} }
Ok(()) Ok(())
}, }
hir::Expr::Dict(_dict) => { hir::Expr::Dict(_dict) => {
todo!() todo!()
} }
@ -1778,13 +1809,13 @@ impl Context {
self.deref_expr_t(&mut binop.lhs)?; self.deref_expr_t(&mut binop.lhs)?;
self.deref_expr_t(&mut binop.rhs)?; self.deref_expr_t(&mut binop.rhs)?;
Ok(()) Ok(())
}, }
hir::Expr::UnaryOp(unaryop) => { hir::Expr::UnaryOp(unaryop) => {
let t = unaryop.signature_mut_t().unwrap(); let t = unaryop.signature_mut_t().unwrap();
*t = self.deref_tyvar(mem::take(t))?; *t = self.deref_tyvar(mem::take(t))?;
self.deref_expr_t(&mut unaryop.expr)?; self.deref_expr_t(&mut unaryop.expr)?;
Ok(()) Ok(())
}, }
hir::Expr::Call(call) => { hir::Expr::Call(call) => {
let t = call.signature_mut_t().unwrap(); let t = call.signature_mut_t().unwrap();
*t = self.deref_tyvar(mem::take(t))?; *t = self.deref_tyvar(mem::take(t))?;
@ -1796,15 +1827,15 @@ impl Context {
hir::Expr::Decl(decl) => { hir::Expr::Decl(decl) => {
decl.t = self.deref_tyvar(mem::take(&mut decl.t))?; decl.t = self.deref_tyvar(mem::take(&mut decl.t))?;
Ok(()) Ok(())
}, }
hir::Expr::Def(def) => { hir::Expr::Def(def) => {
match &mut def.sig { match &mut def.sig {
hir::Signature::Var(var) => { hir::Signature::Var(var) => {
var.t = self.deref_tyvar(mem::take(&mut var.t))?; var.t = self.deref_tyvar(mem::take(&mut var.t))?;
}, }
hir::Signature::Subr(subr) => { hir::Signature::Subr(subr) => {
subr.t = self.deref_tyvar(mem::take(&mut subr.t))?; subr.t = self.deref_tyvar(mem::take(&mut subr.t))?;
}, }
} }
for chunk in def.body.block.iter_mut() { for chunk in def.body.block.iter_mut() {
self.deref_expr_t(chunk)?; self.deref_expr_t(chunk)?;
@ -2311,7 +2342,7 @@ impl Context {
sub_loc, sub_loc,
sup_loc, sup_loc,
self.caused_by(), self.caused_by(),
)) ));
} else { } else {
*constraint = Constraint::sandwiched(l.clone(), mem::take(sup)); *constraint = Constraint::sandwiched(l.clone(), mem::take(sup));
} }
@ -2328,7 +2359,7 @@ impl Context {
sub_loc, sub_loc,
sup_loc, sup_loc,
self.caused_by(), self.caused_by(),
)) ));
} else { } else {
let union = self.union(l, sub); let union = self.union(l, sub);
*constraint = Constraint::sandwiched(union, mem::take(sub)); *constraint = Constraint::sandwiched(union, mem::take(sub));
@ -2336,7 +2367,7 @@ impl Context {
} }
Constraint::TypeOf(_t) => { Constraint::TypeOf(_t) => {
*constraint = Constraint::SupertypeOf(l.clone()); *constraint = Constraint::SupertypeOf(l.clone());
}, }
_ => {} _ => {}
}, },
_ => {} _ => {}
@ -2358,7 +2389,7 @@ impl Context {
sub_loc, sub_loc,
sup_loc, sup_loc,
self.caused_by(), self.caused_by(),
)) ));
} else { } else {
*constraint = Constraint::sandwiched(sub.clone(), r.clone()); *constraint = Constraint::sandwiched(sub.clone(), r.clone());
} }
@ -2366,9 +2397,7 @@ impl Context {
// sub_unify(?T(<: Int), Nat): (?T(<: Nat)) // sub_unify(?T(<: Int), Nat): (?T(<: Nat))
// sub_unify(?T(<: Nat), Int): (/* OK */) // sub_unify(?T(<: Nat), Int): (/* OK */)
// sub_unify(?T(<: Str), Int): (/* Error */) // TODO: // sub_unify(?T(<: Str), Int): (/* Error */) // TODO:
Constraint::SubtypeOf(sup) Constraint::SubtypeOf(sup) if self.rec_full_supertype_of(sup, r) => {
if self.rec_full_supertype_of(sup, r) =>
{
*constraint = Constraint::SubtypeOf(r.clone()); *constraint = Constraint::SubtypeOf(r.clone());
} }
// sub_unify((Int <: ?T <: Ratio), Nat): (/* Error */) // sub_unify((Int <: ?T <: Ratio), Nat): (/* Error */)
@ -2388,13 +2417,13 @@ impl Context {
// sub_unify(?T(: Type), Int): (?T(<: Int)) // sub_unify(?T(: Type), Int): (?T(<: Int))
Constraint::TypeOf(_t) => { Constraint::TypeOf(_t) => {
*constraint = Constraint::SubtypeOf(r.clone()); *constraint = Constraint::SubtypeOf(r.clone());
}, }
_ => {} _ => {}
}, },
_ => {} _ => {}
} }
return Ok(()); return Ok(());
}, }
(Type::FreeVar(_fv), _r) => todo!(), (Type::FreeVar(_fv), _r) => todo!(),
(l @ Refinement(_), r @ Refinement(_)) => return self.unify(l, r, sub_loc, sup_loc), (l @ Refinement(_), r @ Refinement(_)) => return self.unify(l, r, sub_loc, sup_loc),
_ => {} _ => {}
@ -3299,9 +3328,7 @@ impl Context {
} }
// `(?T :> X) :> Y` is true // `(?T :> X) :> Y` is true
// `(?T :> Str) :> Int` is true (?T :> Str or Int) // `(?T :> Str) :> Int` is true (?T :> Str or Int)
Constraint::SupertypeOf(_sub) => { Constraint::SupertypeOf(_sub) => true,
true
},
// `(Nat <: ?T <: Ratio) :> Nat` can be true // `(Nat <: ?T <: Ratio) :> Nat` can be true
Constraint::Sandwiched { sup, .. } => { Constraint::Sandwiched { sup, .. } => {
self.formal_supertype_of(sup, rhs, bounds, lhs_variance) self.formal_supertype_of(sup, rhs, bounds, lhs_variance)
@ -3331,8 +3358,8 @@ impl Context {
// `Str :> (?T <: Int)` is false // `Str :> (?T <: Int)` is false
Constraint::SubtypeOf(sup) => { Constraint::SubtypeOf(sup) => {
self.formal_supertype_of(lhs, sup, bounds, lhs_variance) self.formal_supertype_of(lhs, sup, bounds, lhs_variance)
|| self.formal_subtype_of(lhs, sup, bounds, lhs_variance) || self.formal_subtype_of(lhs, sup, bounds, lhs_variance)
}, }
// `Int :> (?T :> Nat)` can be true, `Nat :> (?T :> Int)` is false // `Int :> (?T :> Nat)` can be true, `Nat :> (?T :> Int)` is false
Constraint::SupertypeOf(sub) => { Constraint::SupertypeOf(sub) => {
self.formal_supertype_of(lhs, sub, bounds, lhs_variance) self.formal_supertype_of(lhs, sub, bounds, lhs_variance)
@ -3386,9 +3413,7 @@ impl Context {
// Int :> {I: Int | ...} == true // Int :> {I: Int | ...} == true
// Real :> {I: Int | ...} == false // Real :> {I: Int | ...} == false
// Int :> {I: Str| ...} == false // Int :> {I: Str| ...} == false
(l, Refinement(r)) => { (l, Refinement(r)) => self.formal_supertype_of(l, &r.t, bounds, lhs_variance),
self.formal_supertype_of(l, &r.t, bounds, lhs_variance)
},
// ({I: Int | True} :> Int) == true, ({N: Nat | ...} :> Int) == false, ({I: Int | I >= 0} :> Int) == false // ({I: Int | True} :> Int) == true, ({N: Nat | ...} :> Int) == false, ({I: Int | I >= 0} :> Int) == false
(Refinement(l), r) => { (Refinement(l), r) => {
if l.preds if l.preds
@ -3991,7 +4016,9 @@ impl Context {
ctxs.sort_by(|(lhs, _), (rhs, _)| { ctxs.sort_by(|(lhs, _), (rhs, _)| {
// HACK: Equal for unrelated types // HACK: Equal for unrelated types
// This doesn't work with [Int, Str, Nat] for example // This doesn't work with [Int, Str, Nat] for example
self.cmp_t(lhs, rhs).try_into().unwrap_or_else(|_| panic!("{lhs}, {rhs}")) // _or(Ordering::Equal) self.cmp_t(lhs, rhs)
.try_into()
.unwrap_or_else(|_| panic!("{lhs}, {rhs}")) // _or(Ordering::Equal)
}); });
ctxs.into_iter().map(|(_, ctx)| ctx) ctxs.into_iter().map(|(_, ctx)| ctx)
} }
@ -4041,14 +4068,8 @@ impl Context {
} }
} }
pub(crate) fn rec_type_ctx_by_name<'a>( pub(crate) fn rec_type_ctx_by_name<'a>(&'a self, t_name: &'a str) -> Option<&'a Context> {
&'a self, if let Some((_, ctx)) = self.types.iter().find(|(t, _ctx)| t.name() == t_name) {
t_name: &'a str,
) -> Option<&'a Context> {
if let Some((_, ctx)) = self.types
.iter()
.find(|(t, _ctx)| t.name() == t_name)
{
return Some(ctx); return Some(ctx);
} }
if let Some(outer) = &self.outer { if let Some(outer) = &self.outer {
@ -4060,11 +4081,13 @@ impl Context {
fn rec_get_const_param_defaults(&self, name: &str) -> Option<&Vec<ConstTemplate>> { fn rec_get_const_param_defaults(&self, name: &str) -> Option<&Vec<ConstTemplate>> {
if let Some(impls) = self.const_param_defaults.get(name) { if let Some(impls) = self.const_param_defaults.get(name) {
return Some(impls) return Some(impls);
} }
if let Some(outer) = &self.outer { if let Some(outer) = &self.outer {
outer.rec_get_const_param_defaults(name) outer.rec_get_const_param_defaults(name)
} else { None } } else {
None
}
} }
// 再帰サブルーチン/型の推論を可能にするため、予め登録しておく // 再帰サブルーチン/型の推論を可能にするため、予め登録しておく

View file

@ -455,7 +455,6 @@ impl TyCheckError {
Self::new(ErrorCore::unreachable(fn_name, line), "".into()) Self::new(ErrorCore::unreachable(fn_name, line), "".into())
} }
pub fn reassign_error(loc: Location, caused_by: Str, name: &str) -> Self { pub fn reassign_error(loc: Location, caused_by: Str, name: &str) -> Self {
let name = readable_name(name); let name = readable_name(name);
Self::new( Self::new(

View file

@ -38,7 +38,13 @@ impl SubstContext {
} }
} }
fn substitute(&self, quant_t: Type, ty_ctx: &Context, level: usize, ctx: &Context) -> TyCheckResult<Type> { fn substitute(
&self,
quant_t: Type,
ty_ctx: &Context,
level: usize,
ctx: &Context,
) -> TyCheckResult<Type> {
let bounds = ty_ctx.type_params_bounds(); let bounds = ty_ctx.type_params_bounds();
let tv_ctx = TyVarContext::new(level, bounds, ctx); let tv_ctx = TyVarContext::new(level, bounds, ctx);
let (inst, _) = Context::instantiate_t(quant_t, tv_ctx); let (inst, _) = Context::instantiate_t(quant_t, tv_ctx);
@ -366,7 +372,10 @@ impl Evaluator {
if let Some(outer) = &ctx.outer { if let Some(outer) = &ctx.outer {
self.eval_t_params(Type::MonoProj { lhs, rhs }, outer, level) self.eval_t_params(Type::MonoProj { lhs, rhs }, outer, level)
} else { } else {
todo!("{lhs}.{rhs} not found in {}", erg_common::fmt_iter(ctx.rec_sorted_type_ctxs(&lhs))) todo!(
"{lhs}.{rhs} not found in {}",
erg_common::fmt_iter(ctx.rec_sorted_type_ctxs(&lhs))
)
} }
} }
Type::Ref(l) => Ok(Type::ref_(self.eval_t_params(*l, ctx, level)?)), Type::Ref(l) => Ok(Type::ref_(self.eval_t_params(*l, ctx, level)?)),

View file

@ -10,7 +10,7 @@ use Type::*;
use erg_parser::ast::VarName; use erg_parser::ast::VarName;
use crate::context::{Context, DefaultInfo, ParamSpec, ConstTemplate}; use crate::context::{ConstTemplate, Context, DefaultInfo, ParamSpec};
use crate::varinfo::{Mutability, VarInfo, VarKind, Visibility}; use crate::varinfo::{Mutability, VarInfo, VarKind, Visibility};
use DefaultInfo::*; use DefaultInfo::*;
use Mutability::*; use Mutability::*;
@ -66,8 +66,10 @@ impl Context {
if let Some(impls) = self.poly_trait_impls.get_mut(impl_trait.name()) { if let Some(impls) = self.poly_trait_impls.get_mut(impl_trait.name()) {
impls.push((t.clone(), impl_trait.clone())); impls.push((t.clone(), impl_trait.clone()));
} else { } else {
self.poly_trait_impls self.poly_trait_impls.insert(
.insert(Str::rc(impl_trait.name()), vec![(t.clone(), impl_trait.clone())]); Str::rc(impl_trait.name()),
vec![(t.clone(), impl_trait.clone())],
);
} }
} }
} }
@ -153,7 +155,10 @@ impl Context {
); );
let self_t = mono_q("Self"); let self_t = mono_q("Self");
let t = fn0_met(self_t.clone(), Nat); let t = fn0_met(self_t.clone(), Nat);
let t = quant(t, set! {subtype(self_t.clone(), poly("Seq", vec![TyParam::erased(Type)]))}); let t = quant(
t,
set! {subtype(self_t.clone(), poly("Seq", vec![TyParam::erased(Type)]))},
);
seq.register_decl("__len__", t, Public); seq.register_decl("__len__", t, Public);
let t = Type::fn1_met(self_t.clone(), Nat, mono_q("T")); let t = Type::fn1_met(self_t.clone(), Nat, mono_q("T"));
let t = quant( let t = quant(
@ -169,43 +174,69 @@ impl Context {
let r_bound = static_instance("R", Type); let r_bound = static_instance("R", Type);
let params = vec![PS::t("R", WithDefault)]; let params = vec![PS::t("R", WithDefault)];
let ty_params = vec![ty_tp(mono_q("R"))]; let ty_params = vec![ty_tp(mono_q("R"))];
let mut add = Self::poly_trait("Add", params.clone(), vec![ let mut add = Self::poly_trait(
poly("Output", vec![ty_tp(mono_q("R"))]), "Add",
], Self::TOP_LEVEL); params.clone(),
let self_bound = subtype( vec![poly("Output", vec![ty_tp(mono_q("R"))])],
mono_q("Self"), Self::TOP_LEVEL,
poly("Add", ty_params.clone()), );
let self_bound = subtype(mono_q("Self"), poly("Add", ty_params.clone()));
let op_t = fn1_met(
poly_q("Self", ty_params.clone()),
r.clone(),
mono_proj(mono_q("Self"), "AddO"),
); );
let op_t = fn1_met(poly_q("Self", ty_params.clone()), r.clone(), mono_proj(mono_q("Self"), "AddO"));
let op_t = quant(op_t, set! {r_bound.clone(), self_bound}); let op_t = quant(op_t, set! {r_bound.clone(), self_bound});
add.register_decl("__add__", op_t, Public); add.register_decl("__add__", op_t, Public);
add.register_decl("AddO", Type, Public); add.register_decl("AddO", Type, Public);
let mut sub = Self::poly_trait("Sub", params.clone(), vec![ let mut sub = Self::poly_trait(
poly("Output", vec![ty_tp(mono_q("R"))]), "Sub",
], Self::TOP_LEVEL); params.clone(),
let self_bound = subtype( vec![poly("Output", vec![ty_tp(mono_q("R"))])],
mono_q("Self"), Self::TOP_LEVEL,
poly("Sub", ty_params.clone()), );
let self_bound = subtype(mono_q("Self"), poly("Sub", ty_params.clone()));
let op_t = fn1_met(
poly_q("Self", ty_params.clone()),
r.clone(),
mono_proj(mono_q("Self"), "SubO"),
); );
let op_t = fn1_met(poly_q("Self", ty_params.clone()), r.clone(), mono_proj(mono_q("Self"), "SubO"));
let op_t = quant(op_t, set! {r_bound.clone(), self_bound}); let op_t = quant(op_t, set! {r_bound.clone(), self_bound});
sub.register_decl("__sub__", op_t, Public); sub.register_decl("__sub__", op_t, Public);
sub.register_decl("SubO", Type, Public); sub.register_decl("SubO", Type, Public);
let mut mul = Self::poly_trait("Mul", params.clone(), vec![ let mut mul = Self::poly_trait(
poly("Output", vec![ty_tp(mono_q("R"))]), "Mul",
], Self::TOP_LEVEL); params.clone(),
let op_t = fn1_met(poly("Mul", ty_params.clone()), r.clone(), mono_proj(mono_q("Self"), "MulO")); vec![poly("Output", vec![ty_tp(mono_q("R"))])],
Self::TOP_LEVEL,
);
let op_t = fn1_met(
poly("Mul", ty_params.clone()),
r.clone(),
mono_proj(mono_q("Self"), "MulO"),
);
mul.register_decl("__mul__", op_t, Public); mul.register_decl("__mul__", op_t, Public);
mul.register_decl("MulO", Type, Public); mul.register_decl("MulO", Type, Public);
let mut div = Self::poly_trait("Div", params.clone(), vec![ let mut div = Self::poly_trait(
poly("Output", vec![ty_tp(mono_q("R"))]), "Div",
], Self::TOP_LEVEL); params.clone(),
let op_t = fn1_met(poly("Div", ty_params.clone()), r, mono_proj(mono_q("Self"), "DivO")); vec![poly("Output", vec![ty_tp(mono_q("R"))])],
Self::TOP_LEVEL,
);
let op_t = fn1_met(
poly("Div", ty_params.clone()),
r,
mono_proj(mono_q("Self"), "DivO"),
);
div.register_decl("__div__", op_t, Public); div.register_decl("__div__", op_t, Public);
div.register_decl("DivO", Type, Public); div.register_decl("DivO", Type, Public);
self.register_type(mono("Named"), named, Const); self.register_type(mono("Named"), named, Const);
self.register_type(poly("Eq", vec![ty_tp(mono_q("R"))]), eq, Const); self.register_type(poly("Eq", vec![ty_tp(mono_q("R"))]), eq, Const);
self.register_type(poly("PartialOrd", vec![ty_tp(mono_q("R"))]), partial_ord, Const); self.register_type(
poly("PartialOrd", vec![ty_tp(mono_q("R"))]),
partial_ord,
Const,
);
self.register_type(mono("Ord"), ord, Const); self.register_type(mono("Ord"), ord, Const);
self.register_type(poly("Seq", vec![ty_tp(mono_q("T"))]), seq, Const); self.register_type(poly("Seq", vec![ty_tp(mono_q("T"))]), seq, Const);
self.register_type(poly("Input", vec![ty_tp(mono_q("T"))]), input, Const); self.register_type(poly("Input", vec![ty_tp(mono_q("T"))]), input, Const);
@ -215,12 +246,30 @@ impl Context {
self.register_type(poly("Mul", ty_params.clone()), mul, Const); self.register_type(poly("Mul", ty_params.clone()), mul, Const);
self.register_type(poly("Div", ty_params), div, Const); self.register_type(poly("Div", ty_params), div, Const);
// self.register_type(mono("Num"), num, Const); // self.register_type(mono("Num"), num, Const);
self.register_const_param_defaults("Eq", vec![ConstTemplate::Obj(ConstObj::t(mono_q("Self")))]); self.register_const_param_defaults(
self.register_const_param_defaults("PartialOrd", vec![ConstTemplate::app("Self", vec![], vec![])]); "Eq",
self.register_const_param_defaults("Add", vec![ConstTemplate::Obj(ConstObj::t(mono_q("Self")))]); vec![ConstTemplate::Obj(ConstObj::t(mono_q("Self")))],
self.register_const_param_defaults("Sub", vec![ConstTemplate::Obj(ConstObj::t(mono_q("Self")))]); );
self.register_const_param_defaults("Mul", vec![ConstTemplate::Obj(ConstObj::t(mono_q("Self")))]); self.register_const_param_defaults(
self.register_const_param_defaults("Div", vec![ConstTemplate::Obj(ConstObj::t(mono_q("Self")))]); "PartialOrd",
vec![ConstTemplate::app("Self", vec![], vec![])],
);
self.register_const_param_defaults(
"Add",
vec![ConstTemplate::Obj(ConstObj::t(mono_q("Self")))],
);
self.register_const_param_defaults(
"Sub",
vec![ConstTemplate::Obj(ConstObj::t(mono_q("Self")))],
);
self.register_const_param_defaults(
"Mul",
vec![ConstTemplate::Obj(ConstObj::t(mono_q("Self")))],
);
self.register_const_param_defaults(
"Div",
vec![ConstTemplate::Obj(ConstObj::t(mono_q("Self")))],
);
} }
fn init_builtin_classes(&mut self) { fn init_builtin_classes(&mut self) {
@ -394,7 +443,7 @@ impl Context {
mono("Mutate"), mono("Mutate"),
poly("Seq", vec![ty_tp(Str)]), poly("Seq", vec![ty_tp(Str)]),
poly("Add", vec![ty_tp(Str)]), poly("Add", vec![ty_tp(Str)]),
poly("Mul", vec![ty_tp(Nat)]) poly("Mul", vec![ty_tp(Nat)]),
], ],
Self::TOP_LEVEL, Self::TOP_LEVEL,
); );
@ -417,7 +466,13 @@ impl Context {
vec![PS::t_nd("T"), PS::named_nd("N", Nat)], vec![PS::t_nd("T"), PS::named_nd("N", Nat)],
vec![Obj], vec![Obj],
vec![ vec![
poly("Eq", vec![ty_tp(Type::poly("Array", vec![ty_tp(mono_q("T")), mono_q_tp("N")]))]), poly(
"Eq",
vec![ty_tp(Type::poly(
"Array",
vec![ty_tp(mono_q("T")), mono_q_tp("N")],
))],
),
mono("Mutate"), mono("Mutate"),
poly("Seq", vec![ty_tp(mono_q("T"))]), poly("Seq", vec![ty_tp(mono_q("T"))]),
poly("Output", vec![ty_tp(mono_q("T"))]), poly("Output", vec![ty_tp(mono_q("T"))]),
@ -447,10 +502,7 @@ impl Context {
let mut type_ = Self::mono_class( let mut type_ = Self::mono_class(
"Type", "Type",
vec![Obj], vec![Obj],
vec![ vec![poly("Eq", vec![ty_tp(Type)]), mono("Named")],
poly("Eq", vec![ty_tp(Type)]),
mono("Named")
],
Self::TOP_LEVEL, Self::TOP_LEVEL,
); );
type_.register_impl( type_.register_impl(
@ -462,10 +514,7 @@ impl Context {
let module = Self::mono_class( let module = Self::mono_class(
"Module", "Module",
vec![Obj], vec![Obj],
vec![ vec![poly("Eq", vec![ty_tp(Module)]), mono("Named")],
poly("Eq", vec![ty_tp(Module)]),
mono("Named")
],
Self::TOP_LEVEL, Self::TOP_LEVEL,
); );
let array_mut_t = Type::poly("Array!", vec![ty_tp(mono_q("T")), mono_q_tp("N")]); let array_mut_t = Type::poly("Array!", vec![ty_tp(mono_q("T")), mono_q_tp("N")]);
@ -473,10 +522,7 @@ impl Context {
"Array!", "Array!",
vec![PS::t_nd("T"), PS::named_nd("N", NatMut)], vec![PS::t_nd("T"), PS::named_nd("N", NatMut)],
vec![poly("Range", vec![ty_tp(mono_q("T")), mono_q_tp("N")]), Obj], vec![poly("Range", vec![ty_tp(mono_q("T")), mono_q_tp("N")]), Obj],
vec![ vec![mono("Mutate"), poly("Seq", vec![ty_tp(mono_q("T"))])],
mono("Mutate"),
poly("Seq", vec![ty_tp(mono_q("T"))]),
],
Self::TOP_LEVEL, Self::TOP_LEVEL,
); );
let t = Type::pr_met( let t = Type::pr_met(
@ -500,7 +546,10 @@ impl Context {
vec![PS::t_nd("T")], vec![PS::t_nd("T")],
vec![Obj], vec![Obj],
vec![ vec![
poly("Eq", vec![ty_tp(Type::poly("Range", vec![ty_tp(mono_q("T"))]))]), poly(
"Eq",
vec![ty_tp(Type::poly("Range", vec![ty_tp(mono_q("T"))]))],
),
mono("Mutate"), mono("Mutate"),
poly("Seq", vec![ty_tp(mono_q("T"))]), poly("Seq", vec![ty_tp(mono_q("T"))]),
poly("Output", vec![ty_tp(mono_q("T"))]), poly("Output", vec![ty_tp(mono_q("T"))]),
@ -635,16 +684,22 @@ impl Context {
); );
self.register_impl("__sub__", op_t, Const, Private); self.register_impl("__sub__", op_t, Const, Private);
let op_t = Type::func2(l.clone(), r.clone(), mono_proj(mono_q("L"), "MulO")); let op_t = Type::func2(l.clone(), r.clone(), mono_proj(mono_q("L"), "MulO"));
let op_t = quant(op_t, set! { let op_t = quant(
static_instance("R", Type), op_t,
subtype(l.clone(), poly("Mul", params.clone())) set! {
}); static_instance("R", Type),
subtype(l.clone(), poly("Mul", params.clone()))
},
);
self.register_impl("__mul__", op_t, Const, Private); self.register_impl("__mul__", op_t, Const, Private);
let op_t = Type::func2(l.clone(), r.clone(), mono_proj(mono_q("L"), "DivO")); let op_t = Type::func2(l.clone(), r.clone(), mono_proj(mono_q("L"), "DivO"));
let op_t = quant(op_t, set! { let op_t = quant(
static_instance("R", Type), op_t,
subtype(l, poly("Mul", params.clone())) set! {
}); static_instance("R", Type),
subtype(l, poly("Mul", params.clone()))
},
);
self.register_impl("__div__", op_t, Const, Private); self.register_impl("__div__", op_t, Const, Private);
let m = mono_q("M"); let m = mono_q("M");
let op_t = Type::func2(m.clone(), m.clone(), m.clone()); let op_t = Type::func2(m.clone(), m.clone(), m.clone());
@ -705,14 +760,8 @@ impl Context {
params, params,
vec![Type::from(&m..=&n)], vec![Type::from(&m..=&n)],
vec![ vec![
poly( poly("Add", vec![TyParam::from(&o..=&p)]),
"Add", poly("Sub", vec![TyParam::from(&o..=&p)]),
vec![TyParam::from(&o..=&p)],
),
poly(
"Sub",
vec![TyParam::from(&o..=&p)],
),
], ],
Self::TOP_LEVEL, Self::TOP_LEVEL,
); );
@ -728,7 +777,10 @@ impl Context {
Type::from(m.clone() - p.clone()..=n.clone() - o.clone()), Type::from(m.clone() - p.clone()..=n.clone() - o.clone()),
); );
interval.register_impl("__sub__", op_t, Const, Public); interval.register_impl("__sub__", op_t, Const, Public);
interval.register_const("AddO", ConstObj::t(Type::from(m.clone() + o.clone()..=n.clone() + p.clone()))); interval.register_const(
"AddO",
ConstObj::t(Type::from(m.clone() + o.clone()..=n.clone() + p.clone())),
);
interval.register_const("SubO", ConstObj::t(Type::from(m - p..=n - o))); interval.register_const("SubO", ConstObj::t(Type::from(m - p..=n - o)));
self.register_patch("Interval", interval, Const); self.register_patch("Interval", interval, Const);
// eq.register_impl("__ne__", op_t, Const, Public); // eq.register_impl("__ne__", op_t, Const, Public);

View file

@ -171,12 +171,9 @@ impl ASTLowerer {
)); ));
} }
let obj = self.lower_expr(*call.obj, false)?; let obj = self.lower_expr(*call.obj, false)?;
let t = self.ctx.get_call_t( let t = self
&obj, .ctx
&hir_args.pos_args, .get_call_t(&obj, &hir_args.pos_args, &hir_args.kw_args, &self.ctx.name)?;
&hir_args.kw_args,
&self.ctx.name,
)?;
Ok(hir::Call::new(obj, hir_args, t)) Ok(hir::Call::new(obj, hir_args, t))
} }

View file

@ -36,9 +36,11 @@ impl Runnable for DummyVM {
loop { loop {
match TcpStream::connect(&addr) { match TcpStream::connect(&addr) {
Ok(stream) => { Ok(stream) => {
stream.set_read_timeout(Some(Duration::from_secs(cfg.py_server_timeout))).unwrap(); stream
break Some(stream) .set_read_timeout(Some(Duration::from_secs(cfg.py_server_timeout)))
}, .unwrap();
break Some(stream);
}
Err(_) => { Err(_) => {
println!("Retrying to connect to the REPL server..."); println!("Retrying to connect to the REPL server...");
sleep(Duration::from_millis(500)); sleep(Duration::from_millis(500));
@ -46,7 +48,9 @@ impl Runnable for DummyVM {
} }
} }
} }
} else { None }; } else {
None
};
Self { Self {
compiler: Compiler::new(cfg.copy()), compiler: Compiler::new(cfg.copy()),
cfg, cfg,
@ -115,7 +119,7 @@ impl Runnable for DummyVM {
Result::Err(e) => { Result::Err(e) => {
self.finish(); self.finish();
panic!("{}", format!("Sending error: {e}")) panic!("{}", format!("Sending error: {e}"))
}, }
}; };
if res.ends_with("None") { if res.ends_with("None") {
res.truncate(res.len() - 5); res.truncate(res.len() - 5);