diff --git a/compiler/erg_compiler/context/compare.rs b/compiler/erg_compiler/context/compare.rs index 65d114ef..6dfa9127 100644 --- a/compiler/erg_compiler/context/compare.rs +++ b/compiler/erg_compiler/context/compare.rs @@ -911,7 +911,7 @@ impl Context { #[inline] fn type_of(&self, p: &TyParam) -> Type { - self.get_tp_t(p).unwrap() + self.get_tp_t(p).unwrap_or(Type::Obj) } // sup/inf({±∞}) = ±∞ではあるが、Inf/NegInfにはOrdを実装しない @@ -926,7 +926,7 @@ impl Context { if lhs == &refine.var => { if let Some(max) = &maybe_max { - if self.try_cmp(rhs, max).unwrap() == Greater { + if self.try_cmp(rhs, max) == Some(Greater) { maybe_max = Some(rhs.clone()); } } else { @@ -954,7 +954,7 @@ impl Context { if lhs == &refine.var => { if let Some(min) = &maybe_min { - if self.try_cmp(rhs, min).unwrap() == Less { + if self.try_cmp(rhs, min) == Some(Less) { maybe_min = Some(rhs.clone()); } } else { diff --git a/compiler/erg_compiler/context/initialize/const_func.rs b/compiler/erg_compiler/context/initialize/const_func.rs index 081984f0..aa5aed54 100644 --- a/compiler/erg_compiler/context/initialize/const_func.rs +++ b/compiler/erg_compiler/context/initialize/const_func.rs @@ -3,7 +3,7 @@ use std::mem; use erg_common::Str; use erg_common::astr::AtomicStr; -use erg_common::color::{RED, RESET}; +use erg_common::color::{RED, RESET, YELLOW}; use erg_common::error::{ErrorCore, ErrorKind, Location}; use erg_type::constructors::{and, builtin_mono, mono}; use erg_type::value::{EvalValueResult, TypeKind, TypeObj, ValueObj}; @@ -18,20 +18,32 @@ pub fn class_func( let require = args.remove_left_or_key("Requirement").ok_or_else(|| { ErrorCore::new( line!() as usize, - ErrorKind::KeyError, + ErrorKind::TypeError, Location::Unknown, AtomicStr::from(format!("{RED}Requirement{RESET} is not passed")), None, ) })?; - let require = require.as_type().unwrap(); + let require = if let Some(t) = require.as_type() { + t + } else { + return Err(ErrorCore::new( + line!() as usize, + ErrorKind::TypeError, + Location::Unknown, + AtomicStr::from(format!( + "non-type object {RED}{require}{RESET} is passed to {YELLOW}Requirement{RESET}", + )), + None, + )); + }; let impls = args.remove_left_or_key("Impl"); let impls = impls.map(|v| v.as_type().unwrap()); let t = mono(mod_name, __name__.unwrap_or(Str::ever(""))); Ok(ValueObj::gen_t(TypeKind::Class, t, require, impls, None)) } -/// Super: Type, Impl := Type, Additional := Type -> ClassType +/// Super: ClassType, Impl := Type, Additional := Type -> ClassType pub fn inherit_func( mut args: ValueArgs, mod_name: Str, @@ -46,7 +58,19 @@ pub fn inherit_func( None, ) })?; - let sup = sup.as_type().unwrap(); + let sup = if let Some(t) = sup.as_type() { + t + } else { + return Err(ErrorCore::new( + line!() as usize, + ErrorKind::TypeError, + Location::Unknown, + AtomicStr::from(format!( + "non-class object {RED}{sup}{RESET} is passed to {YELLOW}Super{RESET}", + )), + None, + )); + }; let impls = args.remove_left_or_key("Impl"); let impls = impls.map(|v| v.as_type().unwrap()); let additional = args.remove_left_or_key("Additional"); @@ -97,7 +121,7 @@ pub fn inheritable_func( } } -/// Requirement: Type, Impl := Type -> ClassType +/// Requirement: Type, Impl := Type -> TraitType pub fn trait_func( mut args: ValueArgs, mod_name: Str, @@ -112,14 +136,26 @@ pub fn trait_func( None, ) })?; - let require = require.as_type().unwrap(); + let require = if let Some(t) = require.as_type() { + t + } else { + return Err(ErrorCore::new( + line!() as usize, + ErrorKind::TypeError, + Location::Unknown, + AtomicStr::from(format!( + "non-type object {RED}{require}{RESET} is passed to {YELLOW}Requirement{RESET}", + )), + None, + )); + }; let impls = args.remove_left_or_key("Impl"); let impls = impls.map(|v| v.as_type().unwrap()); let t = mono(mod_name, __name__.unwrap_or(Str::ever(""))); Ok(ValueObj::gen_t(TypeKind::Trait, t, require, impls, None)) } -/// Super: Type, Impl := Type, Additional := Type -> ClassType +/// Super: TraitType, Impl := Type, Additional := Type -> TraitType pub fn subsume_func( mut args: ValueArgs, mod_name: Str, @@ -134,7 +170,19 @@ pub fn subsume_func( None, ) })?; - let sup = sup.as_type().unwrap(); + let sup = if let Some(t) = sup.as_type() { + t + } else { + return Err(ErrorCore::new( + line!() as usize, + ErrorKind::TypeError, + Location::Unknown, + AtomicStr::from(format!( + "non-trait object {RED}{sup}{RESET} is passed to {YELLOW}Super{RESET}", + )), + None, + )); + }; let impls = args.remove_left_or_key("Impl"); let impls = impls.map(|v| v.as_type().unwrap()); let additional = args.remove_left_or_key("Additional"); diff --git a/compiler/erg_compiler/context/inquire.rs b/compiler/erg_compiler/context/inquire.rs index 3c72ed31..fdf727ea 100644 --- a/compiler/erg_compiler/context/inquire.rs +++ b/compiler/erg_compiler/context/inquire.rs @@ -1427,14 +1427,12 @@ impl Context { let insts = self.rec_get_trait_impls(&sup.name()); let candidates = insts.into_iter().filter_map(move |inst| { if self.supertype_of(&inst.sup_trait, &sup) { - Some( - self.eval_t_params( - mono_proj(inst.sub_type, rhs), - self.level, - Location::Unknown, - ) - .unwrap(), + self.eval_t_params( + mono_proj(inst.sub_type, rhs), + self.level, + Location::Unknown, ) + .ok() } else { None } diff --git a/compiler/erg_compiler/effectcheck.rs b/compiler/erg_compiler/effectcheck.rs index dd8fa883..1984044b 100644 --- a/compiler/erg_compiler/effectcheck.rs +++ b/compiler/erg_compiler/effectcheck.rs @@ -58,7 +58,7 @@ impl SideEffectChecker { /// /// However, it is not permitted to cause side effects within an instant block in a function /// (side effects are allowed in instant blocks in procedures and modules) - fn in_context_se_allowed(&self) -> bool { + fn in_context_effects_allowed(&self) -> bool { // if toplevel if self.block_stack.len() == 1 { return true; @@ -255,7 +255,7 @@ impl SideEffectChecker { .as_ref() .map(|name| name.is_procedural()) .unwrap_or(false)) - && !self.in_context_se_allowed() + && !self.in_context_effects_allowed() { self.errs.push(EffectError::has_effect( line!() as usize, diff --git a/compiler/erg_compiler/error.rs b/compiler/erg_compiler/error.rs index a993cdac..7be0f54e 100644 --- a/compiler/erg_compiler/error.rs +++ b/compiler/erg_compiler/error.rs @@ -995,19 +995,19 @@ passed keyword args: {RED}{kw_args_len}{RESET}" switch_lang!( "japanese" => format!( "{RED}{name}{RESET}は{}行目ですでに移動されています", - moved_loc.ln_begin().unwrap() + moved_loc.ln_begin().unwrap_or(0) ), "simplified_chinese" => format!( "{RED}{name}{RESET}已移至第{}行", - moved_loc.ln_begin().unwrap() + moved_loc.ln_begin().unwrap_or(0) ), "traditional_chinese" => format!( "{RED}{name}{RESET}已移至第{}行", - moved_loc.ln_begin().unwrap() + moved_loc.ln_begin().unwrap_or(0) ), "english" => format!( "{RED}{name}{RESET} was moved in line {}", - moved_loc.ln_begin().unwrap() + moved_loc.ln_begin().unwrap_or(0) ), ), None, diff --git a/compiler/erg_compiler/link.rs b/compiler/erg_compiler/link.rs index dc498f4a..56b54c54 100644 --- a/compiler/erg_compiler/link.rs +++ b/compiler/erg_compiler/link.rs @@ -43,7 +43,7 @@ impl Linker { let code = Expr::Code(Block::new(Vec::from(hir.module))); let module_type = Expr::Accessor(Accessor::private_with_line( Str::ever("#ModuleType"), - def.ln_begin().unwrap(), + def.ln_begin().unwrap_or(0), )); let args = Args::new(vec![PosArg::new(mod_name.clone())], None, vec![], None); @@ -59,7 +59,7 @@ impl Linker { )); let exec = Expr::Accessor(Accessor::public_with_line( Str::ever("exec"), - mod_def.ln_begin().unwrap(), + mod_def.ln_begin().unwrap_or(0), )); let module = Expr::Accessor(Accessor::Ident(def.sig.ident().clone())); let __dict__ = Identifier::public("__dict__"); diff --git a/compiler/erg_type/value.rs b/compiler/erg_type/value.rs index ae492471..58997796 100644 --- a/compiler/erg_type/value.rs +++ b/compiler/erg_type/value.rs @@ -802,8 +802,12 @@ pub mod value_set { // false -> SyntaxError pub fn is_homogeneous(set: &Set) -> bool { - let l_first = set.iter().next().unwrap().class(); - set.iter().all(|c| c.class() == l_first) + if let Some(first) = set.iter().next() { + let l_first = first.class(); + set.iter().all(|c| c.class() == l_first) + } else { + true + } } pub fn inner_class(set: &Set) -> Type {