mirror of
https://github.com/erg-lang/erg.git
synced 2025-08-03 10:23:20 +00:00
feat: fix bugs
This commit is contained in:
parent
37ef01c89a
commit
d039e21628
3 changed files with 33 additions and 7 deletions
|
@ -205,6 +205,14 @@ impl<K: Hash + Eq, V> Dict<K, V> {
|
|||
self.dict.remove(k)
|
||||
}
|
||||
|
||||
pub fn remove_entry<Q: ?Sized>(&mut self, k: &Q) -> Option<(K, V)>
|
||||
where
|
||||
K: Borrow<Q>,
|
||||
Q: Hash + Eq,
|
||||
{
|
||||
self.dict.remove_entry(k)
|
||||
}
|
||||
|
||||
/// NOTE: This method does not consider pairing with values and keys. That is, a value may be paired with a different key (can be considered equal).
|
||||
/// If you need to consider the pairing of the keys and values, use `guaranteed_extend` instead.
|
||||
#[inline]
|
||||
|
|
|
@ -1998,7 +1998,7 @@ impl Context {
|
|||
(Type::Refinement(l), Type::Refinement(r)) if l.t == r.t => {
|
||||
self.get_nominal_super_type_ctxs(&l.t)
|
||||
}
|
||||
_ => None,
|
||||
_ => self.get_nominal_type_ctx(&Obj).map(|(_, ctx)| vec![ctx]),
|
||||
},
|
||||
_ => self
|
||||
.get_simple_nominal_super_type_ctxs(t)
|
||||
|
|
|
@ -1246,21 +1246,28 @@ impl ASTLowerer {
|
|||
if let Err(errs) = self.module.context.assign_params(&mut params, None) {
|
||||
self.errs.extend(errs);
|
||||
}
|
||||
if !in_statement {
|
||||
let guards = mem::take(&mut self.module.context.get_mut_outer().unwrap().guards);
|
||||
let overwritten = {
|
||||
let mut overwritten = vec![];
|
||||
let guards = if in_statement {
|
||||
mem::take(&mut self.module.context.guards)
|
||||
} else {
|
||||
mem::take(&mut self.module.context.get_mut_outer().unwrap().guards)
|
||||
};
|
||||
for guard in guards.into_iter() {
|
||||
if let Variable::Var(name) = &guard.var {
|
||||
let vi = self
|
||||
.module
|
||||
.context
|
||||
.locals
|
||||
.remove(name)
|
||||
.map(|vi| {
|
||||
.remove_entry(name)
|
||||
.map(|(name, vi)| {
|
||||
overwritten.push((name, vi.clone()));
|
||||
let t = self.module.context.intersection(&vi.t, &guard.to);
|
||||
VarInfo { t, ..vi }
|
||||
})
|
||||
.unwrap_or_else(|| {
|
||||
if let Some((_, vi)) = self.module.context.get_var_kv(name) {
|
||||
if let Some((n, vi)) = self.module.context.get_var_kv(name) {
|
||||
overwritten.push((n.clone(), vi.clone()));
|
||||
let t = self.module.context.intersection(&vi.t, &guard.to);
|
||||
VarInfo { t, ..vi.clone() }
|
||||
} else {
|
||||
|
@ -1277,7 +1284,8 @@ impl ASTLowerer {
|
|||
.insert(VarName::from_str(name.clone()), vi);
|
||||
}
|
||||
}
|
||||
}
|
||||
overwritten
|
||||
};
|
||||
if let Err(errs) = self.module.context.preregister(&lambda.body) {
|
||||
self.errs.extend(errs);
|
||||
}
|
||||
|
@ -1287,6 +1295,16 @@ impl ASTLowerer {
|
|||
}
|
||||
errs
|
||||
})?;
|
||||
if in_statement {
|
||||
for (var, vi) in overwritten.into_iter() {
|
||||
if vi.kind.is_parameter() {
|
||||
// removed from `locals` and remains in `params`
|
||||
self.module.context.locals.remove(&var);
|
||||
} else {
|
||||
self.module.context.locals.insert(var, vi);
|
||||
}
|
||||
}
|
||||
}
|
||||
// suppress warns of lambda types, e.g. `(x: Int, y: Int) -> Int`
|
||||
if self.module.context.subtype_of(body.ref_t(), &Type::Type) {
|
||||
for param in params.non_defaults.iter() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue