Follow clippy warnings

This commit is contained in:
Yuna Tomida 2022-09-10 17:32:25 +09:00
parent 9783813ae0
commit d956c3f61d
No known key found for this signature in database
GPG key ID: E6EC40A47CA07A6F
34 changed files with 448 additions and 450 deletions

View file

@ -146,33 +146,20 @@ impl Default for ErgConfig {
} else {
Input::REPL
};
Self::new("exec", 1, false, None, 10, input, "<module>", 2)
Self {
mode: "exec",
opt_level: 1,
dump_as_pyc: false,
python_ver: None,
py_server_timeout: 10,
input,
module: "<module>",
verbose: 2,
}
}
}
impl ErgConfig {
pub const fn new(
mode: &'static str,
opt_level: u8,
dump_as_pyc: bool,
python_ver: Option<u32>,
py_server_timeout: u64,
input: Input,
module: &'static str,
verbose: u8,
) -> Self {
Self {
mode,
opt_level,
dump_as_pyc,
python_ver,
py_server_timeout,
input,
module,
verbose,
}
}
/// cloneのエイリアス(実際のcloneコストは低いので)
#[inline]
pub fn copy(&self) -> Self {

View file

@ -1,5 +1,5 @@
use std::borrow::Borrow;
use std::collections::hash_map::{IntoIter, IntoValues, Iter, IterMut, Keys, Values, ValuesMut};
use std::collections::hash_map::{IntoValues, Iter, IterMut, Keys, Values, ValuesMut};
use std::fmt::{self, Write};
use std::hash::{Hash, Hasher};
use std::iter::FromIterator;
@ -119,11 +119,6 @@ impl<K, V> Dict<K, V> {
self.dict.iter()
}
#[inline]
pub fn into_iter(self) -> IntoIter<K, V> {
self.dict.into_iter()
}
#[inline]
pub fn iter_mut(&mut self) -> IterMut<K, V> {
self.dict.iter_mut()
@ -134,6 +129,15 @@ impl<K, V> Dict<K, V> {
}
}
impl<K, V> IntoIterator for Dict<K, V> {
type Item = (K, V);
type IntoIter = <FxHashMap<K, V> as IntoIterator>::IntoIter;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.dict.into_iter()
}
}
impl<K: Hash + Eq, V> Dict<K, V> {
#[inline]
pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V>

View file

@ -3,7 +3,8 @@
//! エラー処理に関する汎用的なコンポーネントを提供する
use std::cmp;
use std::fmt;
use std::io::{stderr, BufWriter, Write};
use std::fmt::Write as _;
use std::io::{stderr, BufWriter, Write as _};
use crate::color::*;
use crate::config::Input;
@ -362,7 +363,7 @@ pub trait ErrorDisplay {
/// As for the internal error, do not put the fn name here.
fn caused_by(&self) -> &str;
/// the previous error that caused this error.
fn ref_inner(&self) -> Option<&Box<Self>>;
fn ref_inner(&self) -> Option<&Self>;
fn write_to_stderr(&self) {
let mut writer = BufWriter::new(stderr());
@ -469,10 +470,12 @@ pub trait ErrorDisplay {
} else {
pointer += &"^".repeat(cmp::max(1, codes[i].len()));
}
res += &format!(
"{lineno}{VBAR_UNICODE} {code}\n{pointer}\n",
writeln!(
res,
"{lineno}{VBAR_UNICODE} {code}\n{pointer}",
code = codes[i]
);
)
.unwrap();
}
res + RESET
}

View file

@ -7,13 +7,20 @@ pub fn levenshtein(lhs: &str, rhs: &str) -> usize {
let r_len = rhs.len();
// l_len+1 × r_len+1 array
let mut table = vec![vec![0; r_len + 1]; l_len + 1];
for i in 0..l_len + 1 {
table[i][0] = i;
}
for i in 0..r_len + 1 {
table[0][i] = i;
}
let _ = table
.iter_mut()
.take(l_len + 1)
.enumerate()
.map(|(i, row)| row[0] = i)
.collect::<()>();
let _ = table[0]
.iter_mut()
.take(r_len + 1)
.enumerate()
.map(|(i, elem)| *elem = i)
.collect::<()>();
for i1 in 0..l_len {
#[allow(clippy::needless_range_loop)]
for i2 in 0..r_len {
let cost = if lhs[i1] == rhs[i2] { 0 } else { 1 };
table[i1 + 1][i2 + 1] = *[

View file

@ -1,5 +1,5 @@
use std::borrow::Borrow;
use std::collections::hash_set::{IntoIter, Iter};
use std::collections::hash_set::Iter;
use std::fmt;
use std::hash::{Hash, Hasher};
use std::iter::FromIterator;
@ -105,9 +105,13 @@ impl<T: Hash> Set<T> {
pub fn iter(&self) -> Iter<'_, T> {
self.elems.iter()
}
}
impl<T: Hash> IntoIterator for Set<T> {
type Item = T;
type IntoIter = <FxHashSet<T> as IntoIterator>::IntoIter;
#[inline]
pub fn into_iter(self) -> IntoIter<T> {
fn into_iter(self) -> Self::IntoIter {
self.elems.into_iter()
}
}

View file

@ -111,6 +111,12 @@ impl Borrow<str> for Str {
}
}
impl AsRef<str> for Str {
fn as_ref(&self) -> &str {
self.borrow()
}
}
impl Str {
pub const fn ever(s: &'static str) -> Self {
Str::Static(s)
@ -120,10 +126,6 @@ impl Str {
Str::Rc(s.into())
}
pub fn as_ref(&self) -> &str {
self.borrow()
}
pub fn into_rc(self) -> RcStr {
match self {
Str::Rc(s) => s,

View file

@ -63,6 +63,7 @@ fn dfs<T: Eq + Hash + Clone, U>(
}
/// perform topological sort on a graph
#[allow(clippy::result_unit_err)]
pub fn tsort<T: Eq + Hash + Clone, U>(g: Graph<T, U>) -> Result<Graph<T, U>, ()> {
let n = g.len();
let mut idx = Vec::with_capacity(n);

View file

@ -32,7 +32,8 @@ use crate::hir::{
use AccessKind::*;
fn is_python_global(name: &str) -> bool {
match name {
matches!(
name,
"ArithmeticError"
| "AssertionError"
| "AttributeError"
@ -186,9 +187,8 @@ fn is_python_global(name: &str) -> bool {
| "tuple"
| "type"
| "vars"
| "zip" => true,
_ => false,
}
| "zip"
)
}
fn convert_to_python_attr(class: &str, uniq_obj_name: Option<&str>, name: Str) -> Str {
@ -732,7 +732,7 @@ impl CodeGenerator {
self.write_arg(cellvars_len);
opcode_flag += 8;
}
self.emit_load_const(name.clone());
self.emit_load_const(name);
self.write_instr(MAKE_FUNCTION);
self.write_arg(opcode_flag);
// stack_dec: <code obj> + <name> -> <function>
@ -1225,6 +1225,7 @@ impl CodeGenerator {
self.write_instr(CALL_FUNCTION);
self.write_arg(2);
// (1 (subroutine) + argc + kwsc) input objects -> 1 return object
#[allow(clippy::identity_op)]
self.stack_dec_n((1 + 2 + 0) - 1);
let ident = Identifier::private(Str::ever("#rec"));
self.emit_store_instr(ident, Name);
@ -1237,6 +1238,7 @@ impl CodeGenerator {
self.write_instr(CALL_FUNCTION);
self.write_arg(attrs_len as u8);
// (1 (subroutine) + argc + kwsc) input objects -> 1 return object
#[allow(clippy::identity_op)]
self.stack_dec_n((1 + attrs_len + 0) - 1);
}
other => {

View file

@ -33,7 +33,7 @@ impl TypeCmpCache {
where
SubtypePair: Borrow<Q>,
{
self.cache.get(pair).map(|b| *b)
self.cache.get(pair).copied()
}
pub fn register(&mut self, pair: SubtypePair, b: bool) {

View file

@ -171,15 +171,15 @@ impl Context {
&& subr
.non_default_params
.iter()
.all(|pt| self.supertype_of(&Type, &pt.typ()))
.all(|pt| self.supertype_of(&Type, pt.typ()))
&& subr
.default_params
.iter()
.all(|pt| self.supertype_of(&Type, &pt.typ()))
.all(|pt| self.supertype_of(&Type, pt.typ()))
&& subr
.var_params
.as_ref()
.map(|va| self.supertype_of(&Type, &va.typ()))
.map(|va| self.supertype_of(&Type, va.typ()))
.unwrap_or(true)
&& self.supertype_of(&Type, &subr.return_t),
),
@ -251,20 +251,14 @@ impl Context {
if let Some(res) = self.inquire_cache(rhs, lhs) {
return res;
}
match self.classes_supertype_of(lhs, rhs) {
(Absolutely, judge) => {
if let (Absolutely, judge) = self.classes_supertype_of(lhs, rhs) {
self.register_cache(rhs, lhs, judge);
return judge;
}
_ => {}
}
match self.trait_supertype_of(lhs, rhs) {
(Absolutely, judge) => {
if let (Absolutely, judge) = self.trait_supertype_of(lhs, rhs) {
self.register_cache(rhs, lhs, judge);
return judge;
}
_ => {}
}
for patch in self.patches.values() {
if let ContextKind::GluePatch(tr_inst) = &patch.kind {
if tr_inst.sub_type.has_qvar() || tr_inst.sup_trait.has_qvar() {
@ -277,13 +271,13 @@ impl Context {
if self.supertype_of(&tr_inst.sub_type, rhs)
&& self.subtype_of(&tr_inst.sup_trait, lhs)
{
self.register_cache(&rhs, &lhs, true);
self.register_cache(rhs, lhs, true);
return true;
}
}
}
}
self.register_cache(&rhs, &lhs, false);
self.register_cache(rhs, lhs, false);
false
}
@ -620,6 +614,7 @@ impl Context {
// if `rhs` is {S: Str | ... }, `defined_rhs` will be Str
let (defined_rhs, _) = self.rec_get_nominal_type_ctx(rhs).unwrap();
let super_traits = self.rec_get_nominal_super_trait_ctxs(rhs);
#[allow(clippy::useless_conversion)]
for (sup_trait, _) in super_traits.into_iter() {
if self.sup_conforms(lhs, defined_rhs, sup_trait) {
return true;
@ -636,8 +631,8 @@ impl Context {
pub(crate) fn poly_supertype_of(
&self,
typ: &Type,
lparams: &Vec<TyParam>,
rparams: &Vec<TyParam>,
lparams: &[TyParam],
rparams: &[TyParam],
) -> bool {
let (_, ctx) = self
.rec_get_nominal_type_ctx(typ)
@ -754,6 +749,7 @@ impl Context {
}
}
#[allow(clippy::wrong_self_convention)]
pub(crate) fn into_refinement(&self, t: Type) -> RefinementType {
match t {
Nat => {

View file

@ -70,8 +70,7 @@ impl Context {
fn register_type(&mut self, t: Type, ctx: Self, muty: Mutability) {
if t.typarams_len().is_none() {
self.register_mono_type(t, ctx, muty);
} else {
if t.is_class() {
} else if t.is_class() {
self.register_poly_class(t, ctx, muty);
} else if t.is_trait() {
self.register_poly_trait(t, ctx, muty);
@ -79,7 +78,6 @@ impl Context {
todo!()
}
}
}
fn register_mono_type(&mut self, t: Type, ctx: Self, muty: Mutability) {
if self.mono_types.contains_key(&t.name()) {
@ -218,7 +216,7 @@ impl Context {
static_instance("R", Type)
},
);
eq.register_decl("__eq__", op_t.clone(), Public);
eq.register_decl("__eq__", op_t, Public);
let mut partial_ord = Self::poly_trait(
"PartialOrd",
vec![PS::t("R", WithDefault)],
@ -233,7 +231,7 @@ impl Context {
static_instance("R", Type)
},
);
partial_ord.register_decl("__lt__", op_t.clone(), Public);
partial_ord.register_decl("__lt__", op_t, Public);
let ord = Self::mono_trait(
"Ord",
vec![poly_trait("Eq", vec![]), poly_trait("PartialOrd", vec![])],
@ -270,7 +268,7 @@ impl Context {
seq.register_decl("get", t, Public);
let params = vec![PS::t("T", NonDefault)];
let input = Self::poly_trait("Input", params.clone(), vec![], Self::TOP_LEVEL);
let output = Self::poly_trait("Output", params.clone(), vec![], Self::TOP_LEVEL);
let output = Self::poly_trait("Output", params, vec![], Self::TOP_LEVEL);
let r = mono_q("R");
let r_bound = static_instance("R", Type);
let params = vec![PS::t("R", WithDefault)];
@ -310,13 +308,13 @@ impl Context {
mul.register_decl("MulO", Type, Public);
let mut div = Self::poly_trait(
"Div",
params.clone(),
params,
vec![poly_trait("Output", vec![ty_tp(mono_q("R"))])],
Self::TOP_LEVEL,
);
let op_t = fn1_met(mono_q("Self"), r, mono_proj(mono_q("Self"), "DivO"));
let self_bound = subtypeof(mono_q("Self"), poly_trait("Div", ty_params.clone()));
let op_t = quant(op_t, set! {r_bound.clone(), self_bound});
let op_t = quant(op_t, set! {r_bound, self_bound});
div.register_decl("__div__", op_t, Public);
div.register_decl("DivO", Type, Public);
self.register_type(trait_("Named"), named, Const);
@ -609,7 +607,7 @@ impl Context {
let m = mono_q_tp("M");
let array_t = array(mono_q("T"), n.clone());
let t = fn_met(
array_t.clone(),
array_t,
vec![param_t("rhs", array(mono_q("T"), m.clone()))],
None,
vec![],
@ -622,8 +620,8 @@ impl Context {
array_.register_impl("concat", t, Immutable, Public);
let n = mono_q_tp("N");
let array_inner = mono_q("T");
let array_t = array(array_inner.clone(), n.clone());
let proj_t = mono_proj(array_inner.clone(), "ImmutType");
let array_t = array(array_inner.clone(), n);
let proj_t = mono_proj(array_inner, "ImmutType");
let t = fn_met(
array_t.clone(),
vec![param_t(
@ -1189,12 +1187,12 @@ impl Context {
},
);
self.register_impl("__mul__", op_t, Const, Private);
let op_t = bin_op(l.clone(), r.clone(), mono_proj(mono_q("L"), "DivO"));
let op_t = bin_op(l.clone(), r, mono_proj(mono_q("L"), "DivO"));
let op_t = quant(
op_t,
set! {
static_instance("R", Type),
subtypeof(l, poly_trait("Mul", params.clone()))
subtypeof(l, poly_trait("Mul", params))
},
);
self.register_impl("__div__", op_t, Const, Private);
@ -1223,7 +1221,7 @@ impl Context {
self.register_impl("__or__", bin_op(Bool, Bool, Bool), Const, Private);
let t = mono_q("T");
let op_t = bin_op(t.clone(), t.clone(), range(t.clone()));
let op_t = quant(op_t, set! {subtypeof(t.clone(), trait_("Ord"))});
let op_t = quant(op_t, set! {subtypeof(t, trait_("Ord"))});
self.register_decl("__rng__", op_t.clone(), Private);
self.register_decl("__lorng__", op_t.clone(), Private);
self.register_decl("__rorng__", op_t.clone(), Private);

View file

@ -171,7 +171,7 @@ impl Context {
.collect::<Vec<_>>();
let mut return_t = branch_ts[0].typ().return_t().unwrap().clone();
for arg_t in branch_ts.iter().skip(1) {
return_t = self.rec_union(&return_t, &arg_t.typ().return_t().unwrap());
return_t = self.rec_union(&return_t, arg_t.typ().return_t().unwrap());
}
let param_ty = ParamTy::anonymous(match_target_expr_t.clone());
let param_ts = [vec![param_ty], branch_ts.to_vec()].concat();
@ -520,8 +520,7 @@ impl Context {
Type::Subr(subr) => {
let callee = if let Some(name) = method_name {
let attr = hir::Attribute::new(obj.clone(), name.clone(), Type::Ellipsis);
let acc = hir::Expr::Accessor(hir::Accessor::Attr(attr));
acc
hir::Expr::Accessor(hir::Accessor::Attr(attr))
} else {
obj.clone()
};
@ -668,7 +667,7 @@ impl Context {
&self,
callee: &hir::Expr,
arg: &hir::KwArg,
default_params: &Vec<ParamTy>,
default_params: &[ParamTy],
passed_params: &mut Set<Str>,
) -> TyCheckResult<()> {
let arg_t = arg.expr.ref_t();
@ -744,7 +743,7 @@ impl Context {
);
self.substitute_call(obj, method_name, &instance, pos_args, kw_args)?;
log!(info "Substituted:\ninstance: {instance}");
let res = self.eval.eval_t_params(instance, &self, self.level)?;
let res = self.eval.eval_t_params(instance, self, self.level)?;
log!(info "Params evaluated:\nres: {res}\n");
self.propagate(&res, obj)?;
log!(info "Propagated:\nres: {res}\n");
@ -981,7 +980,7 @@ impl Context {
ctx.super_classes
.iter()
.chain(ctx.super_traits.iter())
.map(|sup| self.rec_get_nominal_type_ctx(&sup).unwrap()),
.map(|sup| self.rec_get_nominal_type_ctx(sup).unwrap()),
)
} else {
todo!("{t} not found")

View file

@ -103,7 +103,7 @@ impl TyVarContext {
params: Vec<TyParam>,
ctx: &Context,
) -> Type {
if let Some(temp_defaults) = ctx.rec_get_const_param_defaults(&name) {
if let Some(temp_defaults) = ctx.rec_get_const_param_defaults(name) {
let (_, ctx) = ctx
.rec_get_nominal_type_ctx(&poly_trait(name.clone(), params.clone()))
.unwrap_or_else(|| panic!("{} not found", name));
@ -123,7 +123,7 @@ impl TyVarContext {
.collect();
let mut inst_defaults = vec![];
for template in temp_defaults
.into_iter()
.iter()
.take(defined_params_len - given_params_len)
{
let tp = self.instantiate_const_template(&tvar_name, name, template);
@ -197,8 +197,7 @@ impl TyVarContext {
&named_free_var(name.clone(), self.level, constraint),
);
}
} else {
if let Some(tp) = self.typaram_instances.get(&name) {
} else if let Some(tp) = self.typaram_instances.get(&name) {
tp.update_constraint(constraint);
} else {
self.push_or_init_typaram(
@ -209,7 +208,6 @@ impl TyVarContext {
}
}
}
}
fn _instantiate_pred(&self, _pred: Predicate) -> Predicate {
todo!()
@ -471,7 +469,7 @@ impl Context {
};
if let Some(decl_pt) = opt_decl_t {
self.sub_unify(
&decl_pt.typ(),
decl_pt.typ(),
&spec_t,
None,
sig.t_spec.as_ref().map(|s| s.loc()),
@ -530,7 +528,7 @@ impl Context {
pub(crate) fn instantiate_const_expr(&self, expr: &ast::ConstExpr) -> TyParam {
match expr {
ast::ConstExpr::Lit(lit) => TyParam::Value(eval_lit(&lit)),
ast::ConstExpr::Lit(lit) => TyParam::Value(eval_lit(lit)),
ast::ConstExpr::Accessor(ast::ConstAccessor::Local(name)) => {
TyParam::Mono(name.inspect().clone())
}
@ -836,16 +834,14 @@ impl Context {
pub(crate) fn instantiate(&self, quantified: Type, callee: &hir::Expr) -> TyCheckResult<Type> {
match quantified {
Quantified(quant) => {
let mut tv_ctx = TyVarContext::new(self.level, quant.bounds, &self);
let mut tv_ctx = TyVarContext::new(self.level, quant.bounds, self);
let t = Self::instantiate_t(*quant.unbound_callable, &mut tv_ctx);
match &t {
Type::Subr(subr) => match subr.kind.self_t() {
Some(l) => {
if let Type::Subr(subr) = &t {
if let Some(l) = subr.kind.self_t() {
self.unify(l, callee.ref_t(), None, Some(callee.loc()))?;
}
_ => {}
},
_ => unreachable!(),
} else {
unreachable!()
}
Ok(t)
}

View file

@ -1,5 +1,7 @@
//! Defines `Context`.
//!
//! `Context` is used for type inference and type checking.
#![allow(clippy::result_unit_err)]
pub mod cache;
pub mod compare;
pub mod hint;
@ -91,7 +93,7 @@ impl TyParamIdx {
TyParam::Type(t) if t.as_ref() == target => return Some(Self::Nth(i)),
TyParam::Type(t) if t.is_monomorphic() => {}
TyParam::Type(inner) => {
if let Some(inner) = Self::search(&inner, target) {
if let Some(inner) = Self::search(inner, target) {
return Some(Self::nested(i, inner));
}
}
@ -111,7 +113,7 @@ impl TyParamIdx {
match self {
Self::Nth(n) => {
let tps = from.typarams();
let tp = tps.iter().nth(n).unwrap();
let tp = tps.get(n).unwrap();
match tp {
TyParam::Type(t) => *t.clone(),
_ => todo!(),
@ -328,6 +330,7 @@ impl Context {
)
}
#[allow(clippy::too_many_arguments)]
pub fn with_capacity(
name: Str,
kind: ContextKind,

View file

@ -274,14 +274,14 @@ impl Context {
let sub_t = if sig.ident.is_procedural() {
proc(
non_default_params.clone(),
var_args.as_ref().map(|v| *(*v).clone()),
var_args.cloned(),
default_params.clone(),
body_t.clone(),
)
} else {
func(
non_default_params.clone(),
var_args.as_ref().map(|v| *(*v).clone()),
var_args.cloned(),
default_params.clone(),
body_t.clone(),
)

View file

@ -63,9 +63,9 @@ impl Context {
pub fn test_instantiation_and_generalization(&self) -> Result<(), ()> {
let t = mono_q("T");
let eq = poly_trait("Eq", vec![TyParam::t(t.clone())]);
let bound = TyBound::subtype_of(t.clone(), eq.clone());
let bound = TyBound::subtype_of(t.clone(), eq);
let bounds = set! {bound};
let unbound_t = func1(t.clone(), t.clone());
let unbound_t = func1(t.clone(), t);
let quantified = quant(unbound_t.clone(), bounds.clone());
println!("quantified : {quantified}");
let mut tv_ctx = TyVarContext::new(self.level + 1, bounds, self);

View file

@ -28,7 +28,7 @@ impl Context {
pub const GENERIC_LEVEL: usize = usize::MAX;
/// 型を非依存化する
fn _independentise<'a>(_t: Type, _ts: &[Type]) -> Type {
fn _independentise(_t: Type, _ts: &[Type]) -> Type {
todo!()
}
@ -194,7 +194,7 @@ impl Context {
let sub = self.generalize_t_inner(sub.clone(), bounds, lazy_inits);
let sup = self.generalize_t_inner(sup.clone(), bounds, lazy_inits);
// let bs = sub_bs.concat(sup_bs);
bounds.insert(TyBound::sandwiched(sub, mono_q(name.clone()), sup));
bounds.insert(TyBound::sandwiched(sub, mono_q(name), sup));
}
Constraint::TypeOf(t) => {
let t = self.generalize_t_inner(t.clone(), bounds, lazy_inits);
@ -378,7 +378,7 @@ impl Context {
pub(crate) fn deref_toplevel(&mut self, mut hir: hir::HIR) -> TyCheckResult<hir::HIR> {
self.level = 0;
for chunk in hir.module.iter_mut() {
self.deref_expr_t(chunk).map_err(|e| e)?;
self.deref_expr_t(chunk)?;
}
Ok(hir)
}
@ -805,7 +805,7 @@ impl Context {
{
self.unify(l.typ(), r.typ(), lhs_loc, rhs_loc)?;
}
for (l, r) in ls.var_params.as_ref().zip(rs.var_params.as_ref()) {
if let Some((l, r)) = ls.var_params.as_ref().zip(rs.var_params.as_ref()) {
self.unify(l.typ(), r.typ(), lhs_loc, rhs_loc)?;
}
for lpt in ls.default_params.iter() {
@ -1051,7 +1051,7 @@ impl Context {
rfv.update_constraint(new_constraint);
lfv.link(maybe_sup);
}
return Ok(())
Ok(())
}
(_, Type::FreeVar(rfv)) if rfv.is_unbound() => {
// NOTE: cannot `borrow_mut` because of cycle reference
@ -1107,7 +1107,7 @@ impl Context {
},
_ => {}
}
return Ok(());
Ok(())
}
(Type::FreeVar(lfv), _) if lfv.is_unbound() => {
let lfv_ref = &mut *lfv.borrow_mut();
@ -1156,7 +1156,7 @@ impl Context {
},
_ => {}
}
return Ok(());
Ok(())
}
(Type::FreeVar(_fv), _r) => todo!(),
(Type::Subr(lsub), Type::Subr(rsub)) => {
@ -1169,7 +1169,7 @@ impl Context {
|(l, r)| self.unify(l.typ(), r.typ(), sub_loc, sup_loc),
)?;
self.unify(&lsub.return_t, &rsub.return_t, sub_loc, sup_loc)?;
return Ok(());
Ok(())
}
(Type::MonoProj { .. }, _) => todo!(),
(_, Type::MonoProj { .. }) => todo!(),

View file

@ -118,7 +118,7 @@ impl ErrorDisplay for CompileError {
fn caused_by(&self) -> &str {
&self.caused_by
}
fn ref_inner(&self) -> Option<&Box<Self>> {
fn ref_inner(&self) -> Option<&Self> {
None
}
}
@ -245,7 +245,7 @@ impl ErrorDisplay for TyCheckError {
fn caused_by(&self) -> &str {
&self.caused_by
}
fn ref_inner(&self) -> Option<&Box<Self>> {
fn ref_inner(&self) -> Option<&Self> {
None
}
}

View file

@ -176,13 +176,7 @@ impl Evaluator {
fn eval_const_acc(&self, _acc: &Accessor, ctx: &Context) -> Option<ValueObj> {
match _acc {
Accessor::Local(local) => {
if let Some(val) = ctx.rec_get_const_obj(local.inspect()) {
Some(val.clone())
} else {
None
}
}
Accessor::Local(local) => ctx.rec_get_const_obj(local.inspect()).cloned(),
Accessor::Attr(attr) => {
let _obj = self.eval_const_expr(&attr.obj, ctx)?;
todo!()
@ -220,7 +214,7 @@ impl Evaluator {
if let Expr::Accessor(acc) = call.obj.as_ref() {
match acc {
Accessor::Local(name) if name.is_const() => {
if let Some(ValueObj::Subr(subr)) = ctx.rec_get_const_obj(&name.inspect()) {
if let Some(ValueObj::Subr(subr)) = ctx.rec_get_const_obj(name.inspect()) {
let args = self.eval_args(&call.args)?;
Some(subr.call(args))
} else {
@ -382,9 +376,7 @@ impl Evaluator {
fn eval_unary_tp(&self, op: OpKind, val: &TyParam) -> EvalResult<TyParam> {
match val {
TyParam::Value(c) => self
.eval_unary_lit(op, c.clone())
.map(|v| TyParam::Value(v)),
TyParam::Value(c) => self.eval_unary_lit(op, c.clone()).map(TyParam::Value),
TyParam::FreeVar(fv) if fv.is_linked() => self.eval_unary_tp(op, &*fv.crack()),
e @ TyParam::Erased(_) => Ok(e.clone()),
other => todo!("{op} {other}"),

View file

@ -703,12 +703,12 @@ impl RecordAttrs {
self.0.len()
}
pub fn iter(&self) -> impl Iterator<Item = &Def> {
self.0.iter()
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn into_iter(self) -> impl Iterator<Item = Def> {
self.0.into_iter()
pub fn iter(&self) -> impl Iterator<Item = &Def> {
self.0.iter()
}
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut Def> {
@ -720,6 +720,14 @@ impl RecordAttrs {
}
}
impl IntoIterator for RecordAttrs {
type Item = Def;
type IntoIter = <Vec<Self::Item> as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
#[derive(Clone, Debug)]
pub struct Record {
l_brace: Token,
@ -772,7 +780,7 @@ pub struct BinOp {
impl NestedDisplay for BinOp {
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, level: usize) -> fmt::Result {
write!(f, "`{}`(: {}):\n", self.op.content, self.sig_t)?;
writeln!(f, "`{}`(: {}):", self.op.content, self.sig_t)?;
self.lhs.fmt_nest(f, level + 1)?;
writeln!(f)?;
self.rhs.fmt_nest(f, level + 1)

View file

@ -1,4 +1,5 @@
//! defines the compiler for Erg (ergc).
#![allow(clippy::large_enum_variant)]
extern crate erg_common;
pub extern crate erg_parser;

View file

@ -500,7 +500,7 @@ impl ASTLowerer {
let found_body_t = block.ref_t();
let expect_body_t = t.return_t().unwrap();
if let Err(e) =
self.return_t_check(sig.loc(), sig.ident.inspect(), &expect_body_t, found_body_t)
self.return_t_check(sig.loc(), sig.ident.inspect(), expect_body_t, found_body_t)
{
self.errs.push(e);
}

View file

@ -1,6 +1,7 @@
//! defines `Expr` (Expression, the minimum executing unit of Erg).
use std::borrow::Borrow;
use std::fmt;
use std::fmt::Write as _;
use erg_common::error::Location;
use erg_common::set::Set as HashSet;
@ -134,7 +135,7 @@ pub struct Args {
impl NestedDisplay for Args {
fn fmt_nest(&self, f: &mut std::fmt::Formatter<'_>, level: usize) -> std::fmt::Result {
fmt_lines(self.pos_args.iter(), f, level)?;
writeln!(f, "")?;
writeln!(f)?;
fmt_lines(self.kw_args.iter(), f, level)
}
}
@ -504,7 +505,7 @@ impl NestedDisplay for ArrayComprehension {
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result {
let mut generators = String::new();
for (name, gen) in self.generators.iter() {
generators.push_str(&format!("{} <- {}, ", name, gen));
write!(generators, "{} <- {}, ", name, gen).unwrap();
}
write!(
f,
@ -678,8 +679,12 @@ impl RecordAttrs {
pub fn iter(&self) -> impl Iterator<Item = &Def> {
self.0.iter()
}
}
pub fn into_iter(self) -> impl IntoIterator<Item = Def> {
impl IntoIterator for RecordAttrs {
type Item = Def;
type IntoIter = <Vec<Def> as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
@ -1220,7 +1225,7 @@ pub struct ConstArgs {
impl NestedDisplay for ConstArgs {
fn fmt_nest(&self, f: &mut std::fmt::Formatter<'_>, level: usize) -> std::fmt::Result {
fmt_lines(self.pos_args(), f, level)?;
writeln!(f, "")?;
writeln!(f)?;
fmt_lines(self.kw_args(), f, level)
}
}
@ -1713,6 +1718,7 @@ impl VarName {
Self(Token::static_symbol(symbol))
}
#[allow(clippy::should_implement_trait)]
pub fn from_str(symbol: Str) -> Self {
Self(Token::from_str(TokenKind::Symbol, &symbol))
}
@ -1817,7 +1823,7 @@ impl Identifier {
}
pub const fn inspect(&self) -> &Str {
&self.name.inspect()
self.name.inspect()
}
pub fn is_procedural(&self) -> bool {
@ -2298,6 +2304,12 @@ impl Locational for Params {
}
}
type RawParams = (
Vec<ParamSignature>,
Option<Box<ParamSignature>>,
Vec<ParamSignature>,
Option<(Token, Token)>,
);
impl Params {
pub fn new(
non_defaults: Vec<ParamSignature>,
@ -2313,14 +2325,7 @@ impl Params {
}
}
pub fn deconstruct(
self,
) -> (
Vec<ParamSignature>,
Option<Box<ParamSignature>>,
Vec<ParamSignature>,
Option<(Token, Token)>,
) {
pub fn deconstruct(self) -> RawParams {
(self.non_defaults, self.var_args, self.defaults, self.parens)
}

View file

@ -124,7 +124,7 @@ impl ErrorDisplay for ParserRunnerError {
fn caused_by(&self) -> &str {
""
}
fn ref_inner(&self) -> Option<&Box<Self>> {
fn ref_inner(&self) -> Option<&Self> {
None
}
}

View file

@ -91,6 +91,7 @@ impl Lexer /*<'a>*/ {
}
}
#[allow(clippy::should_implement_trait)]
pub fn from_str(src: Str) -> Self {
let escaped = normalize_newline(&src);
Lexer {
@ -769,7 +770,7 @@ impl Iterator for Lexer /*<'a>*/ {
}
None => {
let token = self.emit_token(Illegal, "-");
return Some(Err(LexError::simple_syntax_error(0, token.loc())));
Some(Err(LexError::simple_syntax_error(0, token.loc())))
}
}
}

View file

@ -1,5 +1,6 @@
//! Implements `Parser` for Erg. `Parser` parses the source code to generate `AST`,
//! and performs type checking and other optimizations if necessary.
#![allow(clippy::large_enum_variant)]
extern crate erg_common;
pub mod ast;

View file

@ -163,7 +163,7 @@ impl Parser {
self.tokens.insert(0, token);
}
fn stack_dec(&mut self) -> () {
fn stack_dec(&mut self) {
self.level -= 1;
}
}
@ -221,8 +221,10 @@ impl ParserRunner {
/// Parses with default configuration
pub fn parse_with_default_config(input: Input) -> Result<AST, ParserRunnerErrors> {
let mut cfg = ErgConfig::default();
cfg.input = input;
let cfg = ErgConfig {
input,
..Default::default()
};
let mut self_ = Self::new(cfg);
self_.parse()
}
@ -278,12 +280,11 @@ impl Parser {
Some(t) if t.is(Indent) || t.is(Dedent) => {
switch_unreachable!()
}
Some(_) => match self.try_reduce_chunk(true) {
Ok(expr) => {
Some(_) => {
if let Ok(expr) = self.try_reduce_chunk(true) {
chunks.push(expr);
}
Err(_) => {}
},
}
_ => switch_unreachable!(),
}
}
@ -318,16 +319,13 @@ impl Parser {
} else if t.is(EOF) {
break;
}
match self.try_reduce_chunk(true) {
Ok(expr) => {
if let Ok(expr) = self.try_reduce_chunk(true) {
block.push(expr);
if self.cur_is(Dedent) {
self.skip();
break;
}
}
Err(_) => {}
}
}
_ => switch_unreachable!(),
}
@ -1281,12 +1279,9 @@ impl Parser {
}
let mut expr = self.try_reduce_expr(true).map_err(|_| self.stack_dec())?;
let rparen = self.lpop();
match &mut expr {
Expr::Tuple(Tuple::Normal(tup)) => {
if let Expr::Tuple(Tuple::Normal(tup)) = &mut expr {
tup.elems.paren = Some((lparen, rparen));
}
_ => {}
}
self.level -= 1;
Ok(expr)
}
@ -1328,7 +1323,7 @@ impl Parser {
self.level -= 1;
let err = self.skip_and_throw_syntax_err(caused_by!());
self.errs.push(err);
return Err(());
Err(())
}
}
}

View file

@ -43,7 +43,16 @@ fn parse_test2_advanced_syntax() -> Result<(), ParserRunnerErrors> {
fn parse_test_from_code(file_path: &'static str) -> Result<(), ParserRunnerErrors> {
let input = Input::File(file_path.into());
let cfg = ErgConfig::new("exec", 1, false, None, 100, input.clone(), "<module>", 2);
let cfg = ErgConfig {
mode: "exec",
opt_level: 1,
dump_as_pyc: false,
python_ver: None,
py_server_timeout: 100,
input: input.clone(),
module: "<module>",
verbose: 2,
};
let lexer = Lexer::new(input.clone());
let mut parser = ParserRunner::new(cfg);
match parser.parse_token_stream(

View file

@ -1,6 +1,7 @@
use std::fmt;
use std::fmt::Write as _;
use std::fs::File;
use std::io::{BufReader, Read, Write};
use std::io::{BufReader, Read, Write as _};
use std::path::Path;
use erg_common::impl_display_from_debug;
@ -171,44 +172,6 @@ impl Default for CodeObj {
}
impl CodeObj {
pub fn new<S: Into<Str>>(
argcount: u32,
posonlyargcount: u32,
kwonlyargcount: u32,
nlocals: u32,
stacksize: u32,
flags: u32,
code: Vec<u8>,
consts: Vec<ValueObj>,
names: Vec<Str>,
varnames: Vec<Str>,
freevars: Vec<Str>,
cellvars: Vec<Str>,
filename: Str,
name: S,
firstlineno: u32,
lnotab: Vec<u8>,
) -> Self {
Self {
argcount,
posonlyargcount,
kwonlyargcount,
nlocals,
stacksize,
flags,
code,
consts,
names,
varnames,
freevars,
cellvars,
filename,
name: name.into(),
firstlineno,
lnotab,
}
}
pub fn empty<S: Into<Str>, T: Into<Str>>(
params: Vec<Str>,
filename: S,
@ -269,7 +232,7 @@ impl CodeObj {
let name = des.deserialize_str(v, python_ver)?;
let firstlineno = Deserializer::deserialize_u32(v);
let lnotab = des.deserialize_bytes(v)?;
Ok(CodeObj::new(
Ok(CodeObj {
argcount,
posonlyargcount,
kwonlyargcount,
@ -286,7 +249,7 @@ impl CodeObj {
name,
firstlineno,
lnotab,
))
})
}
pub fn into_bytes(self, python_ver: u32) -> Vec<u8> {
@ -337,54 +300,54 @@ impl CodeObj {
tables += "Constants:\n";
}
for (i, obj) in self.consts.iter().enumerate() {
tables += &format!(" {}: {}\n", i, obj);
writeln!(tables, " {}: {}", i, obj).unwrap();
}
if !self.names.is_empty() {
tables += "Names:\n";
}
for (i, name) in self.names.iter().enumerate() {
tables += &format!(" {}: {}\n", i, name);
writeln!(tables, " {}: {}", i, name).unwrap();
}
if !self.varnames.is_empty() {
tables += "Varnames:\n";
}
for (i, varname) in self.varnames.iter().enumerate() {
tables += &format!(" {}: {}\n", i, varname);
writeln!(tables, " {}: {}", i, varname).unwrap();
}
if !self.cellvars.is_empty() {
tables += "Cellvars:\n";
}
for (i, cellvar) in self.cellvars.iter().enumerate() {
tables += &format!(" {}: {}\n", i, cellvar);
writeln!(tables, " {}: {}", i, cellvar).unwrap();
}
if !self.freevars.is_empty() {
tables += "Freevars:\n";
}
for (i, freevar) in self.freevars.iter().enumerate() {
tables += &format!(" {}: {}\n", i, freevar);
writeln!(tables, " {}: {}\n", i, freevar).unwrap();
}
tables
}
fn attrs_info(&self) -> String {
let mut attrs = "".to_string();
attrs += &format!("Name: {}\n", self.name);
attrs += &format!("FileName: {}\n", self.filename);
attrs += &format!("Argument count: {}\n", self.argcount);
attrs += &format!("Positional-only arguments: {}\n", self.posonlyargcount);
attrs += &format!("Kw-only arguments: {}\n", self.kwonlyargcount);
attrs += &format!("Number of locals: {}\n", self.nlocals);
attrs += &format!("Stack size: {}\n", self.stacksize);
writeln!(attrs, "Name: {}", self.name).unwrap();
writeln!(attrs, "FileName: {}", self.filename).unwrap();
writeln!(attrs, "Argument count: {}", self.argcount).unwrap();
writeln!(attrs, "Positional-only arguments: {}", self.posonlyargcount).unwrap();
writeln!(attrs, "Kw-only arguments: {}", self.kwonlyargcount).unwrap();
writeln!(attrs, "Number of locals: {}", self.nlocals).unwrap();
writeln!(attrs, "Stack size: {}", self.stacksize).unwrap();
let mut flagged = "".to_string();
for i in 0..32 {
if (self.flags & (1 << i)) != 0 {
let flag: CodeObjFlags = 2u32.pow(i).into();
flagged += &format!("{:?}, ", flag);
write!(flagged, "{:?}, ", flag).unwrap();
}
}
flagged.pop();
flagged.pop();
attrs += &format!("Flags: {}\n", flagged);
writeln!(attrs, "Flags: {}", flagged).unwrap();
attrs
}
@ -397,22 +360,22 @@ impl CodeObj {
let mut sdelta = lnotab_iter.next().unwrap_or(&0);
let mut ldelta = lnotab_iter.next().unwrap_or(&0);
let mut instrs = "".to_string();
instrs += &format!("lnotab: {:?}\n", self.lnotab);
writeln!(instrs, "lnotab: {:?}", self.lnotab).unwrap();
if *sdelta != 0 {
instrs += &format!("{}:\n", lineno);
writeln!(instrs, "{}:", lineno).unwrap();
}
loop {
if *sdelta == line_offset {
line_offset = 0;
lineno += ldelta;
instrs += &format!("{}:\n", lineno);
writeln!(instrs, "{}:", lineno).unwrap();
sdelta = lnotab_iter.next().unwrap_or(&0);
ldelta = lnotab_iter.next().unwrap_or(&0);
}
if let (Some(op), Some(arg)) = (code_iter.next(), code_iter.next()) {
let op = Opcode::from(*op);
let s_op = op.to_string();
instrs += &format!("{:>15} {:<25}", idx, s_op);
write!(instrs, "{:>15} {:<25}", idx, s_op).unwrap();
match op {
Opcode::COMPARE_OP => {
let op = match arg {
@ -424,7 +387,7 @@ impl CodeObj {
5 => ">=",
_ => "?",
};
instrs += &format!("{} ({})", arg, op);
write!(instrs, "{} ({})", arg, op).unwrap();
}
Opcode::STORE_NAME
| Opcode::LOAD_NAME
@ -435,30 +398,52 @@ impl CodeObj {
| Opcode::LOAD_METHOD
| Opcode::IMPORT_NAME
| Opcode::IMPORT_FROM => {
instrs += &format!("{} ({})", arg, self.names.get(*arg as usize).unwrap());
write!(
instrs,
"{} ({})",
arg,
self.names.get(*arg as usize).unwrap()
)
.unwrap();
}
Opcode::STORE_DEREF | Opcode::LOAD_DEREF => {
instrs +=
&format!("{} ({})", arg, self.freevars.get(*arg as usize).unwrap());
write!(
instrs,
"{} ({})",
arg,
self.freevars.get(*arg as usize).unwrap()
)
.unwrap();
}
Opcode::STORE_FAST | Opcode::LOAD_FAST => {
instrs +=
&format!("{} ({})", arg, self.varnames.get(*arg as usize).unwrap());
write!(
instrs,
"{} ({})",
arg,
self.varnames.get(*arg as usize).unwrap()
)
.unwrap();
}
Opcode::LOAD_CONST => {
instrs += &format!("{} ({})", arg, self.consts.get(*arg as usize).unwrap());
write!(
instrs,
"{} ({})",
arg,
self.consts.get(*arg as usize).unwrap()
)
.unwrap();
}
Opcode::FOR_ITER => {
instrs += &format!("{} (to {})", arg, idx + arg * 2 + 2);
write!(instrs, "{} (to {})", arg, idx + arg * 2 + 2).unwrap();
}
Opcode::JUMP_FORWARD => {
instrs += &format!("{} (to {})", arg, idx + arg * 2 + 2);
write!(instrs, "{} (to {})", arg, idx + arg * 2 + 2).unwrap();
}
Opcode::JUMP_ABSOLUTE => {
instrs += &format!("{} (to {})", arg, arg * 2);
write!(instrs, "{} (to {})", arg, arg * 2).unwrap();
}
Opcode::POP_JUMP_IF_FALSE | Opcode::POP_JUMP_IF_TRUE => {
instrs += &format!("{} (to {})", arg, arg * 2);
write!(instrs, "{} (to {})", arg, arg * 2).unwrap();
}
Opcode::MAKE_FUNCTION => {
let flag = match arg {
@ -466,17 +451,17 @@ impl CodeObj {
// TODO:
_ => "",
};
instrs += &format!("{} {}", arg, flag);
write!(instrs, "{} {}", arg, flag).unwrap();
}
// Ergでは引数で型キャストする
Opcode::BINARY_ADD
| Opcode::BINARY_SUBTRACT
| Opcode::BINARY_MULTIPLY
| Opcode::BINARY_TRUE_DIVIDE => {
instrs += &format!("{} ({:?})", arg, TypePair::from(*arg));
write!(instrs, "{} ({:?})", arg, TypePair::from(*arg)).unwrap();
}
other if other.take_arg() => {
instrs += &format!("{}", arg);
write!(instrs, "{}", arg).unwrap();
}
_ => {}
}
@ -492,7 +477,7 @@ impl CodeObj {
pub fn code_info(&self) -> String {
let mut info = "".to_string();
info += &format!("Disassembly of {:?}:\n", self);
writeln!(info, "Disassembly of {:?}:", self).unwrap();
info += &self.attrs_info();
info += &self.tables_info();
info += &self.instr_info();

View file

@ -1,3 +1,5 @@
use std::convert::TryInto;
use crate::*;
#[inline]
@ -54,11 +56,15 @@ pub fn enum_t(s: Set<ValueObj>) -> Type {
}
#[inline]
pub fn int_interval<P: Into<TyParam>, Q: Into<TyParam>>(op: IntervalOp, l: P, r: Q) -> Type {
let l = l.into();
let r = r.into();
let l = l.try_into().unwrap_or_else(|l| todo!("{l}"));
let r = r.try_into().unwrap_or_else(|r| todo!("{r}"));
pub fn int_interval<P, PErr, Q, QErr>(op: IntervalOp, l: P, r: Q) -> Type
where
P: TryInto<TyParam, Error = PErr>,
PErr: fmt::Debug,
Q: TryInto<TyParam, Error = QErr>,
QErr: fmt::Debug,
{
let l = l.try_into().unwrap_or_else(|l| todo!("{l:?}"));
let r = r.try_into().unwrap_or_else(|r| todo!("{r:?}"));
let name = Str::from(fresh_varname());
let pred = match op {
IntervalOp::LeftOpen if l == TyParam::value(NegInf) => Predicate::le(name.clone(), r),
@ -165,8 +171,8 @@ pub fn func2(l: Type, r: Type, return_t: Type) -> Type {
pub fn bin_op(l: Type, r: Type, return_t: Type) -> Type {
nd_func(
vec![
ParamTy::kw(Str::ever("lhs"), l.clone()),
ParamTy::kw(Str::ever("rhs"), r.clone()),
ParamTy::kw(Str::ever("lhs"), l),
ParamTy::kw(Str::ever("rhs"), r),
],
None,
return_t,

View file

@ -216,7 +216,7 @@ impl Deserializer {
let name = self.deserialize_str(v, python_ver)?;
let firstlineno = Self::deserialize_u32(v);
let lnotab = self.deserialize_bytes(v)?;
Ok(ValueObj::from(CodeObj::new(
Ok(ValueObj::from(CodeObj {
argcount,
posonlyargcount,
kwonlyargcount,
@ -233,7 +233,7 @@ impl Deserializer {
name,
firstlineno,
lnotab,
)))
}))
}
DataTypePrefix::None => Ok(ValueObj::None),
other => Err(DeserializeError::new(

View file

@ -212,9 +212,8 @@ impl Constraint {
}
pub fn update_cyclicity(&mut self, new_cyclicity: Cyclicity) {
match self {
Self::Sandwiched { cyclicity, .. } => *cyclicity = cyclicity.combine(new_cyclicity),
_ => (),
if let Self::Sandwiched { cyclicity, .. } = self {
*cyclicity = cyclicity.combine(new_cyclicity);
}
}
}

View file

@ -1,6 +1,8 @@
//! defines `Type` (type kind).
//!
//! Type(コンパイラ等で使われる「型」を表現する)を定義する
#![allow(clippy::derive_hash_xor_eq)]
#![allow(clippy::large_enum_variant)]
pub mod codeobj;
pub mod constructors;
pub mod deserialize;
@ -47,11 +49,11 @@ pub trait HasType {
}
#[inline]
fn lhs_t(&self) -> &Type {
&self.ref_t().non_default_params().unwrap()[0].typ()
self.ref_t().non_default_params().unwrap()[0].typ()
}
#[inline]
fn rhs_t(&self) -> &Type {
&self.ref_t().non_default_params().unwrap()[1].typ()
self.ref_t().non_default_params().unwrap()[1].typ()
}
}
@ -697,7 +699,7 @@ impl LimitedDisplay for SubrType {
param.typ().limited_fmt(f, limit - 1)?;
}
if let Some(var_params) = &self.var_params {
if self.non_default_params.len() != 0 {
if !self.non_default_params.is_empty() {
write!(f, ", ")?;
}
write!(f, "...")?;
@ -1495,9 +1497,9 @@ impl HasLevel for Type {
for pt in subr.non_default_params.iter() {
pt.typ().update_level(level);
}
subr.var_params
.as_ref()
.map(|pt| pt.typ().update_level(level));
if let Some(pt) = subr.var_params.as_ref() {
pt.typ().update_level(level);
}
for pt in subr.default_params.iter() {
pt.typ().update_level(level);
}
@ -1551,7 +1553,9 @@ impl HasLevel for Type {
for pt in subr.non_default_params.iter() {
pt.typ().lift();
}
subr.var_params.as_ref().map(|pt| pt.typ().lift());
if let Some(pt) = subr.var_params.as_ref() {
pt.typ().lift();
}
for pt in subr.default_params.iter() {
pt.typ().lift();
}
@ -1892,10 +1896,7 @@ impl Type {
}
pub fn is_monomorphic(&self) -> bool {
match self.typarams_len() {
Some(0) | None => true,
_ => false,
}
matches!(self.typarams_len(), Some(0) | None)
}
pub const fn is_callable(&self) -> bool {
@ -2092,13 +2093,13 @@ impl Type {
}
}
pub const fn var_args(&self) -> Option<&Box<ParamTy>> {
pub fn var_args(&self) -> Option<&ParamTy> {
match self {
Self::FreeVar(_) => panic!("fv"),
Self::Subr(SubrType {
var_params: var_args,
..
}) => var_args.as_ref(),
}) => var_args.as_deref(),
Self::Callable { param_ts: _, .. } => todo!(),
_ => None,
}
@ -2133,21 +2134,15 @@ impl Type {
}
pub fn update_constraint(&self, new_constraint: Constraint) {
match self {
Self::FreeVar(fv) => {
if let Self::FreeVar(fv) = self {
fv.update_constraint(new_constraint);
}
_ => {}
}
}
pub fn update_cyclicity(&self, new_cyclicity: Cyclicity) {
match self {
Self::FreeVar(fv) => {
if let Self::FreeVar(fv) = self {
fv.update_cyclicity(new_cyclicity);
}
_ => {}
}
}
}

View file

@ -633,9 +633,8 @@ impl TyParam {
}
pub fn update_constraint(&self, new_constraint: Constraint) {
match self {
Self::Type(t) => t.update_constraint(new_constraint),
_ => {}
if let Self::Type(t) = self {
t.update_constraint(new_constraint);
}
}
}