mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-28 20:14:45 +00:00
chore: eliminate clippy warns
This commit is contained in:
parent
1b04cbe802
commit
936b6e2f95
26 changed files with 231 additions and 98 deletions
|
@ -154,7 +154,9 @@ impl<'b> CompletionOrderSetter<'b> {
|
||||||
{
|
{
|
||||||
orders.push(CompletionOrder::TypeMatched);
|
orders.push(CompletionOrder::TypeMatched);
|
||||||
} else if self.arg_pt.map_or(false, |pt| {
|
} else if self.arg_pt.map_or(false, |pt| {
|
||||||
let Some(return_t) = self.vi.t.return_t() else { return false; };
|
let Some(return_t) = self.vi.t.return_t() else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
if return_t.has_qvar() {
|
if return_t.has_qvar() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,7 +75,7 @@ impl<Checker: BuildRunnable, Parser: Parsable> Server<Checker, Parser> {
|
||||||
.errors
|
.errors
|
||||||
.clone()
|
.clone()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.chain(artifact.warns.clone().into_iter())
|
.chain(artifact.warns.clone())
|
||||||
.collect();
|
.collect();
|
||||||
let uri_and_diags = self.make_uri_and_diags(diags);
|
let uri_and_diags = self.make_uri_and_diags(diags);
|
||||||
if uri_and_diags.is_empty() {
|
if uri_and_diags.is_empty() {
|
||||||
|
|
|
@ -146,7 +146,8 @@ impl<'s, C: BuildRunnable, P: Parsable> InlayHintGenerator<'s, C, P> {
|
||||||
if d_param.sig.raw.t_spec.is_some() {
|
if d_param.sig.raw.t_spec.is_some() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let (Some(ln_end), Some(col_end)) = (d_param.sig.ln_end(), d_param.sig.col_end()) else {
|
let (Some(ln_end), Some(col_end)) = (d_param.sig.ln_end(), d_param.sig.col_end())
|
||||||
|
else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
let hint = self.type_anot(ln_end, col_end, &d_param.sig.vi.t, false);
|
let hint = self.type_anot(ln_end, col_end, &d_param.sig.vi.t, false);
|
||||||
|
@ -158,7 +159,9 @@ impl<'s, C: BuildRunnable, P: Parsable> InlayHintGenerator<'s, C, P> {
|
||||||
fn get_subr_def_hint(&self, def: &Def) -> Vec<InlayHint> {
|
fn get_subr_def_hint(&self, def: &Def) -> Vec<InlayHint> {
|
||||||
let mut result = vec![];
|
let mut result = vec![];
|
||||||
result.extend(self.get_block_hint(&def.body.block));
|
result.extend(self.get_block_hint(&def.body.block));
|
||||||
let Signature::Subr(subr) = &def.sig else { unreachable!() };
|
let Signature::Subr(subr) = &def.sig else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
if subr.ref_t().is_quantified_subr() && subr.bounds.is_empty() {
|
if subr.ref_t().is_quantified_subr() && subr.bounds.is_empty() {
|
||||||
let subr = subr.ref_t().to_string();
|
let subr = subr.ref_t().to_string();
|
||||||
let ty_bounds = format!("|{}|", subr.split('|').nth(1).unwrap_or(""));
|
let ty_bounds = format!("|{}|", subr.split('|').nth(1).unwrap_or(""));
|
||||||
|
@ -259,7 +262,8 @@ impl<'s, C: BuildRunnable, P: Parsable> InlayHintGenerator<'s, C, P> {
|
||||||
if disp_arg.trim_start_matches("::") == &name[..] {
|
if disp_arg.trim_start_matches("::") == &name[..] {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let (Some(ln_begin), Some(col_begin)) = (pos_arg.ln_begin(), pos_arg.col_begin()) else {
|
let (Some(ln_begin), Some(col_begin)) = (pos_arg.ln_begin(), pos_arg.col_begin())
|
||||||
|
else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
// f i -> ...
|
// f i -> ...
|
||||||
|
|
|
@ -863,7 +863,9 @@ impl<Checker: BuildRunnable, Parser: Parsable> Server<Checker, Parser> {
|
||||||
.and_then(|p| p.parent().unwrap().read_dir().map_err(|_| ()))
|
.and_then(|p| p.parent().unwrap().read_dir().map_err(|_| ()))
|
||||||
{
|
{
|
||||||
for neighbor in dir {
|
for neighbor in dir {
|
||||||
let Ok(neighbor) = neighbor else { continue; };
|
let Ok(neighbor) = neighbor else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
let uri = NormalizedUrl::from_file_path(neighbor.path()).unwrap();
|
let uri = NormalizedUrl::from_file_path(neighbor.path()).unwrap();
|
||||||
if let Some(mod_ctx) = &self.modules.get(&uri) {
|
if let Some(mod_ctx) = &self.modules.get(&uri) {
|
||||||
ctxs.push(&mod_ctx.context);
|
ctxs.push(&mod_ctx.context);
|
||||||
|
|
|
@ -562,7 +562,10 @@ pub fn opt_which_python() -> Result<String, String> {
|
||||||
return Err(format!("{}: {python} not found", fn_name_full!()));
|
return Err(format!("{}: {python} not found", fn_name_full!()));
|
||||||
};
|
};
|
||||||
let Ok(res) = String::from_utf8(out.stdout) else {
|
let Ok(res) = String::from_utf8(out.stdout) else {
|
||||||
return Err(format!("{}: failed to commnunicate with Python", fn_name_full!()));
|
return Err(format!(
|
||||||
|
"{}: failed to commnunicate with Python",
|
||||||
|
fn_name_full!()
|
||||||
|
));
|
||||||
};
|
};
|
||||||
let res = res.split('\n').next().unwrap_or("").replace('\r', "");
|
let res = res.split('\n').next().unwrap_or("").replace('\r', "");
|
||||||
if res.is_empty() {
|
if res.is_empty() {
|
||||||
|
|
|
@ -90,7 +90,9 @@ fn escape_name(name: &str, vis: &VisibilityModifier, def_line: u32, def_col: u32
|
||||||
fn escape_ident(ident: Identifier) -> Str {
|
fn escape_ident(ident: Identifier) -> Str {
|
||||||
let vis = ident.vis();
|
let vis = ident.vis();
|
||||||
if &ident.inspect()[..] == "Self" {
|
if &ident.inspect()[..] == "Self" {
|
||||||
let Ok(ty) = <&Type>::try_from(ident.vi.t.singleton_value().unwrap()) else { unreachable!() };
|
let Ok(ty) = <&Type>::try_from(ident.vi.t.singleton_value().unwrap()) else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
escape_name(
|
escape_name(
|
||||||
&ty.local_name(),
|
&ty.local_name(),
|
||||||
&ident.vi.vis.modifier,
|
&ident.vi.vis.modifier,
|
||||||
|
@ -1098,7 +1100,9 @@ impl PyCodeGenerator {
|
||||||
fn emit_trait_block(&mut self, kind: DefKind, sig: &Signature, mut block: Block) -> CodeObj {
|
fn emit_trait_block(&mut self, kind: DefKind, sig: &Signature, mut block: Block) -> CodeObj {
|
||||||
debug_assert_eq!(kind, DefKind::Trait);
|
debug_assert_eq!(kind, DefKind::Trait);
|
||||||
let name = sig.ident().inspect().clone();
|
let name = sig.ident().inspect().clone();
|
||||||
let Expr::Call(mut trait_call) = block.remove(0) else { unreachable!() };
|
let Expr::Call(mut trait_call) = block.remove(0) else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
let req = if let Some(Expr::Record(req)) = trait_call.args.remove_left_or_key("Requirement")
|
let req = if let Some(Expr::Record(req)) = trait_call.args.remove_left_or_key("Requirement")
|
||||||
{
|
{
|
||||||
req.attrs.into_iter()
|
req.attrs.into_iter()
|
||||||
|
@ -1770,7 +1774,7 @@ impl PyCodeGenerator {
|
||||||
// else block
|
// else block
|
||||||
let idx_else_begin = match self.py_version.minor {
|
let idx_else_begin = match self.py_version.minor {
|
||||||
Some(11) => self.lasti() - idx_pop_jump_if_false - 2,
|
Some(11) => self.lasti() - idx_pop_jump_if_false - 2,
|
||||||
Some(10 | 9 | 8 | 7) => self.lasti() + 2,
|
Some(7..=10) => self.lasti() + 2,
|
||||||
_ => self.lasti() + 2,
|
_ => self.lasti() + 2,
|
||||||
};
|
};
|
||||||
self.fill_jump(idx_pop_jump_if_false + 1, idx_else_begin - 2);
|
self.fill_jump(idx_pop_jump_if_false + 1, idx_else_begin - 2);
|
||||||
|
@ -1830,7 +1834,9 @@ impl PyCodeGenerator {
|
||||||
// but after executing this instruction, stack_len should be 1
|
// but after executing this instruction, stack_len should be 1
|
||||||
// cannot detect where to jump to at this moment, so put as 0
|
// cannot detect where to jump to at this moment, so put as 0
|
||||||
self.write_arg(0);
|
self.write_arg(0);
|
||||||
let Expr::Lambda(lambda) = args.remove(0) else { unreachable!() };
|
let Expr::Lambda(lambda) = args.remove(0) else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
// If there is nothing on the stack at the start, init_stack_len == 2 (an iterator and the first iterator value)
|
// If there is nothing on the stack at the start, init_stack_len == 2 (an iterator and the first iterator value)
|
||||||
let init_stack_len = self.stack_len();
|
let init_stack_len = self.stack_len();
|
||||||
let params = self.gen_param_names(&lambda.params);
|
let params = self.gen_param_names(&lambda.params);
|
||||||
|
@ -1849,7 +1855,7 @@ impl PyCodeGenerator {
|
||||||
self.write_arg(0);
|
self.write_arg(0);
|
||||||
self.fill_jump(idx + 1, self.lasti() - idx_for_iter);
|
self.fill_jump(idx + 1, self.lasti() - idx_for_iter);
|
||||||
}
|
}
|
||||||
Some(10 | 9 | 8 | 7) => {
|
Some(7..=10) => {
|
||||||
self.write_instr(Opcode309::JUMP_ABSOLUTE);
|
self.write_instr(Opcode309::JUMP_ABSOLUTE);
|
||||||
self.write_arg(0);
|
self.write_arg(0);
|
||||||
self.fill_jump(idx + 1, idx_for_iter);
|
self.fill_jump(idx + 1, idx_for_iter);
|
||||||
|
@ -1884,7 +1890,9 @@ impl PyCodeGenerator {
|
||||||
self.write_instr(Opcode310::POP_JUMP_IF_FALSE);
|
self.write_instr(Opcode310::POP_JUMP_IF_FALSE);
|
||||||
self.write_arg(0);
|
self.write_arg(0);
|
||||||
self.stack_dec();
|
self.stack_dec();
|
||||||
let Expr::Lambda(lambda) = args.remove(0) else { unreachable!() };
|
let Expr::Lambda(lambda) = args.remove(0) else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
let init_stack_len = self.stack_len();
|
let init_stack_len = self.stack_len();
|
||||||
let params = self.gen_param_names(&lambda.params);
|
let params = self.gen_param_names(&lambda.params);
|
||||||
self.emit_frameless_block(lambda.body, params);
|
self.emit_frameless_block(lambda.body, params);
|
||||||
|
@ -1929,7 +1937,9 @@ impl PyCodeGenerator {
|
||||||
self.dup_top();
|
self.dup_top();
|
||||||
}
|
}
|
||||||
// compilerで型チェック済み(可読性が下がるため、matchでNamedは使えない)
|
// compilerで型チェック済み(可読性が下がるため、matchでNamedは使えない)
|
||||||
let Expr::Lambda(mut lambda) = expr else { unreachable!() };
|
let Expr::Lambda(mut lambda) = expr else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
debug_power_assert!(lambda.params.len(), ==, 1);
|
debug_power_assert!(lambda.params.len(), ==, 1);
|
||||||
if !lambda.params.defaults.is_empty() {
|
if !lambda.params.defaults.is_empty() {
|
||||||
todo!("default values in match expression are not supported yet")
|
todo!("default values in match expression are not supported yet")
|
||||||
|
@ -2084,7 +2094,9 @@ impl PyCodeGenerator {
|
||||||
return self.deopt_instr(ControlKind::With, args);
|
return self.deopt_instr(ControlKind::With, args);
|
||||||
}
|
}
|
||||||
let expr = args.remove(0);
|
let expr = args.remove(0);
|
||||||
let Expr::Lambda(lambda) = args.remove(0) else { unreachable!() };
|
let Expr::Lambda(lambda) = args.remove(0) else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
let params = self.gen_param_names(&lambda.params);
|
let params = self.gen_param_names(&lambda.params);
|
||||||
self.emit_expr(expr);
|
self.emit_expr(expr);
|
||||||
self.write_instr(Opcode311::BEFORE_WITH);
|
self.write_instr(Opcode311::BEFORE_WITH);
|
||||||
|
@ -2132,7 +2144,9 @@ impl PyCodeGenerator {
|
||||||
return self.deopt_instr(ControlKind::With, args);
|
return self.deopt_instr(ControlKind::With, args);
|
||||||
}
|
}
|
||||||
let expr = args.remove(0);
|
let expr = args.remove(0);
|
||||||
let Expr::Lambda(lambda) = args.remove(0) else { unreachable!() };
|
let Expr::Lambda(lambda) = args.remove(0) else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
let params = self.gen_param_names(&lambda.params);
|
let params = self.gen_param_names(&lambda.params);
|
||||||
self.emit_expr(expr);
|
self.emit_expr(expr);
|
||||||
let idx_setup_with = self.lasti();
|
let idx_setup_with = self.lasti();
|
||||||
|
@ -2185,7 +2199,9 @@ impl PyCodeGenerator {
|
||||||
return self.deopt_instr(ControlKind::With, args);
|
return self.deopt_instr(ControlKind::With, args);
|
||||||
}
|
}
|
||||||
let expr = args.remove(0);
|
let expr = args.remove(0);
|
||||||
let Expr::Lambda(lambda) = args.remove(0) else { unreachable!() };
|
let Expr::Lambda(lambda) = args.remove(0) else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
let params = self.gen_param_names(&lambda.params);
|
let params = self.gen_param_names(&lambda.params);
|
||||||
self.emit_expr(expr);
|
self.emit_expr(expr);
|
||||||
let idx_setup_with = self.lasti();
|
let idx_setup_with = self.lasti();
|
||||||
|
@ -2238,7 +2254,9 @@ impl PyCodeGenerator {
|
||||||
return self.deopt_instr(ControlKind::With, args);
|
return self.deopt_instr(ControlKind::With, args);
|
||||||
}
|
}
|
||||||
let expr = args.remove(0);
|
let expr = args.remove(0);
|
||||||
let Expr::Lambda(lambda) = args.remove(0) else { unreachable!() };
|
let Expr::Lambda(lambda) = args.remove(0) else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
let params = self.gen_param_names(&lambda.params);
|
let params = self.gen_param_names(&lambda.params);
|
||||||
self.emit_expr(expr);
|
self.emit_expr(expr);
|
||||||
let idx_setup_with = self.lasti();
|
let idx_setup_with = self.lasti();
|
||||||
|
@ -2270,7 +2288,9 @@ impl PyCodeGenerator {
|
||||||
return self.deopt_instr(ControlKind::With, args);
|
return self.deopt_instr(ControlKind::With, args);
|
||||||
}
|
}
|
||||||
let expr = args.remove(0);
|
let expr = args.remove(0);
|
||||||
let Expr::Lambda(lambda) = args.remove(0) else { unreachable!() };
|
let Expr::Lambda(lambda) = args.remove(0) else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
let params = self.gen_param_names(&lambda.params);
|
let params = self.gen_param_names(&lambda.params);
|
||||||
self.emit_expr(expr);
|
self.emit_expr(expr);
|
||||||
let idx_setup_with = self.lasti();
|
let idx_setup_with = self.lasti();
|
||||||
|
@ -2485,7 +2505,9 @@ impl PyCodeGenerator {
|
||||||
/// TODO: should be `X = X + 1` in the above case
|
/// TODO: should be `X = X + 1` in the above case
|
||||||
fn emit_call_update_311(&mut self, obj: Expr, mut args: Args) {
|
fn emit_call_update_311(&mut self, obj: Expr, mut args: Args) {
|
||||||
log!(info "entered {}", fn_name!());
|
log!(info "entered {}", fn_name!());
|
||||||
let Expr::Accessor(acc) = obj else { unreachable!() };
|
let Expr::Accessor(acc) = obj else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
let func = args.remove_left_or_key("f").unwrap();
|
let func = args.remove_left_or_key("f").unwrap();
|
||||||
if !self.mutate_op_loaded {
|
if !self.mutate_op_loaded {
|
||||||
self.load_mutate_op();
|
self.load_mutate_op();
|
||||||
|
@ -2510,7 +2532,9 @@ impl PyCodeGenerator {
|
||||||
/// X = X + 1
|
/// X = X + 1
|
||||||
fn emit_call_update_310(&mut self, obj: Expr, mut args: Args) {
|
fn emit_call_update_310(&mut self, obj: Expr, mut args: Args) {
|
||||||
log!(info "entered {}", fn_name!());
|
log!(info "entered {}", fn_name!());
|
||||||
let Expr::Accessor(acc) = obj else { unreachable!() };
|
let Expr::Accessor(acc) = obj else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
let func = args.remove_left_or_key("f").unwrap();
|
let func = args.remove_left_or_key("f").unwrap();
|
||||||
if !self.mutate_op_loaded {
|
if !self.mutate_op_loaded {
|
||||||
self.load_mutate_op();
|
self.load_mutate_op();
|
||||||
|
|
|
@ -98,8 +98,12 @@ impl Context {
|
||||||
return self.same_type_of(l.as_ref(), r.typ());
|
return self.same_type_of(l.as_ref(), r.typ());
|
||||||
}
|
}
|
||||||
(l, r) if l.has_unbound_var() || r.has_unbound_var() => {
|
(l, r) if l.has_unbound_var() || r.has_unbound_var() => {
|
||||||
let Ok(lt) = self.get_tp_t(l) else { return false; };
|
let Ok(lt) = self.get_tp_t(l) else {
|
||||||
let Ok(rt) = self.get_tp_t(r) else { return false };
|
return false;
|
||||||
|
};
|
||||||
|
let Ok(rt) = self.get_tp_t(r) else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
return self.same_type_of(<, &rt);
|
return self.same_type_of(<, &rt);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
@ -796,7 +800,7 @@ impl Context {
|
||||||
};
|
};
|
||||||
ctx.type_dir(self)
|
ctx.type_dir(self)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.chain(mod_fields.into_iter())
|
.chain(mod_fields)
|
||||||
.map(|(name, vi)| {
|
.map(|(name, vi)| {
|
||||||
(
|
(
|
||||||
Field::new(vi.vis.modifier.clone(), name.inspect().clone()),
|
Field::new(vi.vis.modifier.clone(), name.inspect().clone()),
|
||||||
|
|
|
@ -421,7 +421,9 @@ impl Context {
|
||||||
match acc {
|
match acc {
|
||||||
Accessor::Ident(ident) => self.get_mod(ident.inspect()),
|
Accessor::Ident(ident) => self.get_mod(ident.inspect()),
|
||||||
Accessor::Attr(attr) => {
|
Accessor::Attr(attr) => {
|
||||||
let Expr::Accessor(acc) = attr.obj.as_ref() else { return None; };
|
let Expr::Accessor(acc) = attr.obj.as_ref() else {
|
||||||
|
return None;
|
||||||
|
};
|
||||||
self.get_mod_ctx_from_acc(acc)
|
self.get_mod_ctx_from_acc(acc)
|
||||||
.and_then(|ctx| ctx.get_mod(attr.ident.inspect()))
|
.and_then(|ctx| ctx.get_mod(attr.ident.inspect()))
|
||||||
}
|
}
|
||||||
|
|
|
@ -858,7 +858,9 @@ impl<'c, 'q, 'l, L: Locational> Dereferencer<'c, 'q, 'l, L> {
|
||||||
// ?T -> K(?T)
|
// ?T -> K(?T)
|
||||||
// ?T -> ?U(:> ?T)
|
// ?T -> ?U(:> ?T)
|
||||||
fn eliminate_needless_quant(&mut self, subr: Type) -> TyCheckResult<Type> {
|
fn eliminate_needless_quant(&mut self, subr: Type) -> TyCheckResult<Type> {
|
||||||
let Ok(mut subr) = SubrType::try_from(subr) else { unreachable!() };
|
let Ok(mut subr) = SubrType::try_from(subr) else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
let essential_qnames = subr.essential_qnames();
|
let essential_qnames = subr.essential_qnames();
|
||||||
let mut _self = Dereferencer::new(
|
let mut _self = Dereferencer::new(
|
||||||
self.ctx,
|
self.ctx,
|
||||||
|
@ -1227,7 +1229,9 @@ impl Context {
|
||||||
hir::Expr::Def(def) => {
|
hir::Expr::Def(def) => {
|
||||||
let qnames = if let Type::Quantified(quant) = def.sig.ref_t() {
|
let qnames = if let Type::Quantified(quant) = def.sig.ref_t() {
|
||||||
// double quantification is not allowed
|
// double quantification is not allowed
|
||||||
let Ok(subr) = <&SubrType>::try_from(quant.as_ref()) else { unreachable!() };
|
let Ok(subr) = <&SubrType>::try_from(quant.as_ref()) else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
subr.essential_qnames()
|
subr.essential_qnames()
|
||||||
} else {
|
} else {
|
||||||
qnames.clone()
|
qnames.clone()
|
||||||
|
@ -1245,7 +1249,9 @@ impl Context {
|
||||||
}
|
}
|
||||||
hir::Expr::Lambda(lambda) => {
|
hir::Expr::Lambda(lambda) => {
|
||||||
let qnames = if let Type::Quantified(quant) = lambda.ref_t() {
|
let qnames = if let Type::Quantified(quant) = lambda.ref_t() {
|
||||||
let Ok(subr) = <&SubrType>::try_from(quant.as_ref()) else { unreachable!() };
|
let Ok(subr) = <&SubrType>::try_from(quant.as_ref()) else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
subr.essential_qnames()
|
subr.essential_qnames()
|
||||||
} else {
|
} else {
|
||||||
qnames.clone()
|
qnames.clone()
|
||||||
|
|
|
@ -426,11 +426,10 @@ impl Context {
|
||||||
.skip(1)
|
.skip(1)
|
||||||
.map(|a| ParamTy::Pos(a.expr.ref_t().clone()))
|
.map(|a| ParamTy::Pos(a.expr.ref_t().clone()))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
let Some(mut return_t) = branch_ts.get(0).and_then(|branch| {
|
let Some(mut return_t) = branch_ts
|
||||||
branch.typ()
|
.get(0)
|
||||||
.return_t()
|
.and_then(|branch| branch.typ().return_t().cloned())
|
||||||
.cloned()
|
else {
|
||||||
}) else {
|
|
||||||
return Err(TyCheckErrors::from(TyCheckError::args_missing_error(
|
return Err(TyCheckErrors::from(TyCheckError::args_missing_error(
|
||||||
self.cfg.input.clone(),
|
self.cfg.input.clone(),
|
||||||
line!() as usize,
|
line!() as usize,
|
||||||
|
@ -926,12 +925,16 @@ impl Context {
|
||||||
for ty in intersecs.iter() {
|
for ty in intersecs.iter() {
|
||||||
match (ty.is_method(), input_t.is_method()) {
|
match (ty.is_method(), input_t.is_method()) {
|
||||||
(true, false) => {
|
(true, false) => {
|
||||||
let Type::Subr(sub) = &mut input_t else { unreachable!() };
|
let Type::Subr(sub) = &mut input_t else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
sub.non_default_params
|
sub.non_default_params
|
||||||
.insert(0, ParamTy::kw(Str::ever("self"), obj.t()));
|
.insert(0, ParamTy::kw(Str::ever("self"), obj.t()));
|
||||||
}
|
}
|
||||||
(false, true) => {
|
(false, true) => {
|
||||||
let Type::Subr(sub) = &mut input_t else { unreachable!() };
|
let Type::Subr(sub) = &mut input_t else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
sub.non_default_params.remove(0);
|
sub.non_default_params.remove(0);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
@ -940,7 +943,9 @@ impl Context {
|
||||||
return Ok(ty.clone());
|
return Ok(ty.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let Type::Subr(subr_t) = input_t else { unreachable!() };
|
let Type::Subr(subr_t) = input_t else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
Err(TyCheckError::overload_error(
|
Err(TyCheckError::overload_error(
|
||||||
self.cfg.input.clone(),
|
self.cfg.input.clone(),
|
||||||
line!() as usize,
|
line!() as usize,
|
||||||
|
@ -1207,7 +1212,8 @@ impl Context {
|
||||||
namespace.caused_by(),
|
namespace.caused_by(),
|
||||||
op.inspect(),
|
op.inspect(),
|
||||||
None,
|
None,
|
||||||
).into());
|
)
|
||||||
|
.into());
|
||||||
};
|
};
|
||||||
// not a `Token::from_str(op.kind, cont)` because ops are defined as symbols
|
// not a `Token::from_str(op.kind, cont)` because ops are defined as symbols
|
||||||
let symbol = Token::symbol_with_loc(Str::rc(cont), Location::concat(&args[0], &args[1]));
|
let symbol = Token::symbol_with_loc(Str::rc(cont), Location::concat(&args[0], &args[1]));
|
||||||
|
@ -1261,7 +1267,8 @@ impl Context {
|
||||||
namespace.caused_by(),
|
namespace.caused_by(),
|
||||||
op.inspect(),
|
op.inspect(),
|
||||||
None,
|
None,
|
||||||
).into());
|
)
|
||||||
|
.into());
|
||||||
};
|
};
|
||||||
let symbol = Token::symbol(cont);
|
let symbol = Token::symbol(cont);
|
||||||
let ident = Identifier::private_from_token(symbol.clone());
|
let ident = Identifier::private_from_token(symbol.clone());
|
||||||
|
@ -1637,7 +1644,7 @@ impl Context {
|
||||||
.map_or(vec![], |ctx| vec![ctx])
|
.map_or(vec![], |ctx| vec![ctx])
|
||||||
})
|
})
|
||||||
.unwrap_or(vec![]);
|
.unwrap_or(vec![]);
|
||||||
let fallbacks = one.into_iter().chain(two.into_iter());
|
let fallbacks = one.into_iter().chain(two);
|
||||||
for typ_ctx in fallbacks {
|
for typ_ctx in fallbacks {
|
||||||
if let Some(call_vi) = typ_ctx.get_current_scope_var(&VarName::from_static("__call__"))
|
if let Some(call_vi) = typ_ctx.get_current_scope_var(&VarName::from_static("__call__"))
|
||||||
{
|
{
|
||||||
|
|
|
@ -203,7 +203,9 @@ impl TyVarCache {
|
||||||
// T<inst> is uninitialized
|
// T<inst> is uninitialized
|
||||||
// T<inst>.link(T<tv>);
|
// T<inst>.link(T<tv>);
|
||||||
// T <: Eq(T <: Eq(T <: ...))
|
// T <: Eq(T <: Eq(T <: ...))
|
||||||
let Type::FreeVar(free_inst) = inst else { todo!("{inst}") };
|
let Type::FreeVar(free_inst) = inst else {
|
||||||
|
todo!("{inst}")
|
||||||
|
};
|
||||||
if free_inst.constraint_is_uninited() {
|
if free_inst.constraint_is_uninited() {
|
||||||
inst.destructive_link(tv);
|
inst.destructive_link(tv);
|
||||||
} else {
|
} else {
|
||||||
|
@ -279,7 +281,9 @@ impl TyVarCache {
|
||||||
inst.destructive_link(tp);
|
inst.destructive_link(tp);
|
||||||
} else {
|
} else {
|
||||||
let old_type = free_inst.get_type().unwrap();
|
let old_type = free_inst.get_type().unwrap();
|
||||||
let Ok(tv) = <&FreeTyParam>::try_from(tp) else { todo!("{tp}") };
|
let Ok(tv) = <&FreeTyParam>::try_from(tp) else {
|
||||||
|
todo!("{tp}")
|
||||||
|
};
|
||||||
let new_type = tv.get_type().unwrap();
|
let new_type = tv.get_type().unwrap();
|
||||||
let new_constraint = Constraint::new_type_of(ctx.intersection(&old_type, &new_type));
|
let new_constraint = Constraint::new_type_of(ctx.intersection(&old_type, &new_type));
|
||||||
free_inst.update_constraint(new_constraint, true);
|
free_inst.update_constraint(new_constraint, true);
|
||||||
|
|
|
@ -909,7 +909,9 @@ impl Context {
|
||||||
} else if ctx.kind.is_type() && !ctx.params.is_empty() {
|
} else if ctx.kind.is_type() && !ctx.params.is_empty() {
|
||||||
Ok(TyParam::t(poly(ctx.name.clone(), args)))
|
Ok(TyParam::t(poly(ctx.name.clone(), args)))
|
||||||
} else {
|
} else {
|
||||||
let ast::ConstExpr::Accessor(ast::ConstAccessor::Local(ident)) = app.obj.as_ref() else {
|
let ast::ConstExpr::Accessor(ast::ConstAccessor::Local(ident)) =
|
||||||
|
app.obj.as_ref()
|
||||||
|
else {
|
||||||
return type_feature_error!(self, app.loc(), "instantiating const callee");
|
return type_feature_error!(self, app.loc(), "instantiating const callee");
|
||||||
};
|
};
|
||||||
Ok(TyParam::app(ident.inspect().clone(), args))
|
Ok(TyParam::app(ident.inspect().clone(), args))
|
||||||
|
@ -1095,7 +1097,7 @@ impl Context {
|
||||||
self,
|
self,
|
||||||
bin.loc(),
|
bin.loc(),
|
||||||
&format!("instantiating const expression {bin}")
|
&format!("instantiating const expression {bin}")
|
||||||
)
|
);
|
||||||
};
|
};
|
||||||
let lhs = self.instantiate_const_expr(
|
let lhs = self.instantiate_const_expr(
|
||||||
&bin.lhs,
|
&bin.lhs,
|
||||||
|
@ -1117,7 +1119,7 @@ impl Context {
|
||||||
self,
|
self,
|
||||||
unary.loc(),
|
unary.loc(),
|
||||||
&format!("instantiating const expression {unary}")
|
&format!("instantiating const expression {unary}")
|
||||||
)
|
);
|
||||||
};
|
};
|
||||||
let val = self.instantiate_const_expr(
|
let val = self.instantiate_const_expr(
|
||||||
&unary.expr,
|
&unary.expr,
|
||||||
|
|
|
@ -950,7 +950,9 @@ impl Context {
|
||||||
/// HACK: The constant expression evaluator can evaluate attributes when the type of the receiver is known.
|
/// HACK: The constant expression evaluator can evaluate attributes when the type of the receiver is known.
|
||||||
/// import/pyimport is not a constant function, but specially assumes that the type of the module is known in the eval phase.
|
/// import/pyimport is not a constant function, but specially assumes that the type of the module is known in the eval phase.
|
||||||
fn pre_import(&mut self, def: &ast::Def) -> TyCheckResult<()> {
|
fn pre_import(&mut self, def: &ast::Def) -> TyCheckResult<()> {
|
||||||
let Some(ast::Expr::Call(call)) = def.body.block.first() else { unreachable!() };
|
let Some(ast::Expr::Call(call)) = def.body.block.first() else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
let Some(ast::Expr::Literal(mod_name)) = call.args.get_left_or_key("Path") else {
|
let Some(ast::Expr::Literal(mod_name)) = call.args.get_left_or_key("Path") else {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
};
|
};
|
||||||
|
@ -974,7 +976,9 @@ impl Context {
|
||||||
params: vec![arg],
|
params: vec![arg],
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let Some(ident) = def.sig.ident() else { return res };
|
let Some(ident) = def.sig.ident() else {
|
||||||
|
return res;
|
||||||
|
};
|
||||||
let Some((_, vi)) = self.get_var_info(ident.inspect()) else {
|
let Some((_, vi)) = self.get_var_info(ident.inspect()) else {
|
||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
|
@ -1453,7 +1457,13 @@ impl Context {
|
||||||
2,
|
2,
|
||||||
self.level,
|
self.level,
|
||||||
);
|
);
|
||||||
let Some(TypeObj::Builtin{ t: Type::Record(req), .. }) = gen.base_or_sup() else { todo!("{gen}") };
|
let Some(TypeObj::Builtin {
|
||||||
|
t: Type::Record(req),
|
||||||
|
..
|
||||||
|
}) = gen.base_or_sup()
|
||||||
|
else {
|
||||||
|
todo!("{gen}")
|
||||||
|
};
|
||||||
self.register_instance_attrs(&mut ctx, req)?;
|
self.register_instance_attrs(&mut ctx, req)?;
|
||||||
self.register_gen_mono_type(ident, gen, ctx, Const)
|
self.register_gen_mono_type(ident, gen, ctx, Const)
|
||||||
} else {
|
} else {
|
||||||
|
@ -1509,7 +1519,9 @@ impl Context {
|
||||||
}
|
}
|
||||||
GenTypeObj::Patch(_) => {
|
GenTypeObj::Patch(_) => {
|
||||||
if gen.typ().is_monomorphic() {
|
if gen.typ().is_monomorphic() {
|
||||||
let Some(TypeObj::Builtin{ t: base, .. }) = gen.base_or_sup() else { todo!("{gen}") };
|
let Some(TypeObj::Builtin { t: base, .. }) = gen.base_or_sup() else {
|
||||||
|
todo!("{gen}")
|
||||||
|
};
|
||||||
let ctx = Self::mono_patch(
|
let ctx = Self::mono_patch(
|
||||||
gen.typ().qual_name(),
|
gen.typ().qual_name(),
|
||||||
base.clone(),
|
base.clone(),
|
||||||
|
@ -1829,7 +1841,11 @@ impl Context {
|
||||||
mod_name: &Literal,
|
mod_name: &Literal,
|
||||||
) -> CompileResult<PathBuf> {
|
) -> CompileResult<PathBuf> {
|
||||||
let ValueObj::Str(__name__) = &mod_name.value else {
|
let ValueObj::Str(__name__) = &mod_name.value else {
|
||||||
let name = if kind.is_erg_import() { "import" } else { "pyimport" };
|
let name = if kind.is_erg_import() {
|
||||||
|
"import"
|
||||||
|
} else {
|
||||||
|
"pyimport"
|
||||||
|
};
|
||||||
return Err(TyCheckErrors::from(TyCheckError::type_mismatch_error(
|
return Err(TyCheckErrors::from(TyCheckError::type_mismatch_error(
|
||||||
self.cfg.input.clone(),
|
self.cfg.input.clone(),
|
||||||
line!() as usize,
|
line!() as usize,
|
||||||
|
|
|
@ -1129,7 +1129,9 @@ impl<'c, 'l, 'u, L: Locational> Unifier<'c, 'l, 'u, L> {
|
||||||
self.sub_unify(&sub_subr.return_t, &sup_subr.return_t)?;
|
self.sub_unify(&sub_subr.return_t, &sup_subr.return_t)?;
|
||||||
}
|
}
|
||||||
(Quantified(sub_subr), Subr(sup_subr)) => {
|
(Quantified(sub_subr), Subr(sup_subr)) => {
|
||||||
let Ok(sub_subr) = <&SubrType>::try_from(sub_subr.as_ref()) else { unreachable!() };
|
let Ok(sub_subr) = <&SubrType>::try_from(sub_subr.as_ref()) else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
sub_subr
|
sub_subr
|
||||||
.non_default_params
|
.non_default_params
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -1164,7 +1166,9 @@ impl<'c, 'l, 'u, L: Locational> Unifier<'c, 'l, 'u, L> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(Subr(sub_subr), Quantified(sup_subr)) => {
|
(Subr(sub_subr), Quantified(sup_subr)) => {
|
||||||
let Ok(sup_subr) = <&SubrType>::try_from(sup_subr.as_ref()) else { unreachable!() };
|
let Ok(sup_subr) = <&SubrType>::try_from(sup_subr.as_ref()) else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
sub_subr
|
sub_subr
|
||||||
.non_default_params
|
.non_default_params
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -1447,7 +1451,6 @@ impl<'c, 'l, 'u, L: Locational> Unifier<'c, 'l, 'u, L> {
|
||||||
(Type::Refinement(lhs), Type::Refinement(rhs)) => {
|
(Type::Refinement(lhs), Type::Refinement(rhs)) => {
|
||||||
if let Some(_union) = self.unify(&lhs.t, &rhs.t) {
|
if let Some(_union) = self.unify(&lhs.t, &rhs.t) {
|
||||||
return Some(self.ctx.union_refinement(lhs, rhs).into());
|
return Some(self.ctx.union_refinement(lhs, rhs).into());
|
||||||
} else {
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|
|
@ -137,7 +137,7 @@ impl ASTLinker {
|
||||||
decl.expr.loc(),
|
decl.expr.loc(),
|
||||||
"".into(),
|
"".into(),
|
||||||
"".into(),
|
"".into(),
|
||||||
None
|
None,
|
||||||
));
|
));
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
|
@ -205,7 +205,9 @@ impl ASTLowerer {
|
||||||
match chunk {
|
match chunk {
|
||||||
Expr::Lit(lit) if lit.is_doc_comment() => {
|
Expr::Lit(lit) if lit.is_doc_comment() => {
|
||||||
let first_line = lit.ln_begin().unwrap_or(1);
|
let first_line = lit.ln_begin().unwrap_or(1);
|
||||||
let ValueObj::Str(content) = &lit.value else { return; };
|
let ValueObj::Str(content) = &lit.value else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
if content.starts_with("erg\n") {
|
if content.starts_with("erg\n") {
|
||||||
let code = content.trim_start_matches("erg\n");
|
let code = content.trim_start_matches("erg\n");
|
||||||
let indent = code.chars().take_while(|c| c.is_whitespace()).count();
|
let indent = code.chars().take_while(|c| c.is_whitespace()).count();
|
||||||
|
|
|
@ -1754,7 +1754,11 @@ impl ASTLowerer {
|
||||||
&class,
|
&class,
|
||||||
)));
|
)));
|
||||||
};
|
};
|
||||||
let Some(class_type) = self.module.context.rec_get_const_obj(hir_def.sig.ident().inspect()) else {
|
let Some(class_type) = self
|
||||||
|
.module
|
||||||
|
.context
|
||||||
|
.rec_get_const_obj(hir_def.sig.ident().inspect())
|
||||||
|
else {
|
||||||
return unreachable_error!(LowerErrors, LowerError, self);
|
return unreachable_error!(LowerErrors, LowerError, self);
|
||||||
};
|
};
|
||||||
let ValueObj::Type(TypeObj::Generated(type_obj)) = class_type else {
|
let ValueObj::Type(TypeObj::Generated(type_obj)) = class_type else {
|
||||||
|
@ -1766,7 +1770,10 @@ impl ASTLowerer {
|
||||||
if let Some(sup_type) = call.args.get_left_or_key("Super") {
|
if let Some(sup_type) = call.args.get_left_or_key("Super") {
|
||||||
Self::check_inheritable(&self.cfg, &mut self.errs, type_obj, sup_type, &hir_def.sig);
|
Self::check_inheritable(&self.cfg, &mut self.errs, type_obj, sup_type, &hir_def.sig);
|
||||||
}
|
}
|
||||||
let Some(__new__) = class_ctx.get_current_scope_var(&VarName::from_static("__new__")).or(class_ctx.get_current_scope_var(&VarName::from_static("__call__"))) else {
|
let Some(__new__) = class_ctx
|
||||||
|
.get_current_scope_var(&VarName::from_static("__new__"))
|
||||||
|
.or(class_ctx.get_current_scope_var(&VarName::from_static("__call__")))
|
||||||
|
else {
|
||||||
return unreachable_error!(LowerErrors, LowerError, self);
|
return unreachable_error!(LowerErrors, LowerError, self);
|
||||||
};
|
};
|
||||||
let need_to_gen_new = class_ctx
|
let need_to_gen_new = class_ctx
|
||||||
|
@ -2180,10 +2187,7 @@ impl ASTLowerer {
|
||||||
|
|
||||||
fn check_collision_and_push(&mut self, class: Type, impl_trait: Option<Type>) {
|
fn check_collision_and_push(&mut self, class: Type, impl_trait: Option<Type>) {
|
||||||
let methods = self.module.context.pop();
|
let methods = self.module.context.pop();
|
||||||
let Some((_, class_root)) = self
|
let Some((_, class_root)) = self.module.context.get_mut_nominal_type_ctx(&class) else {
|
||||||
.module
|
|
||||||
.context
|
|
||||||
.get_mut_nominal_type_ctx(&class) else {
|
|
||||||
log!(err "{class} not found");
|
log!(err "{class} not found");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
@ -2222,7 +2226,9 @@ impl ASTLowerer {
|
||||||
|
|
||||||
fn push_patch(&mut self) {
|
fn push_patch(&mut self) {
|
||||||
let methods = self.module.context.pop();
|
let methods = self.module.context.pop();
|
||||||
let ContextKind::PatchMethodDefs(base) = &methods.kind else { unreachable!() };
|
let ContextKind::PatchMethodDefs(base) = &methods.kind else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
let patch_name = *methods.name.split_with(&["::", "."]).last().unwrap();
|
let patch_name = *methods.name.split_with(&["::", "."]).last().unwrap();
|
||||||
let patch_root = self
|
let patch_root = self
|
||||||
.module
|
.module
|
||||||
|
|
|
@ -667,7 +667,9 @@ impl PyScriptGenerator {
|
||||||
Some("for" | "for!") => {
|
Some("for" | "for!") => {
|
||||||
let mut code = "for ".to_string();
|
let mut code = "for ".to_string();
|
||||||
let iter = call.args.remove(0);
|
let iter = call.args.remove(0);
|
||||||
let Expr::Lambda(block) = call.args.remove(0) else { todo!() };
|
let Expr::Lambda(block) = call.args.remove(0) else {
|
||||||
|
todo!()
|
||||||
|
};
|
||||||
let non_default = block.params.non_defaults.get(0).unwrap();
|
let non_default = block.params.non_defaults.get(0).unwrap();
|
||||||
let param = match &non_default.raw.pat {
|
let param = match &non_default.raw.pat {
|
||||||
ParamPattern::VarName(name) => name.token(),
|
ParamPattern::VarName(name) => name.token(),
|
||||||
|
@ -682,7 +684,9 @@ impl PyScriptGenerator {
|
||||||
Some("while" | "while!") => {
|
Some("while" | "while!") => {
|
||||||
let mut code = "while ".to_string();
|
let mut code = "while ".to_string();
|
||||||
let cond = call.args.remove(0);
|
let cond = call.args.remove(0);
|
||||||
let Expr::Lambda(block) = call.args.remove(0) else { todo!() };
|
let Expr::Lambda(block) = call.args.remove(0) else {
|
||||||
|
todo!()
|
||||||
|
};
|
||||||
code += &format!("{}:\n", self.transpile_expr(cond));
|
code += &format!("{}:\n", self.transpile_expr(cond));
|
||||||
code += &self.transpile_block(block.body, Discard);
|
code += &self.transpile_block(block.body, Discard);
|
||||||
code
|
code
|
||||||
|
@ -694,7 +698,9 @@ impl PyScriptGenerator {
|
||||||
|
|
||||||
fn transpile_if(&mut self, mut call: Call) -> String {
|
fn transpile_if(&mut self, mut call: Call) -> String {
|
||||||
let cond = self.transpile_expr(call.args.remove(0));
|
let cond = self.transpile_expr(call.args.remove(0));
|
||||||
let Expr::Lambda(mut then_block) = call.args.remove(0) else { todo!() };
|
let Expr::Lambda(mut then_block) = call.args.remove(0) else {
|
||||||
|
todo!()
|
||||||
|
};
|
||||||
let else_block = call.args.try_remove(0).map(|ex| {
|
let else_block = call.args.try_remove(0).map(|ex| {
|
||||||
if let Expr::Lambda(blk) = ex {
|
if let Expr::Lambda(blk) = ex {
|
||||||
blk
|
blk
|
||||||
|
|
|
@ -39,7 +39,7 @@ pub fn consts_into_bytes(consts: Vec<ValueObj>, python_ver: PythonVersion) -> Ve
|
||||||
|
|
||||||
pub fn jump_abs_addr(minor_ver: u8, op: u8, idx: usize, arg: usize) -> usize {
|
pub fn jump_abs_addr(minor_ver: u8, op: u8, idx: usize, arg: usize) -> usize {
|
||||||
match minor_ver {
|
match minor_ver {
|
||||||
7 | 8 | 9 => jump_abs_addr_309(Opcode309::from(op), idx, arg),
|
7..=9 => jump_abs_addr_309(Opcode309::from(op), idx, arg),
|
||||||
10 => jump_abs_addr_310(Opcode310::from(op), idx, arg),
|
10 => jump_abs_addr_310(Opcode310::from(op), idx, arg),
|
||||||
11 => jump_abs_addr_311(Opcode311::from(op), idx, arg),
|
11 => jump_abs_addr_311(Opcode311::from(op), idx, arg),
|
||||||
n => todo!("unsupported version: {n}"),
|
n => todo!("unsupported version: {n}"),
|
||||||
|
|
|
@ -1107,7 +1107,9 @@ mod tests {
|
||||||
fn cmp_freevar() {
|
fn cmp_freevar() {
|
||||||
enable_overflow_stacktrace!();
|
enable_overflow_stacktrace!();
|
||||||
let t = named_uninit_var("T".into());
|
let t = named_uninit_var("T".into());
|
||||||
let Type::FreeVar(fv) = t.clone() else { unreachable!() };
|
let Type::FreeVar(fv) = t.clone() else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
let constraint = Constraint::new_subtype_of(poly("Add", vec![ty_tp(t.clone())]));
|
let constraint = Constraint::new_subtype_of(poly("Add", vec![ty_tp(t.clone())]));
|
||||||
fv.update_constraint(constraint.clone(), true);
|
fv.update_constraint(constraint.clone(), true);
|
||||||
let u = named_free_var("T".into(), 1, constraint);
|
let u = named_free_var("T".into(), 1, constraint);
|
||||||
|
|
|
@ -558,7 +558,7 @@ impl SubrType {
|
||||||
pub fn param_names(&self) -> impl Iterator<Item = &str> + Clone {
|
pub fn param_names(&self) -> impl Iterator<Item = &str> + Clone {
|
||||||
self.non_default_params
|
self.non_default_params
|
||||||
.iter()
|
.iter()
|
||||||
.chain(self.var_params.as_deref().into_iter())
|
.chain(self.var_params.as_deref())
|
||||||
.chain(self.default_params.iter())
|
.chain(self.default_params.iter())
|
||||||
.map(|pt| pt.name().map_or("_", |s| &s[..]))
|
.map(|pt| pt.name().map_or("_", |s| &s[..]))
|
||||||
}
|
}
|
||||||
|
@ -1371,14 +1371,9 @@ impl HasType for Type {
|
||||||
.default_params
|
.default_params
|
||||||
.iter()
|
.iter()
|
||||||
.map(|pt| pt.typ().clone())
|
.map(|pt| pt.typ().clone())
|
||||||
.chain(
|
.chain(sub.var_params.as_deref().map(|pt| pt.typ().clone()))
|
||||||
sub.var_params
|
|
||||||
.as_deref()
|
|
||||||
.map(|pt| pt.typ().clone())
|
|
||||||
.into_iter(),
|
|
||||||
)
|
|
||||||
.chain(sub.non_default_params.iter().map(|pt| pt.typ().clone()))
|
.chain(sub.non_default_params.iter().map(|pt| pt.typ().clone()))
|
||||||
.chain([*sub.return_t.clone()].into_iter())
|
.chain([*sub.return_t.clone()])
|
||||||
.collect(),
|
.collect(),
|
||||||
Self::Callable { param_ts, .. } => param_ts.clone(),
|
Self::Callable { param_ts, .. } => param_ts.clone(),
|
||||||
Self::Poly { params, .. } => params.iter().filter_map(get_t_from_tp).collect(),
|
Self::Poly { params, .. } => params.iter().filter_map(get_t_from_tp).collect(),
|
||||||
|
|
|
@ -142,7 +142,11 @@ impl Parser {
|
||||||
|
|
||||||
fn convert_def_to_var_record_attr(&mut self, mut attr: Def) -> ParseResult<VarRecordAttr> {
|
fn convert_def_to_var_record_attr(&mut self, mut attr: Def) -> ParseResult<VarRecordAttr> {
|
||||||
debug_call_info!(self);
|
debug_call_info!(self);
|
||||||
let Signature::Var(VarSignature{ pat: VarPattern::Ident(lhs), .. }) = attr.sig else {
|
let Signature::Var(VarSignature {
|
||||||
|
pat: VarPattern::Ident(lhs),
|
||||||
|
..
|
||||||
|
}) = attr.sig
|
||||||
|
else {
|
||||||
let err = ParseError::simple_syntax_error(line!() as usize, attr.sig.loc());
|
let err = ParseError::simple_syntax_error(line!() as usize, attr.sig.loc());
|
||||||
self.errs.push(err);
|
self.errs.push(err);
|
||||||
return Err(());
|
return Err(());
|
||||||
|
@ -293,7 +297,11 @@ impl Parser {
|
||||||
let sig = self
|
let sig = self
|
||||||
.convert_rhs_to_sig(*t_app.obj)
|
.convert_rhs_to_sig(*t_app.obj)
|
||||||
.map_err(|_| self.stack_dec(fn_name!()))?;
|
.map_err(|_| self.stack_dec(fn_name!()))?;
|
||||||
let Signature::Var(VarSignature { pat: VarPattern::Ident(ident), .. }) = sig else {
|
let Signature::Var(VarSignature {
|
||||||
|
pat: VarPattern::Ident(ident),
|
||||||
|
..
|
||||||
|
}) = sig
|
||||||
|
else {
|
||||||
let err = ParseError::simple_syntax_error(line!() as usize, sig.loc());
|
let err = ParseError::simple_syntax_error(line!() as usize, sig.loc());
|
||||||
self.errs.push(err);
|
self.errs.push(err);
|
||||||
debug_exit_info!(self);
|
debug_exit_info!(self);
|
||||||
|
@ -343,7 +351,11 @@ impl Parser {
|
||||||
let lhs = self
|
let lhs = self
|
||||||
.convert_rhs_to_sig(*tasc.expr)
|
.convert_rhs_to_sig(*tasc.expr)
|
||||||
.map_err(|_| self.stack_dec(fn_name!()))?;
|
.map_err(|_| self.stack_dec(fn_name!()))?;
|
||||||
let Signature::Var(VarSignature{ pat: VarPattern::Ident(lhs), .. }) = lhs else {
|
let Signature::Var(VarSignature {
|
||||||
|
pat: VarPattern::Ident(lhs),
|
||||||
|
..
|
||||||
|
}) = lhs
|
||||||
|
else {
|
||||||
let err = ParseError::simple_syntax_error(line!() as usize, lhs.loc());
|
let err = ParseError::simple_syntax_error(line!() as usize, lhs.loc());
|
||||||
self.errs.push(err);
|
self.errs.push(err);
|
||||||
return Err(());
|
return Err(());
|
||||||
|
@ -541,7 +553,11 @@ impl Parser {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn convert_def_to_param_record_attr(&mut self, mut attr: Def) -> ParseResult<ParamRecordAttr> {
|
fn convert_def_to_param_record_attr(&mut self, mut attr: Def) -> ParseResult<ParamRecordAttr> {
|
||||||
let Signature::Var(VarSignature{ pat: VarPattern::Ident(lhs), .. }) = attr.sig else {
|
let Signature::Var(VarSignature {
|
||||||
|
pat: VarPattern::Ident(lhs),
|
||||||
|
..
|
||||||
|
}) = attr.sig
|
||||||
|
else {
|
||||||
let err = ParseError::simple_syntax_error(line!() as usize, attr.sig.loc());
|
let err = ParseError::simple_syntax_error(line!() as usize, attr.sig.loc());
|
||||||
self.errs.push(err);
|
self.errs.push(err);
|
||||||
debug_exit_info!(self);
|
debug_exit_info!(self);
|
||||||
|
|
|
@ -149,7 +149,9 @@ impl Desugarer {
|
||||||
},
|
},
|
||||||
Expr::DataPack(pack) => {
|
Expr::DataPack(pack) => {
|
||||||
let class = desugar(*pack.class);
|
let class = desugar(*pack.class);
|
||||||
let Expr::Record(args) = desugar(Expr::Record(pack.args)) else { unreachable!() };
|
let Expr::Record(args) = desugar(Expr::Record(pack.args)) else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
Expr::DataPack(DataPack::new(class, pack.connector, args))
|
Expr::DataPack(DataPack::new(class, pack.connector, args))
|
||||||
}
|
}
|
||||||
Expr::Array(array) => match array {
|
Expr::Array(array) => match array {
|
||||||
|
@ -273,7 +275,9 @@ impl Desugarer {
|
||||||
Expr::Def(Def::new(def.sig, body))
|
Expr::Def(Def::new(def.sig, body))
|
||||||
}
|
}
|
||||||
Expr::ClassDef(class_def) => {
|
Expr::ClassDef(class_def) => {
|
||||||
let Expr::Def(def) = desugar(Expr::Def(class_def.def)) else { unreachable!() };
|
let Expr::Def(def) = desugar(Expr::Def(class_def.def)) else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
let methods = class_def
|
let methods = class_def
|
||||||
.methods_list
|
.methods_list
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -282,7 +286,9 @@ impl Desugarer {
|
||||||
Expr::ClassDef(ClassDef::new(def, methods))
|
Expr::ClassDef(ClassDef::new(def, methods))
|
||||||
}
|
}
|
||||||
Expr::PatchDef(class_def) => {
|
Expr::PatchDef(class_def) => {
|
||||||
let Expr::Def(def) = desugar(Expr::Def(class_def.def)) else { unreachable!() };
|
let Expr::Def(def) = desugar(Expr::Def(class_def.def)) else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
let methods = class_def
|
let methods = class_def
|
||||||
.methods_list
|
.methods_list
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -401,7 +407,9 @@ impl Desugarer {
|
||||||
if let Some(Expr::Def(previous)) = new.last() {
|
if let Some(Expr::Def(previous)) = new.last() {
|
||||||
if previous.is_subr() && previous.sig.name_as_str() == def.sig.name_as_str()
|
if previous.is_subr() && previous.sig.name_as_str() == def.sig.name_as_str()
|
||||||
{
|
{
|
||||||
let Some(Expr::Def(previous)) = new.pop() else { unreachable!() };
|
let Some(Expr::Def(previous)) = new.pop() else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
let name = def.sig.ident().unwrap().clone();
|
let name = def.sig.ident().unwrap().clone();
|
||||||
let id = def.body.id;
|
let id = def.body.id;
|
||||||
let op = def.body.op.clone();
|
let op = def.body.op.clone();
|
||||||
|
@ -479,8 +487,12 @@ impl Desugarer {
|
||||||
|
|
||||||
fn add_arg_to_match_call(&self, mut previous: Def, def: Def) -> (Call, Option<TypeSpecWithOp>) {
|
fn add_arg_to_match_call(&self, mut previous: Def, def: Def) -> (Call, Option<TypeSpecWithOp>) {
|
||||||
let op = Token::from_str(TokenKind::FuncArrow, "->");
|
let op = Token::from_str(TokenKind::FuncArrow, "->");
|
||||||
let Expr::Call(mut call) = previous.body.block.remove(0) else { unreachable!() };
|
let Expr::Call(mut call) = previous.body.block.remove(0) else {
|
||||||
let Signature::Subr(sig) = def.sig else { unreachable!() };
|
unreachable!()
|
||||||
|
};
|
||||||
|
let Signature::Subr(sig) = def.sig else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
let return_t_spec = sig.return_t_spec;
|
let return_t_spec = sig.return_t_spec;
|
||||||
let first_arg = sig.params.non_defaults.first().unwrap();
|
let first_arg = sig.params.non_defaults.first().unwrap();
|
||||||
// 最後の定義の引数名を関数全体の引数名にする
|
// 最後の定義の引数名を関数全体の引数名にする
|
||||||
|
@ -509,7 +521,9 @@ impl Desugarer {
|
||||||
// TODO: procedural match
|
// TODO: procedural match
|
||||||
fn gen_match_call(&self, previous: Def, def: Def) -> (Call, Option<TypeSpecWithOp>) {
|
fn gen_match_call(&self, previous: Def, def: Def) -> (Call, Option<TypeSpecWithOp>) {
|
||||||
let op = Token::from_str(TokenKind::FuncArrow, "->");
|
let op = Token::from_str(TokenKind::FuncArrow, "->");
|
||||||
let Signature::Subr(prev_sig) = previous.sig else { unreachable!() };
|
let Signature::Subr(prev_sig) = previous.sig else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
let params_len = prev_sig.params.len();
|
let params_len = prev_sig.params.len();
|
||||||
let params = if params_len == 1 {
|
let params = if params_len == 1 {
|
||||||
prev_sig.params
|
prev_sig.params
|
||||||
|
@ -520,7 +534,9 @@ impl Desugarer {
|
||||||
let match_symbol = Expr::static_local("match");
|
let match_symbol = Expr::static_local("match");
|
||||||
let sig = LambdaSignature::new(params, prev_sig.return_t_spec, prev_sig.bounds);
|
let sig = LambdaSignature::new(params, prev_sig.return_t_spec, prev_sig.bounds);
|
||||||
let first_branch = Lambda::new(sig, op.clone(), previous.body.block, previous.body.id);
|
let first_branch = Lambda::new(sig, op.clone(), previous.body.block, previous.body.id);
|
||||||
let Signature::Subr(sig) = def.sig else { unreachable!() };
|
let Signature::Subr(sig) = def.sig else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
let params = if sig.params.len() == 1 {
|
let params = if sig.params.len() == 1 {
|
||||||
sig.params
|
sig.params
|
||||||
} else {
|
} else {
|
||||||
|
@ -588,10 +604,13 @@ impl Desugarer {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn desugar_pattern_in_module(&mut self, module: Module) -> Module {
|
fn desugar_pattern_in_module(&mut self, module: Module) -> Module {
|
||||||
|
// https://github.com/rust-lang/rust-clippy/issues/11300
|
||||||
|
#[allow(clippy::useless_conversion)]
|
||||||
Module::new(self.desugar_pattern(module.into_iter()))
|
Module::new(self.desugar_pattern(module.into_iter()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn desugar_pattern_in_block(&mut self, block: Block) -> Block {
|
fn desugar_pattern_in_block(&mut self, block: Block) -> Block {
|
||||||
|
#[allow(clippy::useless_conversion)]
|
||||||
Block::new(self.desugar_pattern(block.into_iter()))
|
Block::new(self.desugar_pattern(block.into_iter()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3472,7 +3472,11 @@ impl Parser {
|
||||||
let Expr::Call(mut call) = expect_call else {
|
let Expr::Call(mut call) = expect_call else {
|
||||||
let caused_by = caused_by!();
|
let caused_by = caused_by!();
|
||||||
log!(err "error caused by: {caused_by}");
|
log!(err "error caused by: {caused_by}");
|
||||||
let err = self.get_stream_op_syntax_error(line!() as usize, expect_call.loc(), caused_by!());
|
let err = self.get_stream_op_syntax_error(
|
||||||
|
line!() as usize,
|
||||||
|
expect_call.loc(),
|
||||||
|
caused_by!(),
|
||||||
|
);
|
||||||
self.errs.push(err);
|
self.errs.push(err);
|
||||||
debug_exit_info!(self);
|
debug_exit_info!(self);
|
||||||
return Err(());
|
return Err(());
|
||||||
|
@ -3480,8 +3484,12 @@ impl Parser {
|
||||||
let ExprOrOp::Expr(first_arg) = stack.pop().unwrap() else {
|
let ExprOrOp::Expr(first_arg) = stack.pop().unwrap() else {
|
||||||
let caused_by = caused_by!();
|
let caused_by = caused_by!();
|
||||||
log!(err "error caused by: {caused_by}");
|
log!(err "error caused by: {caused_by}");
|
||||||
self.errs
|
self.errs.push(ParseError::compiler_bug(
|
||||||
.push(ParseError::compiler_bug(line!() as usize, call.loc(), fn_name!(), line!()));
|
line!() as usize,
|
||||||
|
call.loc(),
|
||||||
|
fn_name!(),
|
||||||
|
line!(),
|
||||||
|
));
|
||||||
debug_exit_info!(self);
|
debug_exit_info!(self);
|
||||||
return Err(());
|
return Err(());
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue