diff --git a/crates/els/server.rs b/crates/els/server.rs index 93bdde4d2..87b31fde7 100644 --- a/crates/els/server.rs +++ b/crates/els/server.rs @@ -889,7 +889,10 @@ impl Server { let uri = NormalizedUrl::new(params.text_document.uri); self.send_log(format!("{method}: {uri}"))?; let code = self.file_cache.get_entire_code(&uri)?; - self.recheck_file(uri, code) + let token = self.start_work_done_progress("checking files ..."); + let res = self.recheck_file(uri, code); + self.stop_work_done_progress(token, "checking done"); + res } "textDocument/didChange" => { let params = DidChangeTextDocumentParams::deserialize(msg["params"].clone())?; diff --git a/crates/erg_compiler/context/generalize.rs b/crates/erg_compiler/context/generalize.rs index f86a105a0..803e1de7c 100644 --- a/crates/erg_compiler/context/generalize.rs +++ b/crates/erg_compiler/context/generalize.rs @@ -18,7 +18,7 @@ use crate::ty::{HasType, Predicate, SubrType, Type}; use crate::context::{Context, Variance}; use crate::error::{TyCheckError, TyCheckErrors, TyCheckResult}; -use crate::{feature_error, hir}; +use crate::{feature_error, hir, unreachable_error}; use Type::*; use Variance::*; @@ -781,7 +781,7 @@ impl<'c, 'q, 'l, L: Locational> Dereferencer<'c, 'q, 'l, L> { self.deref_tyvar(sup)?, )), Constraint::TypeOf(t) => Ok(Constraint::new_type_of(self.deref_tyvar(t)?)), - _ => unreachable!(), + _ => unreachable_error!(TyCheckErrors, TyCheckError, self.ctx), } } @@ -1652,7 +1652,7 @@ impl Context { } Ok(()) } - hir::Expr::Import(_) => unreachable!(), + hir::Expr::Import(_) => unreachable_error!(TyCheckErrors, TyCheckError, self), } } diff --git a/crates/erg_compiler/context/initialize/const_func.rs b/crates/erg_compiler/context/initialize/const_func.rs index 5e65a4fb9..9e42bdf2f 100644 --- a/crates/erg_compiler/context/initialize/const_func.rs +++ b/crates/erg_compiler/context/initialize/const_func.rs @@ -62,7 +62,7 @@ fn type_mismatch(expected: impl Display, got: impl Display, param: &str) -> Eval pub(crate) fn class_func(mut args: ValueArgs, ctx: &Context) -> EvalValueResult { let base = args.remove_left_or_key("Base"); let impls = args.remove_left_or_key("Impl"); - let impls = impls.map(|v| v.as_type(ctx).unwrap()); + let impls = impls.and_then(|v| v.as_type(ctx)); let t = mono(ctx.name.clone()); match base { Some(value) => { @@ -85,9 +85,9 @@ pub(crate) fn inherit_func(mut args: ValueArgs, ctx: &Context) -> EvalValueResul return Err(type_mismatch("class", sup, "Super")); }; let impls = args.remove_left_or_key("Impl"); - let impls = impls.map(|v| v.as_type(ctx).unwrap()); + let impls = impls.and_then(|v| v.as_type(ctx)); let additional = args.remove_left_or_key("Additional"); - let additional = additional.map(|v| v.as_type(ctx).unwrap()); + let additional = additional.and_then(|v| v.as_type(ctx)); let t = mono(ctx.name.clone()); Ok(ValueObj::gen_t(GenTypeObj::inherited(t, sup, impls, additional)).into()) } @@ -140,7 +140,7 @@ pub(crate) fn trait_func(mut args: ValueArgs, ctx: &Context) -> EvalValueResult< return Err(type_mismatch("type", req, "Requirement")); }; let impls = args.remove_left_or_key("Impl"); - let impls = impls.map(|v| v.as_type(ctx).unwrap()); + let impls = impls.and_then(|v| v.as_type(ctx)); let t = mono(ctx.name.clone()); Ok(ValueObj::gen_t(GenTypeObj::trait_(t, req, impls, true)).into()) } @@ -154,7 +154,7 @@ pub(crate) fn patch_func(mut args: ValueArgs, ctx: &Context) -> EvalValueResult< return Err(type_mismatch("type", base, "Base")); }; let impls = args.remove_left_or_key("Impl"); - let impls = impls.map(|v| v.as_type(ctx).unwrap()); + let impls = impls.and_then(|v| v.as_type(ctx)); let t = mono(ctx.name.clone()); Ok(ValueObj::gen_t(GenTypeObj::patch(t, base, impls)).into()) } @@ -168,9 +168,9 @@ pub(crate) fn subsume_func(mut args: ValueArgs, ctx: &Context) -> EvalValueResul return Err(type_mismatch("trait", sup, "Super")); }; let impls = args.remove_left_or_key("Impl"); - let impls = impls.map(|v| v.as_type(ctx).unwrap()); + let impls = impls.and_then(|v| v.as_type(ctx)); let additional = args.remove_left_or_key("Additional"); - let additional = additional.map(|v| v.as_type(ctx).unwrap()); + let additional = additional.and_then(|v| v.as_type(ctx)); let t = mono(ctx.name.clone()); Ok(ValueObj::gen_t(GenTypeObj::subsumed(t, sup, impls, additional)).into()) } @@ -477,7 +477,7 @@ pub(crate) fn list_union(mut args: ValueArgs, ctx: &Context) -> EvalValueResult< }; let slf = slf .iter() - .map(|t| ctx.convert_value_into_type(t.clone()).unwrap()) + .flat_map(|t| ctx.convert_value_into_type(t.clone())) .collect::>(); let union = slf .iter() diff --git a/crates/erg_compiler/ty/mod.rs b/crates/erg_compiler/ty/mod.rs index 2d541c6a9..a70624c3a 100644 --- a/crates/erg_compiler/ty/mod.rs +++ b/crates/erg_compiler/ty/mod.rs @@ -2660,9 +2660,10 @@ impl Type { Self::FreeVar(fv) if fv.is_linked() => fv.crack().contains_type(target), Self::FreeVar(fv) => { fv.get_subsup().map_or(false, |(sub, sup)| { - fv.do_avoiding_recursion(|| { - sub.contains_type(target) || sup.contains_type(target) - }) + fv.dummy_link(); + let res = sub.contains_type(target) || sup.contains_type(target); + fv.undo(); + res }) || fv.get_type().map_or(false, |t| t.contains_type(target)) } Self::Record(rec) => rec.iter().any(|(_, t)| t.contains_type(target)), @@ -3734,9 +3735,11 @@ impl Type { } Self::FreeVar(ref fv) if fv.constraint_is_sandwiched() => { let (sub, sup) = fv.get_subsup().unwrap(); - let sub = sub.eliminate(target); - let sup = sup.eliminate(target); - self.update_tyvar(sub, sup, None, false); + fv.do_avoiding_recursion(|| { + let sub = sub.eliminate(target); + let sup = sup.eliminate(target); + self.update_tyvar(sub, sup, None, false); + }); self } Self::And(l, r) => { @@ -4031,7 +4034,10 @@ impl Type { return; } if self.level() == Some(GENERIC_LEVEL) { - panic!("{self} is fixed"); + if DEBUG_MODE { + panic!("{self} is fixed"); + } + return; } let to = to.clone().eliminate(self); match self { diff --git a/crates/erg_parser/parse.rs b/crates/erg_parser/parse.rs index 48510aa6a..13d35045b 100644 --- a/crates/erg_parser/parse.rs +++ b/crates/erg_parser/parse.rs @@ -3635,9 +3635,9 @@ impl Parser { let op = Token::new_fake( Plus, "+", - right.ln_begin().unwrap(), - right.col_begin().unwrap(), - right.col_end().unwrap(), + right.ln_begin().unwrap_or(0), + right.col_begin().unwrap_or(0), + right.col_end().unwrap_or(0), ); expr = Expr::BinOp(BinOp::new(op, expr, right)); debug_exit_info!(self); @@ -3667,17 +3667,17 @@ impl Parser { .map_err(|_| self.stack_dec(fn_name!()))?; let str_func = Expr::local( "str", - mid_expr.ln_begin().unwrap(), - mid_expr.col_begin().unwrap(), - mid_expr.col_end().unwrap(), + mid_expr.ln_begin().unwrap_or(0), + mid_expr.col_begin().unwrap_or(0), + mid_expr.col_end().unwrap_or(0), ); let call = Call::new(str_func, None, Args::single(PosArg::new(mid_expr))); let op = Token::new_fake( Plus, "+", - call.ln_begin().unwrap(), - call.col_begin().unwrap(), - call.col_end().unwrap(), + call.ln_begin().unwrap_or(0), + call.col_begin().unwrap_or(0), + call.col_end().unwrap_or(0), ); let bin = BinOp::new(op, expr, Expr::Call(call)); expr = Expr::BinOp(bin); @@ -3692,9 +3692,9 @@ impl Parser { let op = Token::new_fake( Plus, "+", - mid.ln_begin().unwrap(), - mid.col_begin().unwrap(), - mid.col_end().unwrap(), + mid.ln_begin().unwrap_or(0), + mid.col_begin().unwrap_or(0), + mid.col_end().unwrap_or(0), ); expr = Expr::BinOp(BinOp::new(op, expr, mid)); }