Skip to content

Commit

Permalink
fix: reduce unreachables
Browse files Browse the repository at this point in the history
  • Loading branch information
mtshiba committed Jul 15, 2023
1 parent 0152e36 commit 072d62f
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 21 deletions.
5 changes: 4 additions & 1 deletion crates/erg_compiler/context/eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand Down Expand Up @@ -459,7 +460,9 @@ impl Context {
fn eval_const_record(&self, record: &Record) -> EvalResult<ValueObj> {
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()),
),
}
}

Expand Down
3 changes: 2 additions & 1 deletion crates/erg_compiler/declare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -332,7 +333,7 @@ impl ASTLowerer {
fn fake_lower_record(&self, rec: ast::Record) -> LowerResult<hir::Record> {
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() {
Expand Down
5 changes: 4 additions & 1 deletion crates/erg_compiler/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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))
}
}
}

Expand Down
7 changes: 7 additions & 0 deletions crates/erg_parser/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down
56 changes: 38 additions & 18 deletions crates/erg_parser/desugar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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))
}
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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()
Expand Down

0 comments on commit 072d62f

Please sign in to comment.