Cargo fmt

This commit is contained in:
Shunsuke Shibayama 2022-08-14 01:45:15 +09:00
parent fe8c7ff95a
commit 1c3a3a7d0b
13 changed files with 236 additions and 159 deletions

View file

@ -107,8 +107,8 @@ impl Deserializer {
eprintln!("{:?} is not a filename", cfg.input); eprintln!("{:?} is not a filename", cfg.input);
process::exit(1); process::exit(1);
}; };
let codeobj = let codeobj = CodeObj::from_pyc(&filename[..])
CodeObj::from_pyc(&filename[..]).unwrap_or_else(|_| panic!("failed to deserialize {filename}")); .unwrap_or_else(|_| panic!("failed to deserialize {filename}"));
println!("{}", codeobj.code_info()); println!("{}", codeobj.code_info());
} }

View file

@ -345,7 +345,9 @@ pub trait Runnable: Sized {
let output = stdout(); let output = stdout();
let mut output = BufWriter::new(output.lock()); let mut output = BufWriter::new(output.lock());
log!(f output, "{GREEN}[DEBUG] The REPL has started.{RESET}\n"); log!(f output, "{GREEN}[DEBUG] The REPL has started.{RESET}\n");
output.write_all(instance.start_message().as_bytes()).unwrap(); output
.write_all(instance.start_message().as_bytes())
.unwrap();
output.write_all(instance.ps1().as_bytes()).unwrap(); output.write_all(instance.ps1().as_bytes()).unwrap();
output.flush().unwrap(); output.flush().unwrap();
let mut lines = String::new(); let mut lines = String::new();

View file

@ -14,7 +14,7 @@ use crate::set::Set;
use crate::traits::HasType; use crate::traits::HasType;
use crate::ty::ValueObj::{Inf, NegInf}; use crate::ty::ValueObj::{Inf, NegInf};
use crate::value::ValueObj; use crate::value::ValueObj;
use crate::{fmt_set_split_with, fmt_vec, fmt_vec_split_with, set, Str, enum_unwrap}; use crate::{enum_unwrap, fmt_set_split_with, fmt_vec, fmt_vec_split_with, set, Str};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(u8)] #[repr(u8)]
@ -290,10 +290,7 @@ impl<T: Clone + HasLevel> Free<T> {
} }
pub fn type_of(&self) -> Option<Type> { pub fn type_of(&self) -> Option<Type> {
self.0 self.0.borrow().constraint().and_then(|c| c.typ().cloned())
.borrow()
.constraint()
.and_then(|c| c.typ().cloned())
} }
pub fn subtype_of(&self) -> Option<Type> { pub fn subtype_of(&self) -> Option<Type> {
@ -1813,16 +1810,13 @@ impl HasType for Type {
fn inner_ts(&self) -> Vec<Type> { fn inner_ts(&self) -> Vec<Type> {
match self { match self {
Self::Dict { k, v } => vec![k.as_ref().clone(), v.as_ref().clone()], Self::Dict { k, v } => vec![k.as_ref().clone(), v.as_ref().clone()],
Self::Ref(t) Self::Ref(t) | Self::RefMut(t) | Self::Array { t, .. } | Self::VarArgs(t) => {
| Self::RefMut(t) vec![t.as_ref().clone()]
| Self::Array { t, .. } }
| Self::VarArgs(t) => vec![t.as_ref().clone()],
// Self::And(ts) | Self::Or(ts) => , // Self::And(ts) | Self::Or(ts) => ,
Self::Subr(_sub) => todo!(), Self::Subr(_sub) => todo!(),
Self::Callable { param_ts, .. } | Self::Tuple(param_ts) => param_ts.clone(), Self::Callable { param_ts, .. } | Self::Tuple(param_ts) => param_ts.clone(),
Self::Poly { params, .. } => { Self::Poly { params, .. } => params.iter().filter_map(get_t_from_tp).collect(),
params.iter().filter_map(get_t_from_tp).collect()
}
_ => vec![], _ => vec![],
} }
} }
@ -1843,10 +1837,9 @@ impl HasLevel for Type {
fn update_level(&self, level: Level) { fn update_level(&self, level: Level) {
match self { match self {
Self::FreeVar(v) => v.update_level(level), Self::FreeVar(v) => v.update_level(level),
Self::Ref(t) Self::Ref(t) | Self::RefMut(t) | Self::Array { t, .. } | Self::VarArgs(t) => {
| Self::RefMut(t) t.update_level(level)
| Self::Array { t, .. } }
| Self::VarArgs(t) => t.update_level(level),
Self::Callable { param_ts, return_t } => { Self::Callable { param_ts, return_t } => {
for p in param_ts.iter() { for p in param_ts.iter() {
p.update_level(level); p.update_level(level);
@ -1905,10 +1898,7 @@ impl HasLevel for Type {
fn lift(&self) { fn lift(&self) {
match self { match self {
Self::FreeVar(v) => v.lift(), Self::FreeVar(v) => v.lift(),
Self::Ref(t) Self::Ref(t) | Self::RefMut(t) | Self::Array { t, .. } | Self::VarArgs(t) => t.lift(),
| Self::RefMut(t)
| Self::Array { t, .. }
| Self::VarArgs(t) => t.lift(),
Self::Callable { param_ts, return_t } => { Self::Callable { param_ts, return_t } => {
for p in param_ts.iter() { for p in param_ts.iter() {
p.lift(); p.lift();
@ -2385,10 +2375,10 @@ impl Type {
pub fn is_nonelike(&self) -> bool { pub fn is_nonelike(&self) -> bool {
match self { match self {
Self::NoneType => true, Self::NoneType => true,
Self::Poly{ name, params } if &name[..] == "Option" || &name[..] == "Option!" => { Self::Poly { name, params } if &name[..] == "Option" || &name[..] == "Option!" => {
let inner_t = enum_unwrap!(params.first().unwrap(), TyParam::Type); let inner_t = enum_unwrap!(params.first().unwrap(), TyParam::Type);
inner_t.is_nonelike() inner_t.is_nonelike()
}, }
Self::Tuple(ts) => ts.len() == 0, Self::Tuple(ts) => ts.len() == 0,
_ => false, _ => false,
} }
@ -2438,8 +2428,7 @@ impl Type {
FreeKind::Linked(t) => t.rec_eq(other), FreeKind::Linked(t) => t.rec_eq(other),
_ => self == other, _ => self == other,
}, },
| (Self::Ref(l), Self::Ref(r)) (Self::Ref(l), Self::Ref(r)) | (Self::RefMut(l), Self::RefMut(r)) => l.rec_eq(r),
| (Self::RefMut(l), Self::RefMut(r)) => l.rec_eq(r),
(Self::Subr(l), Self::Subr(r)) => { (Self::Subr(l), Self::Subr(r)) => {
match (&l.kind, &r.kind) { match (&l.kind, &r.kind) {
(SubrKind::Func, SubrKind::Func) | (SubrKind::Proc, SubrKind::Proc) => {} (SubrKind::Func, SubrKind::Func) | (SubrKind::Proc, SubrKind::Proc) => {}
@ -2652,9 +2641,7 @@ impl Type {
fv.crack().has_unbound_var() fv.crack().has_unbound_var()
} }
} }
| Self::Ref(t) Self::Ref(t) | Self::RefMut(t) | Self::VarArgs(t) => t.has_unbound_var(),
| Self::RefMut(t)
| Self::VarArgs(t) => t.has_unbound_var(),
Self::And(param_ts) | Self::Not(param_ts) | Self::Or(param_ts) => { Self::And(param_ts) | Self::Not(param_ts) | Self::Or(param_ts) => {
param_ts.iter().any(|t| t.has_unbound_var()) param_ts.iter().any(|t| t.has_unbound_var())
} }
@ -2714,8 +2701,7 @@ impl Type {
match self { match self {
Self::FreeVar(f) if f.is_linked() => f.crack().typarams(), Self::FreeVar(f) if f.is_linked() => f.crack().typarams(),
Self::FreeVar(_unbound) => todo!(), Self::FreeVar(_unbound) => todo!(),
| Self::Ref(t) Self::Ref(t) | Self::RefMut(t) => vec![TyParam::t(*t.clone())],
| Self::RefMut(t) => vec![TyParam::t(*t.clone())],
Self::Array { t, len } => vec![TyParam::t(*t.clone()), len.clone()], Self::Array { t, len } => vec![TyParam::t(*t.clone()), len.clone()],
Self::Dict { k, v } => vec![TyParam::t(*k.clone()), TyParam::t(*v.clone())], Self::Dict { k, v } => vec![TyParam::t(*k.clone()), TyParam::t(*v.clone())],
Self::And(param_ts) Self::And(param_ts)

View file

@ -27,8 +27,8 @@ use Type::*;
use ValueObj::{Inf, NegInf}; use ValueObj::{Inf, NegInf};
use ast::{ use ast::{
DefId, ParamSignature, ParamTySpec, PreDeclTypeSpec, SimpleTypeSpec, TypeBoundSpec, TypeBoundSpecs, DefId, ParamSignature, ParamTySpec, PreDeclTypeSpec, SimpleTypeSpec, TypeBoundSpec,
TypeSpec, VarName, TypeBoundSpecs, TypeSpec, VarName,
}; };
use erg_parser::ast; use erg_parser::ast;
use erg_parser::token::{Token, TokenKind}; use erg_parser::token::{Token, TokenKind};
@ -269,8 +269,10 @@ impl TyVarContext {
} else { } else {
panic!("Type variable {n} is not found. This is a bug.") panic!("Type variable {n} is not found. This is a bug.")
} }
} else { todo!("{t}") } } else {
}, todo!("{t}")
}
}
TyParam::UnaryOp { op, val } => { TyParam::UnaryOp { op, val } => {
let res = self.instantiate_tp(*val); let res = self.instantiate_tp(*val);
TyParam::unary(op, res) TyParam::unary(op, res)
@ -582,10 +584,14 @@ impl Context {
self.name.clone() self.name.clone()
} }
fn registered(&self, name: &Str, recursive: bool) -> bool fn registered(&self, name: &Str, recursive: bool) -> bool {
{ if self.params.iter().any(|(maybe_name, _)| {
if self.params.iter().any(|(maybe_name, _)| maybe_name.as_ref().map(|n| n.inspect() == name).unwrap_or(false)) maybe_name
|| self.locals.contains_key(name) { .as_ref()
.map(|n| n.inspect() == name)
.unwrap_or(false)
}) || self.locals.contains_key(name)
{
return true; return true;
} }
if recursive { if recursive {
@ -771,11 +777,21 @@ impl Context {
} else { } else {
// ok, not defined // ok, not defined
let spec_t = self.instantiate_param_sig_t(sig, opt_decl_t, Normal)?; let spec_t = self.instantiate_param_sig_t(sig, opt_decl_t, Normal)?;
let idx = if let Some(outer) = outer { ParamIdx::nested(outer, nth) } else { ParamIdx::Nth(nth) }; let idx = if let Some(outer) = outer {
let default = if sig.opt_default_val.is_some() { DefaultInfo::WithDefault } else { DefaultInfo::NonDefault }; ParamIdx::nested(outer, nth)
} else {
ParamIdx::Nth(nth)
};
let default = if sig.opt_default_val.is_some() {
DefaultInfo::WithDefault
} else {
DefaultInfo::NonDefault
};
let kind = VarKind::parameter(DefId(get_hash(&(&self.name, v))), idx, default); let kind = VarKind::parameter(DefId(get_hash(&(&self.name, v))), idx, default);
self.params self.params.push((
.push((Some(v.clone()), VarInfo::new(spec_t, Immutable, Private, kind))); Some(v.clone()),
VarInfo::new(spec_t, Immutable, Private, kind),
));
Ok(()) Ok(())
} }
} }
@ -836,14 +852,19 @@ impl Context {
params params
.defaults .defaults
.iter() .iter()
.zip(decl_subr_t.default_params.iter()) .zip(decl_subr_t.default_params.iter()),
) )
.enumerate() .enumerate()
{ {
self.assign_param(sig, None, nth, Some(pt))?; self.assign_param(sig, None, nth, Some(pt))?;
} }
} else { } else {
for (nth, sig) in params.non_defaults.iter().chain(params.defaults.iter()).enumerate() { for (nth, sig) in params
.non_defaults
.iter()
.chain(params.defaults.iter())
.enumerate()
{
self.assign_param(sig, None, nth, None)?; self.assign_param(sig, None, nth, None)?;
} }
} }
@ -1165,7 +1186,9 @@ impl Context {
self.params self.params
.iter() .iter()
.filter(|(opt_name, vi)| vi.kind.is_parameter() && opt_name.is_some()) .filter(|(opt_name, vi)| vi.kind.is_parameter() && opt_name.is_some())
.map(|(name, vi)| TyBound::instance(name.as_ref().unwrap().inspect().clone(), vi.t.clone())) .map(|(name, vi)| {
TyBound::instance(name.as_ref().unwrap().inspect().clone(), vi.t.clone())
})
.collect() .collect()
} }
@ -1181,16 +1204,22 @@ impl Context {
if let Some(name) = opt_name { if let Some(name) = opt_name {
if let Some(t) = self.super_traits.iter().find(|t| { if let Some(t) = self.super_traits.iter().find(|t| {
(t.name() == "Input" || t.name() == "Output") (t.name() == "Input" || t.name() == "Output")
&& t.inner_ts().first().map(|t| t.name() == &name.inspect()[..]).unwrap_or(false) && t.inner_ts()
.first()
.map(|t| t.name() == &name.inspect()[..])
.unwrap_or(false)
}) { }) {
match t.name() { match t.name() {
"Output" => Variance::Covariant, "Output" => Variance::Covariant,
"Input" => Variance::Contravariant, "Input" => Variance::Contravariant,
_ => unreachable!(), _ => unreachable!(),
} }
} else { Variance::Invariant } } else {
Variance::Invariant
}
} else {
Variance::Invariant
} }
else { Variance::Invariant }
}) })
.collect() .collect()
} }
@ -1351,7 +1380,8 @@ impl Context {
self.unify(l, r, None, Some(callee.loc()))?; self.unify(l, r, None, Some(callee.loc()))?;
} }
// if callee is a Module object or some named one // if callee is a Module object or some named one
(None, Some(r)) if self.rec_full_subtype_of(r, &Type::mono("Named")) => {} (None, Some(r))
if self.rec_full_subtype_of(r, &Type::mono("Named")) => {}
(None, None) => {} (None, None) => {}
(l, r) => todo!("{l:?}, {r:?}"), (l, r) => todo!("{l:?}, {r:?}"),
} }
@ -1510,8 +1540,7 @@ impl Context {
for param in params { for param in params {
param.ty = Self::deref_tyvar(mem::take(&mut param.ty))?; param.ty = Self::deref_tyvar(mem::take(&mut param.ty))?;
} }
subr.return_t = subr.return_t = Box::new(Self::deref_tyvar(mem::take(&mut subr.return_t))?);
Box::new(Self::deref_tyvar(mem::take(&mut subr.return_t))?);
Ok(Type::Subr(subr)) Ok(Type::Subr(subr))
} }
t => Ok(t), t => Ok(t),
@ -1566,7 +1595,9 @@ impl Context {
} }
(TyParam::FreeVar(fv), tp) | (tp, TyParam::FreeVar(fv)) => { (TyParam::FreeVar(fv), tp) | (tp, TyParam::FreeVar(fv)) => {
match &*fv.borrow() { match &*fv.borrow() {
FreeKind::Linked(l) => return self.unify_tp(l, tp, bounds, lhs_variance, allow_divergence), FreeKind::Linked(l) => {
return self.unify_tp(l, tp, bounds, lhs_variance, allow_divergence)
}
FreeKind::Unbound { .. } | FreeKind::NamedUnbound { .. } => {} FreeKind::Unbound { .. } | FreeKind::NamedUnbound { .. } => {}
} // &fv is dropped } // &fv is dropped
let fv_t = fv.borrow().constraint().unwrap().typ().unwrap().clone(); // fvを参照しないよいにcloneする(あとでborrow_mutするため) let fv_t = fv.borrow().constraint().unwrap().typ().unwrap().clone(); // fvを参照しないよいにcloneする(あとでborrow_mutするため)
@ -1803,7 +1834,8 @@ impl Context {
} }
(Type::Refinement(l), Type::Refinement(r)) => { (Type::Refinement(l), Type::Refinement(r)) => {
if !self.formal_supertype_of(&l.t, &r.t, None, None) if !self.formal_supertype_of(&l.t, &r.t, None, None)
&& !self.formal_supertype_of(&r.t, &l.t, None, None) { && !self.formal_supertype_of(&r.t, &l.t, None, None)
{
return Err(TyCheckError::unification_error( return Err(TyCheckError::unification_error(
lhs_t, lhs_t,
rhs_t, rhs_t,
@ -1841,7 +1873,7 @@ impl Context {
} }
self.unify(&ls.return_t, &rs.return_t, lhs_loc, rhs_loc) self.unify(&ls.return_t, &rs.return_t, lhs_loc, rhs_loc)
} }
| (Type::Ref(l), Type::Ref(r)) (Type::Ref(l), Type::Ref(r))
| (Type::RefMut(l), Type::RefMut(r)) | (Type::RefMut(l), Type::RefMut(r))
| (VarArgs(l), VarArgs(r)) => self.unify(l, r, lhs_loc, rhs_loc), | (VarArgs(l), VarArgs(r)) => self.unify(l, r, lhs_loc, rhs_loc),
// REVIEW: // REVIEW:
@ -1901,7 +1933,7 @@ impl Context {
(l, Type::FreeVar(fv)) if fv.is_linked() => { (l, Type::FreeVar(fv)) if fv.is_linked() => {
self.reunify(l, &fv.crack(), bef_loc, aft_loc) self.reunify(l, &fv.crack(), bef_loc, aft_loc)
} }
| (Type::Ref(l), Type::Ref(r)) (Type::Ref(l), Type::Ref(r))
| (Type::RefMut(l), Type::RefMut(r)) | (Type::RefMut(l), Type::RefMut(r))
| (Type::VarArgs(l), Type::VarArgs(r)) => self.reunify(l, r, bef_loc, aft_loc), | (Type::VarArgs(l), Type::VarArgs(r)) => self.reunify(l, r, bef_loc, aft_loc),
// REVIEW: // REVIEW:
@ -1995,7 +2027,9 @@ impl Context {
} }
// sub_unify(Nat, (Ratio :> ?T :> Int)): (/* OK */) // sub_unify(Nat, (Ratio :> ?T :> Int)): (/* OK */)
// sub_unify(Int, (Ratio :> ?T :> Nat)): (Ratio :> ?T :> Int) // sub_unify(Int, (Ratio :> ?T :> Nat)): (Ratio :> ?T :> Int)
Constraint::Sandwiched { sub, sup } if self.rec_full_supertype_of(l, sub) => { Constraint::Sandwiched { sub, sup }
if self.rec_full_supertype_of(l, sub) =>
{
*constraint = Constraint::Sandwiched { *constraint = Constraint::Sandwiched {
sub: l.clone(), sub: l.clone(),
sup: mem::take(sup), sup: mem::take(sup),
@ -2417,9 +2451,14 @@ impl Context {
.or_else(|| { .or_else(|| {
self.params self.params
.iter() .iter()
.find(|(opt_name, _)| opt_name.as_ref().map(|n| &n.inspect()[..] == name).unwrap_or(false)) .find(|(opt_name, _)| {
opt_name
.as_ref()
.map(|n| &n.inspect()[..] == name)
.unwrap_or(false)
})
.map(|(_, vi)| vi) .map(|(_, vi)| vi)
}) })
} }
fn get_context( fn get_context(
@ -2532,8 +2571,7 @@ impl Context {
} }
pub(crate) fn get_var_t(&self, name: &Token, namespace: &Str) -> TyCheckResult<Type> { pub(crate) fn get_var_t(&self, name: &Token, namespace: &Str) -> TyCheckResult<Type> {
if let Some(vi) = self.get_current_scope_var(&name.inspect()[..]) if let Some(vi) = self.get_current_scope_var(&name.inspect()[..]) {
{
Ok(vi.t()) Ok(vi.t())
} else { } else {
if let Some(parent) = self.outer.as_ref() { if let Some(parent) = self.outer.as_ref() {
@ -2683,13 +2721,16 @@ impl Context {
lhs_variance: Option<&Vec<Variance>>, lhs_variance: Option<&Vec<Variance>>,
) -> bool { ) -> bool {
match (lhs, rhs) { match (lhs, rhs) {
(TyParam::Type(lhs), TyParam::Type(rhs)) => return self.same_type_of(lhs, rhs, bounds, lhs_variance), (TyParam::Type(lhs), TyParam::Type(rhs)) => {
return self.same_type_of(lhs, rhs, bounds, lhs_variance)
}
(TyParam::Mono(l), TyParam::Mono(r)) => { (TyParam::Mono(l), TyParam::Mono(r)) => {
if let (Some((l, _)), Some((r, _))) = ( if let (Some((l, _)), Some((r, _))) = (
self.types.iter().find(|(t, _)| t.name() == &l[..]), self.types.iter().find(|(t, _)| t.name() == &l[..]),
self.types.iter().find(|(t, _)| t.name() == &r[..]), self.types.iter().find(|(t, _)| t.name() == &r[..]),
) { ) {
return self.formal_supertype_of(l, r, bounds, None) || self.subtype_of(l, r, bounds, lhs_variance); return self.formal_supertype_of(l, r, bounds, None)
|| self.subtype_of(l, r, bounds, lhs_variance);
} }
} }
(TyParam::MonoQVar(name), other) | (other, TyParam::MonoQVar(name)) => { (TyParam::MonoQVar(name), other) | (other, TyParam::MonoQVar(name)) => {
@ -2865,10 +2906,12 @@ impl Context {
.all(|(l, r)| self.subtype_of(&l.ty, &r.ty, bounds, lhs_variance)) .all(|(l, r)| self.subtype_of(&l.ty, &r.ty, bounds, lhs_variance))
&& ls.default_params.iter() && ls.default_params.iter()
.zip(rs.default_params.iter()) .zip(rs.default_params.iter())
.all(|(l, r)| self.subtype_of(&l.ty, &r.ty, bounds, lhs_variance)) // contravariant .all(|(l, r)| self.subtype_of(&l.ty, &r.ty, bounds, lhs_variance))
// contravariant
} }
(Type::Array { t: lhs, len: llen }, Type::Array { t: rhs, len: rlen }) => { (Type::Array { t: lhs, len: llen }, Type::Array { t: rhs, len: rlen }) => {
self.eq_tp(llen, rlen, bounds, lhs_variance) && self.formal_supertype_of(lhs, rhs, bounds, lhs_variance) self.eq_tp(llen, rlen, bounds, lhs_variance)
&& self.formal_supertype_of(lhs, rhs, bounds, lhs_variance)
} }
(Tuple(lhs), Tuple(rhs)) => { (Tuple(lhs), Tuple(rhs)) => {
lhs.len() == rhs.len() lhs.len() == rhs.len()
@ -2878,8 +2921,9 @@ impl Context {
.all(|(l, r)| self.formal_supertype_of(l, r, bounds, lhs_variance)) .all(|(l, r)| self.formal_supertype_of(l, r, bounds, lhs_variance))
} }
// RefMut, OptionMut are invariant // RefMut, OptionMut are invariant
| (Ref(lhs), Ref(rhs)) (Ref(lhs), Ref(rhs)) | (VarArgs(lhs), VarArgs(rhs)) => {
| (VarArgs(lhs), VarArgs(rhs)) => self.formal_supertype_of(lhs, rhs, bounds, lhs_variance), self.formal_supertype_of(lhs, rhs, bounds, lhs_variance)
}
// true if it can be a supertype, false if it cannot (due to type constraints) // true if it can be a supertype, false if it cannot (due to type constraints)
// No type constraints are imposed here, as subsequent type decisions are made according to the possibilities // No type constraints are imposed here, as subsequent type decisions are made according to the possibilities
(FreeVar(v), rhs) => { (FreeVar(v), rhs) => {
@ -2888,11 +2932,15 @@ impl Context {
FreeKind::Unbound { constraint, .. } FreeKind::Unbound { constraint, .. }
| FreeKind::NamedUnbound { constraint, .. } => match constraint { | FreeKind::NamedUnbound { constraint, .. } => match constraint {
// `(?T <: Int) :> Nat` can be true, `(?T <: Nat) :> Int` is false // `(?T <: Int) :> Nat` can be true, `(?T <: Nat) :> Int` is false
Constraint::SubtypeOf(sup) => self.formal_supertype_of(sup, rhs, bounds, lhs_variance), Constraint::SubtypeOf(sup) => {
self.formal_supertype_of(sup, rhs, bounds, lhs_variance)
}
// `(?T :> X) :> Y` is true, // `(?T :> X) :> Y` is true,
Constraint::SupertypeOf(_) => true, Constraint::SupertypeOf(_) => true,
// `(Nat <: ?T <: Ratio) :> Nat` can be true // `(Nat <: ?T <: Ratio) :> Nat` can be true
Constraint::Sandwiched { sup, .. } => self.formal_supertype_of(sup, rhs, bounds, lhs_variance), Constraint::Sandwiched { sup, .. } => {
self.formal_supertype_of(sup, rhs, bounds, lhs_variance)
}
// (?v: Type, rhs): OK // (?v: Type, rhs): OK
// (?v: Nat, rhs): Something wrong // (?v: Nat, rhs): Something wrong
// Class <: Type, but Nat <!: Type (Nat: Type) // Class <: Type, but Nat <!: Type (Nat: Type)
@ -2914,9 +2962,13 @@ impl Context {
// `Nat :> (?T <: Int)` can be true => `X :> (?T <: Y)` can be true // `Nat :> (?T <: Int)` can be true => `X :> (?T <: Y)` can be true
Constraint::SubtypeOf(_sup) => true, Constraint::SubtypeOf(_sup) => true,
// `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) => self.formal_supertype_of(lhs, sub, bounds, lhs_variance), Constraint::SupertypeOf(sub) => {
self.formal_supertype_of(lhs, sub, bounds, lhs_variance)
}
// `Int :> (Nat <: ?T <: Ratio)` can be true, `Nat :> (Int <: ?T <: Ratio)` is false // `Int :> (Nat <: ?T <: Ratio)` can be true, `Nat :> (Int <: ?T <: Ratio)` is false
Constraint::Sandwiched { sub, .. } => self.formal_supertype_of(lhs, sub, bounds, lhs_variance), Constraint::Sandwiched { sub, .. } => {
self.formal_supertype_of(lhs, sub, bounds, lhs_variance)
}
Constraint::TypeOf(t) => { Constraint::TypeOf(t) => {
if self.formal_supertype_of(&Type, t, bounds, lhs_variance) { if self.formal_supertype_of(&Type, t, bounds, lhs_variance) {
true true
@ -2989,14 +3041,25 @@ impl Context {
if bounds.is_some() { if bounds.is_some() {
panic!("Nested quantification") panic!("Nested quantification")
} else { } else {
self.formal_supertype_of(q.unbound_callable.as_ref(), r, Some(&q.bounds), lhs_variance) self.formal_supertype_of(
q.unbound_callable.as_ref(),
r,
Some(&q.bounds),
lhs_variance,
)
} }
} }
(lhs, Or(tys)) => tys.iter().all(|t| self.formal_supertype_of(lhs, t, bounds, lhs_variance)), (lhs, Or(tys)) => tys
(And(tys), rhs) => tys.iter().all(|t| self.formal_supertype_of(t, rhs, bounds, lhs_variance)), .iter()
.all(|t| self.formal_supertype_of(lhs, t, bounds, lhs_variance)),
(And(tys), rhs) => tys
.iter()
.all(|t| self.formal_supertype_of(t, rhs, bounds, lhs_variance)),
(VarArgs(lhs), rhs) => self.formal_supertype_of(lhs, rhs, bounds, lhs_variance), (VarArgs(lhs), rhs) => self.formal_supertype_of(lhs, rhs, bounds, lhs_variance),
// TはすべてのRef(T)のメソッドを持つので、Ref(T)のサブタイプ // TはすべてのRef(T)のメソッドを持つので、Ref(T)のサブタイプ
(Ref(lhs), rhs) | (RefMut(lhs), rhs) => self.formal_supertype_of(lhs, rhs, bounds, lhs_variance), (Ref(lhs), rhs) | (RefMut(lhs), rhs) => {
self.formal_supertype_of(lhs, rhs, bounds, lhs_variance)
}
( (
Poly { Poly {
name: ln, name: ln,
@ -3010,30 +3073,24 @@ impl Context {
if let Some(lhs_variance) = lhs_variance { if let Some(lhs_variance) = lhs_variance {
ln == rn ln == rn
&& lp.len() == rp.len() && lp.len() == rp.len()
&& lp && lp.iter().zip(rp.iter()).zip(lhs_variance.iter()).all(
.iter() |((l, r), variance)| match (l, r, variance) {
.zip(rp.iter()) (TyParam::Type(l), TyParam::Type(r), Variance::Contravariant) => {
.zip(lhs_variance.iter()) self.subtype_of(l, r, bounds, Some(lhs_variance))
.all(|((l, r), variance)| {
match (l, r, variance) {
(TyParam::Type(l), TyParam::Type(r), Variance::Contravariant) => {
self.subtype_of(l, r, bounds, Some(lhs_variance))
},
(TyParam::Type(l), TyParam::Type(r), Variance::Covariant) => {
self.formal_supertype_of(l, r, bounds, Some(lhs_variance))
},
_ => self.eq_tp(l, r, bounds, Some(lhs_variance)),
} }
}) (TyParam::Type(l), TyParam::Type(r), Variance::Covariant) => {
self.formal_supertype_of(l, r, bounds, Some(lhs_variance))
}
_ => self.eq_tp(l, r, bounds, Some(lhs_variance)),
},
)
} else { } else {
ln == rn ln == rn
&& lp.len() == rp.len() && lp.len() == rp.len()
&& lp && lp
.iter() .iter()
.zip(rp.iter()) .zip(rp.iter())
.all(|(l, r)| { .all(|(l, r)| self.eq_tp(l, r, bounds, None))
self.eq_tp(l, r, bounds, None)
})
} }
} }
(MonoQVar(name), r) => { (MonoQVar(name), r) => {
@ -3059,7 +3116,7 @@ impl Context {
} else { } else {
todo!() todo!()
} }
}, }
(PolyQVar { .. }, _r) => todo!(), (PolyQVar { .. }, _r) => todo!(),
(_l, PolyQVar { .. }) => todo!(), (_l, PolyQVar { .. }) => todo!(),
(_l, _r) => false, (_l, _r) => false,
@ -3085,7 +3142,7 @@ impl Context {
lhs_variance: Option<&Vec<Variance>>, lhs_variance: Option<&Vec<Variance>>,
) -> bool { ) -> bool {
self.formal_supertype_of(lhs, rhs, bounds, lhs_variance) self.formal_supertype_of(lhs, rhs, bounds, lhs_variance)
&& self.subtype_of(lhs, rhs, bounds, lhs_variance) && self.subtype_of(lhs, rhs, bounds, lhs_variance)
} }
fn try_cmp( fn try_cmp(
@ -3218,7 +3275,8 @@ impl Context {
fn union_refinement(&self, lhs: &RefinementType, rhs: &RefinementType) -> RefinementType { fn union_refinement(&self, lhs: &RefinementType, rhs: &RefinementType) -> RefinementType {
if !self.formal_supertype_of(&lhs.t, &rhs.t, None, None) if !self.formal_supertype_of(&lhs.t, &rhs.t, None, None)
&& !self.subtype_of(&lhs.t, &rhs.t, None, None) { && !self.subtype_of(&lhs.t, &rhs.t, None, None)
{
log!("{lhs}\n{rhs}"); log!("{lhs}\n{rhs}");
todo!() todo!()
} else { } else {
@ -3293,7 +3351,9 @@ impl Context {
// |T <: Nat| <: |T <: Int| // |T <: Nat| <: |T <: Int|
// |I: Nat| <: |I: Int| // |I: Nat| <: |I: Int|
(Constraint::SubtypeOf(lhs), Constraint::SubtypeOf(rhs)) (Constraint::SubtypeOf(lhs), Constraint::SubtypeOf(rhs))
| (Constraint::TypeOf(lhs), Constraint::TypeOf(rhs)) => self.rec_full_subtype_of(lhs, rhs), | (Constraint::TypeOf(lhs), Constraint::TypeOf(rhs)) => {
self.rec_full_subtype_of(lhs, rhs)
}
// |Int <: T| <: |Nat <: T| // |Int <: T| <: |Nat <: T|
(Constraint::SupertypeOf(lhs), Constraint::SupertypeOf(rhs)) => { (Constraint::SupertypeOf(lhs), Constraint::SupertypeOf(rhs)) => {
self.rec_full_supertype_of(lhs, rhs) self.rec_full_supertype_of(lhs, rhs)
@ -3539,10 +3599,7 @@ impl Context {
} }
/// tと一致ないしそれよりも大きい型のContextを返す /// tと一致ないしそれよりも大きい型のContextを返す
fn sorted_type_ctxs<'a>( fn sorted_type_ctxs<'a>(&'a self, t: &'a Type) -> impl Iterator<Item = &'a Context> {
&'a self,
t: &'a Type,
) -> impl Iterator<Item = &'a Context> {
let mut ctxs = self._type_ctxs(t).collect::<Vec<_>>(); let mut ctxs = self._type_ctxs(t).collect::<Vec<_>>();
ctxs.sort_by(|(lhs, _), (rhs, _)| self.cmp_t(lhs, rhs).try_into().unwrap()); ctxs.sort_by(|(lhs, _), (rhs, _)| self.cmp_t(lhs, rhs).try_into().unwrap());
ctxs.into_iter().map(|(_, ctx)| ctx) ctxs.into_iter().map(|(_, ctx)| ctx)

View file

@ -58,12 +58,11 @@ impl SideEffectChecker {
Expr::BinOp(bin) => { Expr::BinOp(bin) => {
self.check_expr(&bin.lhs, true); self.check_expr(&bin.lhs, true);
self.check_expr(&bin.rhs, true); self.check_expr(&bin.rhs, true);
}, }
Expr::UnaryOp(unary) => { Expr::UnaryOp(unary) => {
self.check_expr(&unary.expr, true); self.check_expr(&unary.expr, true);
}, }
Expr::Accessor(_) Expr::Accessor(_) | Expr::Lit(_) => {}
| Expr::Lit(_) => {},
other => todo!("{other}"), other => todo!("{other}"),
} }
} }

View file

@ -25,10 +25,13 @@ struct SubstContext {
impl SubstContext { impl SubstContext {
pub fn new(substituted: &Type, ty_ctx: &Context) -> Self { pub fn new(substituted: &Type, ty_ctx: &Context) -> Self {
let param_names = ty_ctx let param_names = ty_ctx.params.iter().map(|(opt_name, _)| {
.params opt_name
.iter() .as_ref()
.map(|(opt_name, _)| opt_name.as_ref().map(|n| n.inspect().clone()).unwrap_or(Str::ever("_")).clone()); .map(|n| n.inspect().clone())
.unwrap_or(Str::ever("_"))
.clone()
});
let self_ = SubstContext { let self_ = SubstContext {
params: param_names params: param_names
.zip(substituted.typarams().into_iter()) .zip(substituted.typarams().into_iter())

View file

@ -34,7 +34,8 @@ impl Context {
if self.locals.get(&name).is_some() { if self.locals.get(&name).is_some() {
panic!("already registered: {name}"); panic!("already registered: {name}");
} else { } else {
self.locals.insert(name, VarInfo::new(t, muty, vis, Builtin)); self.locals
.insert(name, VarInfo::new(t, muty, vis, Builtin));
} }
} }
@ -111,8 +112,12 @@ impl Context {
set! {subtype(mono_q("Self"), mono("Ord")), subtype(mono_q("R"), poly("Ord", vec![]))}, set! {subtype(mono_q("Self"), mono("Ord")), subtype(mono_q("R"), poly("Ord", vec![]))},
); );
ord.register_decl("__lt__", op_t.clone(), Public); ord.register_decl("__lt__", op_t.clone(), Public);
let mut seq = let mut seq = Self::poly_trait(
Self::poly_trait("Seq", vec![PS::t("T", NonDefault)], vec![poly("Output", vec![ty_tp(mono_q("T"))])], Self::TOP_LEVEL); "Seq",
vec![PS::t("T", NonDefault)],
vec![poly("Output", vec![ty_tp(mono_q("T"))])],
Self::TOP_LEVEL,
);
let self_t = poly_q("Self", vec![TyParam::t(mono_q("T"))]); let self_t = poly_q("Self", vec![TyParam::t(mono_q("T"))]);
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(), mono("Seq"))}); let t = quant(t, set! {subtype(self_t.clone(), mono("Seq"))});

View file

@ -50,17 +50,15 @@ impl ASTLowerer {
expect: &Type, expect: &Type,
found: &Type, found: &Type,
) -> LowerResult<()> { ) -> LowerResult<()> {
self.ctx self.ctx.unify(expect, found, Some(loc), None).or_else(|_| {
.unify(expect, found, Some(loc), None) Err(LowerError::type_mismatch_error(
.or_else(|_| { loc,
Err(LowerError::type_mismatch_error( self.ctx.caused_by(),
loc, name,
self.ctx.caused_by(), expect,
name, found,
expect, ))
found, })
))
})
} }
fn use_check(&self, expr: hir::Expr, mode: &str) -> LowerResult<hir::Expr> { fn use_check(&self, expr: hir::Expr, mode: &str) -> LowerResult<hir::Expr> {
@ -126,8 +124,7 @@ impl ASTLowerer {
ast::Accessor::Attr(a) => { ast::Accessor::Attr(a) => {
let obj = self.lower_expr(*a.obj, true)?; let obj = self.lower_expr(*a.obj, true)?;
let t = if check { let t = if check {
self.ctx self.ctx.get_attr_t(&obj, &a.name.symbol, &self.ctx.name)?
.get_attr_t(&obj, &a.name.symbol, &self.ctx.name)?
} else { } else {
Type::ASTOmitted Type::ASTOmitted
}; };
@ -144,9 +141,7 @@ impl ASTLowerer {
let lhs = hir::PosArg::new(self.lower_expr(*args.next().unwrap(), true)?); let lhs = hir::PosArg::new(self.lower_expr(*args.next().unwrap(), true)?);
let rhs = hir::PosArg::new(self.lower_expr(*args.next().unwrap(), true)?); let rhs = hir::PosArg::new(self.lower_expr(*args.next().unwrap(), true)?);
let args = [lhs, rhs]; let args = [lhs, rhs];
let t = self let t = self.ctx.get_binop_t(&bin.op, &args, &self.ctx.name)?;
.ctx
.get_binop_t(&bin.op, &args, &self.ctx.name)?;
let mut args = args.into_iter(); let mut args = args.into_iter();
let lhs = args.next().unwrap().expr; let lhs = args.next().unwrap().expr;
let rhs = args.next().unwrap().expr; let rhs = args.next().unwrap().expr;
@ -158,9 +153,7 @@ impl ASTLowerer {
let mut args = unary.args.into_iter(); let mut args = unary.args.into_iter();
let arg = hir::PosArg::new(self.lower_expr(*args.next().unwrap(), true)?); let arg = hir::PosArg::new(self.lower_expr(*args.next().unwrap(), true)?);
let args = [arg]; let args = [arg];
let t = self let t = self.ctx.get_unaryop_t(&unary.op, &args, &self.ctx.name)?;
.ctx
.get_unaryop_t(&unary.op, &args, &self.ctx.name)?;
let mut args = args.into_iter(); let mut args = args.into_iter();
let expr = args.next().unwrap().expr; let expr = args.next().unwrap().expr;
Ok(hir::UnaryOp::new(unary.op, expr, t)) Ok(hir::UnaryOp::new(unary.op, expr, t))
@ -220,15 +213,23 @@ impl ASTLowerer {
self.pop_append_errs(); self.pop_append_errs();
e e
})?; })?;
let (non_default_params, default_params): (Vec<_>, Vec<_>) = let (non_default_params, default_params): (Vec<_>, Vec<_>) = self
self.ctx .ctx
.params .params
.iter() .iter()
.partition(|(_, v)| v.kind.has_default()); .partition(|(_, v)| v.kind.has_default());
let non_default_params = non_default_params let non_default_params = non_default_params
.into_iter().map(|(name, vi)| ParamTy::new(name.as_ref().map(|n| n.inspect().clone()), vi.t.clone())).collect(); .into_iter()
.map(|(name, vi)| {
ParamTy::new(name.as_ref().map(|n| n.inspect().clone()), vi.t.clone())
})
.collect();
let default_params = default_params let default_params = default_params
.into_iter().map(|(name, vi)| ParamTy::new(name.as_ref().map(|n| n.inspect().clone()), vi.t.clone())).collect(); .into_iter()
.map(|(name, vi)| {
ParamTy::new(name.as_ref().map(|n| n.inspect().clone()), vi.t.clone())
})
.collect();
let bounds = self let bounds = self
.ctx .ctx
.instantiate_ty_bounds(&lambda.sig.bounds, RegistrationMode::Normal) .instantiate_ty_bounds(&lambda.sig.bounds, RegistrationMode::Normal)

View file

@ -75,7 +75,11 @@ impl ParamIdx {
pub enum VarKind { pub enum VarKind {
Defined(DefId), Defined(DefId),
Declared, Declared,
Parameter { def_id: DefId, idx: ParamIdx, default: DefaultInfo }, Parameter {
def_id: DefId,
idx: ParamIdx,
default: DefaultInfo,
},
Generated, Generated,
DoesNotExist, DoesNotExist,
Builtin, Builtin,
@ -83,7 +87,11 @@ pub enum VarKind {
impl VarKind { impl VarKind {
pub const fn parameter(def_id: DefId, idx: ParamIdx, default: DefaultInfo) -> Self { pub const fn parameter(def_id: DefId, idx: ParamIdx, default: DefaultInfo) -> Self {
Self::Parameter { def_id, idx, default } Self::Parameter {
def_id,
idx,
default,
}
} }
pub const fn idx(&self) -> Option<&ParamIdx> { pub const fn idx(&self) -> Option<&ParamIdx> {

View file

@ -1738,7 +1738,13 @@ pub struct ParamSignature {
impl NestedDisplay for ParamSignature { impl NestedDisplay for ParamSignature {
fn fmt_nest(&self, f: &mut std::fmt::Formatter<'_>, _level: usize) -> std::fmt::Result { fn fmt_nest(&self, f: &mut std::fmt::Formatter<'_>, _level: usize) -> std::fmt::Result {
if let Some(default_val) = &self.opt_default_val { if let Some(default_val) = &self.opt_default_val {
write!(f, "{}{} |= {}", self.pat, fmt_option!(pre ": ", &self.t_spec), default_val) write!(
f,
"{}{} |= {}",
self.pat,
fmt_option!(pre ": ", &self.t_spec),
default_val
)
} else { } else {
write!(f, "{}{}", self.pat, fmt_option!(pre ": ", &self.t_spec),) write!(f, "{}{}", self.pat, fmt_option!(pre ": ", &self.t_spec),)
} }
@ -1758,8 +1764,16 @@ impl Locational for ParamSignature {
} }
impl ParamSignature { impl ParamSignature {
pub const fn new(pat: ParamPattern, t_spec: Option<TypeSpec>, opt_default_val: Option<ConstExpr>) -> Self { pub const fn new(
Self { pat, t_spec, opt_default_val } pat: ParamPattern,
t_spec: Option<TypeSpec>,
opt_default_val: Option<ConstExpr>,
) -> Self {
Self {
pat,
t_spec,
opt_default_val,
}
} }
pub const fn inspect(&self) -> Option<&Str> { pub const fn inspect(&self) -> Option<&Str> {

View file

@ -11,9 +11,8 @@ use erg_common::Str;
use erg_common::{enum_unwrap, set}; use erg_common::{enum_unwrap, set};
use crate::ast::{ use crate::ast::{
Accessor, Args, Block, Call, Def, DefBody, Expr, Lambda, LambdaSignature, Module, Accessor, Args, Block, Call, Def, DefBody, Expr, Lambda, LambdaSignature, Module, ParamPattern,
ParamSignature, ParamPattern, Params, PosArg, Signature, SubrSignature, ParamSignature, Params, PosArg, Signature, SubrSignature, TypeBoundSpecs, VarName, VarPattern,
TypeBoundSpecs, VarName, VarPattern,
}; };
use crate::token::{Token, TokenKind}; use crate::token::{Token, TokenKind};

View file

@ -559,9 +559,7 @@ impl Parser {
if self.cur_is(OrEqual) { if self.cur_is(OrEqual) {
self.skip(); self.skip();
let val = self.try_reduce_const_expr()?; let val = self.try_reduce_const_expr()?;
Ok(ParamSignature::new( Ok(ParamSignature::new(lhs.pat, lhs.t_spec, Some(val)))
lhs.pat, lhs.t_spec, Some(val),
))
} else { } else {
Ok(ParamSignature::new(lhs.pat, lhs.t_spec, None)) Ok(ParamSignature::new(lhs.pat, lhs.t_spec, None))
} }
@ -737,7 +735,7 @@ impl Parser {
} else { } else {
non_default_params.push(param); non_default_params.push(param);
} }
}, }
_ => return Err(self.skip_and_throw_syntax_err(caused_by!())), _ => return Err(self.skip_and_throw_syntax_err(caused_by!())),
} }
loop { loop {
@ -746,17 +744,21 @@ impl Parser {
self.skip(); self.skip();
let param = self.try_reduce_param_sig()?; let param = self.try_reduce_param_sig()?;
match (param.has_default(), default_appeared) { match (param.has_default(), default_appeared) {
(true, true) => { default_params.push(param); }, (true, true) => {
default_params.push(param);
}
(true, false) => { (true, false) => {
default_appeared = true; default_appeared = true;
default_params.push(param); default_params.push(param);
}, }
(false, true) => return Err(ParseError::syntax_error( (false, true) => {
0, return Err(ParseError::syntax_error(
param.loc(), 0,
"non-default argument follows default argument", param.loc(),
None, "non-default argument follows default argument",
)), None,
))
}
(false, false) => { (false, false) => {
non_default_params.push(param); non_default_params.push(param);
} }

View file

@ -79,7 +79,8 @@ impl Runnable for DummyVM {
} }
fn eval(&mut self, src: Str) -> Result<String, CompileErrors> { fn eval(&mut self, src: Str) -> Result<String, CompileErrors> {
self.compiler.compile_and_dump_as_pyc(src, "o.pyc", "eval")?; self.compiler
.compile_and_dump_as_pyc(src, "o.pyc", "eval")?;
let mut res = match self.stream.write("load".as_bytes()) { let mut res = match self.stream.write("load".as_bytes()) {
Result::Ok(_) => { Result::Ok(_) => {
let mut buf = [0; 1024]; let mut buf = [0; 1024];