Remove unwraps

This commit is contained in:
Shunsuke Shibayama 2022-09-24 19:15:55 +09:00
parent ce8125379e
commit f6e1a7b117
7 changed files with 79 additions and 29 deletions

View file

@ -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 {

View file

@ -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("<Lambda>")));
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("<Lambda>")));
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");

View file

@ -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(),
)
.ok()
} else {
None
}

View file

@ -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,

View file

@ -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,

View file

@ -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__");

View file

@ -802,8 +802,12 @@ pub mod value_set {
// false -> SyntaxError
pub fn is_homogeneous(set: &Set<ValueObj>) -> bool {
let l_first = set.iter().next().unwrap().class();
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<ValueObj>) -> Type {