From 7d3116f5466cf870f98ce080eb786591c7034c42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fe=CC=81lix=20Saparelli?= Date: Mon, 15 Aug 2022 17:37:20 +1200 Subject: [PATCH 1/2] Apply trivial clippy fixes --- compiler/erg_common/codeobj.rs | 60 ++++---- compiler/erg_common/dict.rs | 4 +- compiler/erg_common/error.rs | 8 +- compiler/erg_common/fxhash.rs | 10 +- compiler/erg_common/lazy_buffer.rs | 4 + compiler/erg_common/lib.rs | 8 +- compiler/erg_common/python_util.rs | 2 +- compiler/erg_common/serialize.rs | 50 ++++--- compiler/erg_common/set.rs | 4 +- compiler/erg_common/str.rs | 6 +- compiler/erg_common/tsort.rs | 2 +- compiler/erg_common/ty.rs | 34 +++-- compiler/erg_common/value.rs | 20 +-- compiler/erg_compiler/codegen.rs | 49 +++---- compiler/erg_compiler/context.rs | 206 ++++++++++++--------------- compiler/erg_compiler/effectcheck.rs | 6 + compiler/erg_compiler/eval.rs | 49 +++---- compiler/erg_compiler/hir.rs | 29 ++-- compiler/erg_compiler/initialize.rs | 14 +- compiler/erg_compiler/lower.rs | 18 ++- compiler/erg_compiler/ownercheck.rs | 8 +- compiler/erg_parser/ast.rs | 22 +-- compiler/erg_parser/desugar.rs | 6 + compiler/erg_parser/lex.rs | 79 +++++----- compiler/erg_parser/parse.rs | 34 ++--- compiler/erg_parser/token.rs | 12 +- 26 files changed, 360 insertions(+), 384 deletions(-) diff --git a/compiler/erg_common/codeobj.rs b/compiler/erg_common/codeobj.rs index 913581fe7..e5d491dbc 100644 --- a/compiler/erg_common/codeobj.rs +++ b/compiler/erg_common/codeobj.rs @@ -58,33 +58,33 @@ pub enum CodeObjFlags { Illegal = 0x0000, } -impl Into for u32 { - fn into(self) -> CodeObjFlags { - match self { - 0x0001 => CodeObjFlags::Optimized, - 0x0002 => CodeObjFlags::NewLocals, - 0x0004 => CodeObjFlags::VarArgs, - 0x0008 => CodeObjFlags::VarKeywords, - 0x0010 => CodeObjFlags::Nested, - 0x0020 => CodeObjFlags::Generator, - 0x0040 => CodeObjFlags::NoFree, - 0x0080 => CodeObjFlags::Coroutine, - 0x0100 => CodeObjFlags::IterableCoroutine, - 0x0200 => CodeObjFlags::AsyncGenerator, +impl From for CodeObjFlags { + fn from(flags: u32) -> Self { + match flags { + 0x0001 => Self::Optimized, + 0x0002 => Self::NewLocals, + 0x0004 => Self::VarArgs, + 0x0008 => Self::VarKeywords, + 0x0010 => Self::Nested, + 0x0020 => Self::Generator, + 0x0040 => Self::NoFree, + 0x0080 => Self::Coroutine, + 0x0100 => Self::IterableCoroutine, + 0x0200 => Self::AsyncGenerator, // CO_GENERATOR_ALLOWED, - 0x2000 => CodeObjFlags::FutureDivision, - 0x4000 => CodeObjFlags::FutureAbsoluteImport, - 0x8000 => CodeObjFlags::FutureWithStatement, - 0x1_0000 => CodeObjFlags::FuturePrintFunction, - 0x2_0000 => CodeObjFlags::FutureUnicodeLiterals, - 0x4_0000 => CodeObjFlags::FutureBarryAsBDFL, - 0x8_0000 => CodeObjFlags::FutureGeneratorStop, - 0x10_0000 => CodeObjFlags::FutureAnnotations, + 0x2000 => Self::FutureDivision, + 0x4000 => Self::FutureAbsoluteImport, + 0x8000 => Self::FutureWithStatement, + 0x1_0000 => Self::FuturePrintFunction, + 0x2_0000 => Self::FutureUnicodeLiterals, + 0x4_0000 => Self::FutureBarryAsBDFL, + 0x8_0000 => Self::FutureGeneratorStop, + 0x10_0000 => Self::FutureAnnotations, // EVM flags - 0x1000_0000 => CodeObjFlags::EvmDynParam, - 0x2000_0000 => CodeObjFlags::EvmDynamic, - 0x4000_0000 => CodeObjFlags::EvmNoGC, - _ => CodeObjFlags::Illegal, + 0x1000_0000 => Self::EvmDynParam, + 0x2000_0000 => Self::EvmDynamic, + 0x4000_0000 => Self::EvmNoGC, + _ => Self::Illegal, } } } @@ -330,31 +330,31 @@ impl CodeObj { fn tables_info(&self) -> String { let mut tables = "".to_string(); if !self.consts.is_empty() { - tables += &format!("Constants:\n"); + tables += "Constants:\n"; } for (i, obj) in self.consts.iter().enumerate() { tables += &format!(" {}: {}\n", i, obj); } if !self.names.is_empty() { - tables += &format!("Names:\n"); + tables += "Names:\n"; } for (i, name) in self.names.iter().enumerate() { tables += &format!(" {}: {}\n", i, name); } if !self.varnames.is_empty() { - tables += &format!("Varnames:\n"); + tables += "Varnames:\n"; } for (i, varname) in self.varnames.iter().enumerate() { tables += &format!(" {}: {}\n", i, varname); } if !self.cellvars.is_empty() { - tables += &format!("Cellvars:\n"); + tables += "Cellvars:\n"; } for (i, cellvar) in self.cellvars.iter().enumerate() { tables += &format!(" {}: {}\n", i, cellvar); } if !self.freevars.is_empty() { - tables += &format!("Freevars:\n"); + tables += "Freevars:\n"; } for (i, freevar) in self.freevars.iter().enumerate() { tables += &format!(" {}: {}\n", i, freevar); diff --git a/compiler/erg_common/dict.rs b/compiler/erg_common/dict.rs index 2cd4c824f..98920f176 100644 --- a/compiler/erg_common/dict.rs +++ b/compiler/erg_common/dict.rs @@ -1,6 +1,6 @@ use std::borrow::Borrow; use std::collections::hash_map::{IntoIter, IntoValues, Iter, IterMut, Keys, Values, ValuesMut}; -use std::fmt; +use std::fmt::{self, Write}; use std::hash::{Hash, Hasher}; use std::iter::FromIterator; @@ -42,7 +42,7 @@ impl fmt::Display for Dict { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let mut s = "".to_string(); for (k, v) in self.dict.iter() { - s += &format!("{k}: {v}, "); + write!(s, "{k}: {v}, ")?; } s.pop(); s.pop(); diff --git a/compiler/erg_common/error.rs b/compiler/erg_common/error.rs index 31409fc0d..84988a1fc 100644 --- a/compiler/erg_common/error.rs +++ b/compiler/erg_common/error.rs @@ -328,8 +328,8 @@ impl ErrorCore { } } -pub const VBAR_UNICODE: &'static str = "│"; -pub const VBAR_BREAK_UNICODE: &'static str = "·"; +pub const VBAR_UNICODE: &str = "│"; +pub const VBAR_BREAK_UNICODE: &str = "·"; /// format: /// ```console @@ -399,9 +399,9 @@ pub trait ErrorDisplay { let kind = self.core().kind as u8; let (color, err_or_warn) = if kind < 100 { (RED, "Error") - } else if 100 <= kind && kind < 150 { + } else if (100..150).contains(&kind) { (YELLOW, "Warning") - } else if 150 <= kind && kind < 200 { + } else if (150..200).contains(&kind) { (DEEP_RED, "Error") } else { ("", "Exception") diff --git a/compiler/erg_common/fxhash.rs b/compiler/erg_common/fxhash.rs index 678d7bfd0..a622e32f5 100644 --- a/compiler/erg_common/fxhash.rs +++ b/compiler/erg_common/fxhash.rs @@ -52,6 +52,7 @@ pub type FxHashSet = HashSet>; /// out-performs an FNV-based hash within rustc itself -- the collision rate is /// similar or slightly worse than FNV, but the speed of the hash function /// itself is much higher because it works on up to 8 bytes at a time. +#[derive(Default)] pub struct FxHasher { hash: usize, } @@ -61,13 +62,6 @@ const K: usize = 0x9e3779b9; #[cfg(target_pointer_width = "64")] const K: usize = 0x517cc1b727220a95; -impl Default for FxHasher { - #[inline] - fn default() -> FxHasher { - FxHasher { hash: 0 } - } -} - impl FxHasher { #[inline] fn add_to_hash(&mut self, i: usize) { @@ -97,7 +91,7 @@ impl Hasher for FxHasher { hash.add_to_hash(u16::from_ne_bytes(bytes[..2].try_into().unwrap()) as usize); bytes = &bytes[2..]; } - if (size_of::() > 1) && bytes.len() >= 1 { + if (size_of::() > 1) && !bytes.is_empty() { hash.add_to_hash(bytes[0] as usize); } self.hash = hash.hash; diff --git a/compiler/erg_common/lazy_buffer.rs b/compiler/erg_common/lazy_buffer.rs index abd8a7658..280b2244c 100644 --- a/compiler/erg_common/lazy_buffer.rs +++ b/compiler/erg_common/lazy_buffer.rs @@ -27,6 +27,10 @@ where self.buffer.len() } + pub fn is_empty(&self) -> bool { + self.buffer.is_empty() + } + pub fn get_next(&mut self) -> bool { if self.done { return false; diff --git a/compiler/erg_common/lib.rs b/compiler/erg_common/lib.rs index ebd17ad36..e55692ff0 100644 --- a/compiler/erg_common/lib.rs +++ b/compiler/erg_common/lib.rs @@ -43,7 +43,7 @@ pub fn read_file(mut f: std::fs::File) -> std::io::Result { Ok(s) } -pub fn fmt_vec(v: &Vec) -> String { +pub fn fmt_vec(v: &[T]) -> String { fmt_iter(v.iter()) } @@ -51,7 +51,7 @@ pub fn fmt_slice(v: &[T]) -> String { fmt_iter(v.iter()) } -pub fn fmt_vec_split_with(v: &Vec, splitter: &str) -> String { +pub fn fmt_vec_split_with(v: &[T], splitter: &str) -> String { fmt_iter_split_with(v.iter(), splitter) } @@ -102,13 +102,13 @@ pub fn get_hash(t: &T) -> usize { /// \r\n (Windows), \r (old MacOS) -> \n (Unix) #[inline] pub fn normalize_newline(src: &str) -> String { - src.replace("\r\n", "\n").replace("\r", "\n") + src.replace("\r\n", "\n").replace('\r', "\n") } /// cut \n #[inline] pub fn chomp(src: &str) -> String { - normalize_newline(src).replace("\n", "") + normalize_newline(src).replace('\n', "") } pub fn try_map(i: I, f: F) -> Result, E> diff --git a/compiler/erg_common/python_util.rs b/compiler/erg_common/python_util.rs index 412a1f0f9..9bc3694d3 100644 --- a/compiler/erg_common/python_util.rs +++ b/compiler/erg_common/python_util.rs @@ -20,7 +20,7 @@ pub fn which_python() -> String { if res.is_empty() { panic!("python not found"); } - res.to_string() + res } pub fn detect_magic_number() -> u32 { diff --git a/compiler/erg_common/serialize.rs b/compiler/erg_common/serialize.rs index ff71b657f..18b7328b5 100644 --- a/compiler/erg_common/serialize.rs +++ b/compiler/erg_common/serialize.rs @@ -37,30 +37,30 @@ pub fn get_timestamp_bytes() -> [u8; 4] { pub enum DataTypePrefix { /* sized objects */ Illegal = 0, - Int32 = 'i' as u8, // 0x69 - Int64 = 'I' as u8, // 0x49 - Float = 'f' as u8, // 0x66 (float32, not generated anymore?) - BinFloat = 'g' as u8, // 0x67 (float64) - Complex = 'x' as u8, // 0x78 - BinComplex = 'y' as u8, // 0x79 - True = 'T' as u8, // 0x54 - False = 'F' as u8, // 0x46 - None = 'N' as u8, // 0x4E - StopIter = 'S' as u8, // 0x53 - Ref = 'r' as u8, + Int32 = b'i', // 0x69 + Int64 = b'I', // 0x49 + Float = b'f', // 0x66 (float32, not generated anymore?) + BinFloat = b'g', // 0x67 (float64) + Complex = b'x', // 0x78 + BinComplex = b'y', // 0x79 + True = b'T', // 0x54 + False = b'F', // 0x46 + None = b'N', // 0x4E + StopIter = b'S', // 0x53 + Ref = b'r', /* unsized objects (ref counted) */ - Long = 'l' as u8, // 0x6C + len: u32 + payload: 2*len+3byte (~ -2^31-1 && 2^31 ~) - Str = 's' as u8, // 0x73 + len: u32 + payload - ShortAscii = 'z' as u8, // 0x7A + len: u8 + payload - ShortAsciiInterned = 'Z' as u8, // 0x5A + len: u8 + payload - Unicode = 'u' as u8, // 0x75 + len: u32 + payload - Interned = 't' as u8, // 0x74 + len + payload - SmallTuple = ')' as u8, // 0x29 + len: u8 + payload - Tuple = '(' as u8, // 0x28 + len: u32 + payload - Code = 'c' as u8, // 0x63 + Long = b'l', // 0x6C + len: u32 + payload: 2*len+3byte (~ -2^31-1 && 2^31 ~) + Str = b's', // 0x73 + len: u32 + payload + ShortAscii = b'z', // 0x7A + len: u8 + payload + ShortAsciiInterned = b'Z', // 0x5A + len: u8 + payload + Unicode = b'u', // 0x75 + len: u32 + payload + Interned = b't', // 0x74 + len + payload + SmallTuple = b')', // 0x29 + len: u8 + payload + Tuple = b'(', // 0x28 + len: u32 + payload + Code = b'c', // 0x63 /* Erg specific prefix */ - Builtin = 'b' as u8, // 0x62 + str - Nat = 'n' as u8, + Builtin = b'b', // 0x62 + str + Nat = b'n', } impl_display_from_debug!(DataTypePrefix); @@ -103,7 +103,7 @@ impl From for DataTypePrefix { impl DataTypePrefix { pub const fn is_sized(&self) -> bool { - match self { + matches!(self, Self::Long | Self::Str | Self::ShortAscii @@ -113,9 +113,7 @@ impl DataTypePrefix { | Self::SmallTuple | Self::Tuple | Self::Code - | Self::Builtin => false, - _ => true, - } + | Self::Builtin) } } diff --git a/compiler/erg_common/set.rs b/compiler/erg_common/set.rs index 2aec73192..6c86e32ee 100644 --- a/compiler/erg_common/set.rs +++ b/compiler/erg_common/set.rs @@ -168,7 +168,7 @@ impl Set { pub fn union(&self, other: &Set) -> Set { let u = self.elems.union(&other.elems); Self { - elems: u.into_iter().map(|x| x.clone()).collect(), + elems: u.into_iter().cloned().collect(), } } @@ -176,7 +176,7 @@ impl Set { pub fn intersection(&self, other: &Set) -> Set { let u = self.elems.intersection(&other.elems); Self { - elems: u.into_iter().map(|x| x.clone()).collect(), + elems: u.into_iter().cloned().collect(), } } } diff --git a/compiler/erg_common/str.rs b/compiler/erg_common/str.rs index 654810e5c..96c9e7e3c 100644 --- a/compiler/erg_common/str.rs +++ b/compiler/erg_common/str.rs @@ -32,7 +32,7 @@ impl Add<&str> for Str { impl Hash for Str { fn hash(&self, state: &mut H) { match self { - Str::Rc(s) => (&s[..]).hash(state), + Str::Rc(s) => (s[..]).hash(state), Str::Static(s) => s.hash(state), } } @@ -59,14 +59,14 @@ impl From<&'static str> for Str { impl From<&String> for Str { #[inline] fn from(s: &String) -> Self { - Str::Rc((&s[..]).into()) + Str::Rc((s[..]).into()) } } impl From for Str { #[inline] fn from(s: String) -> Self { - Str::Rc((&s[..]).into()) + Str::Rc((s[..]).into()) } } diff --git a/compiler/erg_common/tsort.rs b/compiler/erg_common/tsort.rs index aa95036c3..bb243df26 100644 --- a/compiler/erg_common/tsort.rs +++ b/compiler/erg_common/tsort.rs @@ -44,7 +44,7 @@ fn reorder_by_key(mut g: Graph, idx: Vec) -> Graph { fn dfs(g: &Graph, v: T, used: &mut Set, idx: &mut Vec) { used.insert(v.clone()); - for node_id in g.iter().find(|n| &n.id == &v).unwrap().depends_on.iter() { + for node_id in g.iter().find(|n| n.id == v).unwrap().depends_on.iter() { if !used.contains(node_id) { dfs(g, node_id.clone(), used, idx); } diff --git a/compiler/erg_common/ty.rs b/compiler/erg_common/ty.rs index 356678c50..4baa4c316 100644 --- a/compiler/erg_common/ty.rs +++ b/compiler/erg_common/ty.rs @@ -67,7 +67,7 @@ thread_local! { pub fn fresh_varname() -> String { REFINEMENT_VAR_ID.with(|id| { *id.borrow_mut() += 1; - let i = id.borrow().clone(); + let i = *id.borrow(); format!("%v{i}") }) } @@ -75,7 +75,7 @@ pub fn fresh_varname() -> String { pub fn fresh_param_name() -> String { REFINEMENT_VAR_ID.with(|id| { *id.borrow_mut() += 1; - let i = id.borrow().clone(); + let i = *id.borrow(); format!("%p{i}") }) } @@ -1472,9 +1472,9 @@ impl HasLevel for SubrKind { Self::FuncMethod(t) => t.update_level(level), Self::ProcMethod { before, after } => { before.update_level(level); - after.as_ref().map(|t| { + if let Some(t) = after.as_ref() { t.update_level(level); - }); + } } _ => {} } @@ -1485,9 +1485,9 @@ impl HasLevel for SubrKind { Self::FuncMethod(t) => t.lift(), Self::ProcMethod { before, after } => { before.lift(); - after.as_ref().map(|t| { + if let Some(t) = after.as_ref() { t.lift(); - }); + } } _ => {} } @@ -1546,13 +1546,11 @@ impl SubrKind { } pub fn same_kind_as(&self, other: &Self) -> bool { - match (self, other) { + matches!((self, other), (Self::Func, Self::Func) | (Self::Proc, Self::Proc) | (Self::FuncMethod(_), Self::FuncMethod(_)) - | (Self::ProcMethod { .. }, Self::ProcMethod { .. }) => true, - _ => false, - } + | (Self::ProcMethod { .. }, Self::ProcMethod { .. })) } pub fn self_t(&self) -> Option<&SelfType> { @@ -2029,7 +2027,7 @@ impl Type { Predicate::le(name.clone(), r), ), IntervalOp::Open if l == TyParam::value(NegInf) && r == TyParam::value(Inf) => { - return Type::refinement(name.clone(), Type::Int, set! {}) + return Type::refinement(name, Type::Int, set! {}) } // l<.. {I: classof(l) | I >= l+ε and I <= r-ε} IntervalOp::Open => Predicate::and( @@ -2037,7 +2035,7 @@ impl Type { Predicate::le(name.clone(), TyParam::pred(r)), ), }; - Type::refinement(name.clone(), Type::Int, set! {pred}) + Type::refinement(name, Type::Int, set! {pred}) } pub fn iter(t: Type) -> Self { @@ -2333,7 +2331,7 @@ impl Type { if fv.is_linked() { fv.crack().is_mut() } else { - fv.unbound_name().unwrap().ends_with("!") + fv.unbound_name().unwrap().ends_with('!') } } Self::IntMut @@ -2346,7 +2344,7 @@ impl Type { | Self::MonoQVar(name) | Self::Poly { name, .. } | Self::PolyQVar { name, .. } - | Self::MonoProj { rhs: name, .. } => name.ends_with("!"), + | Self::MonoProj { rhs: name, .. } => name.ends_with('!'), _ => false, } } @@ -2460,9 +2458,9 @@ impl Type { }, ) => todo!(), (Self::Record(_l), Self::Record(_r)) => todo!(), - (Self::Refinement(l), Self::Refinement(r)) => l.t.rec_eq(&r.t) && &l.preds == &r.preds, + (Self::Refinement(l), Self::Refinement(r)) => l.t.rec_eq(&r.t) && l.preds == r.preds, (Self::Quantified(l), Self::Quantified(r)) => { - l.unbound_callable.rec_eq(&r.unbound_callable) && &l.bounds == &r.bounds + l.unbound_callable.rec_eq(&r.unbound_callable) && l.bounds == r.bounds } (Self::And(l), Self::And(r)) | (Self::Not(l), Self::Not(r)) @@ -2567,7 +2565,7 @@ impl Type { Self::Callable { .. } => "Callable", Self::Record(_) => "Record", Self::VarArgs(_) => "VarArgs", - Self::Poly { name, .. } | Self::PolyQVar { name, .. } => &*name, + Self::Poly { name, .. } | Self::PolyQVar { name, .. } => name, // NOTE: compiler/codegen/convert_to_python_methodでクラス名を使うため、こうすると都合が良い Self::Refinement(refine) => refine.t.name(), Self::Quantified(_) => "Quantified", @@ -3038,7 +3036,7 @@ impl From for TypePair { 62 => Self::ProcArray, 63 => Self::ProcProc, 64 => Self::Others, - 65 | _ => Self::Illegals, + _ => Self::Illegals, } } } diff --git a/compiler/erg_common/value.rs b/compiler/erg_common/value.rs index 43b1b248c..45a636730 100644 --- a/compiler/erg_common/value.rs +++ b/compiler/erg_common/value.rs @@ -2,7 +2,7 @@ //! //! コンパイラ、VM等で使われる(データも保持した)値オブジェクトを定義する use std::cmp::Ordering; -use std::fmt; +use std::fmt::{self, Write}; use std::hash::{Hash, Hasher}; use std::ops::Neg; use std::rc::Rc; @@ -56,7 +56,7 @@ impl fmt::Debug for ValueObj { Self::Dict(dict) => { let mut s = "".to_string(); for (k, v) in dict.iter() { - s += &format!("{k}: {v}, "); + write!(s, "{k}: {v}, ")?; } s.pop(); s.pop(); @@ -255,11 +255,11 @@ impl ValueObj { pub fn from_str(t: Type, content: Str) -> Self { match t { - Type::Int => Self::Int(content.replace("_", "").parse::().unwrap()), - Type::Nat => Self::Nat(content.replace("_", "").parse::().unwrap()), - Type::Float => Self::Float(content.replace("_", "").parse::().unwrap()), + Type::Int => Self::Int(content.replace('_', "").parse::().unwrap()), + Type::Nat => Self::Nat(content.replace('_', "").parse::().unwrap()), + Type::Float => Self::Float(content.replace('_', "").parse::().unwrap()), // TODO: - Type::Ratio => Self::Float(content.replace("_", "").parse::().unwrap()), + Type::Ratio => Self::Float(content.replace('_', "").parse::().unwrap()), Type::Str => { if &content[..] == "\"\"" { Self::Str(Str::from("")) @@ -288,18 +288,18 @@ impl ValueObj { match self { Self::Int(i) => [ vec![DataTypePrefix::Int32 as u8], - i32::from(i).to_le_bytes().to_vec(), + i.to_le_bytes().to_vec(), ] .concat(), // TODO: Natとしてシリアライズ Self::Nat(n) => [ vec![DataTypePrefix::Int32 as u8], - i32::from(n as i32).to_le_bytes().to_vec(), + (n as i32).to_le_bytes().to_vec(), ] .concat(), Self::Float(f) => [ vec![DataTypePrefix::BinFloat as u8], - f64::from(f).to_le_bytes().to_vec(), + f.to_le_bytes().to_vec(), ] .concat(), Self::Str(s) => str_into_bytes(s, false), @@ -310,7 +310,7 @@ impl ValueObj { let mut bytes = Vec::with_capacity(arr.len()); bytes.push(DataTypePrefix::Tuple as u8); bytes.append(&mut (arr.len() as u32).to_le_bytes().to_vec()); - for obj in arr.to_vec().into_iter() { + for obj in arr.iter().cloned() { bytes.append(&mut obj.into_bytes()); } bytes diff --git a/compiler/erg_compiler/codegen.rs b/compiler/erg_compiler/codegen.rs index 482e2ecc8..476fde40f 100644 --- a/compiler/erg_compiler/codegen.rs +++ b/compiler/erg_compiler/codegen.rs @@ -51,8 +51,8 @@ fn convert_to_python_attr(class: &str, uniq_obj_name: Option<&str>, name: Str) - fn escape_attr(class: &str, uniq_obj_name: Option<&str>, name: Str) -> Str { let mut name = convert_to_python_attr(class, uniq_obj_name, name).to_string(); - name = name.replace("!", "__erg_proc__"); - name = name.replace("$", "__erg_shared__"); + name = name.replace('!', "__erg_proc__"); + name = name.replace('$', "__erg_shared__"); Str::rc(&name) } @@ -78,8 +78,8 @@ fn convert_to_python_name(name: Str) -> Str { fn escape_name(name: Str) -> Str { let mut name = convert_to_python_name(name).to_string(); - name = name.replace("!", "__erg_proc__"); - name = name.replace("$", "__erg_shared__"); + name = name.replace('!', "__erg_proc__"); + name = name.replace('$', "__erg_shared__"); Str::rc(&name) } @@ -290,15 +290,12 @@ impl CodeGenerator { } else { Some(Name::fast(idx)) } - } else if let Some(idx) = self + } else { self .cur_block_codeobj() .freevars .iter() .position(|f| &**f == name) - { - Some(Name::deref(idx)) - } else { - None + .map(Name::deref) } } @@ -307,7 +304,7 @@ impl CodeGenerator { // search_name()を実行した後なのでcur_blockはskipする for (nth_from_toplevel, block) in self.units.iter_mut().enumerate().rev().skip(1) { let block_is_toplevel = nth_from_toplevel == 0; - if let Some(_) = block.codeobj.cellvars.iter().position(|c| &**c == name) { + if block.codeobj.cellvars.iter().any(|c| &**c == name) { return Some(StoreLoadKind::Deref); } else if let Some(idx) = block.codeobj.varnames.iter().position(|v| &**v == name) { if block_is_toplevel { @@ -319,10 +316,8 @@ impl CodeGenerator { return Some(StoreLoadKind::Deref); } } - if block_is_toplevel { - if let Some(_) = block.codeobj.names.iter().position(|n| &**n == name) { - return Some(StoreLoadKind::Global); - } + if block_is_toplevel && block.codeobj.names.iter().any(|n| &**n == name) { + return Some(StoreLoadKind::Global); } } // 見つからなかった変数(前方参照変数など)はグローバル @@ -363,14 +358,14 @@ impl CodeGenerator { } fn register_attr(&mut self, class: &str, uniq_obj_name: Option<&str>, name: Str) -> Name { - let name = Str::rc(name.split(".").last().unwrap()); + let name = Str::rc(name.split('.').last().unwrap()); let name = escape_attr(class, uniq_obj_name, name); self.mut_cur_block_codeobj().names.push(name); Name::local(self.cur_block_codeobj().names.len() - 1) } fn register_method(&mut self, class: &str, uniq_obj_name: Option<&str>, name: Str) -> Name { - let name = Str::rc(name.split(".").last().unwrap()); + let name = Str::rc(name.split('.').last().unwrap()); let name = escape_attr(class, uniq_obj_name, name); self.mut_cur_block_codeobj().names.push(name); Name::local(self.cur_block_codeobj().names.len() - 1) @@ -493,7 +488,7 @@ impl CodeGenerator { .iter() .map(|p| p.inspect().map(|s| &s[..]).unwrap_or("_")), ) - .map(|s| self.get_cached(&s)) + .map(|s| self.get_cached(s)) .collect() } @@ -590,7 +585,7 @@ impl CodeGenerator { let idx_pop_jump_if_false = self.cur_block().lasti; self.write_instr(POP_JUMP_IF_FALSE); // cannot detect where to jump to at this moment, so put as 0 - self.write_arg(0 as u8); + self.write_arg(0_u8); match args.remove(0) { // then block Expr::Lambda(lambda) => { @@ -603,7 +598,7 @@ impl CodeGenerator { } if args.get(0).is_some() { self.write_instr(JUMP_FORWARD); // jump to end - self.write_arg(0 as u8); + self.write_arg(0_u8); // else block let idx_else_begin = self.cur_block().lasti; self.edit_code(idx_pop_jump_if_false + 1, idx_else_begin / 2); @@ -659,7 +654,7 @@ impl CodeGenerator { let mut absolute_jump_points = vec![]; while let Some(expr) = args.try_remove(0) { // パターンが複数ある場合引数を複製する、ただし最後はしない - if len > 1 && args.len() > 0 { + if len > 1 && !args.is_empty() { self.write_instr(Opcode::DUP_TOP); self.write_arg(0); self.stack_inc(); @@ -1145,9 +1140,9 @@ impl CodeGenerator { if !self.units.is_empty() { let ld = unit.prev_lineno - self.cur_block().prev_lineno; if ld != 0 { - self.mut_cur_block_codeobj().lnotab.last_mut().map(|l| { + if let Some(l) = self.mut_cur_block_codeobj().lnotab.last_mut() { *l += ld as u8; - }); + } self.mut_cur_block().prev_lineno += ld; } } @@ -1204,9 +1199,9 @@ impl CodeGenerator { if !self.units.is_empty() { let ld = unit.prev_lineno - self.cur_block().prev_lineno; if ld != 0 { - self.mut_cur_block_codeobj().lnotab.last_mut().map(|l| { + if let Some(l) = self.mut_cur_block_codeobj().lnotab.last_mut() { *l += ld as u8; - }); + } self.mut_cur_block().prev_lineno += ld; } } @@ -1242,7 +1237,7 @@ impl CodeGenerator { self.edit_code(print_point, Opcode::NOP as usize); } else { self.write_instr(CALL_FUNCTION); - self.write_arg(1 as u8); + self.write_arg(1_u8); } self.stack_dec(); } @@ -1271,9 +1266,9 @@ impl CodeGenerator { if !self.units.is_empty() { let ld = unit.prev_lineno - self.cur_block().prev_lineno; if ld != 0 { - self.mut_cur_block_codeobj().lnotab.last_mut().map(|l| { + if let Some(l) = self.mut_cur_block_codeobj().lnotab.last_mut() { *l += ld as u8; - }); + } self.mut_cur_block().prev_lineno += ld; } } diff --git a/compiler/erg_compiler/context.rs b/compiler/erg_compiler/context.rs index 697069f53..a9c150fc0 100644 --- a/compiler/erg_compiler/context.rs +++ b/compiler/erg_compiler/context.rs @@ -176,7 +176,7 @@ impl TyVarContext { Type::Poly { params, .. } => params.iter().fold(dep, |acc, arg| { [acc, Self::rec_tp_inner_qvars(arg, vec![])].concat() }), - Type::VarArgs(t) => Self::rec_t_inner_qvars(&t, dep), + Type::VarArgs(t) => Self::rec_t_inner_qvars(t, dep), Type::Subr(_subr) => todo!(), Type::Callable { param_ts: _, return_t: _ } => todo!(), Type::And(_) | Type::Or(_) | Type::Not(_) => todo!(), @@ -210,11 +210,10 @@ impl TyVarContext { TyBound::Subtype { sub, sup } => { let sup = match sup { Type::Poly { name, params } => { - let sup = Type::poly( + Type::poly( name, params.into_iter().map(|p| self.instantiate_tp(p)).collect(), - ); - sup + ) } Type::MonoProj { lhs, rhs } => Type::mono_proj(self.instantiate_t(*lhs), rhs), sup => sup, @@ -226,11 +225,10 @@ impl TyVarContext { TyBound::Supertype { sup, sub } => { let sub = match sub { Type::Poly { name, params } => { - let sub = Type::poly( + Type::poly( name, params.into_iter().map(|p| self.instantiate_tp(p)).collect(), - ); - sub + ) } Type::MonoProj { lhs, rhs } => Type::mono_proj(self.instantiate_t(*lhs), rhs), sub => sub, @@ -242,22 +240,20 @@ impl TyVarContext { TyBound::Sandwiched { sub, mid, sup } => { let sub = match sub { Type::Poly { name, params } => { - let sub = Type::poly( + Type::poly( name, params.into_iter().map(|p| self.instantiate_tp(p)).collect(), - ); - sub + ) } Type::MonoProj { lhs, rhs } => Type::mono_proj(self.instantiate_t(*lhs), rhs), sub => sub, }; let sup = match sup { Type::Poly { name, params } => { - let sup = Type::poly( + Type::poly( name, params.into_iter().map(|p| self.instantiate_tp(p)).collect(), - ); - sup + ) } Type::MonoProj { lhs, rhs } => Type::mono_proj(self.instantiate_t(*lhs), rhs), sup => sup, @@ -269,16 +265,15 @@ impl TyVarContext { TyBound::Instance { name, t } => { let t = match t { Type::Poly { name, params } => { - let t = Type::poly( + Type::poly( name, params.into_iter().map(|p| self.instantiate_tp(p)).collect(), - ); - t + ) } t => t, }; // TODO: type-like types - if &t == &Type { + if t == Type { let constraint = Constraint::TypeOf(t); self.push_tyvar( name.clone(), @@ -299,10 +294,10 @@ impl TyVarContext { match quantified { Type::MonoQVar(n) => { if let Some(t) = self.get_tyvar(&n) { - return t.clone(); + t.clone() } else if let Some(t) = self.get_typaram(&n) { if let TyParam::Type(t) = t { - return *t.clone(); + *t.clone() } else { todo!() } @@ -318,9 +313,9 @@ impl TyVarContext { match quantified { TyParam::MonoQVar(n) => { if let Some(t) = self.get_typaram(&n) { - return t.clone(); + t.clone() } else if let Some(t) = self.get_tyvar(&n) { - return TyParam::t(t.clone()); + TyParam::t(t.clone()) } else { panic!("Type parameter {n} is not found. This is a bug.") } @@ -328,9 +323,9 @@ impl TyVarContext { TyParam::Type(t) => { if let Type::MonoQVar(n) = *t { if let Some(t) = self.get_typaram(&n) { - return t.clone(); + t.clone() } else if let Some(t) = self.get_tyvar(&n) { - return TyParam::t(t.clone()); + TyParam::t(t.clone()) } else { panic!("Type variable {n} is not found. This is a bug.") } @@ -710,9 +705,7 @@ impl Context { v.inspect(), )); } - let kind = id - .map(|id| VarKind::Defined(id)) - .unwrap_or(VarKind::Declared); + let kind = id.map_or(VarKind::Declared, VarKind::Defined); let sig_t = self.instantiate_var_sig_t(sig, opt_t, PreRegister)?; self.decls .insert(v.clone(), VarInfo::new(sig_t, muty, vis, kind)); @@ -743,9 +736,7 @@ impl Context { ) -> TyCheckResult<()> { let name = sig.name.inspect(); let muty = Mutability::from(&name[..]); - let kind = id - .map(|id| VarKind::Defined(id)) - .unwrap_or(VarKind::Declared); + let kind = id.map_or(VarKind::Declared, VarKind::Defined); if self.registered(name, name.is_uppercase()) { return Err(TyCheckError::duplicate_decl_error( sig.loc(), @@ -805,7 +796,7 @@ impl Context { v.inspect(), )) } else { - if let Some(_) = self.decls.remove(v.inspect()) { + if self.decls.remove(v.inspect()).is_some() { // something to do? } let vi = VarInfo::new(generalized, muty, vis, VarKind::Defined(id)); @@ -957,7 +948,7 @@ impl Context { let name = &sig.name; // FIXME: constでない関数 let t = self - .get_current_scope_var(&name.inspect()) + .get_current_scope_var(name.inspect()) .map(|v| &v.t) .unwrap(); let non_default_params = t.non_default_params().unwrap(); @@ -1490,7 +1481,7 @@ impl Context { ) .map_err(|e| { // REVIEW: - let name = callee.var_full_name().unwrap_or("".to_string()); + let name = callee.var_full_name().unwrap_or_else(|| "".to_string()); let name = name + "::" + param_ty.name.as_ref().map(|s| &s[..]).unwrap_or(""); TyCheckError::type_mismatch_error( @@ -1649,18 +1640,12 @@ impl Context { /// 可変依存型の変更を伝搬させる fn propagate(&self, t: &Type, callee: &hir::Expr) -> TyCheckResult<()> { - match t { - Type::Subr(subr) => match &subr.kind { - SubrKind::ProcMethod { - before: _, - after: Some(after), - } => { - let receiver_t = callee.receiver_t().unwrap(); - self.reunify(receiver_t, after, Some(callee.loc()), None)?; - } - _ => {} - }, - _ => {} + if let Type::Subr(SubrType { + kind: SubrKind::ProcMethod { after: Some(after), .. }, + .. + }) = t { + let receiver_t = callee.receiver_t().unwrap(); + self.reunify(receiver_t, after, Some(callee.loc()), None)?; } Ok(()) } @@ -1682,7 +1667,7 @@ impl Context { return Ok(()); } match (l, r) { - (TyParam::Type(l), TyParam::Type(r)) => self.unify(&l, &r, None, None), + (TyParam::Type(l), TyParam::Type(r)) => self.unify(l, r, None, None), (ltp @ TyParam::FreeVar(lfv), rtp @ TyParam::FreeVar(rfv)) if lfv.is_unbound() && rfv.is_unbound() => { @@ -1701,11 +1686,11 @@ impl Context { FreeKind::Unbound { .. } | FreeKind::NamedUnbound { .. } => {} } // &fv is dropped let fv_t = fv.borrow().constraint().unwrap().typ().unwrap().clone(); // fvを参照しないよいにcloneする(あとでborrow_mutするため) - let tp_t = self.eval.get_tp_t(tp, bounds, &self)?; + let tp_t = self.eval.get_tp_t(tp, bounds, self)?; if self.rec_full_supertype_of(&fv_t, &tp_t) { // 外部未連携型変数の場合、linkしないで制約を弱めるだけにする(see compiler/inference.md) if fv.level() < Some(self.level) { - let new_constraint = Constraint::SubtypeOf(tp_t.clone()); + let new_constraint = Constraint::SubtypeOf(tp_t); if self.is_sub_constraint_of( fv.borrow().constraint().unwrap(), &new_constraint, @@ -1717,17 +1702,15 @@ impl Context { fv.link(tp); } Ok(()) + } else if allow_divergence + && (self.eq_tp(tp, &TyParam::value(Inf), None, None) + || self.eq_tp(tp, &TyParam::value(NegInf), None, None)) + && self.rec_full_subtype_of(&fv_t, &Type::mono("Num")) + { + fv.link(tp); + Ok(()) } else { - if allow_divergence - && (self.eq_tp(&tp, &TyParam::value(Inf), None, None) - || self.eq_tp(&tp, &TyParam::value(NegInf), None, None)) - && self.rec_full_subtype_of(&fv_t, &Type::mono("Num")) - { - fv.link(tp); - Ok(()) - } else { - Err(TyCheckError::unreachable(fn_name!(), line!())) - } + Err(TyCheckError::unreachable(fn_name!(), line!())) } } (TyParam::UnaryOp { op: lop, val: lval }, TyParam::UnaryOp { op: rop, val: rval }) @@ -1769,7 +1752,7 @@ impl Context { *l.borrow_mut() = r.borrow().clone(); Ok(()) } - (TyParam::Type(l), TyParam::Type(r)) => self.reunify(&l, &r, None, None), + (TyParam::Type(l), TyParam::Type(r)) => self.reunify(l, r, None, None), (TyParam::UnaryOp { op: lop, val: lval }, TyParam::UnaryOp { op: rop, val: rval }) if lop == rop => { @@ -2333,7 +2316,7 @@ impl Context { self.instantiate_typespec(spec, mode)? } else { match &sig.pat { - ast::ParamPattern::Lit(lit) => Type::enum_t(set![self.eval.eval_const_lit(&lit)]), + ast::ParamPattern::Lit(lit) => Type::enum_t(set![self.eval.eval_const_lit(lit)]), // TODO: Array _ => { let level = if mode == PreRegister { @@ -2607,7 +2590,7 @@ impl Context { self.caused_by(), "match", &Type::mono("LambdaFunc"), - &t, + t, )); } } @@ -2633,13 +2616,13 @@ impl Context { // NG: expr_t: Nat, union_pat_t: {1, 2} // OK: expr_t: Int, union_pat_t: {1} | 'T if expr_t.has_no_unbound_var() - && self.formal_supertype_of(&expr_t, &union_pat_t, None, None) - && !self.formal_supertype_of(&union_pat_t, &expr_t, None, None) + && self.formal_supertype_of(expr_t, &union_pat_t, None, None) + && !self.formal_supertype_of(&union_pat_t, expr_t, None, None) { return Err(TyCheckError::match_error( pos_args[0].loc(), self.caused_by(), - &expr_t, + expr_t, )); } let branch_ts = pos_args @@ -2658,7 +2641,7 @@ impl Context { }; let param_ts = [ vec![ParamTy::anonymous(expr_t)], - branch_ts.iter().map(|pt| pt.clone()).collect(), + branch_ts.to_vec(), ] .concat(); let t = Type::func(param_ts, vec![], return_t); @@ -2749,8 +2732,8 @@ impl Context { ) -> TyCheckResult { erg_common::debug_power_assert!(args.len() == 2); let symbol = Token::symbol(binop_to_dname(op.inspect())); - let mut op = hir::Expr::Accessor(hir::Accessor::local(symbol, Type::ASTOmitted)); - self.get_call_t(&mut op, args, &[], namespace).map_err(|e| { + let op = hir::Expr::Accessor(hir::Accessor::local(symbol, Type::ASTOmitted)); + self.get_call_t(&op, args, &[], namespace).map_err(|e| { // HACK: dname.loc()はダミーLocationしか返さないので、エラーならop.loc()で上書きする let core = ErrorCore::new( e.core.errno, @@ -2771,8 +2754,8 @@ impl Context { ) -> TyCheckResult { erg_common::debug_power_assert!(args.len() == 1); let symbol = Token::symbol(unaryop_to_dname(op.inspect())); - let mut op = hir::Expr::Accessor(hir::Accessor::local(symbol, Type::ASTOmitted)); - self.get_call_t(&mut op, args, &[], namespace).map_err(|e| { + let op = hir::Expr::Accessor(hir::Accessor::local(symbol, Type::ASTOmitted)); + self.get_call_t(&op, args, &[], namespace).map_err(|e| { let core = ErrorCore::new( e.core.errno, e.core.kind, @@ -2809,7 +2792,7 @@ impl Context { log!("Substituted:\ninstance: {instance}"); let res = self.deref_tyvar(instance)?; log!("Eliminated:\nres: {res}\n"); - let res = self.eval.eval_t_params(res, &self, self.level)?; + let res = self.eval.eval_t_params(res, self, self.level)?; log!("Params Evaluated:\nres: {res}\n"); let res = self.deref_tyvar(res)?; log!("Eliminated (2):\nres: {res}\n"); @@ -2873,13 +2856,13 @@ impl Context { | FreeKind::NamedUnbound { constraint, .. } => { let t = constraint.typ().unwrap(); let other_t = self.type_of(other, bounds); - return self.formal_supertype_of(&t, &other_t, bounds, lhs_variance); + return self.formal_supertype_of(t, &other_t, bounds, lhs_variance); } }, (l, r) if l == r => return true, _ => {} } - self.eval.shallow_eq_tp(lhs, rhs, &self) + self.eval.shallow_eq_tp(lhs, rhs, self) } /// e.g. @@ -3292,7 +3275,7 @@ impl Context { // try_cmp((n: 2.._), 1) -> Some(Greater) // try_cmp((n: -1.._), 1) -> Some(Any) (l @ (TyParam::Erased(_) | TyParam::FreeVar(_) | TyParam::MonoQVar(_)), p) => { - let t = self.eval.get_tp_t(l, bounds, &self).unwrap(); + let t = self.eval.get_tp_t(l, bounds, self).unwrap(); let inf = self.inf(&t); let sup = self.sup(&t); if let (Some(inf), Some(sup)) = (inf, sup) { @@ -3355,7 +3338,7 @@ impl Context { Refinement(r) => r, t => { let var = Str::from(fresh_varname()); - RefinementType::new(var.clone(), t, set! {}) + RefinementType::new(var, t, set! {}) } } } @@ -3486,7 +3469,7 @@ impl Context { #[inline] fn type_of(&self, p: &TyParam, bounds: Option<&Set>) -> Type { - self.eval.get_tp_t(p, bounds, &self).unwrap() + self.eval.get_tp_t(p, bounds, self).unwrap() } // sup/inf({±∞}) = ±∞ではあるが、Inf/NegInfにはOrdを実装しない @@ -3501,7 +3484,7 @@ impl Context { if lhs == &refine.var => { if let Some(max) = &maybe_max { - if self.try_cmp(rhs, &max, None).unwrap() == Greater { + if self.try_cmp(rhs, max, None).unwrap() == Greater { maybe_max = Some(rhs.clone()); } } else { @@ -3529,7 +3512,7 @@ impl Context { if lhs == &refine.var => { if let Some(min) = &maybe_min { - if self.try_cmp(rhs, &min, None).unwrap() == Less { + if self.try_cmp(rhs, min, None).unwrap() == Less { maybe_min = Some(rhs.clone()); } } else { @@ -3753,24 +3736,22 @@ impl Context { fn rec_get_patch(&self, name: &VarName) -> Option<&Context> { if let Some(patch) = self.patches.get(name) { - return Some(patch); + Some(patch) + } else if let Some(outer) = &self.outer { + outer.rec_get_patch(name) } else { - if let Some(outer) = &self.outer { - return outer.rec_get_patch(name); - } + None } - None } fn rec_get_mod(&self, name: &str) -> Option<&Context> { if let Some(mod_) = self.mods.get(name) { - return Some(mod_); + Some(mod_) + } else if let Some(outer) = &self.outer { + outer.rec_get_mod(name) } else { - if let Some(outer) = &self.outer { - return outer.rec_get_mod(name); - } + None } - None } fn rec_get_trait_impls(&self, name: &Str) -> Vec { @@ -3785,37 +3766,34 @@ impl Context { } // 再帰サブルーチン/型の推論を可能にするため、予め登録しておく - pub(crate) fn preregister(&mut self, block: &Vec) -> TyCheckResult<()> { + pub(crate) fn preregister(&mut self, block: &[ast::Expr]) -> TyCheckResult<()> { for expr in block.iter() { - match expr { - ast::Expr::Def(def) => { - let id = Some(def.body.id); - let eval_body_t = || { - self.eval - .eval_const_block(&def.body.block, &self) - .map(|c| Type::enum_t(set![c])) - }; - match &def.sig { - ast::Signature::Subr(sig) => { - let opt_ret_t = if let Some(spec) = sig.return_t_spec.as_ref() { - Some(self.instantiate_typespec(spec, PreRegister)?) - } else { - eval_body_t() - }; - self.declare_sub(&sig, opt_ret_t, id)?; - } - ast::Signature::Var(sig) if sig.is_const() => { - let t = if let Some(spec) = sig.t_spec.as_ref() { - Some(self.instantiate_typespec(spec, PreRegister)?) - } else { - eval_body_t() - }; - self.declare_var(&sig, t, id)?; - } - _ => {} + if let ast::Expr::Def(def) = expr { + let id = Some(def.body.id); + let eval_body_t = || { + self.eval + .eval_const_block(&def.body.block, self) + .map(|c| Type::enum_t(set![c])) + }; + match &def.sig { + ast::Signature::Subr(sig) => { + let opt_ret_t = if let Some(spec) = sig.return_t_spec.as_ref() { + Some(self.instantiate_typespec(spec, PreRegister)?) + } else { + eval_body_t() + }; + self.declare_sub(sig, opt_ret_t, id)?; } + ast::Signature::Var(sig) if sig.is_const() => { + let t = if let Some(spec) = sig.t_spec.as_ref() { + Some(self.instantiate_typespec(spec, PreRegister)?) + } else { + eval_body_t() + }; + self.declare_var(sig, t, id)?; + } + _ => {} } - _ => {} } } Ok(()) diff --git a/compiler/erg_compiler/effectcheck.rs b/compiler/erg_compiler/effectcheck.rs index a5f1ec86c..484d88e0b 100644 --- a/compiler/erg_compiler/effectcheck.rs +++ b/compiler/erg_compiler/effectcheck.rs @@ -219,3 +219,9 @@ impl SideEffectChecker { } } } + +impl Default for SideEffectChecker { + fn default() -> Self { + Self::new() + } +} diff --git a/compiler/erg_compiler/eval.rs b/compiler/erg_compiler/eval.rs index b54ab5e38..f6305d6cb 100644 --- a/compiler/erg_compiler/eval.rs +++ b/compiler/erg_compiler/eval.rs @@ -28,17 +28,14 @@ impl SubstContext { let param_names = ty_ctx.params.iter().map(|(opt_name, _)| { opt_name .as_ref() - .map(|n| n.inspect().clone()) - .unwrap_or(Str::ever("_")) - .clone() + .map_or_else(|| Str::ever("_"), |n| n.inspect().clone()) }); - let self_ = SubstContext { + // REVIEW: 順番は保証されるか? 引数がunnamed_paramsに入る可能性は? + SubstContext { params: param_names .zip(substituted.typarams().into_iter()) .collect(), - }; - // REVIEW: 順番は保証されるか? 引数がunnamed_paramsに入る可能性は? - self_ + } } fn substitute(&self, quant_t: Type, ty_ctx: &Context, level: usize) -> TyCheckResult { @@ -58,10 +55,8 @@ impl SubstContext { if let Some(v) = self.params.get(&name) { ty_ctx.unify_tp(param, v, None, None, false)?; } - } else { - if fv.is_unbound() { - panic!() - } + } else if fv.is_unbound() { + panic!() } } TyParam::BinOp { lhs, rhs, .. } => { @@ -192,28 +187,28 @@ impl Evaluator { match op { Add => lhs .try_add(rhs) - .ok_or(EvalError::unreachable(fn_name!(), line!())), + .ok_or_else(|| EvalError::unreachable(fn_name!(), line!())), Sub => lhs .try_sub(rhs) - .ok_or(EvalError::unreachable(fn_name!(), line!())), + .ok_or_else(|| EvalError::unreachable(fn_name!(), line!())), Mul => lhs .try_mul(rhs) - .ok_or(EvalError::unreachable(fn_name!(), line!())), + .ok_or_else(|| EvalError::unreachable(fn_name!(), line!())), Div => lhs .try_div(rhs) - .ok_or(EvalError::unreachable(fn_name!(), line!())), + .ok_or_else(|| EvalError::unreachable(fn_name!(), line!())), Gt => lhs .try_gt(rhs) - .ok_or(EvalError::unreachable(fn_name!(), line!())), + .ok_or_else(|| EvalError::unreachable(fn_name!(), line!())), Ge => lhs .try_ge(rhs) - .ok_or(EvalError::unreachable(fn_name!(), line!())), + .ok_or_else(|| EvalError::unreachable(fn_name!(), line!())), Eq => lhs .try_eq(rhs) - .ok_or(EvalError::unreachable(fn_name!(), line!())), + .ok_or_else(|| EvalError::unreachable(fn_name!(), line!())), Ne => lhs .try_ne(rhs) - .ok_or(EvalError::unreachable(fn_name!(), line!())), + .ok_or_else(|| EvalError::unreachable(fn_name!(), line!())), other => todo!("{other}"), } } @@ -227,7 +222,7 @@ impl Evaluator { match (lhs, rhs) { (TyParam::ConstObj(ConstObj::Value(lhs)), TyParam::ConstObj(ConstObj::Value(rhs))) => { self.eval_bin_lit(op, lhs.clone(), rhs.clone()) - .map(|v| TyParam::value(v)) + .map(TyParam::value) } ( TyParam::ConstObj(ConstObj::MutValue(lhs)), @@ -272,14 +267,14 @@ impl Evaluator { fn eval_unary_tp(&self, op: OpKind, val: &TyParam) -> EvalResult { match val { - TyParam::ConstObj(c) => self.eval_unary_lit(op, c.clone()).map(|c| TyParam::cons(c)), + TyParam::ConstObj(c) => self.eval_unary_lit(op, c.clone()).map(TyParam::cons), TyParam::FreeVar(fv) if fv.is_linked() => self.eval_unary_tp(op, &*fv.crack()), e @ TyParam::Erased(_) => Ok(e.clone()), other => todo!("{op} {other}"), } } - fn eval_app(&self, _name: &Str, _args: &Vec) -> EvalResult { + fn eval_app(&self, _name: &Str, _args: &[TyParam]) -> EvalResult { todo!() } @@ -294,7 +289,7 @@ impl Evaluator { ConstObj::Value(v) => Some(TyParam::value(v.clone())), _ => None, }) - .ok_or(EvalError::unreachable(fn_name!(), line!())), + .ok_or_else(|| EvalError::unreachable(fn_name!(), line!())), TyParam::BinOp { op, lhs, rhs } => self.eval_bin_tp(*op, lhs, rhs), TyParam::UnaryOp { op, val } => self.eval_unary_tp(*op, val), TyParam::App { name, args } => self.eval_app(name, args), @@ -443,7 +438,7 @@ impl Evaluator { match p { TyParam::ConstObj(ConstObj::Value(v)) => Ok(Type::enum_t(set![v])), TyParam::ConstObj(ConstObj::MutValue(v)) => Ok(v.borrow().class().mutate()), - TyParam::Erased(t) => Ok((&*t).clone()), + TyParam::Erased(t) => Ok((*t).clone()), TyParam::FreeVar(fv) => { if let Some(t) = fv.type_of() { Ok(t) @@ -459,7 +454,7 @@ impl Evaluator { ConstObj::Value(v) => Some(Type::enum_t(set![v.clone()])), _ => None, }) - .ok_or(EvalError::unreachable(fn_name!(), line!())), + .ok_or_else(|| EvalError::unreachable(fn_name!(), line!())), TyParam::MonoQVar(name) => { if let Some(bs) = bounds { if let Some(bound) = bs.iter().find(|b| b.mentions_as_instance(&name)) { @@ -483,7 +478,7 @@ impl Evaluator { let p = self.eval_tp(p, ctx)?; match p { TyParam::ConstObj(ConstObj::Value(v)) => Ok(v.class()), - TyParam::Erased(t) => Ok((&*t).clone()), + TyParam::Erased(t) => Ok((*t).clone()), TyParam::FreeVar(fv) => { if let Some(t) = fv.type_of() { Ok(t) @@ -499,7 +494,7 @@ impl Evaluator { ConstObj::Value(v) => Some(v.class()), _ => None, }) - .ok_or(EvalError::unreachable(fn_name!(), line!())), + .ok_or_else(|| EvalError::unreachable(fn_name!(), line!())), other => todo!("{other}"), } } diff --git a/compiler/erg_compiler/hir.rs b/compiler/erg_compiler/hir.rs index b2affa606..aa766bde2 100644 --- a/compiler/erg_compiler/hir.rs +++ b/compiler/erg_compiler/hir.rs @@ -108,7 +108,7 @@ pub struct KwArg { impl NestedDisplay for KwArg { fn fmt_nest(&self, f: &mut std::fmt::Formatter<'_>, level: usize) -> std::fmt::Result { - write!(f, "{}:\n", self.keyword)?; + writeln!(f, "{}:", self.keyword)?; self.expr.fmt_nest(f, level + 1) } } @@ -189,6 +189,11 @@ impl Args { self.pos_args.len() + self.kw_args.len() } + #[inline] + pub fn is_empty(&self) -> bool { + self.pos_args.is_empty() && self.kw_args.is_empty() + } + #[inline] pub fn kw_len(&self) -> usize { self.kw_args.len() @@ -563,9 +568,9 @@ pub struct BinOp { impl NestedDisplay for BinOp { fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, level: usize) -> fmt::Result { - write!(f, "`{}`:\n", self.op.content)?; + writeln!(f, "`{}`:", self.op.content)?; self.lhs.fmt_nest(f, level + 1)?; - write!(f, "\n")?; + writeln!(f)?; self.rhs.fmt_nest(f, level + 1) } } @@ -573,15 +578,15 @@ impl NestedDisplay for BinOp { impl HasType for BinOp { #[inline] fn ref_t(&self) -> &Type { - &self.sig_t.return_t().unwrap() + self.sig_t.return_t().unwrap() } #[inline] fn lhs_t(&self) -> &Type { - &self.sig_t.lhs_t() + self.sig_t.lhs_t() } #[inline] fn rhs_t(&self) -> &Type { - &self.sig_t.rhs_t() + self.sig_t.rhs_t() } #[inline] fn signature_t(&self) -> Option<&Type> { @@ -613,7 +618,7 @@ pub struct UnaryOp { impl HasType for UnaryOp { #[inline] fn ref_t(&self) -> &Type { - &self.sig_t.return_t().unwrap() + self.sig_t.return_t().unwrap() } #[inline] fn lhs_t(&self) -> &Type { @@ -631,7 +636,7 @@ impl HasType for UnaryOp { impl NestedDisplay for UnaryOp { fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, level: usize) -> fmt::Result { - write!(f, "`{}`: {}:\n", self.op, self.sig_t)?; + writeln!(f, "`{}`: {}:", self.op, self.sig_t)?; self.expr.fmt_nest(f, level + 1) } } @@ -660,7 +665,7 @@ pub struct Call { impl NestedDisplay for Call { fn fmt_nest(&self, f: &mut std::fmt::Formatter<'_>, level: usize) -> std::fmt::Result { - write!(f, "({}): {}:\n", self.obj, self.sig_t)?; + writeln!(f, "({}): {}:", self.obj, self.sig_t)?; self.args.fmt_nest(f, level + 1) } } @@ -670,7 +675,7 @@ impl_display_from_nested!(Call); impl HasType for Call { #[inline] fn ref_t(&self) -> &Type { - &self.sig_t.return_t().unwrap() + self.sig_t.return_t().unwrap() } #[inline] fn lhs_t(&self) -> &Type { @@ -821,7 +826,7 @@ impl HasType for Lambda { impl NestedDisplay for Lambda { fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, level: usize) -> fmt::Result { - write!(f, "{} {}\n", self.params, self.op.content)?; + writeln!(f, "{} {}", self.params, self.op.content)?; self.body.fmt_nest(f, level + 1) } } @@ -943,7 +948,7 @@ pub struct Def { impl NestedDisplay for Def { fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, level: usize) -> fmt::Result { - write!(f, "{} {}\n", self.sig, self.body.op.content)?; + writeln!(f, "{} {}", self.sig, self.body.op.content)?; self.body.block.fmt_nest(f, level + 1) } } diff --git a/compiler/erg_compiler/initialize.rs b/compiler/erg_compiler/initialize.rs index b5452db42..05b159691 100644 --- a/compiler/erg_compiler/initialize.rs +++ b/compiler/erg_compiler/initialize.rs @@ -111,7 +111,7 @@ impl Context { op_t, set! {subtype(mono_q("Self"), mono("Eq")), subtype(mono_q("R"), poly("Eq", vec![]))}, ); - eq.register_decl("__eq__", op_t.clone(), Public); + eq.register_decl("__eq__", op_t, Public); let mut ord = Self::poly_trait( "Ord", vec![PS::t("R", WithDefault)], @@ -123,7 +123,7 @@ impl Context { op_t, 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, Public); let mut seq = Self::poly_trait( "Seq", vec![PS::t("T", NonDefault)], @@ -142,7 +142,7 @@ impl Context { seq.register_decl("get", t, Public); let params = vec![PS::t("T", NonDefault)]; 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, o) = (mono_q("R"), mono_q("O")); let (r_bound, o_bound) = (static_instance("R", Type), static_instance("O", Type)); let params = vec![PS::t("R", WithDefault), PS::t("O", WithDefault)]; @@ -167,7 +167,7 @@ impl Context { poly("Sub", ty_params.clone()), ); let op_t = fn1_met(poly_q("Self", ty_params.clone()), r.clone(), o.clone()); - let op_t = quant(op_t, set! {r_bound.clone(), o_bound.clone(), self_bound}); + let op_t = quant(op_t, set! {r_bound, o_bound, self_bound}); sub.register_decl("__sub__", op_t, Public); let mut mul = Self::poly_trait("Mul", params.clone(), vec![ poly("Output", vec![ty_tp(mono_q("R"))]), @@ -175,7 +175,7 @@ impl Context { ], Self::TOP_LEVEL); let op_t = fn1_met(poly("Mul", ty_params.clone()), r.clone(), o.clone()); mul.register_decl("__mul__", op_t, Public); - let mut div = Self::poly_trait("Div", params.clone(), vec![ + let mut div = Self::poly_trait("Div", params, vec![ poly("Output", vec![ty_tp(mono_q("R"))]), poly("Output", vec![ty_tp(mono_q("O"))]), ], Self::TOP_LEVEL); @@ -618,8 +618,8 @@ impl Context { let op_t = Type::func2(l.clone(), r.clone(), o.clone()); let op_t = quant(op_t, set! {subtype(l.clone(), poly("Mul", params.clone()))}); self.register_impl("__mul__", op_t, Const, Private); - let op_t = Type::func2(l.clone(), r.clone(), o.clone()); - let op_t = quant(op_t, set! {subtype(l, poly("Mul", params.clone()))}); + let op_t = Type::func2(l.clone(), r, o); + let op_t = quant(op_t, set! {subtype(l, poly("Mul", params))}); self.register_impl("__div__", op_t, Const, Private); let m = mono_q("M"); let op_t = Type::func2(m.clone(), m.clone(), m.clone()); diff --git a/compiler/erg_compiler/lower.rs b/compiler/erg_compiler/lower.rs index d7fb8a4d8..d6c22c772 100644 --- a/compiler/erg_compiler/lower.rs +++ b/compiler/erg_compiler/lower.rs @@ -50,14 +50,14 @@ impl ASTLowerer { expect: &Type, found: &Type, ) -> LowerResult<()> { - self.ctx.unify(expect, found, Some(loc), None).or_else(|_| { - Err(LowerError::type_mismatch_error( + self.ctx.unify(expect, found, Some(loc), None).map_err(|_| { + LowerError::type_mismatch_error( loc, self.ctx.caused_by(), name, expect, found, - )) + ) }) } @@ -176,9 +176,9 @@ impl ASTLowerer { self.lower_expr(arg.expr, true)?, )); } - let mut obj = self.lower_expr(*call.obj, false)?; + let obj = self.lower_expr(*call.obj, false)?; let t = self.ctx.get_call_t( - &mut obj, + &obj, hir_args.pos_args(), hir_args.kw_args(), &self.ctx.name, @@ -283,7 +283,7 @@ impl ASTLowerer { .map(|vi| vi.t.clone()); let name = sig.pat.inspect().unwrap(); if let Some(expect_body_t) = opt_expect_body_t { - if let Err(e) = self.return_t_check(sig.loc(), name, &expect_body_t, &found_body_t) { + if let Err(e) = self.return_t_check(sig.loc(), name, &expect_body_t, found_body_t) { self.errs.push(e); } } @@ -416,3 +416,9 @@ impl ASTLowerer { } } } + +impl Default for ASTLowerer { + fn default() -> Self { + Self::new() + } +} diff --git a/compiler/erg_compiler/ownercheck.rs b/compiler/erg_compiler/ownercheck.rs index 2d6a2a43a..47a0280c3 100644 --- a/compiler/erg_compiler/ownercheck.rs +++ b/compiler/erg_compiler/ownercheck.rs @@ -83,7 +83,7 @@ impl OwnershipChecker { fn check_expr(&mut self, expr: &Expr, ownership: Ownership) { match expr { Expr::Def(def) => { - self.define(&def); + self.define(def); let name_and_vis = match &def.sig { Signature::Var(var) => // TODO: visibility @@ -249,3 +249,9 @@ impl OwnershipChecker { panic!("variable not found: {name}"); } } + +impl Default for OwnershipChecker { + fn default() -> Self { + Self::new() + } +} diff --git a/compiler/erg_parser/ast.rs b/compiler/erg_parser/ast.rs index 8adb98ff8..850b09605 100644 --- a/compiler/erg_parser/ast.rs +++ b/compiler/erg_parser/ast.rs @@ -25,7 +25,7 @@ pub fn fmt_lines<'a, T: NestedDisplay + 'a>( line.fmt_nest(f, level)?; } for arg in iter { - write!(f, "\n")?; + writeln!(f)?; arg.fmt_nest(f, level)?; } Ok(()) @@ -107,7 +107,7 @@ pub struct KwArg { impl NestedDisplay for KwArg { fn fmt_nest(&self, f: &mut std::fmt::Formatter<'_>, level: usize) -> std::fmt::Result { - write!(f, "{}:\n", self.keyword)?; + writeln!(f, "{}:", self.keyword)?; self.expr.fmt_nest(f, level + 1) } } @@ -453,9 +453,9 @@ pub struct BinOp { impl NestedDisplay for BinOp { fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, level: usize) -> fmt::Result { - write!(f, "`{}`:\n", self.op.content)?; + writeln!(f, "`{}`:", self.op.content)?; self.args[0].fmt_nest(f, level + 1)?; - write!(f, "\n")?; + writeln!(f)?; self.args[1].fmt_nest(f, level + 1) } } @@ -485,7 +485,7 @@ pub struct UnaryOp { impl NestedDisplay for UnaryOp { fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, level: usize) -> fmt::Result { - write!(f, "`{}`:\n", self.op.content)?; + writeln!(f, "`{}`:", self.op.content)?; self.args[0].fmt_nest(f, level + 1) } } @@ -515,7 +515,7 @@ pub struct Call { impl NestedDisplay for Call { fn fmt_nest(&self, f: &mut std::fmt::Formatter<'_>, level: usize) -> std::fmt::Result { - write!(f, "({}):\n", self.obj)?; + writeln!(f, "({}):", self.obj)?; self.args.fmt_nest(f, level + 1) } } @@ -1186,7 +1186,7 @@ impl fmt::Display for TypeSpec { Self::Not(lhs, rhs) => write!(f, "{lhs} not {rhs}"), Self::Or(lhs, rhs) => write!(f, "{lhs} or {rhs}"), Self::Array { t, len } => write!(f, "[{t}; {len}]"), - Self::Tuple(tys) => write!(f, "({})", fmt_vec(&tys)), + Self::Tuple(tys) => write!(f, "({})", fmt_vec(tys)), Self::Enum(elems) => write!(f, "{{{elems}}}"), Self::Interval { op, lhs, rhs } => write!(f, "{lhs}{}{rhs}", op.inspect()), Self::Subr(s) => write!(f, "{s}"), @@ -1537,7 +1537,7 @@ impl VarPattern { Self::Array(VarArrayPattern { elems, .. }) | Self::Tuple(VarTuplePattern { elems, .. }) | Self::Record(VarRecordPattern { elems, .. }) => { - elems.iter().map(|s| s.pat.inspects()).flatten().collect() + elems.iter().flat_map(|s| s.pat.inspects()).collect() } _ => vec![], } @@ -1992,7 +1992,7 @@ pub struct Lambda { impl NestedDisplay for Lambda { fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, level: usize) -> fmt::Result { - write!(f, "{} {}\n", self.sig, self.op.content)?; + writeln!(f, "{} {}", self.sig, self.op.content)?; self.body.fmt_nest(f, level + 1) } } @@ -2026,7 +2026,7 @@ impl Signature { pub fn name_as_str(&self) -> &Str { match self { Self::Var(v) => v.pat.inspect().unwrap(), - Self::Subr(s) => &s.name.inspect(), + Self::Subr(s) => s.name.inspect(), } } @@ -2083,7 +2083,7 @@ pub struct Def { impl NestedDisplay for Def { fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, level: usize) -> fmt::Result { - write!(f, "{} {}\n", self.sig, self.body.op.content)?; + writeln!(f, "{} {}", self.sig, self.body.op.content)?; self.body.block.fmt_nest(f, level + 1) } } diff --git a/compiler/erg_parser/desugar.rs b/compiler/erg_parser/desugar.rs index ab9dbdbf3..7d724dd94 100644 --- a/compiler/erg_parser/desugar.rs +++ b/compiler/erg_parser/desugar.rs @@ -193,3 +193,9 @@ impl Desugarer { todo!() } } + +impl Default for Desugarer { + fn default() -> Self { + Self::new() + } +} diff --git a/compiler/erg_parser/lex.rs b/compiler/erg_parser/lex.rs index 36818e022..570785f0d 100644 --- a/compiler/erg_parser/lex.rs +++ b/compiler/erg_parser/lex.rs @@ -1,4 +1,6 @@ //! defines and implements `Lexer` (Tokenizer). +use std::cmp::Ordering; + use erg_common::cache::Cache; use erg_common::config::ErgConfig; use erg_common::config::Input; @@ -105,7 +107,7 @@ impl Lexer /*<'a>*/ { pub fn lex(self) -> Result { let mut result = TokenStream::empty(); let mut errs = LexErrors::empty(); - for i in self.into_iter() { + for i in self { match i { Ok(token) => result.push(token), Err(err) => { @@ -172,19 +174,14 @@ impl Lexer /*<'a>*/ { /// Detect `c` is a bidirectional overriding character. /// [CVE-2021-42574: homoglyph atack](https://blog.rust-lang.org/2021/11/01/cve-2021-42574.html) countermeasures. pub fn is_bidi(c: char) -> bool { - match c { - '\u{200F}' | '\u{202B}' | '\u{202E}' | '\u{2067}' => true, - _ => false, - } + matches!(c, '\u{200F}' | '\u{202B}' | '\u{202E}' | '\u{2067}') } #[inline] fn is_definable_operator(s: &str) -> bool { - match s { + matches!(s, "+" | "-" | "*" | "/" | "//" | "**" | "%" | ".." | "..=" | "~" | "&&" | "||" | "^^" - | ">>" | "<<" | "==" | "!=" | ">" | "<" | ">=" | "<=" | "dot" | "cross" => true, - _ => false, - } + | ">>" | "<<" | "==" | "!=" | ">" | "<" | ">=" | "<=" | "dot" | "cross") } // +, -, * etc. may be pre/bin @@ -209,32 +206,32 @@ impl Lexer /*<'a>*/ { } fn is_zero(s: &str) -> bool { - s.replace("-0", "").replace("0", "").is_empty() + s.replace("-0", "").replace('0', "").is_empty() } /// emit_tokenで一気にcol_token_startsを移動させるのでここでは移動させない fn consume(&mut self) -> Option { let now = self.cursor; self.cursor += 1; - self.chars.get(now).map(|x| *x) + self.chars.get(now).copied() } fn peek_prev_ch(&self) -> Option { if self.cursor == 0 { None } else { - self.chars.get(self.cursor - 1).map(|x| *x) + self.chars.get(self.cursor - 1).copied() } } #[inline] fn peek_cur_ch(&self) -> Option { - self.chars.get(self.cursor).map(|x| *x) + self.chars.get(self.cursor).copied() } #[inline] fn peek_next_ch(&self) -> Option { - self.chars.get(self.cursor + 1).map(|x| *x) + self.chars.get(self.cursor + 1).copied() } fn lex_comment(&mut self) -> LexResult<()> { @@ -322,31 +319,33 @@ impl Lexer /*<'a>*/ { sum + *x }; let sum_indent = self.indent_stack.iter().fold(0, calc_indent_and_validate); - if sum_indent < spaces.len() { - let indent_len = spaces.len() - sum_indent; - self.col_token_starts += sum_indent; - let indent = self.emit_token(Indent, &" ".repeat(indent_len)); - self.indent_stack.push(indent_len); - Some(Ok(indent)) - } else if sum_indent > spaces.len() { - if is_valid_dedent { - let dedent = self.emit_token(Dedent, ""); - self.indent_stack.pop(); - Some(Ok(dedent)) - } else { - let invalid_dedent = self.emit_token(Dedent, ""); - Some(Err(LexError::syntax_error( - 0, - invalid_dedent.loc(), - switch_lang!("invalid indent", "インデントが不正です"), - None, - ))) + match sum_indent.cmp(&spaces.len()) { + Ordering::Less => { + let indent_len = spaces.len() - sum_indent; + self.col_token_starts += sum_indent; + let indent = self.emit_token(Indent, &" ".repeat(indent_len)); + self.indent_stack.push(indent_len); + Some(Ok(indent)) + } + Ordering::Greater => { + if is_valid_dedent { + let dedent = self.emit_token(Dedent, ""); + self.indent_stack.pop(); + Some(Ok(dedent)) + } else { + let invalid_dedent = self.emit_token(Dedent, ""); + Some(Err(LexError::syntax_error( + 0, + invalid_dedent.loc(), + switch_lang!("invalid indent", "インデントが不正です"), + None, + ))) + } + } + Ordering::Equal /* if indent_sum == space.len() */ => { + self.col_token_starts += spaces.len(); + None } - } else - /* if indent_sum == space.len() */ - { - self.col_token_starts += spaces.len(); - None } } @@ -495,7 +494,7 @@ impl Lexer /*<'a>*/ { fn lex_str(&mut self) -> LexResult { let mut s = "\"".to_string(); while let Some(c) = self.peek_cur_ch() { - if c == '\"' && s.chars().last() != Some('\\') { + if c == '\"' && !s.ends_with('\\') { s.push(self.consume().unwrap()); let token = self.emit_token(StrLit, &s); return Ok(token); @@ -805,7 +804,7 @@ impl Iterator for Lexer /*<'a>*/ { ))) } None => { - if self.indent_stack.len() == 0 { + if self.indent_stack.is_empty() { self.accept(EOF, "") } else { self.indent_stack.pop(); diff --git a/compiler/erg_parser/parse.rs b/compiler/erg_parser/parse.rs index 4001f3cda..7be4a08c2 100644 --- a/compiler/erg_parser/parse.rs +++ b/compiler/erg_parser/parse.rs @@ -158,12 +158,10 @@ impl Parser { Side::LhsAssign } // (cur) -> ... ; ... = - else { - if self.arrow_distance(0, 0) == 1 { - Side::LhsLambda - } else { - Side::Rhs - } + else if self.arrow_distance(0, 0) == 1 { + Side::LhsLambda + } else { + Side::Rhs } } } @@ -454,15 +452,8 @@ impl Parser { #[inline] fn opt_reduce_decorators(&mut self) -> ParseResult> { let mut decs = set![]; - loop { - match self.opt_reduce_decorator()? { - Some(deco) => { - decs.insert(deco); - } - None => { - break; - } - } + while let Some(deco) = self.opt_reduce_decorator()? { + decs.insert(deco); } Ok(decs) } @@ -521,14 +512,13 @@ impl Parser { } None } + } else if self.cur_is(Colon) { + self.skip(); + Some(self.try_reduce_type_spec()?) } else { - if self.cur_is(Colon) { - self.skip(); - Some(self.try_reduce_type_spec()?) - } else { - None - } + None }; + Ok(Signature::Var(VarSignature::new( VarPattern::VarName(name), t_spec, @@ -1236,7 +1226,7 @@ impl Parser { }; Ok(KwArg::new(keyword, self.try_reduce_expr()?)) } else { - return Err(ParseError::simple_syntax_error(0, t.loc())); + Err(ParseError::simple_syntax_error(0, t.loc())) } } Some(other) => Err(ParseError::simple_syntax_error(0, other.loc())), diff --git a/compiler/erg_parser/token.rs b/compiler/erg_parser/token.rs index 9b7cf7ab0..e30bcf346 100644 --- a/compiler/erg_parser/token.rs +++ b/compiler/erg_parser/token.rs @@ -293,11 +293,7 @@ impl TokenKind { } pub const fn is_right_associative(&self) -> bool { - match self { - FuncArrow | ProcArrow | Equal => true, - // PreDollar | PreAt => true, - _ => false, - } + matches!(self, FuncArrow | ProcArrow | Equal /* | PreDollar | PreAt */) } } @@ -337,7 +333,7 @@ impl fmt::Debug for Token { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Token") .field("kind", &self.kind) - .field("content", &self.content.replace("\n", "\\n")) + .field("content", &self.content.replace('\n', "\\n")) .field("lineno", &self.lineno) .field("col_begin", &self.col_begin) .finish() @@ -346,7 +342,7 @@ impl fmt::Debug for Token { impl fmt::Display for Token { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{:?} {}", self.kind, self.content.replace("\n", "\\n")) + write!(f, "{:?} {}", self.kind, self.content.replace('\n', "\\n")) } } @@ -451,7 +447,7 @@ impl Token { } pub fn is_procedural(&self) -> bool { - self.inspect().ends_with("!") + self.inspect().ends_with('!') } } From 8efffbfbc060beb21ffc58c0e5e3b4ed032a8fdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fe=CC=81lix=20Saparelli?= Date: Mon, 15 Aug 2022 17:44:15 +1200 Subject: [PATCH 2/2] Apply formatting --- compiler/erg_common/serialize.rs | 34 ++++---- compiler/erg_common/ty.rs | 10 ++- compiler/erg_common/value.rs | 6 +- compiler/erg_compiler/codegen.rs | 12 +-- compiler/erg_compiler/context.rs | 118 +++++++++++++++------------- compiler/erg_compiler/eval.rs | 4 +- compiler/erg_compiler/initialize.rs | 65 ++++++++++----- compiler/erg_compiler/lower.rs | 8 +- compiler/erg_parser/lex.rs | 28 ++++++- compiler/erg_parser/token.rs | 5 +- 10 files changed, 171 insertions(+), 119 deletions(-) diff --git a/compiler/erg_common/serialize.rs b/compiler/erg_common/serialize.rs index 18b7328b5..a4d2717be 100644 --- a/compiler/erg_common/serialize.rs +++ b/compiler/erg_common/serialize.rs @@ -49,15 +49,15 @@ pub enum DataTypePrefix { StopIter = b'S', // 0x53 Ref = b'r', /* unsized objects (ref counted) */ - Long = b'l', // 0x6C + len: u32 + payload: 2*len+3byte (~ -2^31-1 && 2^31 ~) - Str = b's', // 0x73 + len: u32 + payload + Long = b'l', // 0x6C + len: u32 + payload: 2*len+3byte (~ -2^31-1 && 2^31 ~) + Str = b's', // 0x73 + len: u32 + payload ShortAscii = b'z', // 0x7A + len: u8 + payload ShortAsciiInterned = b'Z', // 0x5A + len: u8 + payload - Unicode = b'u', // 0x75 + len: u32 + payload - Interned = b't', // 0x74 + len + payload + Unicode = b'u', // 0x75 + len: u32 + payload + Interned = b't', // 0x74 + len + payload SmallTuple = b')', // 0x29 + len: u8 + payload - Tuple = b'(', // 0x28 + len: u32 + payload - Code = b'c', // 0x63 + Tuple = b'(', // 0x28 + len: u32 + payload + Code = b'c', // 0x63 /* Erg specific prefix */ Builtin = b'b', // 0x62 + str Nat = b'n', @@ -103,17 +103,19 @@ impl From for DataTypePrefix { impl DataTypePrefix { pub const fn is_sized(&self) -> bool { - matches!(self, + matches!( + self, Self::Long - | Self::Str - | Self::ShortAscii - | Self::ShortAsciiInterned - | Self::Unicode - | Self::Interned - | Self::SmallTuple - | Self::Tuple - | Self::Code - | Self::Builtin) + | Self::Str + | Self::ShortAscii + | Self::ShortAsciiInterned + | Self::Unicode + | Self::Interned + | Self::SmallTuple + | Self::Tuple + | Self::Code + | Self::Builtin + ) } } diff --git a/compiler/erg_common/ty.rs b/compiler/erg_common/ty.rs index 4baa4c316..f6e84cb3d 100644 --- a/compiler/erg_common/ty.rs +++ b/compiler/erg_common/ty.rs @@ -1546,11 +1546,13 @@ impl SubrKind { } pub fn same_kind_as(&self, other: &Self) -> bool { - matches!((self, other), + matches!( + (self, other), (Self::Func, Self::Func) - | (Self::Proc, Self::Proc) - | (Self::FuncMethod(_), Self::FuncMethod(_)) - | (Self::ProcMethod { .. }, Self::ProcMethod { .. })) + | (Self::Proc, Self::Proc) + | (Self::FuncMethod(_), Self::FuncMethod(_)) + | (Self::ProcMethod { .. }, Self::ProcMethod { .. }) + ) } pub fn self_t(&self) -> Option<&SelfType> { diff --git a/compiler/erg_common/value.rs b/compiler/erg_common/value.rs index 45a636730..39a4d5abb 100644 --- a/compiler/erg_common/value.rs +++ b/compiler/erg_common/value.rs @@ -286,11 +286,7 @@ impl ValueObj { pub fn into_bytes(self) -> Vec { match self { - Self::Int(i) => [ - vec![DataTypePrefix::Int32 as u8], - i.to_le_bytes().to_vec(), - ] - .concat(), + Self::Int(i) => [vec![DataTypePrefix::Int32 as u8], i.to_le_bytes().to_vec()].concat(), // TODO: Natとしてシリアライズ Self::Nat(n) => [ vec![DataTypePrefix::Int32 as u8], diff --git a/compiler/erg_compiler/codegen.rs b/compiler/erg_compiler/codegen.rs index 476fde40f..43f0b8a20 100644 --- a/compiler/erg_compiler/codegen.rs +++ b/compiler/erg_compiler/codegen.rs @@ -290,12 +290,12 @@ impl CodeGenerator { } else { Some(Name::fast(idx)) } - } else { self - .cur_block_codeobj() - .freevars - .iter() - .position(|f| &**f == name) - .map(Name::deref) + } else { + self.cur_block_codeobj() + .freevars + .iter() + .position(|f| &**f == name) + .map(Name::deref) } } diff --git a/compiler/erg_compiler/context.rs b/compiler/erg_compiler/context.rs index a9c150fc0..0a23ddff8 100644 --- a/compiler/erg_compiler/context.rs +++ b/compiler/erg_compiler/context.rs @@ -178,7 +178,10 @@ impl TyVarContext { }), Type::VarArgs(t) => Self::rec_t_inner_qvars(t, dep), Type::Subr(_subr) => todo!(), - Type::Callable { param_ts: _, return_t: _ } => todo!(), + Type::Callable { + param_ts: _, + return_t: _, + } => todo!(), Type::And(_) | Type::Or(_) | Type::Not(_) => todo!(), Type::Record(_) => todo!(), Type::Quantified(_) => todo!(), @@ -209,67 +212,66 @@ impl TyVarContext { match bound { TyBound::Subtype { sub, sup } => { let sup = match sup { - Type::Poly { name, params } => { - Type::poly( - name, - params.into_iter().map(|p| self.instantiate_tp(p)).collect(), - ) - } + Type::Poly { name, params } => Type::poly( + name, + params.into_iter().map(|p| self.instantiate_tp(p)).collect(), + ), Type::MonoProj { lhs, rhs } => Type::mono_proj(self.instantiate_t(*lhs), rhs), sup => sup, }; let constraint = Constraint::SubtypeOf(sup); let name = Str::rc(sub.name()); - self.push_tyvar(name.clone(), Type::named_free_var(name, self.level, constraint)); + self.push_tyvar( + name.clone(), + Type::named_free_var(name, self.level, constraint), + ); } TyBound::Supertype { sup, sub } => { let sub = match sub { - Type::Poly { name, params } => { - Type::poly( - name, - params.into_iter().map(|p| self.instantiate_tp(p)).collect(), - ) - } + Type::Poly { name, params } => Type::poly( + name, + params.into_iter().map(|p| self.instantiate_tp(p)).collect(), + ), Type::MonoProj { lhs, rhs } => Type::mono_proj(self.instantiate_t(*lhs), rhs), sub => sub, }; let constraint = Constraint::SupertypeOf(sub); let name = Str::rc(sup.name()); - self.push_tyvar(name.clone(), Type::named_free_var(name, self.level, constraint)); + self.push_tyvar( + name.clone(), + Type::named_free_var(name, self.level, constraint), + ); } TyBound::Sandwiched { sub, mid, sup } => { let sub = match sub { - Type::Poly { name, params } => { - Type::poly( - name, - params.into_iter().map(|p| self.instantiate_tp(p)).collect(), - ) - } + Type::Poly { name, params } => Type::poly( + name, + params.into_iter().map(|p| self.instantiate_tp(p)).collect(), + ), Type::MonoProj { lhs, rhs } => Type::mono_proj(self.instantiate_t(*lhs), rhs), sub => sub, }; let sup = match sup { - Type::Poly { name, params } => { - Type::poly( - name, - params.into_iter().map(|p| self.instantiate_tp(p)).collect(), - ) - } + Type::Poly { name, params } => Type::poly( + name, + params.into_iter().map(|p| self.instantiate_tp(p)).collect(), + ), Type::MonoProj { lhs, rhs } => Type::mono_proj(self.instantiate_t(*lhs), rhs), sup => sup, }; let constraint = Constraint::Sandwiched { sub, sup }; let name = Str::rc(mid.name()); - self.push_tyvar(name.clone(), Type::named_free_var(name, self.level, constraint)); + self.push_tyvar( + name.clone(), + Type::named_free_var(name, self.level, constraint), + ); } TyBound::Instance { name, t } => { let t = match t { - Type::Poly { name, params } => { - Type::poly( - name, - params.into_iter().map(|p| self.instantiate_tp(p)).collect(), - ) - } + Type::Poly { name, params } => Type::poly( + name, + params.into_iter().map(|p| self.instantiate_tp(p)).collect(), + ), t => t, }; // TODO: type-like types @@ -1552,18 +1554,19 @@ impl Context { // in toplevel: ?T(<: Int)[n] should replaced to Int (if n > 0) Type::FreeVar(fv) if fv.is_unbound() => { match fv.borrow().constraint().unwrap() { - Constraint::SubtypeOf(sup) - | Constraint::Sandwiched { sup, .. } if self.level <= fv.level().unwrap() => { + Constraint::SubtypeOf(sup) | Constraint::Sandwiched { sup, .. } + if self.level <= fv.level().unwrap() => + { return Ok(sup.clone()); - }, + } // REVIEW: really? Constraint::SupertypeOf(sub) if self.level <= fv.level().unwrap() => { return Ok(sub.clone()); - }, - _ => {}, + } + _ => {} } Ok(Type::FreeVar(fv)) - }, + } Type::FreeVar(fv) if fv.is_linked() => Ok(fv.unwrap()), // 未連携型変数のチェックはモジュール全体の型検査が終わった後にやる // Type::FreeVar(_) => @@ -1619,21 +1622,23 @@ impl Context { subr.return_t = Box::new(self.monomorphise(mem::take(&mut subr.return_t))?); Ok(Type::Subr(subr)) } - Type::Poly{ name, params } => { + Type::Poly { name, params } => { let impls = self.rec_get_trait_impls(&name); if impls.is_empty() { panic!("{} is not implemented", name); } - let min = self.smallest_t(impls.clone().into_iter()).unwrap_or_else(move || { - panic!("cannot determine the smallest type: {}", fmt_vec(&impls)) - }); + let min = self + .smallest_t(impls.clone().into_iter()) + .unwrap_or_else(move || { + panic!("cannot determine the smallest type: {}", fmt_vec(&impls)) + }); dbg!(&min); for (param, min_param) in params.iter().zip(min.typarams()) { self.unify_tp(param, &min_param, None, None, false)?; } dbg!(¶ms); Ok(min) - }, + } _ => Ok(maybe_poly), } } @@ -1641,9 +1646,12 @@ impl Context { /// 可変依存型の変更を伝搬させる fn propagate(&self, t: &Type, callee: &hir::Expr) -> TyCheckResult<()> { if let Type::Subr(SubrType { - kind: SubrKind::ProcMethod { after: Some(after), .. }, + kind: SubrKind::ProcMethod { + after: Some(after), .. + }, .. - }) = t { + }) = t + { let receiver_t = callee.receiver_t().unwrap(); self.reunify(receiver_t, after, Some(callee.loc()), None)?; } @@ -2120,7 +2128,7 @@ impl Context { } Constraint::TypeOf(_t) => { *constraint = Constraint::SupertypeOf(l.clone()); - }, + } _ => {} }, _ => {} @@ -2639,11 +2647,7 @@ impl Context { } else { expr_t.clone() }; - let param_ts = [ - vec![ParamTy::anonymous(expr_t)], - branch_ts.to_vec(), - ] - .concat(); + let param_ts = [vec![ParamTy::anonymous(expr_t)], branch_ts.to_vec()].concat(); let t = Type::func(param_ts, vec![], return_t); Ok(t) } @@ -2908,7 +2912,9 @@ impl Context { } } for (patch_name, sub, sup) in self.glue_patch_and_types.iter() { - let patch = self.rec_get_patch(patch_name).unwrap_or_else(|| panic!("{patch_name} not found")); + let patch = self + .rec_get_patch(patch_name) + .unwrap_or_else(|| panic!("{patch_name} not found")); let bounds = patch.type_params_bounds(); let variance = patch.type_params_variance(); if self.formal_supertype_of(sub, rhs, Some(&bounds), Some(&variance)) @@ -3757,7 +3763,9 @@ impl Context { fn rec_get_trait_impls(&self, name: &Str) -> Vec { let impls = if let Some(impls) = self.poly_trait_impls.get(name) { impls.clone() - } else { vec![] }; + } else { + vec![] + }; if let Some(outer) = &self.outer { [impls, outer.rec_get_trait_impls(name)].concat() } else { diff --git a/compiler/erg_compiler/eval.rs b/compiler/erg_compiler/eval.rs index f6305d6cb..119675913 100644 --- a/compiler/erg_compiler/eval.rs +++ b/compiler/erg_compiler/eval.rs @@ -309,7 +309,9 @@ impl Evaluator { level: usize, ) -> EvalResult { match substituted { - Type::FreeVar(fv) if fv.is_linked() => self.eval_t_params(fv.crack().clone(), ctx, level), + Type::FreeVar(fv) if fv.is_linked() => { + self.eval_t_params(fv.crack().clone(), ctx, level) + } Type::Subr(mut subr) => { let kind = match subr.kind { SubrKind::FuncMethod(self_t) => { diff --git a/compiler/erg_compiler/initialize.rs b/compiler/erg_compiler/initialize.rs index 05b159691..3a544f188 100644 --- a/compiler/erg_compiler/initialize.rs +++ b/compiler/erg_compiler/initialize.rs @@ -59,10 +59,8 @@ impl Context { if let Some(impls) = self.poly_trait_impls.get_mut(impl_trait.name()) { impls.push(impl_trait.clone()); } else { - self.poly_trait_impls.insert( - Str::rc(impl_trait.name()), - vec![impl_trait.clone()], - ); + self.poly_trait_impls + .insert(Str::rc(impl_trait.name()), vec![impl_trait.clone()]); } } } @@ -147,10 +145,15 @@ impl Context { let (r_bound, o_bound) = (static_instance("R", Type), static_instance("O", Type)); let params = vec![PS::t("R", WithDefault), PS::t("O", WithDefault)]; let ty_params = vec![mono_q_tp("R"), mono_q_tp("O")]; - let mut add = Self::poly_trait("Add", params.clone(), vec![ - poly("Output", vec![ty_tp(mono_q("R"))]), - poly("Output", vec![ty_tp(mono_q("O"))]), - ], Self::TOP_LEVEL); + let mut add = Self::poly_trait( + "Add", + params.clone(), + vec![ + poly("Output", vec![ty_tp(mono_q("R"))]), + poly("Output", vec![ty_tp(mono_q("O"))]), + ], + Self::TOP_LEVEL, + ); let self_bound = subtype( poly_q("Self", ty_params.clone()), poly("Add", ty_params.clone()), @@ -158,10 +161,15 @@ impl Context { let op_t = fn1_met(poly_q("Self", ty_params.clone()), r.clone(), o.clone()); let op_t = quant(op_t, set! {r_bound.clone(), o_bound.clone(), self_bound}); add.register_decl("__add__", op_t, Public); - let mut sub = Self::poly_trait("Sub", params.clone(), vec![ - poly("Output", vec![ty_tp(mono_q("R"))]), - poly("Output", vec![ty_tp(mono_q("O"))]), - ], Self::TOP_LEVEL); + let mut sub = Self::poly_trait( + "Sub", + params.clone(), + vec![ + poly("Output", vec![ty_tp(mono_q("R"))]), + poly("Output", vec![ty_tp(mono_q("O"))]), + ], + Self::TOP_LEVEL, + ); let self_bound = subtype( poly_q("Self", ty_params.clone()), poly("Sub", ty_params.clone()), @@ -169,16 +177,26 @@ impl Context { let op_t = fn1_met(poly_q("Self", ty_params.clone()), r.clone(), o.clone()); let op_t = quant(op_t, set! {r_bound, o_bound, self_bound}); sub.register_decl("__sub__", op_t, Public); - let mut mul = Self::poly_trait("Mul", params.clone(), vec![ - poly("Output", vec![ty_tp(mono_q("R"))]), - poly("Output", vec![ty_tp(mono_q("O"))]), - ], Self::TOP_LEVEL); + let mut mul = Self::poly_trait( + "Mul", + params.clone(), + vec![ + poly("Output", vec![ty_tp(mono_q("R"))]), + poly("Output", vec![ty_tp(mono_q("O"))]), + ], + Self::TOP_LEVEL, + ); let op_t = fn1_met(poly("Mul", ty_params.clone()), r.clone(), o.clone()); mul.register_decl("__mul__", op_t, Public); - let mut div = Self::poly_trait("Div", params, vec![ - poly("Output", vec![ty_tp(mono_q("R"))]), - poly("Output", vec![ty_tp(mono_q("O"))]), - ], Self::TOP_LEVEL); + let mut div = Self::poly_trait( + "Div", + params, + vec![ + poly("Output", vec![ty_tp(mono_q("R"))]), + poly("Output", vec![ty_tp(mono_q("O"))]), + ], + Self::TOP_LEVEL, + ); let op_t = fn1_met(poly("Div", ty_params.clone()), r, o); div.register_decl("__div__", op_t, Public); /*let sup = poly( @@ -380,7 +398,12 @@ impl Context { let mut str_ = Self::mono_class( "Str", vec![Obj], - vec![mono("Eq"), mono("Mutate"), poly("Seq", vec![ty_tp(Str)]), poly("Add", vec![ty_tp(Str), ty_tp(Str)])], + vec![ + mono("Eq"), + mono("Mutate"), + poly("Seq", vec![ty_tp(Str)]), + poly("Add", vec![ty_tp(Str), ty_tp(Str)]), + ], Self::TOP_LEVEL, ); str_.register_impl("__add__", fn1_met(Str, Str, Str), Const, Public); diff --git a/compiler/erg_compiler/lower.rs b/compiler/erg_compiler/lower.rs index d6c22c772..c4e765ed5 100644 --- a/compiler/erg_compiler/lower.rs +++ b/compiler/erg_compiler/lower.rs @@ -51,13 +51,7 @@ impl ASTLowerer { found: &Type, ) -> LowerResult<()> { self.ctx.unify(expect, found, Some(loc), None).map_err(|_| { - LowerError::type_mismatch_error( - loc, - self.ctx.caused_by(), - name, - expect, - found, - ) + LowerError::type_mismatch_error(loc, self.ctx.caused_by(), name, expect, found) }) } diff --git a/compiler/erg_parser/lex.rs b/compiler/erg_parser/lex.rs index 570785f0d..fd22cbdc8 100644 --- a/compiler/erg_parser/lex.rs +++ b/compiler/erg_parser/lex.rs @@ -179,9 +179,31 @@ impl Lexer /*<'a>*/ { #[inline] fn is_definable_operator(s: &str) -> bool { - matches!(s, - "+" | "-" | "*" | "/" | "//" | "**" | "%" | ".." | "..=" | "~" | "&&" | "||" | "^^" - | ">>" | "<<" | "==" | "!=" | ">" | "<" | ">=" | "<=" | "dot" | "cross") + matches!( + s, + "+" | "-" + | "*" + | "/" + | "//" + | "**" + | "%" + | ".." + | "..=" + | "~" + | "&&" + | "||" + | "^^" + | ">>" + | "<<" + | "==" + | "!=" + | ">" + | "<" + | ">=" + | "<=" + | "dot" + | "cross" + ) } // +, -, * etc. may be pre/bin diff --git a/compiler/erg_parser/token.rs b/compiler/erg_parser/token.rs index e30bcf346..7dd0d85b7 100644 --- a/compiler/erg_parser/token.rs +++ b/compiler/erg_parser/token.rs @@ -293,7 +293,10 @@ impl TokenKind { } pub const fn is_right_associative(&self) -> bool { - matches!(self, FuncArrow | ProcArrow | Equal /* | PreDollar | PreAt */) + matches!( + self, + FuncArrow | ProcArrow | Equal /* | PreDollar | PreAt */ + ) } }