From 072d62f7b30d8c7e7ac007dd20426e9bc6e4fe84 Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Sat, 15 Jul 2023 12:40:23 +0900 Subject: [PATCH] fix: reduce `unreachable`s --- crates/erg_compiler/context/eval.rs | 5 ++- crates/erg_compiler/declare.rs | 3 +- crates/erg_compiler/lower.rs | 5 ++- crates/erg_parser/ast.rs | 7 ++++ crates/erg_parser/desugar.rs | 56 +++++++++++++++++++---------- 5 files changed, 55 insertions(+), 21 deletions(-) diff --git a/crates/erg_compiler/context/eval.rs b/crates/erg_compiler/context/eval.rs index 070434707..35dad6eea 100644 --- a/crates/erg_compiler/context/eval.rs +++ b/crates/erg_compiler/context/eval.rs @@ -14,6 +14,7 @@ use OpKind::*; use erg_parser::ast::Dict as AstDict; use erg_parser::ast::Set as AstSet; use erg_parser::ast::*; +use erg_parser::desugar::Desugarer; use erg_parser::token::{Token, TokenKind}; use crate::ty::constructors::{ @@ -459,7 +460,9 @@ impl Context { fn eval_const_record(&self, record: &Record) -> EvalResult { match record { Record::Normal(rec) => self.eval_const_normal_record(rec), - Record::Mixed(_rec) => unreachable_error!(self), // should be desugared + Record::Mixed(mixed) => self.eval_const_normal_record( + &Desugarer::desugar_shortened_record_inner(mixed.clone()), + ), } } diff --git a/crates/erg_compiler/declare.rs b/crates/erg_compiler/declare.rs index dc09bde2d..7568fe603 100644 --- a/crates/erg_compiler/declare.rs +++ b/crates/erg_compiler/declare.rs @@ -5,6 +5,7 @@ use erg_common::traits::{Locational, Runnable, Stream}; use erg_common::{enum_unwrap, fn_name, log, set, Str, Triple}; use erg_parser::ast::{self, AscriptionKind, Identifier, VarName, AST}; +use erg_parser::desugar::Desugarer; use crate::context::instantiate::TyVarCache; use crate::lower::ASTLowerer; @@ -332,7 +333,7 @@ impl ASTLowerer { fn fake_lower_record(&self, rec: ast::Record) -> LowerResult { let rec = match rec { ast::Record::Normal(rec) => rec, - ast::Record::Mixed(_mixed) => unreachable!(), + ast::Record::Mixed(mixed) => Desugarer::desugar_shortened_record_inner(mixed), }; let mut elems = Vec::new(); for elem in rec.attrs.into_iter() { diff --git a/crates/erg_compiler/lower.rs b/crates/erg_compiler/lower.rs index 561566bab..6210695be 100644 --- a/crates/erg_compiler/lower.rs +++ b/crates/erg_compiler/lower.rs @@ -18,6 +18,7 @@ use erg_common::{fmt_option, fn_name, log, switch_lang, Str}; use erg_parser::ast::{self, AscriptionKind, VisModifierSpec}; use erg_parser::ast::{OperationKind, TypeSpecWithOp, VarName, AST}; use erg_parser::build_ast::ASTBuilder; +use erg_parser::desugar::Desugarer; use erg_parser::token::{Token, TokenKind}; use erg_parser::Parser; @@ -381,7 +382,9 @@ impl ASTLowerer { log!(info "entered {}({record})", fn_name!()); match record { ast::Record::Normal(rec) => self.lower_normal_record(rec), - ast::Record::Mixed(_rec) => unreachable!(), // should be desugared + ast::Record::Mixed(mixed) => { + self.lower_normal_record(Desugarer::desugar_shortened_record_inner(mixed)) + } } } diff --git a/crates/erg_parser/ast.rs b/crates/erg_parser/ast.rs index 210da6604..80e959b1c 100644 --- a/crates/erg_parser/ast.rs +++ b/crates/erg_parser/ast.rs @@ -4159,6 +4159,13 @@ impl Signature { } } + pub fn t_spec_op_mut(&mut self) -> Option<&mut TypeSpecWithOp> { + match self { + Self::Var(v) => v.t_spec.as_mut(), + Self::Subr(c) => c.return_t_spec.as_mut(), + } + } + pub fn is_const(&self) -> bool { match self { Self::Var(var) => var.is_const(), diff --git a/crates/erg_parser/desugar.rs b/crates/erg_parser/desugar.rs index 1e983d3e2..cc585318f 100644 --- a/crates/erg_parser/desugar.rs +++ b/crates/erg_parser/desugar.rs @@ -261,16 +261,11 @@ impl Desugarer { for chunk in def.body.block.into_iter() { chunks.push(desugar(chunk)); } + if let Some(t_op) = def.sig.t_spec_op_mut() { + *t_op.t_spec_as_expr = desugar(*t_op.t_spec_as_expr.clone()); + } if let Signature::Subr(mut subr) = def.sig { - let mut defaults = vec![]; - for default in subr.params.defaults.into_iter() { - let default_val = desugar(default.default_val); - defaults.push(DefaultParamSignature { - default_val, - ..default - }); - } - subr.params.defaults = defaults; + subr.params = Self::perform_desugar_params(desugar, subr.params); def.sig = Signature::Subr(subr); } let body = DefBody::new(def.body.op, Block::new(chunks), def.body.id); @@ -304,15 +299,10 @@ impl Desugarer { for chunk in lambda.body.into_iter() { chunks.push(desugar(chunk)); } - let mut defaults = vec![]; - for default in lambda.sig.params.defaults.into_iter() { - let default_val = desugar(default.default_val); - defaults.push(DefaultParamSignature { - default_val, - ..default - }); + if let Some(t_op) = &mut lambda.sig.return_t_spec { + *t_op.t_spec_as_expr = desugar(*t_op.t_spec_as_expr.clone()); } - lambda.sig.params.defaults = defaults; + lambda.sig.params = Self::perform_desugar_params(desugar, lambda.sig.params); let body = Block::new(chunks); Expr::Lambda(Lambda::new(lambda.sig, lambda.op, body, lambda.id)) } @@ -370,6 +360,36 @@ impl Desugarer { } } + fn perform_desugar_params(mut desugar: impl FnMut(Expr) -> Expr, mut params: Params) -> Params { + let mut non_defaults = vec![]; + for mut non_default in params.non_defaults.into_iter() { + non_default.t_spec = non_default.t_spec.map(|t_spec| { + TypeSpecWithOp::new(t_spec.op, t_spec.t_spec, desugar(*t_spec.t_spec_as_expr)) + }); + non_defaults.push(non_default); + } + params.var_params = params.var_params.map(|mut var_params| { + var_params.t_spec = var_params.t_spec.map(|t_spec| { + TypeSpecWithOp::new(t_spec.op, t_spec.t_spec, desugar(*t_spec.t_spec_as_expr)) + }); + var_params + }); + let mut defaults = vec![]; + for mut default in params.defaults.into_iter() { + let default_val = desugar(default.default_val); + default.sig.t_spec = default.sig.t_spec.map(|t_spec| { + TypeSpecWithOp::new(t_spec.op, t_spec.t_spec, desugar(*t_spec.t_spec_as_expr)) + }); + defaults.push(DefaultParamSignature { + default_val, + ..default + }); + } + params.non_defaults = non_defaults; + params.defaults = defaults; + params + } + /// `fib 0 = 0; fib 1 = 1; fib n = fib(n-1) + fib(n-2)` /// -> `fib n = match n, (0 -> 0), (1 -> 1), n -> fib(n-1) + fib(n-2)` fn desugar_multiple_pattern_def(&self, module: Module) -> Module { @@ -856,7 +876,7 @@ impl Desugarer { } } - pub(crate) fn desugar_shortened_record_inner(record: MixedRecord) -> NormalRecord { + pub fn desugar_shortened_record_inner(record: MixedRecord) -> NormalRecord { let attrs = record .attrs .into_iter()