Follow clippy warnings

This commit is contained in:
Yuna Tomida 2022-09-10 17:32:25 +09:00
parent 9783813ae0
commit d956c3f61d
No known key found for this signature in database
GPG key ID: E6EC40A47CA07A6F
34 changed files with 448 additions and 450 deletions

View file

@ -146,33 +146,20 @@ impl Default for ErgConfig {
} else { } else {
Input::REPL Input::REPL
}; };
Self::new("exec", 1, false, None, 10, input, "<module>", 2) Self {
mode: "exec",
opt_level: 1,
dump_as_pyc: false,
python_ver: None,
py_server_timeout: 10,
input,
module: "<module>",
verbose: 2,
}
} }
} }
impl ErgConfig { impl ErgConfig {
pub const fn new(
mode: &'static str,
opt_level: u8,
dump_as_pyc: bool,
python_ver: Option<u32>,
py_server_timeout: u64,
input: Input,
module: &'static str,
verbose: u8,
) -> Self {
Self {
mode,
opt_level,
dump_as_pyc,
python_ver,
py_server_timeout,
input,
module,
verbose,
}
}
/// cloneのエイリアス(実際のcloneコストは低いので) /// cloneのエイリアス(実際のcloneコストは低いので)
#[inline] #[inline]
pub fn copy(&self) -> Self { pub fn copy(&self) -> Self {

View file

@ -1,5 +1,5 @@
use std::borrow::Borrow; use std::borrow::Borrow;
use std::collections::hash_map::{IntoIter, IntoValues, Iter, IterMut, Keys, Values, ValuesMut}; use std::collections::hash_map::{IntoValues, Iter, IterMut, Keys, Values, ValuesMut};
use std::fmt::{self, Write}; use std::fmt::{self, Write};
use std::hash::{Hash, Hasher}; use std::hash::{Hash, Hasher};
use std::iter::FromIterator; use std::iter::FromIterator;
@ -119,11 +119,6 @@ impl<K, V> Dict<K, V> {
self.dict.iter() self.dict.iter()
} }
#[inline]
pub fn into_iter(self) -> IntoIter<K, V> {
self.dict.into_iter()
}
#[inline] #[inline]
pub fn iter_mut(&mut self) -> IterMut<K, V> { pub fn iter_mut(&mut self) -> IterMut<K, V> {
self.dict.iter_mut() self.dict.iter_mut()
@ -134,6 +129,15 @@ impl<K, V> Dict<K, V> {
} }
} }
impl<K, V> IntoIterator for Dict<K, V> {
type Item = (K, V);
type IntoIter = <FxHashMap<K, V> as IntoIterator>::IntoIter;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.dict.into_iter()
}
}
impl<K: Hash + Eq, V> Dict<K, V> { impl<K: Hash + Eq, V> Dict<K, V> {
#[inline] #[inline]
pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V> pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V>

View file

@ -3,7 +3,8 @@
//! エラー処理に関する汎用的なコンポーネントを提供する //! エラー処理に関する汎用的なコンポーネントを提供する
use std::cmp; use std::cmp;
use std::fmt; use std::fmt;
use std::io::{stderr, BufWriter, Write}; use std::fmt::Write as _;
use std::io::{stderr, BufWriter, Write as _};
use crate::color::*; use crate::color::*;
use crate::config::Input; use crate::config::Input;
@ -362,7 +363,7 @@ pub trait ErrorDisplay {
/// As for the internal error, do not put the fn name here. /// As for the internal error, do not put the fn name here.
fn caused_by(&self) -> &str; fn caused_by(&self) -> &str;
/// the previous error that caused this error. /// the previous error that caused this error.
fn ref_inner(&self) -> Option<&Box<Self>>; fn ref_inner(&self) -> Option<&Self>;
fn write_to_stderr(&self) { fn write_to_stderr(&self) {
let mut writer = BufWriter::new(stderr()); let mut writer = BufWriter::new(stderr());
@ -469,10 +470,12 @@ pub trait ErrorDisplay {
} else { } else {
pointer += &"^".repeat(cmp::max(1, codes[i].len())); pointer += &"^".repeat(cmp::max(1, codes[i].len()));
} }
res += &format!( writeln!(
"{lineno}{VBAR_UNICODE} {code}\n{pointer}\n", res,
"{lineno}{VBAR_UNICODE} {code}\n{pointer}",
code = codes[i] code = codes[i]
); )
.unwrap();
} }
res + RESET res + RESET
} }

View file

@ -7,13 +7,20 @@ pub fn levenshtein(lhs: &str, rhs: &str) -> usize {
let r_len = rhs.len(); let r_len = rhs.len();
// l_len+1 × r_len+1 array // l_len+1 × r_len+1 array
let mut table = vec![vec![0; r_len + 1]; l_len + 1]; let mut table = vec![vec![0; r_len + 1]; l_len + 1];
for i in 0..l_len + 1 { let _ = table
table[i][0] = i; .iter_mut()
} .take(l_len + 1)
for i in 0..r_len + 1 { .enumerate()
table[0][i] = i; .map(|(i, row)| row[0] = i)
} .collect::<()>();
let _ = table[0]
.iter_mut()
.take(r_len + 1)
.enumerate()
.map(|(i, elem)| *elem = i)
.collect::<()>();
for i1 in 0..l_len { for i1 in 0..l_len {
#[allow(clippy::needless_range_loop)]
for i2 in 0..r_len { for i2 in 0..r_len {
let cost = if lhs[i1] == rhs[i2] { 0 } else { 1 }; let cost = if lhs[i1] == rhs[i2] { 0 } else { 1 };
table[i1 + 1][i2 + 1] = *[ table[i1 + 1][i2 + 1] = *[

View file

@ -1,5 +1,5 @@
use std::borrow::Borrow; use std::borrow::Borrow;
use std::collections::hash_set::{IntoIter, Iter}; use std::collections::hash_set::Iter;
use std::fmt; use std::fmt;
use std::hash::{Hash, Hasher}; use std::hash::{Hash, Hasher};
use std::iter::FromIterator; use std::iter::FromIterator;
@ -105,9 +105,13 @@ impl<T: Hash> Set<T> {
pub fn iter(&self) -> Iter<'_, T> { pub fn iter(&self) -> Iter<'_, T> {
self.elems.iter() self.elems.iter()
} }
}
impl<T: Hash> IntoIterator for Set<T> {
type Item = T;
type IntoIter = <FxHashSet<T> as IntoIterator>::IntoIter;
#[inline] #[inline]
pub fn into_iter(self) -> IntoIter<T> { fn into_iter(self) -> Self::IntoIter {
self.elems.into_iter() self.elems.into_iter()
} }
} }

View file

@ -111,6 +111,12 @@ impl Borrow<str> for Str {
} }
} }
impl AsRef<str> for Str {
fn as_ref(&self) -> &str {
self.borrow()
}
}
impl Str { impl Str {
pub const fn ever(s: &'static str) -> Self { pub const fn ever(s: &'static str) -> Self {
Str::Static(s) Str::Static(s)
@ -120,10 +126,6 @@ impl Str {
Str::Rc(s.into()) Str::Rc(s.into())
} }
pub fn as_ref(&self) -> &str {
self.borrow()
}
pub fn into_rc(self) -> RcStr { pub fn into_rc(self) -> RcStr {
match self { match self {
Str::Rc(s) => s, Str::Rc(s) => s,

View file

@ -63,6 +63,7 @@ fn dfs<T: Eq + Hash + Clone, U>(
} }
/// perform topological sort on a graph /// perform topological sort on a graph
#[allow(clippy::result_unit_err)]
pub fn tsort<T: Eq + Hash + Clone, U>(g: Graph<T, U>) -> Result<Graph<T, U>, ()> { pub fn tsort<T: Eq + Hash + Clone, U>(g: Graph<T, U>) -> Result<Graph<T, U>, ()> {
let n = g.len(); let n = g.len();
let mut idx = Vec::with_capacity(n); let mut idx = Vec::with_capacity(n);

View file

@ -32,163 +32,163 @@ use crate::hir::{
use AccessKind::*; use AccessKind::*;
fn is_python_global(name: &str) -> bool { fn is_python_global(name: &str) -> bool {
match name { matches!(
name,
"ArithmeticError" "ArithmeticError"
| "AssertionError" | "AssertionError"
| "AttributeError" | "AttributeError"
| "BaseException" | "BaseException"
| "BlockingIOError" | "BlockingIOError"
| "BrokenPipeError" | "BrokenPipeError"
| "BufferError" | "BufferError"
| "BytesWarning" | "BytesWarning"
| "ChildProcessError" | "ChildProcessError"
| "ConnectionAbortedError" | "ConnectionAbortedError"
| "ConnectionError" | "ConnectionError"
| "ConnectionRefusedError" | "ConnectionRefusedError"
| "ConnectionResetError" | "ConnectionResetError"
| "DeprecationWarning" | "DeprecationWarning"
| "EOFError" | "EOFError"
| "Ellipsis" | "Ellipsis"
| "EncodingWarning" | "EncodingWarning"
| "EnvironmentError" | "EnvironmentError"
| "Exception" | "Exception"
| "False" | "False"
| "FileExistsError" | "FileExistsError"
| "FileNotFoundError" | "FileNotFoundError"
| "FloatingPointError" | "FloatingPointError"
| "FutureWarning" | "FutureWarning"
| "GeneratorExit" | "GeneratorExit"
| "IOError" | "IOError"
| "ImportError" | "ImportError"
| "ImportWarning" | "ImportWarning"
| "IndentationError" | "IndentationError"
| "IndexError" | "IndexError"
| "InterruptedError" | "InterruptedError"
| "IsADirectoryError" | "IsADirectoryError"
| "KeyError" | "KeyError"
| "KeyboardInterrupt" | "KeyboardInterrupt"
| "LookupError" | "LookupError"
| "MemoryError" | "MemoryError"
| "ModuleNotFoundError" | "ModuleNotFoundError"
| "NameError" | "NameError"
| "None" | "None"
| "NotADirectoryError" | "NotADirectoryError"
| "NotImplemented" | "NotImplemented"
| "NotImplementedError" | "NotImplementedError"
| "OSError" | "OSError"
| "OverflowError" | "OverflowError"
| "PendingDeprecationWarning" | "PendingDeprecationWarning"
| "PermissionError" | "PermissionError"
| "ProcessLookupError" | "ProcessLookupError"
| "RecursionError" | "RecursionError"
| "ReferenceError" | "ReferenceError"
| "ResourceWarning" | "ResourceWarning"
| "RuntimeError" | "RuntimeError"
| "RuntimeWarning" | "RuntimeWarning"
| "StopAsyncIteration" | "StopAsyncIteration"
| "StopIteration" | "StopIteration"
| "SyntaxError" | "SyntaxError"
| "SyntaxWarning" | "SyntaxWarning"
| "SystemError" | "SystemError"
| "SystemExit" | "SystemExit"
| "TabError" | "TabError"
| "TimeoutError" | "TimeoutError"
| "True" | "True"
| "TypeError" | "TypeError"
| "UnboundLocalError" | "UnboundLocalError"
| "UnicodeDecodeError" | "UnicodeDecodeError"
| "UnicodeEncodeError" | "UnicodeEncodeError"
| "UnicodeError" | "UnicodeError"
| "UnicodeTranslateError" | "UnicodeTranslateError"
| "UnicodeWarning" | "UnicodeWarning"
| "UserWarning" | "UserWarning"
| "ValueError" | "ValueError"
| "Warning" | "Warning"
| "WindowsError" | "WindowsError"
| "ZeroDivisionError" | "ZeroDivisionError"
| "__build__class__" | "__build__class__"
| "__debug__" | "__debug__"
| "__doc__" | "__doc__"
| "__import__" | "__import__"
| "__loader__" | "__loader__"
| "__name__" | "__name__"
| "__package__" | "__package__"
| "__spec__" | "__spec__"
| "__annotations__" | "__annotations__"
| "__builtins__" | "__builtins__"
| "abs" | "abs"
| "aiter" | "aiter"
| "all" | "all"
| "any" | "any"
| "anext" | "anext"
| "ascii" | "ascii"
| "bin" | "bin"
| "bool" | "bool"
| "breakpoint" | "breakpoint"
| "bytearray" | "bytearray"
| "bytes" | "bytes"
| "callable" | "callable"
| "chr" | "chr"
| "classmethod" | "classmethod"
| "compile" | "compile"
| "complex" | "complex"
| "delattr" | "delattr"
| "dict" | "dict"
| "dir" | "dir"
| "divmod" | "divmod"
| "enumerate" | "enumerate"
| "eval" | "eval"
| "exec" | "exec"
| "filter" | "filter"
| "float" | "float"
| "format" | "format"
| "frozenset" | "frozenset"
| "getattr" | "getattr"
| "globals" | "globals"
| "hasattr" | "hasattr"
| "hash" | "hash"
| "help" | "help"
| "hex" | "hex"
| "id" | "id"
| "input" | "input"
| "int" | "int"
| "isinstance" | "isinstance"
| "issubclass" | "issubclass"
| "iter" | "iter"
| "len" | "len"
| "list" | "list"
| "locals" | "locals"
| "map" | "map"
| "max" | "max"
| "memoryview" | "memoryview"
| "min" | "min"
| "next" | "next"
| "object" | "object"
| "oct" | "oct"
| "open" | "open"
| "ord" | "ord"
| "pow" | "pow"
| "print" | "print"
| "property" | "property"
| "quit" | "quit"
| "range" | "range"
| "repr" | "repr"
| "reversed" | "reversed"
| "round" | "round"
| "set" | "set"
| "setattr" | "setattr"
| "slice" | "slice"
| "sorted" | "sorted"
| "staticmethod" | "staticmethod"
| "str" | "str"
| "sum" | "sum"
| "super" | "super"
| "tuple" | "tuple"
| "type" | "type"
| "vars" | "vars"
| "zip" => true, | "zip"
_ => false, )
}
} }
fn convert_to_python_attr(class: &str, uniq_obj_name: Option<&str>, name: Str) -> Str { fn convert_to_python_attr(class: &str, uniq_obj_name: Option<&str>, name: Str) -> Str {
@ -732,7 +732,7 @@ impl CodeGenerator {
self.write_arg(cellvars_len); self.write_arg(cellvars_len);
opcode_flag += 8; opcode_flag += 8;
} }
self.emit_load_const(name.clone()); self.emit_load_const(name);
self.write_instr(MAKE_FUNCTION); self.write_instr(MAKE_FUNCTION);
self.write_arg(opcode_flag); self.write_arg(opcode_flag);
// stack_dec: <code obj> + <name> -> <function> // stack_dec: <code obj> + <name> -> <function>
@ -1225,6 +1225,7 @@ impl CodeGenerator {
self.write_instr(CALL_FUNCTION); self.write_instr(CALL_FUNCTION);
self.write_arg(2); self.write_arg(2);
// (1 (subroutine) + argc + kwsc) input objects -> 1 return object // (1 (subroutine) + argc + kwsc) input objects -> 1 return object
#[allow(clippy::identity_op)]
self.stack_dec_n((1 + 2 + 0) - 1); self.stack_dec_n((1 + 2 + 0) - 1);
let ident = Identifier::private(Str::ever("#rec")); let ident = Identifier::private(Str::ever("#rec"));
self.emit_store_instr(ident, Name); self.emit_store_instr(ident, Name);
@ -1237,6 +1238,7 @@ impl CodeGenerator {
self.write_instr(CALL_FUNCTION); self.write_instr(CALL_FUNCTION);
self.write_arg(attrs_len as u8); self.write_arg(attrs_len as u8);
// (1 (subroutine) + argc + kwsc) input objects -> 1 return object // (1 (subroutine) + argc + kwsc) input objects -> 1 return object
#[allow(clippy::identity_op)]
self.stack_dec_n((1 + attrs_len + 0) - 1); self.stack_dec_n((1 + attrs_len + 0) - 1);
} }
other => { other => {

View file

@ -33,7 +33,7 @@ impl TypeCmpCache {
where where
SubtypePair: Borrow<Q>, SubtypePair: Borrow<Q>,
{ {
self.cache.get(pair).map(|b| *b) self.cache.get(pair).copied()
} }
pub fn register(&mut self, pair: SubtypePair, b: bool) { pub fn register(&mut self, pair: SubtypePair, b: bool) {

View file

@ -171,15 +171,15 @@ impl Context {
&& subr && subr
.non_default_params .non_default_params
.iter() .iter()
.all(|pt| self.supertype_of(&Type, &pt.typ())) .all(|pt| self.supertype_of(&Type, pt.typ()))
&& subr && subr
.default_params .default_params
.iter() .iter()
.all(|pt| self.supertype_of(&Type, &pt.typ())) .all(|pt| self.supertype_of(&Type, pt.typ()))
&& subr && subr
.var_params .var_params
.as_ref() .as_ref()
.map(|va| self.supertype_of(&Type, &va.typ())) .map(|va| self.supertype_of(&Type, va.typ()))
.unwrap_or(true) .unwrap_or(true)
&& self.supertype_of(&Type, &subr.return_t), && self.supertype_of(&Type, &subr.return_t),
), ),
@ -251,19 +251,13 @@ impl Context {
if let Some(res) = self.inquire_cache(rhs, lhs) { if let Some(res) = self.inquire_cache(rhs, lhs) {
return res; return res;
} }
match self.classes_supertype_of(lhs, rhs) { if let (Absolutely, judge) = self.classes_supertype_of(lhs, rhs) {
(Absolutely, judge) => { self.register_cache(rhs, lhs, judge);
self.register_cache(rhs, lhs, judge); return judge;
return judge;
}
_ => {}
} }
match self.trait_supertype_of(lhs, rhs) { if let (Absolutely, judge) = self.trait_supertype_of(lhs, rhs) {
(Absolutely, judge) => { self.register_cache(rhs, lhs, judge);
self.register_cache(rhs, lhs, judge); return judge;
return judge;
}
_ => {}
} }
for patch in self.patches.values() { for patch in self.patches.values() {
if let ContextKind::GluePatch(tr_inst) = &patch.kind { if let ContextKind::GluePatch(tr_inst) = &patch.kind {
@ -277,13 +271,13 @@ impl Context {
if self.supertype_of(&tr_inst.sub_type, rhs) if self.supertype_of(&tr_inst.sub_type, rhs)
&& self.subtype_of(&tr_inst.sup_trait, lhs) && self.subtype_of(&tr_inst.sup_trait, lhs)
{ {
self.register_cache(&rhs, &lhs, true); self.register_cache(rhs, lhs, true);
return true; return true;
} }
} }
} }
} }
self.register_cache(&rhs, &lhs, false); self.register_cache(rhs, lhs, false);
false false
} }
@ -620,6 +614,7 @@ impl Context {
// if `rhs` is {S: Str | ... }, `defined_rhs` will be Str // if `rhs` is {S: Str | ... }, `defined_rhs` will be Str
let (defined_rhs, _) = self.rec_get_nominal_type_ctx(rhs).unwrap(); let (defined_rhs, _) = self.rec_get_nominal_type_ctx(rhs).unwrap();
let super_traits = self.rec_get_nominal_super_trait_ctxs(rhs); let super_traits = self.rec_get_nominal_super_trait_ctxs(rhs);
#[allow(clippy::useless_conversion)]
for (sup_trait, _) in super_traits.into_iter() { for (sup_trait, _) in super_traits.into_iter() {
if self.sup_conforms(lhs, defined_rhs, sup_trait) { if self.sup_conforms(lhs, defined_rhs, sup_trait) {
return true; return true;
@ -636,8 +631,8 @@ impl Context {
pub(crate) fn poly_supertype_of( pub(crate) fn poly_supertype_of(
&self, &self,
typ: &Type, typ: &Type,
lparams: &Vec<TyParam>, lparams: &[TyParam],
rparams: &Vec<TyParam>, rparams: &[TyParam],
) -> bool { ) -> bool {
let (_, ctx) = self let (_, ctx) = self
.rec_get_nominal_type_ctx(typ) .rec_get_nominal_type_ctx(typ)
@ -754,6 +749,7 @@ impl Context {
} }
} }
#[allow(clippy::wrong_self_convention)]
pub(crate) fn into_refinement(&self, t: Type) -> RefinementType { pub(crate) fn into_refinement(&self, t: Type) -> RefinementType {
match t { match t {
Nat => { Nat => {

View file

@ -70,14 +70,12 @@ impl Context {
fn register_type(&mut self, t: Type, ctx: Self, muty: Mutability) { fn register_type(&mut self, t: Type, ctx: Self, muty: Mutability) {
if t.typarams_len().is_none() { if t.typarams_len().is_none() {
self.register_mono_type(t, ctx, muty); self.register_mono_type(t, ctx, muty);
} else if t.is_class() {
self.register_poly_class(t, ctx, muty);
} else if t.is_trait() {
self.register_poly_trait(t, ctx, muty);
} else { } else {
if t.is_class() { todo!()
self.register_poly_class(t, ctx, muty);
} else if t.is_trait() {
self.register_poly_trait(t, ctx, muty);
} else {
todo!()
}
} }
} }
@ -218,7 +216,7 @@ impl Context {
static_instance("R", Type) static_instance("R", Type)
}, },
); );
eq.register_decl("__eq__", op_t.clone(), Public); eq.register_decl("__eq__", op_t, Public);
let mut partial_ord = Self::poly_trait( let mut partial_ord = Self::poly_trait(
"PartialOrd", "PartialOrd",
vec![PS::t("R", WithDefault)], vec![PS::t("R", WithDefault)],
@ -233,7 +231,7 @@ impl Context {
static_instance("R", Type) static_instance("R", Type)
}, },
); );
partial_ord.register_decl("__lt__", op_t.clone(), Public); partial_ord.register_decl("__lt__", op_t, Public);
let ord = Self::mono_trait( let ord = Self::mono_trait(
"Ord", "Ord",
vec![poly_trait("Eq", vec![]), poly_trait("PartialOrd", vec![])], vec![poly_trait("Eq", vec![]), poly_trait("PartialOrd", vec![])],
@ -270,7 +268,7 @@ impl Context {
seq.register_decl("get", t, Public); seq.register_decl("get", t, Public);
let params = vec![PS::t("T", NonDefault)]; let params = vec![PS::t("T", NonDefault)];
let input = Self::poly_trait("Input", params.clone(), vec![], Self::TOP_LEVEL); let input = Self::poly_trait("Input", params.clone(), vec![], Self::TOP_LEVEL);
let output = Self::poly_trait("Output", params.clone(), vec![], Self::TOP_LEVEL); let output = Self::poly_trait("Output", params, vec![], Self::TOP_LEVEL);
let r = mono_q("R"); let r = mono_q("R");
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)];
@ -310,13 +308,13 @@ impl Context {
mul.register_decl("MulO", Type, Public); mul.register_decl("MulO", Type, Public);
let mut div = Self::poly_trait( let mut div = Self::poly_trait(
"Div", "Div",
params.clone(), params,
vec![poly_trait("Output", vec![ty_tp(mono_q("R"))])], vec![poly_trait("Output", vec![ty_tp(mono_q("R"))])],
Self::TOP_LEVEL, Self::TOP_LEVEL,
); );
let op_t = fn1_met(mono_q("Self"), r, mono_proj(mono_q("Self"), "DivO")); let op_t = fn1_met(mono_q("Self"), r, mono_proj(mono_q("Self"), "DivO"));
let self_bound = subtypeof(mono_q("Self"), poly_trait("Div", ty_params.clone())); let self_bound = subtypeof(mono_q("Self"), poly_trait("Div", ty_params.clone()));
let op_t = quant(op_t, set! {r_bound.clone(), self_bound}); let op_t = quant(op_t, set! {r_bound, self_bound});
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(trait_("Named"), named, Const); self.register_type(trait_("Named"), named, Const);
@ -609,7 +607,7 @@ impl Context {
let m = mono_q_tp("M"); let m = mono_q_tp("M");
let array_t = array(mono_q("T"), n.clone()); let array_t = array(mono_q("T"), n.clone());
let t = fn_met( let t = fn_met(
array_t.clone(), array_t,
vec![param_t("rhs", array(mono_q("T"), m.clone()))], vec![param_t("rhs", array(mono_q("T"), m.clone()))],
None, None,
vec![], vec![],
@ -622,8 +620,8 @@ impl Context {
array_.register_impl("concat", t, Immutable, Public); array_.register_impl("concat", t, Immutable, Public);
let n = mono_q_tp("N"); let n = mono_q_tp("N");
let array_inner = mono_q("T"); let array_inner = mono_q("T");
let array_t = array(array_inner.clone(), n.clone()); let array_t = array(array_inner.clone(), n);
let proj_t = mono_proj(array_inner.clone(), "ImmutType"); let proj_t = mono_proj(array_inner, "ImmutType");
let t = fn_met( let t = fn_met(
array_t.clone(), array_t.clone(),
vec![param_t( vec![param_t(
@ -1189,12 +1187,12 @@ impl Context {
}, },
); );
self.register_impl("__mul__", op_t, Const, Private); self.register_impl("__mul__", op_t, Const, Private);
let op_t = bin_op(l.clone(), r.clone(), mono_proj(mono_q("L"), "DivO")); let op_t = bin_op(l.clone(), r, mono_proj(mono_q("L"), "DivO"));
let op_t = quant( let op_t = quant(
op_t, op_t,
set! { set! {
static_instance("R", Type), static_instance("R", Type),
subtypeof(l, poly_trait("Mul", params.clone())) subtypeof(l, poly_trait("Mul", params))
}, },
); );
self.register_impl("__div__", op_t, Const, Private); self.register_impl("__div__", op_t, Const, Private);
@ -1223,7 +1221,7 @@ impl Context {
self.register_impl("__or__", bin_op(Bool, Bool, Bool), Const, Private); self.register_impl("__or__", bin_op(Bool, Bool, Bool), Const, Private);
let t = mono_q("T"); let t = mono_q("T");
let op_t = bin_op(t.clone(), t.clone(), range(t.clone())); let op_t = bin_op(t.clone(), t.clone(), range(t.clone()));
let op_t = quant(op_t, set! {subtypeof(t.clone(), trait_("Ord"))}); let op_t = quant(op_t, set! {subtypeof(t, trait_("Ord"))});
self.register_decl("__rng__", op_t.clone(), Private); self.register_decl("__rng__", op_t.clone(), Private);
self.register_decl("__lorng__", op_t.clone(), Private); self.register_decl("__lorng__", op_t.clone(), Private);
self.register_decl("__rorng__", op_t.clone(), Private); self.register_decl("__rorng__", op_t.clone(), Private);

View file

@ -171,7 +171,7 @@ impl Context {
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let mut return_t = branch_ts[0].typ().return_t().unwrap().clone(); let mut return_t = branch_ts[0].typ().return_t().unwrap().clone();
for arg_t in branch_ts.iter().skip(1) { for arg_t in branch_ts.iter().skip(1) {
return_t = self.rec_union(&return_t, &arg_t.typ().return_t().unwrap()); return_t = self.rec_union(&return_t, arg_t.typ().return_t().unwrap());
} }
let param_ty = ParamTy::anonymous(match_target_expr_t.clone()); let param_ty = ParamTy::anonymous(match_target_expr_t.clone());
let param_ts = [vec![param_ty], branch_ts.to_vec()].concat(); let param_ts = [vec![param_ty], branch_ts.to_vec()].concat();
@ -520,8 +520,7 @@ impl Context {
Type::Subr(subr) => { Type::Subr(subr) => {
let callee = if let Some(name) = method_name { let callee = if let Some(name) = method_name {
let attr = hir::Attribute::new(obj.clone(), name.clone(), Type::Ellipsis); let attr = hir::Attribute::new(obj.clone(), name.clone(), Type::Ellipsis);
let acc = hir::Expr::Accessor(hir::Accessor::Attr(attr)); hir::Expr::Accessor(hir::Accessor::Attr(attr))
acc
} else { } else {
obj.clone() obj.clone()
}; };
@ -668,7 +667,7 @@ impl Context {
&self, &self,
callee: &hir::Expr, callee: &hir::Expr,
arg: &hir::KwArg, arg: &hir::KwArg,
default_params: &Vec<ParamTy>, default_params: &[ParamTy],
passed_params: &mut Set<Str>, passed_params: &mut Set<Str>,
) -> TyCheckResult<()> { ) -> TyCheckResult<()> {
let arg_t = arg.expr.ref_t(); let arg_t = arg.expr.ref_t();
@ -744,7 +743,7 @@ impl Context {
); );
self.substitute_call(obj, method_name, &instance, pos_args, kw_args)?; self.substitute_call(obj, method_name, &instance, pos_args, kw_args)?;
log!(info "Substituted:\ninstance: {instance}"); log!(info "Substituted:\ninstance: {instance}");
let res = self.eval.eval_t_params(instance, &self, self.level)?; let res = self.eval.eval_t_params(instance, self, self.level)?;
log!(info "Params evaluated:\nres: {res}\n"); log!(info "Params evaluated:\nres: {res}\n");
self.propagate(&res, obj)?; self.propagate(&res, obj)?;
log!(info "Propagated:\nres: {res}\n"); log!(info "Propagated:\nres: {res}\n");
@ -981,7 +980,7 @@ impl Context {
ctx.super_classes ctx.super_classes
.iter() .iter()
.chain(ctx.super_traits.iter()) .chain(ctx.super_traits.iter())
.map(|sup| self.rec_get_nominal_type_ctx(&sup).unwrap()), .map(|sup| self.rec_get_nominal_type_ctx(sup).unwrap()),
) )
} else { } else {
todo!("{t} not found") todo!("{t} not found")

View file

@ -103,7 +103,7 @@ impl TyVarContext {
params: Vec<TyParam>, params: Vec<TyParam>,
ctx: &Context, ctx: &Context,
) -> Type { ) -> 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 (_, ctx) = ctx let (_, ctx) = ctx
.rec_get_nominal_type_ctx(&poly_trait(name.clone(), params.clone())) .rec_get_nominal_type_ctx(&poly_trait(name.clone(), params.clone()))
.unwrap_or_else(|| panic!("{} not found", name)); .unwrap_or_else(|| panic!("{} not found", name));
@ -123,7 +123,7 @@ impl TyVarContext {
.collect(); .collect();
let mut inst_defaults = vec![]; let mut inst_defaults = vec![];
for template in temp_defaults for template in temp_defaults
.into_iter() .iter()
.take(defined_params_len - given_params_len) .take(defined_params_len - given_params_len)
{ {
let tp = self.instantiate_const_template(&tvar_name, name, template); let tp = self.instantiate_const_template(&tvar_name, name, template);
@ -197,15 +197,13 @@ impl TyVarContext {
&named_free_var(name.clone(), self.level, constraint), &named_free_var(name.clone(), self.level, constraint),
); );
} }
} else if let Some(tp) = self.typaram_instances.get(&name) {
tp.update_constraint(constraint);
} else { } else {
if let Some(tp) = self.typaram_instances.get(&name) { self.push_or_init_typaram(
tp.update_constraint(constraint); &name,
} else { &TyParam::named_free_var(name.clone(), self.level, t),
self.push_or_init_typaram( );
&name,
&TyParam::named_free_var(name.clone(), self.level, t),
);
}
} }
} }
} }
@ -471,7 +469,7 @@ impl Context {
}; };
if let Some(decl_pt) = opt_decl_t { if let Some(decl_pt) = opt_decl_t {
self.sub_unify( self.sub_unify(
&decl_pt.typ(), decl_pt.typ(),
&spec_t, &spec_t,
None, None,
sig.t_spec.as_ref().map(|s| s.loc()), sig.t_spec.as_ref().map(|s| s.loc()),
@ -530,7 +528,7 @@ impl Context {
pub(crate) fn instantiate_const_expr(&self, expr: &ast::ConstExpr) -> TyParam { pub(crate) fn instantiate_const_expr(&self, expr: &ast::ConstExpr) -> TyParam {
match expr { match expr {
ast::ConstExpr::Lit(lit) => TyParam::Value(eval_lit(&lit)), ast::ConstExpr::Lit(lit) => TyParam::Value(eval_lit(lit)),
ast::ConstExpr::Accessor(ast::ConstAccessor::Local(name)) => { ast::ConstExpr::Accessor(ast::ConstAccessor::Local(name)) => {
TyParam::Mono(name.inspect().clone()) TyParam::Mono(name.inspect().clone())
} }
@ -836,16 +834,14 @@ impl Context {
pub(crate) fn instantiate(&self, quantified: Type, callee: &hir::Expr) -> TyCheckResult<Type> { pub(crate) fn instantiate(&self, quantified: Type, callee: &hir::Expr) -> TyCheckResult<Type> {
match quantified { match quantified {
Quantified(quant) => { Quantified(quant) => {
let mut tv_ctx = TyVarContext::new(self.level, quant.bounds, &self); let mut tv_ctx = TyVarContext::new(self.level, quant.bounds, self);
let t = Self::instantiate_t(*quant.unbound_callable, &mut tv_ctx); let t = Self::instantiate_t(*quant.unbound_callable, &mut tv_ctx);
match &t { if let Type::Subr(subr) = &t {
Type::Subr(subr) => match subr.kind.self_t() { if let Some(l) = subr.kind.self_t() {
Some(l) => { self.unify(l, callee.ref_t(), None, Some(callee.loc()))?;
self.unify(l, callee.ref_t(), None, Some(callee.loc()))?; }
} } else {
_ => {} unreachable!()
},
_ => unreachable!(),
} }
Ok(t) Ok(t)
} }

View file

@ -1,5 +1,7 @@
//! Defines `Context`. //! Defines `Context`.
//!
//! `Context` is used for type inference and type checking. //! `Context` is used for type inference and type checking.
#![allow(clippy::result_unit_err)]
pub mod cache; pub mod cache;
pub mod compare; pub mod compare;
pub mod hint; pub mod hint;
@ -91,7 +93,7 @@ impl TyParamIdx {
TyParam::Type(t) if t.as_ref() == target => return Some(Self::Nth(i)), TyParam::Type(t) if t.as_ref() == target => return Some(Self::Nth(i)),
TyParam::Type(t) if t.is_monomorphic() => {} TyParam::Type(t) if t.is_monomorphic() => {}
TyParam::Type(inner) => { TyParam::Type(inner) => {
if let Some(inner) = Self::search(&inner, target) { if let Some(inner) = Self::search(inner, target) {
return Some(Self::nested(i, inner)); return Some(Self::nested(i, inner));
} }
} }
@ -111,7 +113,7 @@ impl TyParamIdx {
match self { match self {
Self::Nth(n) => { Self::Nth(n) => {
let tps = from.typarams(); let tps = from.typarams();
let tp = tps.iter().nth(n).unwrap(); let tp = tps.get(n).unwrap();
match tp { match tp {
TyParam::Type(t) => *t.clone(), TyParam::Type(t) => *t.clone(),
_ => todo!(), _ => todo!(),
@ -328,6 +330,7 @@ impl Context {
) )
} }
#[allow(clippy::too_many_arguments)]
pub fn with_capacity( pub fn with_capacity(
name: Str, name: Str,
kind: ContextKind, kind: ContextKind,

View file

@ -274,14 +274,14 @@ impl Context {
let sub_t = if sig.ident.is_procedural() { let sub_t = if sig.ident.is_procedural() {
proc( proc(
non_default_params.clone(), non_default_params.clone(),
var_args.as_ref().map(|v| *(*v).clone()), var_args.cloned(),
default_params.clone(), default_params.clone(),
body_t.clone(), body_t.clone(),
) )
} else { } else {
func( func(
non_default_params.clone(), non_default_params.clone(),
var_args.as_ref().map(|v| *(*v).clone()), var_args.cloned(),
default_params.clone(), default_params.clone(),
body_t.clone(), body_t.clone(),
) )

View file

@ -63,9 +63,9 @@ impl Context {
pub fn test_instantiation_and_generalization(&self) -> Result<(), ()> { pub fn test_instantiation_and_generalization(&self) -> Result<(), ()> {
let t = mono_q("T"); let t = mono_q("T");
let eq = poly_trait("Eq", vec![TyParam::t(t.clone())]); let eq = poly_trait("Eq", vec![TyParam::t(t.clone())]);
let bound = TyBound::subtype_of(t.clone(), eq.clone()); let bound = TyBound::subtype_of(t.clone(), eq);
let bounds = set! {bound}; let bounds = set! {bound};
let unbound_t = func1(t.clone(), t.clone()); let unbound_t = func1(t.clone(), t);
let quantified = quant(unbound_t.clone(), bounds.clone()); let quantified = quant(unbound_t.clone(), bounds.clone());
println!("quantified : {quantified}"); println!("quantified : {quantified}");
let mut tv_ctx = TyVarContext::new(self.level + 1, bounds, self); let mut tv_ctx = TyVarContext::new(self.level + 1, bounds, self);

View file

@ -28,7 +28,7 @@ impl Context {
pub const GENERIC_LEVEL: usize = usize::MAX; pub const GENERIC_LEVEL: usize = usize::MAX;
/// 型を非依存化する /// 型を非依存化する
fn _independentise<'a>(_t: Type, _ts: &[Type]) -> Type { fn _independentise(_t: Type, _ts: &[Type]) -> Type {
todo!() todo!()
} }
@ -194,7 +194,7 @@ impl Context {
let sub = self.generalize_t_inner(sub.clone(), bounds, lazy_inits); let sub = self.generalize_t_inner(sub.clone(), bounds, lazy_inits);
let sup = self.generalize_t_inner(sup.clone(), bounds, lazy_inits); let sup = self.generalize_t_inner(sup.clone(), bounds, lazy_inits);
// let bs = sub_bs.concat(sup_bs); // let bs = sub_bs.concat(sup_bs);
bounds.insert(TyBound::sandwiched(sub, mono_q(name.clone()), sup)); bounds.insert(TyBound::sandwiched(sub, mono_q(name), sup));
} }
Constraint::TypeOf(t) => { Constraint::TypeOf(t) => {
let t = self.generalize_t_inner(t.clone(), bounds, lazy_inits); let t = self.generalize_t_inner(t.clone(), bounds, lazy_inits);
@ -378,7 +378,7 @@ impl Context {
pub(crate) fn deref_toplevel(&mut self, mut hir: hir::HIR) -> TyCheckResult<hir::HIR> { pub(crate) fn deref_toplevel(&mut self, mut hir: hir::HIR) -> TyCheckResult<hir::HIR> {
self.level = 0; self.level = 0;
for chunk in hir.module.iter_mut() { for chunk in hir.module.iter_mut() {
self.deref_expr_t(chunk).map_err(|e| e)?; self.deref_expr_t(chunk)?;
} }
Ok(hir) Ok(hir)
} }
@ -805,7 +805,7 @@ impl Context {
{ {
self.unify(l.typ(), r.typ(), lhs_loc, rhs_loc)?; self.unify(l.typ(), r.typ(), lhs_loc, rhs_loc)?;
} }
for (l, r) in ls.var_params.as_ref().zip(rs.var_params.as_ref()) { if let Some((l, r)) = ls.var_params.as_ref().zip(rs.var_params.as_ref()) {
self.unify(l.typ(), r.typ(), lhs_loc, rhs_loc)?; self.unify(l.typ(), r.typ(), lhs_loc, rhs_loc)?;
} }
for lpt in ls.default_params.iter() { for lpt in ls.default_params.iter() {
@ -1051,7 +1051,7 @@ impl Context {
rfv.update_constraint(new_constraint); rfv.update_constraint(new_constraint);
lfv.link(maybe_sup); lfv.link(maybe_sup);
} }
return Ok(()) Ok(())
} }
(_, Type::FreeVar(rfv)) if rfv.is_unbound() => { (_, Type::FreeVar(rfv)) if rfv.is_unbound() => {
// NOTE: cannot `borrow_mut` because of cycle reference // NOTE: cannot `borrow_mut` because of cycle reference
@ -1107,7 +1107,7 @@ impl Context {
}, },
_ => {} _ => {}
} }
return Ok(()); Ok(())
} }
(Type::FreeVar(lfv), _) if lfv.is_unbound() => { (Type::FreeVar(lfv), _) if lfv.is_unbound() => {
let lfv_ref = &mut *lfv.borrow_mut(); let lfv_ref = &mut *lfv.borrow_mut();
@ -1156,7 +1156,7 @@ impl Context {
}, },
_ => {} _ => {}
} }
return Ok(()); Ok(())
} }
(Type::FreeVar(_fv), _r) => todo!(), (Type::FreeVar(_fv), _r) => todo!(),
(Type::Subr(lsub), Type::Subr(rsub)) => { (Type::Subr(lsub), Type::Subr(rsub)) => {
@ -1169,7 +1169,7 @@ impl Context {
|(l, r)| self.unify(l.typ(), r.typ(), sub_loc, sup_loc), |(l, r)| self.unify(l.typ(), r.typ(), sub_loc, sup_loc),
)?; )?;
self.unify(&lsub.return_t, &rsub.return_t, sub_loc, sup_loc)?; self.unify(&lsub.return_t, &rsub.return_t, sub_loc, sup_loc)?;
return Ok(()); Ok(())
} }
(Type::MonoProj { .. }, _) => todo!(), (Type::MonoProj { .. }, _) => todo!(),
(_, Type::MonoProj { .. }) => todo!(), (_, Type::MonoProj { .. }) => todo!(),

View file

@ -118,7 +118,7 @@ impl ErrorDisplay for CompileError {
fn caused_by(&self) -> &str { fn caused_by(&self) -> &str {
&self.caused_by &self.caused_by
} }
fn ref_inner(&self) -> Option<&Box<Self>> { fn ref_inner(&self) -> Option<&Self> {
None None
} }
} }
@ -245,7 +245,7 @@ impl ErrorDisplay for TyCheckError {
fn caused_by(&self) -> &str { fn caused_by(&self) -> &str {
&self.caused_by &self.caused_by
} }
fn ref_inner(&self) -> Option<&Box<Self>> { fn ref_inner(&self) -> Option<&Self> {
None None
} }
} }

View file

@ -176,13 +176,7 @@ impl Evaluator {
fn eval_const_acc(&self, _acc: &Accessor, ctx: &Context) -> Option<ValueObj> { fn eval_const_acc(&self, _acc: &Accessor, ctx: &Context) -> Option<ValueObj> {
match _acc { match _acc {
Accessor::Local(local) => { Accessor::Local(local) => ctx.rec_get_const_obj(local.inspect()).cloned(),
if let Some(val) = ctx.rec_get_const_obj(local.inspect()) {
Some(val.clone())
} else {
None
}
}
Accessor::Attr(attr) => { Accessor::Attr(attr) => {
let _obj = self.eval_const_expr(&attr.obj, ctx)?; let _obj = self.eval_const_expr(&attr.obj, ctx)?;
todo!() todo!()
@ -220,7 +214,7 @@ impl Evaluator {
if let Expr::Accessor(acc) = call.obj.as_ref() { if let Expr::Accessor(acc) = call.obj.as_ref() {
match acc { match acc {
Accessor::Local(name) if name.is_const() => { Accessor::Local(name) if name.is_const() => {
if let Some(ValueObj::Subr(subr)) = ctx.rec_get_const_obj(&name.inspect()) { if let Some(ValueObj::Subr(subr)) = ctx.rec_get_const_obj(name.inspect()) {
let args = self.eval_args(&call.args)?; let args = self.eval_args(&call.args)?;
Some(subr.call(args)) Some(subr.call(args))
} else { } else {
@ -382,9 +376,7 @@ impl Evaluator {
fn eval_unary_tp(&self, op: OpKind, val: &TyParam) -> EvalResult<TyParam> { fn eval_unary_tp(&self, op: OpKind, val: &TyParam) -> EvalResult<TyParam> {
match val { match val {
TyParam::Value(c) => self TyParam::Value(c) => self.eval_unary_lit(op, c.clone()).map(TyParam::Value),
.eval_unary_lit(op, c.clone())
.map(|v| TyParam::Value(v)),
TyParam::FreeVar(fv) if fv.is_linked() => self.eval_unary_tp(op, &*fv.crack()), TyParam::FreeVar(fv) if fv.is_linked() => self.eval_unary_tp(op, &*fv.crack()),
e @ TyParam::Erased(_) => Ok(e.clone()), e @ TyParam::Erased(_) => Ok(e.clone()),
other => todo!("{op} {other}"), other => todo!("{op} {other}"),

View file

@ -703,12 +703,12 @@ impl RecordAttrs {
self.0.len() self.0.len()
} }
pub fn iter(&self) -> impl Iterator<Item = &Def> { pub fn is_empty(&self) -> bool {
self.0.iter() self.0.is_empty()
} }
pub fn into_iter(self) -> impl Iterator<Item = Def> { pub fn iter(&self) -> impl Iterator<Item = &Def> {
self.0.into_iter() self.0.iter()
} }
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut Def> { pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut Def> {
@ -720,6 +720,14 @@ impl RecordAttrs {
} }
} }
impl IntoIterator for RecordAttrs {
type Item = Def;
type IntoIter = <Vec<Self::Item> as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Record { pub struct Record {
l_brace: Token, l_brace: Token,
@ -772,7 +780,7 @@ pub struct BinOp {
impl NestedDisplay for BinOp { impl NestedDisplay for BinOp {
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, level: usize) -> fmt::Result { fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, level: usize) -> fmt::Result {
write!(f, "`{}`(: {}):\n", self.op.content, self.sig_t)?; writeln!(f, "`{}`(: {}):", self.op.content, self.sig_t)?;
self.lhs.fmt_nest(f, level + 1)?; self.lhs.fmt_nest(f, level + 1)?;
writeln!(f)?; writeln!(f)?;
self.rhs.fmt_nest(f, level + 1) self.rhs.fmt_nest(f, level + 1)

View file

@ -1,4 +1,5 @@
//! defines the compiler for Erg (ergc). //! defines the compiler for Erg (ergc).
#![allow(clippy::large_enum_variant)]
extern crate erg_common; extern crate erg_common;
pub extern crate erg_parser; pub extern crate erg_parser;

View file

@ -500,7 +500,7 @@ impl ASTLowerer {
let found_body_t = block.ref_t(); let found_body_t = block.ref_t();
let expect_body_t = t.return_t().unwrap(); let expect_body_t = t.return_t().unwrap();
if let Err(e) = if let Err(e) =
self.return_t_check(sig.loc(), sig.ident.inspect(), &expect_body_t, found_body_t) self.return_t_check(sig.loc(), sig.ident.inspect(), expect_body_t, found_body_t)
{ {
self.errs.push(e); self.errs.push(e);
} }

View file

@ -1,6 +1,7 @@
//! defines `Expr` (Expression, the minimum executing unit of Erg). //! defines `Expr` (Expression, the minimum executing unit of Erg).
use std::borrow::Borrow; use std::borrow::Borrow;
use std::fmt; use std::fmt;
use std::fmt::Write as _;
use erg_common::error::Location; use erg_common::error::Location;
use erg_common::set::Set as HashSet; use erg_common::set::Set as HashSet;
@ -134,7 +135,7 @@ pub struct Args {
impl NestedDisplay for Args { impl NestedDisplay for Args {
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 {
fmt_lines(self.pos_args.iter(), f, level)?; fmt_lines(self.pos_args.iter(), f, level)?;
writeln!(f, "")?; writeln!(f)?;
fmt_lines(self.kw_args.iter(), f, level) fmt_lines(self.kw_args.iter(), f, level)
} }
} }
@ -504,7 +505,7 @@ impl NestedDisplay for ArrayComprehension {
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result { fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result {
let mut generators = String::new(); let mut generators = String::new();
for (name, gen) in self.generators.iter() { for (name, gen) in self.generators.iter() {
generators.push_str(&format!("{} <- {}, ", name, gen)); write!(generators, "{} <- {}, ", name, gen).unwrap();
} }
write!( write!(
f, f,
@ -678,8 +679,12 @@ impl RecordAttrs {
pub fn iter(&self) -> impl Iterator<Item = &Def> { pub fn iter(&self) -> impl Iterator<Item = &Def> {
self.0.iter() self.0.iter()
} }
}
pub fn into_iter(self) -> impl IntoIterator<Item = Def> { impl IntoIterator for RecordAttrs {
type Item = Def;
type IntoIter = <Vec<Def> as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter() self.0.into_iter()
} }
} }
@ -1220,7 +1225,7 @@ pub struct ConstArgs {
impl NestedDisplay for ConstArgs { impl NestedDisplay for ConstArgs {
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 {
fmt_lines(self.pos_args(), f, level)?; fmt_lines(self.pos_args(), f, level)?;
writeln!(f, "")?; writeln!(f)?;
fmt_lines(self.kw_args(), f, level) fmt_lines(self.kw_args(), f, level)
} }
} }
@ -1713,6 +1718,7 @@ impl VarName {
Self(Token::static_symbol(symbol)) Self(Token::static_symbol(symbol))
} }
#[allow(clippy::should_implement_trait)]
pub fn from_str(symbol: Str) -> Self { pub fn from_str(symbol: Str) -> Self {
Self(Token::from_str(TokenKind::Symbol, &symbol)) Self(Token::from_str(TokenKind::Symbol, &symbol))
} }
@ -1817,7 +1823,7 @@ impl Identifier {
} }
pub const fn inspect(&self) -> &Str { pub const fn inspect(&self) -> &Str {
&self.name.inspect() self.name.inspect()
} }
pub fn is_procedural(&self) -> bool { pub fn is_procedural(&self) -> bool {
@ -2298,6 +2304,12 @@ impl Locational for Params {
} }
} }
type RawParams = (
Vec<ParamSignature>,
Option<Box<ParamSignature>>,
Vec<ParamSignature>,
Option<(Token, Token)>,
);
impl Params { impl Params {
pub fn new( pub fn new(
non_defaults: Vec<ParamSignature>, non_defaults: Vec<ParamSignature>,
@ -2313,14 +2325,7 @@ impl Params {
} }
} }
pub fn deconstruct( pub fn deconstruct(self) -> RawParams {
self,
) -> (
Vec<ParamSignature>,
Option<Box<ParamSignature>>,
Vec<ParamSignature>,
Option<(Token, Token)>,
) {
(self.non_defaults, self.var_args, self.defaults, self.parens) (self.non_defaults, self.var_args, self.defaults, self.parens)
} }

View file

@ -124,7 +124,7 @@ impl ErrorDisplay for ParserRunnerError {
fn caused_by(&self) -> &str { fn caused_by(&self) -> &str {
"" ""
} }
fn ref_inner(&self) -> Option<&Box<Self>> { fn ref_inner(&self) -> Option<&Self> {
None None
} }
} }

View file

@ -91,6 +91,7 @@ impl Lexer /*<'a>*/ {
} }
} }
#[allow(clippy::should_implement_trait)]
pub fn from_str(src: Str) -> Self { pub fn from_str(src: Str) -> Self {
let escaped = normalize_newline(&src); let escaped = normalize_newline(&src);
Lexer { Lexer {
@ -769,7 +770,7 @@ impl Iterator for Lexer /*<'a>*/ {
} }
None => { None => {
let token = self.emit_token(Illegal, "-"); let token = self.emit_token(Illegal, "-");
return Some(Err(LexError::simple_syntax_error(0, token.loc()))); Some(Err(LexError::simple_syntax_error(0, token.loc())))
} }
} }
} }

View file

@ -1,5 +1,6 @@
//! Implements `Parser` for Erg. `Parser` parses the source code to generate `AST`, //! Implements `Parser` for Erg. `Parser` parses the source code to generate `AST`,
//! and performs type checking and other optimizations if necessary. //! and performs type checking and other optimizations if necessary.
#![allow(clippy::large_enum_variant)]
extern crate erg_common; extern crate erg_common;
pub mod ast; pub mod ast;

View file

@ -163,7 +163,7 @@ impl Parser {
self.tokens.insert(0, token); self.tokens.insert(0, token);
} }
fn stack_dec(&mut self) -> () { fn stack_dec(&mut self) {
self.level -= 1; self.level -= 1;
} }
} }
@ -221,8 +221,10 @@ impl ParserRunner {
/// Parses with default configuration /// Parses with default configuration
pub fn parse_with_default_config(input: Input) -> Result<AST, ParserRunnerErrors> { pub fn parse_with_default_config(input: Input) -> Result<AST, ParserRunnerErrors> {
let mut cfg = ErgConfig::default(); let cfg = ErgConfig {
cfg.input = input; input,
..Default::default()
};
let mut self_ = Self::new(cfg); let mut self_ = Self::new(cfg);
self_.parse() self_.parse()
} }
@ -278,12 +280,11 @@ impl Parser {
Some(t) if t.is(Indent) || t.is(Dedent) => { Some(t) if t.is(Indent) || t.is(Dedent) => {
switch_unreachable!() switch_unreachable!()
} }
Some(_) => match self.try_reduce_chunk(true) { Some(_) => {
Ok(expr) => { if let Ok(expr) = self.try_reduce_chunk(true) {
chunks.push(expr); chunks.push(expr);
} }
Err(_) => {} }
},
_ => switch_unreachable!(), _ => switch_unreachable!(),
} }
} }
@ -318,15 +319,12 @@ impl Parser {
} else if t.is(EOF) { } else if t.is(EOF) {
break; break;
} }
match self.try_reduce_chunk(true) { if let Ok(expr) = self.try_reduce_chunk(true) {
Ok(expr) => { block.push(expr);
block.push(expr); if self.cur_is(Dedent) {
if self.cur_is(Dedent) { self.skip();
self.skip(); break;
break;
}
} }
Err(_) => {}
} }
} }
_ => switch_unreachable!(), _ => switch_unreachable!(),
@ -1281,11 +1279,8 @@ impl Parser {
} }
let mut expr = self.try_reduce_expr(true).map_err(|_| self.stack_dec())?; let mut expr = self.try_reduce_expr(true).map_err(|_| self.stack_dec())?;
let rparen = self.lpop(); let rparen = self.lpop();
match &mut expr { if let Expr::Tuple(Tuple::Normal(tup)) = &mut expr {
Expr::Tuple(Tuple::Normal(tup)) => { tup.elems.paren = Some((lparen, rparen));
tup.elems.paren = Some((lparen, rparen));
}
_ => {}
} }
self.level -= 1; self.level -= 1;
Ok(expr) Ok(expr)
@ -1328,7 +1323,7 @@ impl Parser {
self.level -= 1; self.level -= 1;
let err = self.skip_and_throw_syntax_err(caused_by!()); let err = self.skip_and_throw_syntax_err(caused_by!());
self.errs.push(err); self.errs.push(err);
return Err(()); Err(())
} }
} }
} }

View file

@ -43,7 +43,16 @@ fn parse_test2_advanced_syntax() -> Result<(), ParserRunnerErrors> {
fn parse_test_from_code(file_path: &'static str) -> Result<(), ParserRunnerErrors> { fn parse_test_from_code(file_path: &'static str) -> Result<(), ParserRunnerErrors> {
let input = Input::File(file_path.into()); let input = Input::File(file_path.into());
let cfg = ErgConfig::new("exec", 1, false, None, 100, input.clone(), "<module>", 2); let cfg = ErgConfig {
mode: "exec",
opt_level: 1,
dump_as_pyc: false,
python_ver: None,
py_server_timeout: 100,
input: input.clone(),
module: "<module>",
verbose: 2,
};
let lexer = Lexer::new(input.clone()); let lexer = Lexer::new(input.clone());
let mut parser = ParserRunner::new(cfg); let mut parser = ParserRunner::new(cfg);
match parser.parse_token_stream( match parser.parse_token_stream(

View file

@ -1,6 +1,7 @@
use std::fmt; use std::fmt;
use std::fmt::Write as _;
use std::fs::File; use std::fs::File;
use std::io::{BufReader, Read, Write}; use std::io::{BufReader, Read, Write as _};
use std::path::Path; use std::path::Path;
use erg_common::impl_display_from_debug; use erg_common::impl_display_from_debug;
@ -171,44 +172,6 @@ impl Default for CodeObj {
} }
impl CodeObj { impl CodeObj {
pub fn new<S: Into<Str>>(
argcount: u32,
posonlyargcount: u32,
kwonlyargcount: u32,
nlocals: u32,
stacksize: u32,
flags: u32,
code: Vec<u8>,
consts: Vec<ValueObj>,
names: Vec<Str>,
varnames: Vec<Str>,
freevars: Vec<Str>,
cellvars: Vec<Str>,
filename: Str,
name: S,
firstlineno: u32,
lnotab: Vec<u8>,
) -> Self {
Self {
argcount,
posonlyargcount,
kwonlyargcount,
nlocals,
stacksize,
flags,
code,
consts,
names,
varnames,
freevars,
cellvars,
filename,
name: name.into(),
firstlineno,
lnotab,
}
}
pub fn empty<S: Into<Str>, T: Into<Str>>( pub fn empty<S: Into<Str>, T: Into<Str>>(
params: Vec<Str>, params: Vec<Str>,
filename: S, filename: S,
@ -269,7 +232,7 @@ impl CodeObj {
let name = des.deserialize_str(v, python_ver)?; let name = des.deserialize_str(v, python_ver)?;
let firstlineno = Deserializer::deserialize_u32(v); let firstlineno = Deserializer::deserialize_u32(v);
let lnotab = des.deserialize_bytes(v)?; let lnotab = des.deserialize_bytes(v)?;
Ok(CodeObj::new( Ok(CodeObj {
argcount, argcount,
posonlyargcount, posonlyargcount,
kwonlyargcount, kwonlyargcount,
@ -286,7 +249,7 @@ impl CodeObj {
name, name,
firstlineno, firstlineno,
lnotab, lnotab,
)) })
} }
pub fn into_bytes(self, python_ver: u32) -> Vec<u8> { pub fn into_bytes(self, python_ver: u32) -> Vec<u8> {
@ -337,54 +300,54 @@ impl CodeObj {
tables += "Constants:\n"; tables += "Constants:\n";
} }
for (i, obj) in self.consts.iter().enumerate() { for (i, obj) in self.consts.iter().enumerate() {
tables += &format!(" {}: {}\n", i, obj); writeln!(tables, " {}: {}", i, obj).unwrap();
} }
if !self.names.is_empty() { if !self.names.is_empty() {
tables += "Names:\n"; tables += "Names:\n";
} }
for (i, name) in self.names.iter().enumerate() { for (i, name) in self.names.iter().enumerate() {
tables += &format!(" {}: {}\n", i, name); writeln!(tables, " {}: {}", i, name).unwrap();
} }
if !self.varnames.is_empty() { if !self.varnames.is_empty() {
tables += "Varnames:\n"; tables += "Varnames:\n";
} }
for (i, varname) in self.varnames.iter().enumerate() { for (i, varname) in self.varnames.iter().enumerate() {
tables += &format!(" {}: {}\n", i, varname); writeln!(tables, " {}: {}", i, varname).unwrap();
} }
if !self.cellvars.is_empty() { if !self.cellvars.is_empty() {
tables += "Cellvars:\n"; tables += "Cellvars:\n";
} }
for (i, cellvar) in self.cellvars.iter().enumerate() { for (i, cellvar) in self.cellvars.iter().enumerate() {
tables += &format!(" {}: {}\n", i, cellvar); writeln!(tables, " {}: {}", i, cellvar).unwrap();
} }
if !self.freevars.is_empty() { if !self.freevars.is_empty() {
tables += "Freevars:\n"; tables += "Freevars:\n";
} }
for (i, freevar) in self.freevars.iter().enumerate() { for (i, freevar) in self.freevars.iter().enumerate() {
tables += &format!(" {}: {}\n", i, freevar); writeln!(tables, " {}: {}\n", i, freevar).unwrap();
} }
tables tables
} }
fn attrs_info(&self) -> String { fn attrs_info(&self) -> String {
let mut attrs = "".to_string(); let mut attrs = "".to_string();
attrs += &format!("Name: {}\n", self.name); writeln!(attrs, "Name: {}", self.name).unwrap();
attrs += &format!("FileName: {}\n", self.filename); writeln!(attrs, "FileName: {}", self.filename).unwrap();
attrs += &format!("Argument count: {}\n", self.argcount); writeln!(attrs, "Argument count: {}", self.argcount).unwrap();
attrs += &format!("Positional-only arguments: {}\n", self.posonlyargcount); writeln!(attrs, "Positional-only arguments: {}", self.posonlyargcount).unwrap();
attrs += &format!("Kw-only arguments: {}\n", self.kwonlyargcount); writeln!(attrs, "Kw-only arguments: {}", self.kwonlyargcount).unwrap();
attrs += &format!("Number of locals: {}\n", self.nlocals); writeln!(attrs, "Number of locals: {}", self.nlocals).unwrap();
attrs += &format!("Stack size: {}\n", self.stacksize); writeln!(attrs, "Stack size: {}", self.stacksize).unwrap();
let mut flagged = "".to_string(); let mut flagged = "".to_string();
for i in 0..32 { for i in 0..32 {
if (self.flags & (1 << i)) != 0 { if (self.flags & (1 << i)) != 0 {
let flag: CodeObjFlags = 2u32.pow(i).into(); let flag: CodeObjFlags = 2u32.pow(i).into();
flagged += &format!("{:?}, ", flag); write!(flagged, "{:?}, ", flag).unwrap();
} }
} }
flagged.pop(); flagged.pop();
flagged.pop(); flagged.pop();
attrs += &format!("Flags: {}\n", flagged); writeln!(attrs, "Flags: {}", flagged).unwrap();
attrs attrs
} }
@ -397,22 +360,22 @@ impl CodeObj {
let mut sdelta = lnotab_iter.next().unwrap_or(&0); let mut sdelta = lnotab_iter.next().unwrap_or(&0);
let mut ldelta = lnotab_iter.next().unwrap_or(&0); let mut ldelta = lnotab_iter.next().unwrap_or(&0);
let mut instrs = "".to_string(); let mut instrs = "".to_string();
instrs += &format!("lnotab: {:?}\n", self.lnotab); writeln!(instrs, "lnotab: {:?}", self.lnotab).unwrap();
if *sdelta != 0 { if *sdelta != 0 {
instrs += &format!("{}:\n", lineno); writeln!(instrs, "{}:", lineno).unwrap();
} }
loop { loop {
if *sdelta == line_offset { if *sdelta == line_offset {
line_offset = 0; line_offset = 0;
lineno += ldelta; lineno += ldelta;
instrs += &format!("{}:\n", lineno); writeln!(instrs, "{}:", lineno).unwrap();
sdelta = lnotab_iter.next().unwrap_or(&0); sdelta = lnotab_iter.next().unwrap_or(&0);
ldelta = lnotab_iter.next().unwrap_or(&0); ldelta = lnotab_iter.next().unwrap_or(&0);
} }
if let (Some(op), Some(arg)) = (code_iter.next(), code_iter.next()) { if let (Some(op), Some(arg)) = (code_iter.next(), code_iter.next()) {
let op = Opcode::from(*op); let op = Opcode::from(*op);
let s_op = op.to_string(); let s_op = op.to_string();
instrs += &format!("{:>15} {:<25}", idx, s_op); write!(instrs, "{:>15} {:<25}", idx, s_op).unwrap();
match op { match op {
Opcode::COMPARE_OP => { Opcode::COMPARE_OP => {
let op = match arg { let op = match arg {
@ -424,7 +387,7 @@ impl CodeObj {
5 => ">=", 5 => ">=",
_ => "?", _ => "?",
}; };
instrs += &format!("{} ({})", arg, op); write!(instrs, "{} ({})", arg, op).unwrap();
} }
Opcode::STORE_NAME Opcode::STORE_NAME
| Opcode::LOAD_NAME | Opcode::LOAD_NAME
@ -435,30 +398,52 @@ impl CodeObj {
| Opcode::LOAD_METHOD | Opcode::LOAD_METHOD
| Opcode::IMPORT_NAME | Opcode::IMPORT_NAME
| Opcode::IMPORT_FROM => { | Opcode::IMPORT_FROM => {
instrs += &format!("{} ({})", arg, self.names.get(*arg as usize).unwrap()); write!(
instrs,
"{} ({})",
arg,
self.names.get(*arg as usize).unwrap()
)
.unwrap();
} }
Opcode::STORE_DEREF | Opcode::LOAD_DEREF => { Opcode::STORE_DEREF | Opcode::LOAD_DEREF => {
instrs += write!(
&format!("{} ({})", arg, self.freevars.get(*arg as usize).unwrap()); instrs,
"{} ({})",
arg,
self.freevars.get(*arg as usize).unwrap()
)
.unwrap();
} }
Opcode::STORE_FAST | Opcode::LOAD_FAST => { Opcode::STORE_FAST | Opcode::LOAD_FAST => {
instrs += write!(
&format!("{} ({})", arg, self.varnames.get(*arg as usize).unwrap()); instrs,
"{} ({})",
arg,
self.varnames.get(*arg as usize).unwrap()
)
.unwrap();
} }
Opcode::LOAD_CONST => { Opcode::LOAD_CONST => {
instrs += &format!("{} ({})", arg, self.consts.get(*arg as usize).unwrap()); write!(
instrs,
"{} ({})",
arg,
self.consts.get(*arg as usize).unwrap()
)
.unwrap();
} }
Opcode::FOR_ITER => { Opcode::FOR_ITER => {
instrs += &format!("{} (to {})", arg, idx + arg * 2 + 2); write!(instrs, "{} (to {})", arg, idx + arg * 2 + 2).unwrap();
} }
Opcode::JUMP_FORWARD => { Opcode::JUMP_FORWARD => {
instrs += &format!("{} (to {})", arg, idx + arg * 2 + 2); write!(instrs, "{} (to {})", arg, idx + arg * 2 + 2).unwrap();
} }
Opcode::JUMP_ABSOLUTE => { Opcode::JUMP_ABSOLUTE => {
instrs += &format!("{} (to {})", arg, arg * 2); write!(instrs, "{} (to {})", arg, arg * 2).unwrap();
} }
Opcode::POP_JUMP_IF_FALSE | Opcode::POP_JUMP_IF_TRUE => { Opcode::POP_JUMP_IF_FALSE | Opcode::POP_JUMP_IF_TRUE => {
instrs += &format!("{} (to {})", arg, arg * 2); write!(instrs, "{} (to {})", arg, arg * 2).unwrap();
} }
Opcode::MAKE_FUNCTION => { Opcode::MAKE_FUNCTION => {
let flag = match arg { let flag = match arg {
@ -466,17 +451,17 @@ impl CodeObj {
// TODO: // TODO:
_ => "", _ => "",
}; };
instrs += &format!("{} {}", arg, flag); write!(instrs, "{} {}", arg, flag).unwrap();
} }
// Ergでは引数で型キャストする // Ergでは引数で型キャストする
Opcode::BINARY_ADD Opcode::BINARY_ADD
| Opcode::BINARY_SUBTRACT | Opcode::BINARY_SUBTRACT
| Opcode::BINARY_MULTIPLY | Opcode::BINARY_MULTIPLY
| Opcode::BINARY_TRUE_DIVIDE => { | Opcode::BINARY_TRUE_DIVIDE => {
instrs += &format!("{} ({:?})", arg, TypePair::from(*arg)); write!(instrs, "{} ({:?})", arg, TypePair::from(*arg)).unwrap();
} }
other if other.take_arg() => { other if other.take_arg() => {
instrs += &format!("{}", arg); write!(instrs, "{}", arg).unwrap();
} }
_ => {} _ => {}
} }
@ -492,7 +477,7 @@ impl CodeObj {
pub fn code_info(&self) -> String { pub fn code_info(&self) -> String {
let mut info = "".to_string(); let mut info = "".to_string();
info += &format!("Disassembly of {:?}:\n", self); writeln!(info, "Disassembly of {:?}:", self).unwrap();
info += &self.attrs_info(); info += &self.attrs_info();
info += &self.tables_info(); info += &self.tables_info();
info += &self.instr_info(); info += &self.instr_info();

View file

@ -1,3 +1,5 @@
use std::convert::TryInto;
use crate::*; use crate::*;
#[inline] #[inline]
@ -54,11 +56,15 @@ pub fn enum_t(s: Set<ValueObj>) -> Type {
} }
#[inline] #[inline]
pub fn int_interval<P: Into<TyParam>, Q: Into<TyParam>>(op: IntervalOp, l: P, r: Q) -> Type { pub fn int_interval<P, PErr, Q, QErr>(op: IntervalOp, l: P, r: Q) -> Type
let l = l.into(); where
let r = r.into(); P: TryInto<TyParam, Error = PErr>,
let l = l.try_into().unwrap_or_else(|l| todo!("{l}")); PErr: fmt::Debug,
let r = r.try_into().unwrap_or_else(|r| todo!("{r}")); Q: TryInto<TyParam, Error = QErr>,
QErr: fmt::Debug,
{
let l = l.try_into().unwrap_or_else(|l| todo!("{l:?}"));
let r = r.try_into().unwrap_or_else(|r| todo!("{r:?}"));
let name = Str::from(fresh_varname()); let name = Str::from(fresh_varname());
let pred = match op { let pred = match op {
IntervalOp::LeftOpen if l == TyParam::value(NegInf) => Predicate::le(name.clone(), r), IntervalOp::LeftOpen if l == TyParam::value(NegInf) => Predicate::le(name.clone(), r),
@ -165,8 +171,8 @@ pub fn func2(l: Type, r: Type, return_t: Type) -> Type {
pub fn bin_op(l: Type, r: Type, return_t: Type) -> Type { pub fn bin_op(l: Type, r: Type, return_t: Type) -> Type {
nd_func( nd_func(
vec![ vec![
ParamTy::kw(Str::ever("lhs"), l.clone()), ParamTy::kw(Str::ever("lhs"), l),
ParamTy::kw(Str::ever("rhs"), r.clone()), ParamTy::kw(Str::ever("rhs"), r),
], ],
None, None,
return_t, return_t,

View file

@ -216,7 +216,7 @@ impl Deserializer {
let name = self.deserialize_str(v, python_ver)?; let name = self.deserialize_str(v, python_ver)?;
let firstlineno = Self::deserialize_u32(v); let firstlineno = Self::deserialize_u32(v);
let lnotab = self.deserialize_bytes(v)?; let lnotab = self.deserialize_bytes(v)?;
Ok(ValueObj::from(CodeObj::new( Ok(ValueObj::from(CodeObj {
argcount, argcount,
posonlyargcount, posonlyargcount,
kwonlyargcount, kwonlyargcount,
@ -233,7 +233,7 @@ impl Deserializer {
name, name,
firstlineno, firstlineno,
lnotab, lnotab,
))) }))
} }
DataTypePrefix::None => Ok(ValueObj::None), DataTypePrefix::None => Ok(ValueObj::None),
other => Err(DeserializeError::new( other => Err(DeserializeError::new(

View file

@ -212,9 +212,8 @@ impl Constraint {
} }
pub fn update_cyclicity(&mut self, new_cyclicity: Cyclicity) { pub fn update_cyclicity(&mut self, new_cyclicity: Cyclicity) {
match self { if let Self::Sandwiched { cyclicity, .. } = self {
Self::Sandwiched { cyclicity, .. } => *cyclicity = cyclicity.combine(new_cyclicity), *cyclicity = cyclicity.combine(new_cyclicity);
_ => (),
} }
} }
} }

View file

@ -1,6 +1,8 @@
//! defines `Type` (type kind). //! defines `Type` (type kind).
//! //!
//! Type(コンパイラ等で使われる「型」を表現する)を定義する //! Type(コンパイラ等で使われる「型」を表現する)を定義する
#![allow(clippy::derive_hash_xor_eq)]
#![allow(clippy::large_enum_variant)]
pub mod codeobj; pub mod codeobj;
pub mod constructors; pub mod constructors;
pub mod deserialize; pub mod deserialize;
@ -47,11 +49,11 @@ pub trait HasType {
} }
#[inline] #[inline]
fn lhs_t(&self) -> &Type { fn lhs_t(&self) -> &Type {
&self.ref_t().non_default_params().unwrap()[0].typ() self.ref_t().non_default_params().unwrap()[0].typ()
} }
#[inline] #[inline]
fn rhs_t(&self) -> &Type { fn rhs_t(&self) -> &Type {
&self.ref_t().non_default_params().unwrap()[1].typ() self.ref_t().non_default_params().unwrap()[1].typ()
} }
} }
@ -697,7 +699,7 @@ impl LimitedDisplay for SubrType {
param.typ().limited_fmt(f, limit - 1)?; param.typ().limited_fmt(f, limit - 1)?;
} }
if let Some(var_params) = &self.var_params { if let Some(var_params) = &self.var_params {
if self.non_default_params.len() != 0 { if !self.non_default_params.is_empty() {
write!(f, ", ")?; write!(f, ", ")?;
} }
write!(f, "...")?; write!(f, "...")?;
@ -1495,9 +1497,9 @@ impl HasLevel for Type {
for pt in subr.non_default_params.iter() { for pt in subr.non_default_params.iter() {
pt.typ().update_level(level); pt.typ().update_level(level);
} }
subr.var_params if let Some(pt) = subr.var_params.as_ref() {
.as_ref() pt.typ().update_level(level);
.map(|pt| pt.typ().update_level(level)); }
for pt in subr.default_params.iter() { for pt in subr.default_params.iter() {
pt.typ().update_level(level); pt.typ().update_level(level);
} }
@ -1551,7 +1553,9 @@ impl HasLevel for Type {
for pt in subr.non_default_params.iter() { for pt in subr.non_default_params.iter() {
pt.typ().lift(); pt.typ().lift();
} }
subr.var_params.as_ref().map(|pt| pt.typ().lift()); if let Some(pt) = subr.var_params.as_ref() {
pt.typ().lift();
}
for pt in subr.default_params.iter() { for pt in subr.default_params.iter() {
pt.typ().lift(); pt.typ().lift();
} }
@ -1892,10 +1896,7 @@ impl Type {
} }
pub fn is_monomorphic(&self) -> bool { pub fn is_monomorphic(&self) -> bool {
match self.typarams_len() { matches!(self.typarams_len(), Some(0) | None)
Some(0) | None => true,
_ => false,
}
} }
pub const fn is_callable(&self) -> bool { pub const fn is_callable(&self) -> bool {
@ -2092,13 +2093,13 @@ impl Type {
} }
} }
pub const fn var_args(&self) -> Option<&Box<ParamTy>> { pub fn var_args(&self) -> Option<&ParamTy> {
match self { match self {
Self::FreeVar(_) => panic!("fv"), Self::FreeVar(_) => panic!("fv"),
Self::Subr(SubrType { Self::Subr(SubrType {
var_params: var_args, var_params: var_args,
.. ..
}) => var_args.as_ref(), }) => var_args.as_deref(),
Self::Callable { param_ts: _, .. } => todo!(), Self::Callable { param_ts: _, .. } => todo!(),
_ => None, _ => None,
} }
@ -2133,20 +2134,14 @@ impl Type {
} }
pub fn update_constraint(&self, new_constraint: Constraint) { pub fn update_constraint(&self, new_constraint: Constraint) {
match self { if let Self::FreeVar(fv) = self {
Self::FreeVar(fv) => { fv.update_constraint(new_constraint);
fv.update_constraint(new_constraint);
}
_ => {}
} }
} }
pub fn update_cyclicity(&self, new_cyclicity: Cyclicity) { pub fn update_cyclicity(&self, new_cyclicity: Cyclicity) {
match self { if let Self::FreeVar(fv) = self {
Self::FreeVar(fv) => { fv.update_cyclicity(new_cyclicity);
fv.update_cyclicity(new_cyclicity);
}
_ => {}
} }
} }
} }

View file

@ -633,9 +633,8 @@ impl TyParam {
} }
pub fn update_constraint(&self, new_constraint: Constraint) { pub fn update_constraint(&self, new_constraint: Constraint) {
match self { if let Self::Type(t) = self {
Self::Type(t) => t.update_constraint(new_constraint), t.update_constraint(new_constraint);
_ => {}
} }
} }
} }