Skip to content

Commit

Permalink
feat: enhance assert casting
Browse files Browse the repository at this point in the history
  • Loading branch information
mtshiba committed Aug 22, 2023
1 parent 3724a74 commit dc7e0a3
Show file tree
Hide file tree
Showing 12 changed files with 198 additions and 173 deletions.
7 changes: 4 additions & 3 deletions crates/erg_compiler/context/compare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -383,9 +383,9 @@ impl Context {
(Some((_, l_sup)), Some((r_sub, _))) => self.supertype_of(&l_sup, &r_sub),
_ => {
if lfv.is_linked() {
self.supertype_of(&lfv.crack(), rhs)
self.supertype_of(lfv.unsafe_crack(), rhs)
} else if rfv.is_linked() {
self.supertype_of(lhs, &rfv.crack())
self.supertype_of(lhs, rfv.unsafe_crack())
} else {
false
}
Expand Down Expand Up @@ -1418,7 +1418,8 @@ impl Context {
Not(t) => *t.clone(),
Refinement(r) => Type::Refinement(r.clone().invert()),
Guard(guard) => Type::Guard(GuardType::new(
guard.var.clone(),
guard.namespace.clone(),
guard.target.clone(),
self.complement(&guard.to),
)),
Or(l, r) => self.intersection(&self.complement(l), &self.complement(r)),
Expand Down
12 changes: 6 additions & 6 deletions crates/erg_compiler/context/generalize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1092,9 +1092,9 @@ impl Context {
.unbound_name()
.map_or(false, |name| !qnames.contains(&name))
{
let t = mem::take(acc.ref_mut_t());
let t = mem::take(acc.ref_mut_t().unwrap());
let mut dereferencer = Dereferencer::simple(self, qnames, acc);
*acc.ref_mut_t() = dereferencer.deref_tyvar(t)?;
*acc.ref_mut_t().unwrap() = dereferencer.deref_tyvar(t)?;
}
if let hir::Accessor::Attr(attr) = acc {
self.resolve_expr_t(&mut attr.obj, qnames)?;
Expand Down Expand Up @@ -1181,10 +1181,10 @@ impl Context {
let mut dereferencer = Dereferencer::simple(self, qnames, record);
record.t = dereferencer.deref_tyvar(t)?;
for attr in record.attrs.iter_mut() {
let t = mem::take(attr.sig.ref_mut_t());
let t = mem::take(attr.sig.ref_mut_t().unwrap());
let mut dereferencer = Dereferencer::simple(self, qnames, &attr.sig);
let t = dereferencer.deref_tyvar(t)?;
*attr.sig.ref_mut_t() = t;
*attr.sig.ref_mut_t().unwrap() = t;
for chunk in attr.body.block.iter_mut() {
self.resolve_expr_t(chunk, qnames)?;
}
Expand Down Expand Up @@ -1232,9 +1232,9 @@ impl Context {
} else {
qnames.clone()
};
let t = mem::take(def.sig.ref_mut_t());
let t = mem::take(def.sig.ref_mut_t().unwrap());
let mut dereferencer = Dereferencer::simple(self, &qnames, &def.sig);
*def.sig.ref_mut_t() = dereferencer.deref_tyvar(t)?;
*def.sig.ref_mut_t().unwrap() = dereferencer.deref_tyvar(t)?;
if let Some(params) = def.sig.params_mut() {
self.resolve_params_t(params, &qnames)?;
}
Expand Down
16 changes: 12 additions & 4 deletions crates/erg_compiler/context/inquire.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2873,6 +2873,14 @@ impl Context {
}
}

pub(crate) fn rec_get_guards(&self) -> Vec<&GuardType> {
if let Some(outer) = self.get_outer() {
[self.guards.iter().collect(), outer.rec_get_guards()].concat()
} else {
self.guards.iter().collect()
}
}

// TODO: `Override` decorator should also be used
/// e.g.
/// ```erg
Expand Down Expand Up @@ -3203,9 +3211,9 @@ impl Context {
return Err(TyCheckErrors::from(TyCheckError::invalid_type_cast_error(
self.cfg.input.clone(),
line!() as usize,
guard.var.loc(),
guard.target.loc(),
self.caused_by(),
&guard.var.to_string(),
&guard.target.to_string(),
base,
&guard.to,
None,
Expand All @@ -3229,9 +3237,9 @@ impl Context {
Err(TyCheckErrors::from(TyCheckError::invalid_type_cast_error(
self.cfg.input.clone(),
line!() as usize,
guard.var.loc(),
guard.target.loc(),
self.caused_by(),
&guard.var.to_string(),
&guard.target.to_string(),
base,
&guard.to,
None,
Expand Down
84 changes: 48 additions & 36 deletions crates/erg_compiler/context/register.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ use crate::ty::free::{Constraint, HasLevel};
use crate::ty::typaram::TyParam;
use crate::ty::value::{GenTypeObj, TypeObj, ValueObj};
use crate::ty::{
Field, GuardType, HasType, ParamTy, SubrType, Type, Variable, Visibility, VisibilityModifier,
CastTarget, Field, GuardType, HasType, ParamTy, SubrType, Type, Visibility, VisibilityModifier,
};

use crate::build_hir::HIRBuilder;
Expand Down Expand Up @@ -2272,49 +2272,61 @@ impl Context {
}
}

pub(crate) fn get_casted_type(&self, expr: &ast::Expr) -> Option<Type> {
for guard in self.rec_get_guards() {
if !self.name.starts_with(&guard.namespace[..]) {
continue;
}
if let CastTarget::Expr(target) = &guard.target {
if expr == target.as_ref() {
return Some(*guard.to.clone());
}
}
}
None
}

pub(crate) fn cast(
&mut self,
guard: GuardType,
overwritten: &mut Vec<(VarName, VarInfo)>,
) -> TyCheckResult<()> {
if let Variable::Var {
namespace, name, ..
} = &guard.var
{
if !self.name.starts_with(&namespace[..]) {
return Ok(());
}
let vi = if let Some((name, vi)) = self.locals.remove_entry(name) {
overwritten.push((name, vi.clone()));
vi
} else if let Some((n, vi)) = self.get_var_kv(name) {
overwritten.push((n.clone(), vi.clone()));
vi.clone()
} else {
VarInfo::nd_parameter(
*guard.to.clone(),
self.absolutize(().loc()),
self.name.clone(),
)
};
match self.recover_typarams(&vi.t, &guard) {
Ok(t) => {
self.locals
.insert(VarName::from_str(name.clone()), VarInfo { t, ..vi });
match &guard.target {
CastTarget::Var { name, .. } => {
if !self.name.starts_with(&guard.namespace[..]) {
return Ok(());
}
Err(errs) => {
self.locals.insert(VarName::from_str(name.clone()), vi);
return Err(errs);
let vi = if let Some((name, vi)) = self.locals.remove_entry(name) {
overwritten.push((name, vi.clone()));
vi
} else if let Some((n, vi)) = self.get_var_kv(name) {
overwritten.push((n.clone(), vi.clone()));
vi.clone()
} else {
VarInfo::nd_parameter(
*guard.to.clone(),
self.absolutize(().loc()),
self.name.clone(),
)
};
match self.recover_typarams(&vi.t, &guard) {
Ok(t) => {
self.locals
.insert(VarName::from_str(name.clone()), VarInfo { t, ..vi });
}
Err(errs) => {
self.locals.insert(VarName::from_str(name.clone()), vi);
return Err(errs);
}
}
}
} /* else {
return Err(TyCheckErrors::from(TyCheckError::feature_error(
self.cfg.input.clone(),
guard.var.loc(),
&format!("casting {}", guard.var),
self.caused_by(),
)));
} */
CastTarget::Param { .. } => {
// TODO:
}
CastTarget::Expr(_) => {
self.guards.push(guard);
}
}
Ok(())
}

Expand Down
60 changes: 30 additions & 30 deletions crates/erg_compiler/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -413,8 +413,8 @@ impl HasType for Identifier {
&self.vi.t
}
#[inline]
fn ref_mut_t(&mut self) -> &mut Type {
&mut self.vi.t
fn ref_mut_t(&mut self) -> Option<&mut Type> {
Some(&mut self.vi.t)
}
#[inline]
fn signature_t(&self) -> Option<&Type> {
Expand Down Expand Up @@ -545,7 +545,7 @@ impl HasType for Attribute {
self.ident.ref_t()
}
#[inline]
fn ref_mut_t(&mut self) -> &mut Type {
fn ref_mut_t(&mut self) -> Option<&mut Type> {
self.ident.ref_mut_t()
}
#[inline]
Expand Down Expand Up @@ -1221,8 +1221,8 @@ impl HasType for BinOp {
fn ref_t(&self) -> &Type {
self.info.t.return_t().unwrap()
}
fn ref_mut_t(&mut self) -> &mut Type {
self.info.t.mut_return_t().unwrap()
fn ref_mut_t(&mut self) -> Option<&mut Type> {
self.info.t.mut_return_t()
}
#[inline]
fn lhs_t(&self) -> &Type {
Expand Down Expand Up @@ -1268,8 +1268,8 @@ impl HasType for UnaryOp {
fn ref_t(&self) -> &Type {
self.info.t.return_t().unwrap()
}
fn ref_mut_t(&mut self) -> &mut Type {
self.info.t.mut_return_t().unwrap()
fn ref_mut_t(&mut self) -> Option<&mut Type> {
self.info.t.mut_return_t()
}
#[inline]
fn lhs_t(&self) -> &Type {
Expand Down Expand Up @@ -1357,11 +1357,11 @@ impl HasType for Call {
}
}
#[inline]
fn ref_mut_t(&mut self) -> &mut Type {
fn ref_mut_t(&mut self) -> Option<&mut Type> {
if let Some(attr) = self.attr_name.as_mut() {
attr.ref_mut_t().mut_return_t().unwrap()
attr.ref_mut_t()?.mut_return_t()
} else {
self.obj.ref_mut_t().mut_return_t().unwrap()
self.obj.ref_mut_t()?.mut_return_t()
}
}
#[inline]
Expand Down Expand Up @@ -1391,12 +1391,12 @@ impl HasType for Call {
#[inline]
fn signature_mut_t(&mut self) -> Option<&mut Type> {
if let Some(attr) = self.attr_name.as_mut() {
Some(attr.ref_mut_t())
attr.ref_mut_t()
} else {
if let Expr::Call(call) = self.obj.as_ref() {
call.return_t()?;
}
Some(self.obj.ref_mut_t())
self.obj.ref_mut_t()
}
}
}
Expand Down Expand Up @@ -1466,8 +1466,8 @@ impl HasType for Block {
.unwrap_or(Type::FAILURE)
}
#[inline]
fn ref_mut_t(&mut self) -> &mut Type {
self.last_mut().unwrap().ref_mut_t()
fn ref_mut_t(&mut self) -> Option<&mut Type> {
self.last_mut()?.ref_mut_t()
}
#[inline]
fn t(&self) -> Type {
Expand Down Expand Up @@ -1517,8 +1517,8 @@ impl HasType for Dummy {
Type::FAILURE
}
#[inline]
fn ref_mut_t(&mut self) -> &mut Type {
todo!()
fn ref_mut_t(&mut self) -> Option<&mut Type> {
None
}
#[inline]
fn t(&self) -> Type {
Expand Down Expand Up @@ -1583,7 +1583,7 @@ impl HasType for VarSignature {
self.ident.ref_t()
}
#[inline]
fn ref_mut_t(&mut self) -> &mut Type {
fn ref_mut_t(&mut self) -> Option<&mut Type> {
self.ident.ref_mut_t()
}
#[inline]
Expand Down Expand Up @@ -1874,7 +1874,7 @@ impl HasType for SubrSignature {
self.ident.ref_t()
}
#[inline]
fn ref_mut_t(&mut self) -> &mut Type {
fn ref_mut_t(&mut self) -> Option<&mut Type> {
self.ident.ref_mut_t()
}
#[inline]
Expand Down Expand Up @@ -2105,8 +2105,8 @@ impl HasType for Def {
Type::NONE
}
#[inline]
fn ref_mut_t(&mut self) -> &mut Type {
todo!()
fn ref_mut_t(&mut self) -> Option<&mut Type> {
None
}
#[inline]
fn signature_t(&self) -> Option<&Type> {
Expand Down Expand Up @@ -2188,8 +2188,8 @@ impl HasType for Methods {
Type::NONE
}
#[inline]
fn ref_mut_t(&mut self) -> &mut Type {
todo!()
fn ref_mut_t(&mut self) -> Option<&mut Type> {
None
}
#[inline]
fn signature_t(&self) -> Option<&Type> {
Expand Down Expand Up @@ -2242,8 +2242,8 @@ impl HasType for ClassDef {
Type::NONE
}
#[inline]
fn ref_mut_t(&mut self) -> &mut Type {
todo!()
fn ref_mut_t(&mut self) -> Option<&mut Type> {
None
}
#[inline]
fn signature_t(&self) -> Option<&Type> {
Expand Down Expand Up @@ -2312,8 +2312,8 @@ impl HasType for PatchDef {
Type::NONE
}
#[inline]
fn ref_mut_t(&mut self) -> &mut Type {
todo!()
fn ref_mut_t(&mut self) -> Option<&mut Type> {
None
}
#[inline]
fn signature_t(&self) -> Option<&Type> {
Expand Down Expand Up @@ -2368,8 +2368,8 @@ impl HasType for ReDef {
Type::NONE
}
#[inline]
fn ref_mut_t(&mut self) -> &mut Type {
todo!()
fn ref_mut_t(&mut self) -> Option<&mut Type> {
None
}
#[inline]
fn signature_t(&self) -> Option<&Type> {
Expand Down Expand Up @@ -2455,9 +2455,9 @@ impl HasType for TypeAscription {
}
}
#[inline]
fn ref_mut_t(&mut self) -> &mut Type {
fn ref_mut_t(&mut self) -> Option<&mut Type> {
if self.spec.kind().is_force_cast() {
&mut self.spec.spec_t
Some(&mut self.spec.spec_t)
} else {
self.expr.ref_mut_t()
}
Expand Down
Loading

0 comments on commit dc7e0a3

Please sign in to comment.