mirror of
https://github.com/erg-lang/erg.git
synced 2025-10-02 21:44:34 +00:00
Merge branch 'main' into fix-els
This commit is contained in:
commit
fd6e75a435
12 changed files with 198 additions and 173 deletions
|
@ -383,9 +383,9 @@ impl Context {
|
||||||
(Some((_, l_sup)), Some((r_sub, _))) => self.supertype_of(&l_sup, &r_sub),
|
(Some((_, l_sup)), Some((r_sub, _))) => self.supertype_of(&l_sup, &r_sub),
|
||||||
_ => {
|
_ => {
|
||||||
if lfv.is_linked() {
|
if lfv.is_linked() {
|
||||||
self.supertype_of(&lfv.crack(), rhs)
|
self.supertype_of(lfv.unsafe_crack(), rhs)
|
||||||
} else if rfv.is_linked() {
|
} else if rfv.is_linked() {
|
||||||
self.supertype_of(lhs, &rfv.crack())
|
self.supertype_of(lhs, rfv.unsafe_crack())
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
@ -1418,7 +1418,8 @@ impl Context {
|
||||||
Not(t) => *t.clone(),
|
Not(t) => *t.clone(),
|
||||||
Refinement(r) => Type::Refinement(r.clone().invert()),
|
Refinement(r) => Type::Refinement(r.clone().invert()),
|
||||||
Guard(guard) => Type::Guard(GuardType::new(
|
Guard(guard) => Type::Guard(GuardType::new(
|
||||||
guard.var.clone(),
|
guard.namespace.clone(),
|
||||||
|
guard.target.clone(),
|
||||||
self.complement(&guard.to),
|
self.complement(&guard.to),
|
||||||
)),
|
)),
|
||||||
Or(l, r) => self.intersection(&self.complement(l), &self.complement(r)),
|
Or(l, r) => self.intersection(&self.complement(l), &self.complement(r)),
|
||||||
|
|
|
@ -1092,9 +1092,9 @@ impl Context {
|
||||||
.unbound_name()
|
.unbound_name()
|
||||||
.map_or(false, |name| !qnames.contains(&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);
|
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 {
|
if let hir::Accessor::Attr(attr) = acc {
|
||||||
self.resolve_expr_t(&mut attr.obj, qnames)?;
|
self.resolve_expr_t(&mut attr.obj, qnames)?;
|
||||||
|
@ -1181,10 +1181,10 @@ impl Context {
|
||||||
let mut dereferencer = Dereferencer::simple(self, qnames, record);
|
let mut dereferencer = Dereferencer::simple(self, qnames, record);
|
||||||
record.t = dereferencer.deref_tyvar(t)?;
|
record.t = dereferencer.deref_tyvar(t)?;
|
||||||
for attr in record.attrs.iter_mut() {
|
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 mut dereferencer = Dereferencer::simple(self, qnames, &attr.sig);
|
||||||
let t = dereferencer.deref_tyvar(t)?;
|
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() {
|
for chunk in attr.body.block.iter_mut() {
|
||||||
self.resolve_expr_t(chunk, qnames)?;
|
self.resolve_expr_t(chunk, qnames)?;
|
||||||
}
|
}
|
||||||
|
@ -1232,9 +1232,9 @@ impl Context {
|
||||||
} else {
|
} else {
|
||||||
qnames.clone()
|
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);
|
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() {
|
if let Some(params) = def.sig.params_mut() {
|
||||||
self.resolve_params_t(params, &qnames)?;
|
self.resolve_params_t(params, &qnames)?;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
// TODO: `Override` decorator should also be used
|
||||||
/// e.g.
|
/// e.g.
|
||||||
/// ```erg
|
/// ```erg
|
||||||
|
@ -3203,9 +3211,9 @@ impl Context {
|
||||||
return Err(TyCheckErrors::from(TyCheckError::invalid_type_cast_error(
|
return Err(TyCheckErrors::from(TyCheckError::invalid_type_cast_error(
|
||||||
self.cfg.input.clone(),
|
self.cfg.input.clone(),
|
||||||
line!() as usize,
|
line!() as usize,
|
||||||
guard.var.loc(),
|
guard.target.loc(),
|
||||||
self.caused_by(),
|
self.caused_by(),
|
||||||
&guard.var.to_string(),
|
&guard.target.to_string(),
|
||||||
base,
|
base,
|
||||||
&guard.to,
|
&guard.to,
|
||||||
None,
|
None,
|
||||||
|
@ -3229,9 +3237,9 @@ impl Context {
|
||||||
Err(TyCheckErrors::from(TyCheckError::invalid_type_cast_error(
|
Err(TyCheckErrors::from(TyCheckError::invalid_type_cast_error(
|
||||||
self.cfg.input.clone(),
|
self.cfg.input.clone(),
|
||||||
line!() as usize,
|
line!() as usize,
|
||||||
guard.var.loc(),
|
guard.target.loc(),
|
||||||
self.caused_by(),
|
self.caused_by(),
|
||||||
&guard.var.to_string(),
|
&guard.target.to_string(),
|
||||||
base,
|
base,
|
||||||
&guard.to,
|
&guard.to,
|
||||||
None,
|
None,
|
||||||
|
|
|
@ -35,7 +35,7 @@ use crate::ty::free::{Constraint, HasLevel};
|
||||||
use crate::ty::typaram::TyParam;
|
use crate::ty::typaram::TyParam;
|
||||||
use crate::ty::value::{GenTypeObj, TypeObj, ValueObj};
|
use crate::ty::value::{GenTypeObj, TypeObj, ValueObj};
|
||||||
use crate::ty::{
|
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;
|
use crate::build_hir::HIRBuilder;
|
||||||
|
@ -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(
|
pub(crate) fn cast(
|
||||||
&mut self,
|
&mut self,
|
||||||
guard: GuardType,
|
guard: GuardType,
|
||||||
overwritten: &mut Vec<(VarName, VarInfo)>,
|
overwritten: &mut Vec<(VarName, VarInfo)>,
|
||||||
) -> TyCheckResult<()> {
|
) -> TyCheckResult<()> {
|
||||||
if let Variable::Var {
|
match &guard.target {
|
||||||
namespace, name, ..
|
CastTarget::Var { name, .. } => {
|
||||||
} = &guard.var
|
if !self.name.starts_with(&guard.namespace[..]) {
|
||||||
{
|
return Ok(());
|
||||||
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 });
|
|
||||||
}
|
}
|
||||||
Err(errs) => {
|
let vi = if let Some((name, vi)) = self.locals.remove_entry(name) {
|
||||||
self.locals.insert(VarName::from_str(name.clone()), vi);
|
overwritten.push((name, vi.clone()));
|
||||||
return Err(errs);
|
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 {
|
CastTarget::Param { .. } => {
|
||||||
return Err(TyCheckErrors::from(TyCheckError::feature_error(
|
// TODO:
|
||||||
self.cfg.input.clone(),
|
}
|
||||||
guard.var.loc(),
|
CastTarget::Expr(_) => {
|
||||||
&format!("casting {}", guard.var),
|
self.guards.push(guard);
|
||||||
self.caused_by(),
|
}
|
||||||
)));
|
}
|
||||||
} */
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -413,8 +413,8 @@ impl HasType for Identifier {
|
||||||
&self.vi.t
|
&self.vi.t
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn ref_mut_t(&mut self) -> &mut Type {
|
fn ref_mut_t(&mut self) -> Option<&mut Type> {
|
||||||
&mut self.vi.t
|
Some(&mut self.vi.t)
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn signature_t(&self) -> Option<&Type> {
|
fn signature_t(&self) -> Option<&Type> {
|
||||||
|
@ -545,7 +545,7 @@ impl HasType for Attribute {
|
||||||
self.ident.ref_t()
|
self.ident.ref_t()
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn ref_mut_t(&mut self) -> &mut Type {
|
fn ref_mut_t(&mut self) -> Option<&mut Type> {
|
||||||
self.ident.ref_mut_t()
|
self.ident.ref_mut_t()
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -1221,8 +1221,8 @@ impl HasType for BinOp {
|
||||||
fn ref_t(&self) -> &Type {
|
fn ref_t(&self) -> &Type {
|
||||||
self.info.t.return_t().unwrap()
|
self.info.t.return_t().unwrap()
|
||||||
}
|
}
|
||||||
fn ref_mut_t(&mut self) -> &mut Type {
|
fn ref_mut_t(&mut self) -> Option<&mut Type> {
|
||||||
self.info.t.mut_return_t().unwrap()
|
self.info.t.mut_return_t()
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn lhs_t(&self) -> &Type {
|
fn lhs_t(&self) -> &Type {
|
||||||
|
@ -1268,8 +1268,8 @@ impl HasType for UnaryOp {
|
||||||
fn ref_t(&self) -> &Type {
|
fn ref_t(&self) -> &Type {
|
||||||
self.info.t.return_t().unwrap()
|
self.info.t.return_t().unwrap()
|
||||||
}
|
}
|
||||||
fn ref_mut_t(&mut self) -> &mut Type {
|
fn ref_mut_t(&mut self) -> Option<&mut Type> {
|
||||||
self.info.t.mut_return_t().unwrap()
|
self.info.t.mut_return_t()
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn lhs_t(&self) -> &Type {
|
fn lhs_t(&self) -> &Type {
|
||||||
|
@ -1357,11 +1357,11 @@ impl HasType for Call {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[inline]
|
#[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() {
|
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 {
|
} else {
|
||||||
self.obj.ref_mut_t().mut_return_t().unwrap()
|
self.obj.ref_mut_t()?.mut_return_t()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -1391,12 +1391,12 @@ impl HasType for Call {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn signature_mut_t(&mut self) -> Option<&mut Type> {
|
fn signature_mut_t(&mut self) -> Option<&mut Type> {
|
||||||
if let Some(attr) = self.attr_name.as_mut() {
|
if let Some(attr) = self.attr_name.as_mut() {
|
||||||
Some(attr.ref_mut_t())
|
attr.ref_mut_t()
|
||||||
} else {
|
} else {
|
||||||
if let Expr::Call(call) = self.obj.as_ref() {
|
if let Expr::Call(call) = self.obj.as_ref() {
|
||||||
call.return_t()?;
|
call.return_t()?;
|
||||||
}
|
}
|
||||||
Some(self.obj.ref_mut_t())
|
self.obj.ref_mut_t()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1466,8 +1466,8 @@ impl HasType for Block {
|
||||||
.unwrap_or(Type::FAILURE)
|
.unwrap_or(Type::FAILURE)
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn ref_mut_t(&mut self) -> &mut Type {
|
fn ref_mut_t(&mut self) -> Option<&mut Type> {
|
||||||
self.last_mut().unwrap().ref_mut_t()
|
self.last_mut()?.ref_mut_t()
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn t(&self) -> Type {
|
fn t(&self) -> Type {
|
||||||
|
@ -1517,8 +1517,8 @@ impl HasType for Dummy {
|
||||||
Type::FAILURE
|
Type::FAILURE
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn ref_mut_t(&mut self) -> &mut Type {
|
fn ref_mut_t(&mut self) -> Option<&mut Type> {
|
||||||
todo!()
|
None
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn t(&self) -> Type {
|
fn t(&self) -> Type {
|
||||||
|
@ -1583,7 +1583,7 @@ impl HasType for VarSignature {
|
||||||
self.ident.ref_t()
|
self.ident.ref_t()
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn ref_mut_t(&mut self) -> &mut Type {
|
fn ref_mut_t(&mut self) -> Option<&mut Type> {
|
||||||
self.ident.ref_mut_t()
|
self.ident.ref_mut_t()
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -1874,7 +1874,7 @@ impl HasType for SubrSignature {
|
||||||
self.ident.ref_t()
|
self.ident.ref_t()
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn ref_mut_t(&mut self) -> &mut Type {
|
fn ref_mut_t(&mut self) -> Option<&mut Type> {
|
||||||
self.ident.ref_mut_t()
|
self.ident.ref_mut_t()
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -2105,8 +2105,8 @@ impl HasType for Def {
|
||||||
Type::NONE
|
Type::NONE
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn ref_mut_t(&mut self) -> &mut Type {
|
fn ref_mut_t(&mut self) -> Option<&mut Type> {
|
||||||
todo!()
|
None
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn signature_t(&self) -> Option<&Type> {
|
fn signature_t(&self) -> Option<&Type> {
|
||||||
|
@ -2188,8 +2188,8 @@ impl HasType for Methods {
|
||||||
Type::NONE
|
Type::NONE
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn ref_mut_t(&mut self) -> &mut Type {
|
fn ref_mut_t(&mut self) -> Option<&mut Type> {
|
||||||
todo!()
|
None
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn signature_t(&self) -> Option<&Type> {
|
fn signature_t(&self) -> Option<&Type> {
|
||||||
|
@ -2242,8 +2242,8 @@ impl HasType for ClassDef {
|
||||||
Type::NONE
|
Type::NONE
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn ref_mut_t(&mut self) -> &mut Type {
|
fn ref_mut_t(&mut self) -> Option<&mut Type> {
|
||||||
todo!()
|
None
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn signature_t(&self) -> Option<&Type> {
|
fn signature_t(&self) -> Option<&Type> {
|
||||||
|
@ -2312,8 +2312,8 @@ impl HasType for PatchDef {
|
||||||
Type::NONE
|
Type::NONE
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn ref_mut_t(&mut self) -> &mut Type {
|
fn ref_mut_t(&mut self) -> Option<&mut Type> {
|
||||||
todo!()
|
None
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn signature_t(&self) -> Option<&Type> {
|
fn signature_t(&self) -> Option<&Type> {
|
||||||
|
@ -2368,8 +2368,8 @@ impl HasType for ReDef {
|
||||||
Type::NONE
|
Type::NONE
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn ref_mut_t(&mut self) -> &mut Type {
|
fn ref_mut_t(&mut self) -> Option<&mut Type> {
|
||||||
todo!()
|
None
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn signature_t(&self) -> Option<&Type> {
|
fn signature_t(&self) -> Option<&Type> {
|
||||||
|
@ -2455,9 +2455,9 @@ impl HasType for TypeAscription {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[inline]
|
#[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() {
|
if self.spec.kind().is_force_cast() {
|
||||||
&mut self.spec.spec_t
|
Some(&mut self.spec.spec_t)
|
||||||
} else {
|
} else {
|
||||||
self.expr.ref_mut_t()
|
self.expr.ref_mut_t()
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ use crate::ty::constructors::{
|
||||||
use crate::ty::free::Constraint;
|
use crate::ty::free::Constraint;
|
||||||
use crate::ty::typaram::TyParam;
|
use crate::ty::typaram::TyParam;
|
||||||
use crate::ty::value::{GenTypeObj, TypeObj, ValueObj};
|
use crate::ty::value::{GenTypeObj, TypeObj, ValueObj};
|
||||||
use crate::ty::{GuardType, HasType, ParamTy, Predicate, Type, Variable, VisibilityModifier};
|
use crate::ty::{CastTarget, GuardType, HasType, ParamTy, Predicate, Type, VisibilityModifier};
|
||||||
|
|
||||||
use crate::context::{
|
use crate::context::{
|
||||||
ClassDefType, Context, ContextKind, ContextProvider, ControlKind, ModuleContext,
|
ClassDefType, Context, ContextKind, ContextProvider, ControlKind, ModuleContext,
|
||||||
|
@ -50,26 +50,13 @@ use crate::{feature_error, unreachable_error};
|
||||||
|
|
||||||
use VisibilityModifier::*;
|
use VisibilityModifier::*;
|
||||||
|
|
||||||
pub fn acc_to_variable(namespace: Str, acc: &ast::Accessor) -> Option<Variable> {
|
pub fn expr_to_cast_target(expr: &ast::Expr) -> CastTarget {
|
||||||
match acc {
|
match expr {
|
||||||
ast::Accessor::Ident(ident) => Some(Variable::Var {
|
ast::Expr::Accessor(ast::Accessor::Ident(ident)) => CastTarget::Var {
|
||||||
namespace,
|
|
||||||
name: ident.inspect().clone(),
|
name: ident.inspect().clone(),
|
||||||
loc: ident.loc(),
|
loc: ident.loc(),
|
||||||
}),
|
},
|
||||||
ast::Accessor::Attr(attr) => Some(Variable::attr(
|
_ => CastTarget::expr(expr.clone()),
|
||||||
expr_to_variable(namespace, &attr.obj)?,
|
|
||||||
attr.ident.inspect().clone(),
|
|
||||||
attr.loc(),
|
|
||||||
)),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn expr_to_variable(namespace: Str, expr: &ast::Expr) -> Option<Variable> {
|
|
||||||
match expr {
|
|
||||||
ast::Expr::Accessor(acc) => acc_to_variable(namespace, acc),
|
|
||||||
_ => None,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -746,28 +733,29 @@ impl ASTLowerer {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_guard_type(&self, op: &Token, lhs: &ast::Expr, rhs: &ast::Expr) -> Option<Type> {
|
fn get_guard_type(&self, op: &Token, lhs: &ast::Expr, rhs: &ast::Expr) -> Option<Type> {
|
||||||
let var = if op.kind == TokenKind::ContainsOp {
|
let target = if op.kind == TokenKind::ContainsOp {
|
||||||
expr_to_variable(self.module.context.name.clone(), rhs)?
|
expr_to_cast_target(rhs)
|
||||||
} else {
|
} else {
|
||||||
expr_to_variable(self.module.context.name.clone(), lhs)?
|
expr_to_cast_target(lhs)
|
||||||
};
|
};
|
||||||
|
let namespace = self.module.context.name.clone();
|
||||||
match op.kind {
|
match op.kind {
|
||||||
// l in T -> T contains l
|
// l in T -> T contains l
|
||||||
TokenKind::ContainsOp => {
|
TokenKind::ContainsOp => {
|
||||||
let to = self.module.context.expr_to_type(lhs.clone())?;
|
let to = self.module.context.expr_to_type(lhs.clone())?;
|
||||||
Some(guard(var, to))
|
Some(guard(namespace, target, to))
|
||||||
}
|
}
|
||||||
TokenKind::Symbol if &op.content[..] == "isinstance" => {
|
TokenKind::Symbol if &op.content[..] == "isinstance" => {
|
||||||
let to = self.module.context.expr_to_type(rhs.clone())?;
|
let to = self.module.context.expr_to_type(rhs.clone())?;
|
||||||
Some(guard(var, to))
|
Some(guard(namespace, target, to))
|
||||||
}
|
}
|
||||||
TokenKind::IsOp | TokenKind::DblEq => {
|
TokenKind::IsOp | TokenKind::DblEq => {
|
||||||
let value = self.module.context.expr_to_value(rhs.clone())?;
|
let value = self.module.context.expr_to_value(rhs.clone())?;
|
||||||
Some(guard(var, v_enum(set! { value })))
|
Some(guard(namespace, target, v_enum(set! { value })))
|
||||||
}
|
}
|
||||||
TokenKind::IsNotOp | TokenKind::NotEq => {
|
TokenKind::IsNotOp | TokenKind::NotEq => {
|
||||||
let value = self.module.context.expr_to_value(rhs.clone())?;
|
let value = self.module.context.expr_to_value(rhs.clone())?;
|
||||||
let ty = guard(var, v_enum(set! { value }));
|
let ty = guard(namespace, target, v_enum(set! { value }));
|
||||||
Some(self.module.context.complement(&ty))
|
Some(self.module.context.complement(&ty))
|
||||||
}
|
}
|
||||||
TokenKind::Gre => {
|
TokenKind::Gre => {
|
||||||
|
@ -776,7 +764,7 @@ impl ASTLowerer {
|
||||||
let varname = self.fresh_gen.fresh_varname();
|
let varname = self.fresh_gen.fresh_varname();
|
||||||
let pred = Predicate::gt(varname.clone(), TyParam::value(value));
|
let pred = Predicate::gt(varname.clone(), TyParam::value(value));
|
||||||
let refine = refinement(varname, t, pred);
|
let refine = refinement(varname, t, pred);
|
||||||
Some(guard(var, refine))
|
Some(guard(namespace, target, refine))
|
||||||
}
|
}
|
||||||
TokenKind::GreEq => {
|
TokenKind::GreEq => {
|
||||||
let value = self.module.context.expr_to_value(rhs.clone())?;
|
let value = self.module.context.expr_to_value(rhs.clone())?;
|
||||||
|
@ -784,7 +772,7 @@ impl ASTLowerer {
|
||||||
let varname = self.fresh_gen.fresh_varname();
|
let varname = self.fresh_gen.fresh_varname();
|
||||||
let pred = Predicate::ge(varname.clone(), TyParam::value(value));
|
let pred = Predicate::ge(varname.clone(), TyParam::value(value));
|
||||||
let refine = refinement(varname, t, pred);
|
let refine = refinement(varname, t, pred);
|
||||||
Some(guard(var, refine))
|
Some(guard(namespace, target, refine))
|
||||||
}
|
}
|
||||||
TokenKind::Less => {
|
TokenKind::Less => {
|
||||||
let value = self.module.context.expr_to_value(rhs.clone())?;
|
let value = self.module.context.expr_to_value(rhs.clone())?;
|
||||||
|
@ -792,7 +780,7 @@ impl ASTLowerer {
|
||||||
let varname = self.fresh_gen.fresh_varname();
|
let varname = self.fresh_gen.fresh_varname();
|
||||||
let pred = Predicate::lt(varname.clone(), TyParam::value(value));
|
let pred = Predicate::lt(varname.clone(), TyParam::value(value));
|
||||||
let refine = refinement(varname, t, pred);
|
let refine = refinement(varname, t, pred);
|
||||||
Some(guard(var, refine))
|
Some(guard(namespace, target, refine))
|
||||||
}
|
}
|
||||||
TokenKind::LessEq => {
|
TokenKind::LessEq => {
|
||||||
let value = self.module.context.expr_to_value(rhs.clone())?;
|
let value = self.module.context.expr_to_value(rhs.clone())?;
|
||||||
|
@ -800,7 +788,7 @@ impl ASTLowerer {
|
||||||
let varname = self.fresh_gen.fresh_varname();
|
let varname = self.fresh_gen.fresh_varname();
|
||||||
let pred = Predicate::le(varname.clone(), TyParam::value(value));
|
let pred = Predicate::le(varname.clone(), TyParam::value(value));
|
||||||
let refine = refinement(varname, t, pred);
|
let refine = refinement(varname, t, pred);
|
||||||
Some(guard(var, refine))
|
Some(guard(namespace, target, refine))
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
|
@ -930,7 +918,8 @@ impl ASTLowerer {
|
||||||
}
|
}
|
||||||
1 if kind.is_if() => {
|
1 if kind.is_if() => {
|
||||||
let guard = GuardType::new(
|
let guard = GuardType::new(
|
||||||
guard.var.clone(),
|
guard.namespace.clone(),
|
||||||
|
guard.target.clone(),
|
||||||
self.module.context.complement(&guard.to),
|
self.module.context.complement(&guard.to),
|
||||||
);
|
);
|
||||||
self.module.context.guards.push(guard);
|
self.module.context.guards.push(guard);
|
||||||
|
@ -1015,10 +1004,10 @@ impl ASTLowerer {
|
||||||
} else {
|
} else {
|
||||||
if let hir::Expr::Call(call) = &obj {
|
if let hir::Expr::Call(call) = &obj {
|
||||||
if call.return_t().is_some() {
|
if call.return_t().is_some() {
|
||||||
*obj.ref_mut_t() = vi.t;
|
*obj.ref_mut_t().unwrap() = vi.t;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
*obj.ref_mut_t() = vi.t;
|
*obj.ref_mut_t().unwrap() = vi.t;
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
@ -1964,7 +1953,7 @@ impl ASTLowerer {
|
||||||
) {
|
) {
|
||||||
Err(err) => self.errs.push(err),
|
Err(err) => self.errs.push(err),
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
*attr.ref_mut_t() = derefined.clone();
|
*attr.ref_mut_t().unwrap() = derefined.clone();
|
||||||
if let hir::Accessor::Ident(ident) = &attr {
|
if let hir::Accessor::Ident(ident) = &attr {
|
||||||
if let Some(vi) = self
|
if let Some(vi) = self
|
||||||
.module
|
.module
|
||||||
|
@ -2426,27 +2415,36 @@ impl ASTLowerer {
|
||||||
// so turn off type checking (check=false)
|
// so turn off type checking (check=false)
|
||||||
fn lower_expr(&mut self, expr: ast::Expr) -> LowerResult<hir::Expr> {
|
fn lower_expr(&mut self, expr: ast::Expr) -> LowerResult<hir::Expr> {
|
||||||
log!(info "entered {}", fn_name!());
|
log!(info "entered {}", fn_name!());
|
||||||
match expr {
|
let casted = self.module.context.get_casted_type(&expr);
|
||||||
ast::Expr::Literal(lit) => Ok(hir::Expr::Lit(self.lower_literal(lit)?)),
|
let mut expr = match expr {
|
||||||
ast::Expr::Array(arr) => Ok(hir::Expr::Array(self.lower_array(arr)?)),
|
ast::Expr::Literal(lit) => hir::Expr::Lit(self.lower_literal(lit)?),
|
||||||
ast::Expr::Tuple(tup) => Ok(hir::Expr::Tuple(self.lower_tuple(tup)?)),
|
ast::Expr::Array(arr) => hir::Expr::Array(self.lower_array(arr)?),
|
||||||
ast::Expr::Record(rec) => Ok(hir::Expr::Record(self.lower_record(rec)?)),
|
ast::Expr::Tuple(tup) => hir::Expr::Tuple(self.lower_tuple(tup)?),
|
||||||
ast::Expr::Set(set) => Ok(hir::Expr::Set(self.lower_set(set)?)),
|
ast::Expr::Record(rec) => hir::Expr::Record(self.lower_record(rec)?),
|
||||||
ast::Expr::Dict(dict) => Ok(hir::Expr::Dict(self.lower_dict(dict)?)),
|
ast::Expr::Set(set) => hir::Expr::Set(self.lower_set(set)?),
|
||||||
ast::Expr::Accessor(acc) => Ok(hir::Expr::Accessor(self.lower_acc(acc)?)),
|
ast::Expr::Dict(dict) => hir::Expr::Dict(self.lower_dict(dict)?),
|
||||||
ast::Expr::BinOp(bin) => Ok(hir::Expr::BinOp(self.lower_bin(bin))),
|
ast::Expr::Accessor(acc) => hir::Expr::Accessor(self.lower_acc(acc)?),
|
||||||
ast::Expr::UnaryOp(unary) => Ok(hir::Expr::UnaryOp(self.lower_unary(unary))),
|
ast::Expr::BinOp(bin) => hir::Expr::BinOp(self.lower_bin(bin)),
|
||||||
ast::Expr::Call(call) => Ok(hir::Expr::Call(self.lower_call(call)?)),
|
ast::Expr::UnaryOp(unary) => hir::Expr::UnaryOp(self.lower_unary(unary)),
|
||||||
ast::Expr::DataPack(pack) => Ok(hir::Expr::Call(self.lower_pack(pack)?)),
|
ast::Expr::Call(call) => hir::Expr::Call(self.lower_call(call)?),
|
||||||
ast::Expr::Lambda(lambda) => Ok(hir::Expr::Lambda(self.lower_lambda(lambda)?)),
|
ast::Expr::DataPack(pack) => hir::Expr::Call(self.lower_pack(pack)?),
|
||||||
ast::Expr::TypeAscription(tasc) => Ok(hir::Expr::TypeAsc(self.lower_type_asc(tasc)?)),
|
ast::Expr::Lambda(lambda) => hir::Expr::Lambda(self.lower_lambda(lambda)?),
|
||||||
|
ast::Expr::TypeAscription(tasc) => hir::Expr::TypeAsc(self.lower_type_asc(tasc)?),
|
||||||
// Checking is also performed for expressions in Dummy. However, it has no meaning in code generation
|
// Checking is also performed for expressions in Dummy. However, it has no meaning in code generation
|
||||||
ast::Expr::Dummy(dummy) => Ok(hir::Expr::Dummy(self.lower_dummy(dummy)?)),
|
ast::Expr::Dummy(dummy) => hir::Expr::Dummy(self.lower_dummy(dummy)?),
|
||||||
other => {
|
other => {
|
||||||
log!(err "unreachable: {other}");
|
log!(err "unreachable: {other}");
|
||||||
unreachable_error!(LowerErrors, LowerError, self.module.context)
|
return unreachable_error!(LowerErrors, LowerError, self.module.context);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if let Some(casted) = casted {
|
||||||
|
if self.module.context.subtype_of(&casted, expr.ref_t()) {
|
||||||
|
if let Some(ref_mut_t) = expr.ref_mut_t() {
|
||||||
|
*ref_mut_t = casted;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Ok(expr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The meaning of TypeAscription changes between chunk and expr.
|
/// The meaning of TypeAscription changes between chunk and expr.
|
||||||
|
|
|
@ -210,8 +210,8 @@ impl HasType for CodeObj {
|
||||||
fn ref_t(&self) -> &Type {
|
fn ref_t(&self) -> &Type {
|
||||||
&Type::Code
|
&Type::Code
|
||||||
}
|
}
|
||||||
fn ref_mut_t(&mut self) -> &mut Type {
|
fn ref_mut_t(&mut self) -> Option<&mut Type> {
|
||||||
todo!()
|
None
|
||||||
}
|
}
|
||||||
fn signature_t(&self) -> Option<&Type> {
|
fn signature_t(&self) -> Option<&Type> {
|
||||||
None
|
None
|
||||||
|
|
|
@ -474,8 +474,8 @@ pub fn not(ty: Type) -> Type {
|
||||||
Type::Not(Box::new(ty))
|
Type::Not(Box::new(ty))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn guard(var: Variable, to: Type) -> Type {
|
pub fn guard(namespace: Str, target: CastTarget, to: Type) -> Type {
|
||||||
Type::Guard(GuardType::new(var, to))
|
Type::Guard(GuardType::new(namespace, target, to))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bounded(sub: Type, sup: Type) -> Type {
|
pub fn bounded(sub: Type, sup: Type) -> Type {
|
||||||
|
|
|
@ -31,6 +31,7 @@ use erg_common::set::Set;
|
||||||
use erg_common::traits::{LimitedDisplay, Locational, StructuralEq};
|
use erg_common::traits::{LimitedDisplay, Locational, StructuralEq};
|
||||||
use erg_common::{enum_unwrap, fmt_option, ref_addr_eq, set, Str};
|
use erg_common::{enum_unwrap, fmt_option, ref_addr_eq, set, Str};
|
||||||
|
|
||||||
|
use erg_parser::ast::Expr;
|
||||||
use erg_parser::token::TokenKind;
|
use erg_parser::token::TokenKind;
|
||||||
|
|
||||||
pub use const_subr::*;
|
pub use const_subr::*;
|
||||||
|
@ -59,8 +60,7 @@ pub trait HasType {
|
||||||
// 関数呼び出しの場合、.ref_t()は戻り値を返し、signature_t()は関数全体の型を返す
|
// 関数呼び出しの場合、.ref_t()は戻り値を返し、signature_t()は関数全体の型を返す
|
||||||
fn signature_t(&self) -> Option<&Type>;
|
fn signature_t(&self) -> Option<&Type>;
|
||||||
// 最後にHIR全体の型変数を消すために使う
|
// 最後にHIR全体の型変数を消すために使う
|
||||||
/// `x.ref_mut_t()` may panic, in which case `x` is `Call` and `x.ref_t() == Type::Failure`.
|
fn ref_mut_t(&mut self) -> Option<&mut Type>;
|
||||||
fn ref_mut_t(&mut self) -> &mut Type;
|
|
||||||
fn signature_mut_t(&mut self) -> Option<&mut Type>;
|
fn signature_mut_t(&mut self) -> Option<&mut Type>;
|
||||||
#[inline]
|
#[inline]
|
||||||
fn t(&self) -> Type {
|
fn t(&self) -> Type {
|
||||||
|
@ -89,8 +89,8 @@ macro_rules! impl_t {
|
||||||
&self.t
|
&self.t
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn ref_mut_t(&mut self) -> &mut Type {
|
fn ref_mut_t(&mut self) -> Option<&mut Type> {
|
||||||
&mut self.t
|
Some(&mut self.t)
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn signature_t(&self) -> Option<&Type> {
|
fn signature_t(&self) -> Option<&Type> {
|
||||||
|
@ -109,7 +109,7 @@ macro_rules! impl_t {
|
||||||
&self.$attr.ref_t()
|
&self.$attr.ref_t()
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn ref_mut_t(&mut self) -> &mut Type {
|
fn ref_mut_t(&mut self) -> Option<&mut Type> {
|
||||||
self.$attr.ref_mut_t()
|
self.$attr.ref_mut_t()
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -133,7 +133,7 @@ macro_rules! impl_t_for_enum {
|
||||||
$($Enum::$Variant(v) => v.ref_t(),)*
|
$($Enum::$Variant(v) => v.ref_t(),)*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn ref_mut_t(&mut self) -> &mut Type {
|
fn ref_mut_t(&mut self) -> Option<&mut Type> {
|
||||||
match self {
|
match self {
|
||||||
$($Enum::$Variant(v) => v.ref_mut_t(),)*
|
$($Enum::$Variant(v) => v.ref_mut_t(),)*
|
||||||
}
|
}
|
||||||
|
@ -752,80 +752,74 @@ impl ArgsOwnership {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub enum Variable {
|
pub enum CastTarget {
|
||||||
Param {
|
Param {
|
||||||
nth: usize,
|
nth: usize,
|
||||||
name: Str,
|
name: Str,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
},
|
},
|
||||||
Var {
|
Var {
|
||||||
namespace: Str,
|
|
||||||
name: Str,
|
name: Str,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
},
|
},
|
||||||
Attr {
|
// NOTE: `Expr(Expr)` causes a bad memory access error
|
||||||
receiver: Box<Variable>,
|
Expr(Box<Expr>),
|
||||||
attr: Str,
|
|
||||||
loc: Location,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Variable {
|
impl fmt::Display for CastTarget {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
Self::Param { nth, name, .. } => write!(f, "{name}#{nth}"),
|
Self::Param { nth, name, .. } => write!(f, "{name}#{nth}"),
|
||||||
Self::Var { name, .. } => write!(f, "{name}"),
|
Self::Var { name, .. } => write!(f, "{name}"),
|
||||||
Self::Attr { receiver, attr, .. } => write!(f, "{receiver}.{attr}"),
|
Self::Expr(expr) => write!(f, "{expr}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Locational for Variable {
|
impl Locational for CastTarget {
|
||||||
fn loc(&self) -> Location {
|
fn loc(&self) -> Location {
|
||||||
match self {
|
match self {
|
||||||
Self::Param { loc, .. } => *loc,
|
Self::Param { loc, .. } => *loc,
|
||||||
Self::Var { loc, .. } => *loc,
|
Self::Var { loc, .. } => *loc,
|
||||||
Self::Attr { loc, .. } => *loc,
|
Self::Expr(expr) => expr.loc(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Variable {
|
impl CastTarget {
|
||||||
pub const fn param(nth: usize, name: Str, loc: Location) -> Self {
|
pub const fn param(nth: usize, name: Str, loc: Location) -> Self {
|
||||||
Self::Param { nth, name, loc }
|
Self::Param { nth, name, loc }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn attr(receiver: Variable, attr: Str, loc: Location) -> Self {
|
pub fn expr(expr: Expr) -> Self {
|
||||||
Self::Attr {
|
Self::Expr(Box::new(expr))
|
||||||
receiver: Box::new(receiver),
|
|
||||||
attr,
|
|
||||||
loc,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct GuardType {
|
pub struct GuardType {
|
||||||
pub var: Variable,
|
pub namespace: Str,
|
||||||
|
pub target: CastTarget,
|
||||||
pub to: Box<Type>,
|
pub to: Box<Type>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for GuardType {
|
impl fmt::Display for GuardType {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "{{{} in {}}}", self.var, self.to)
|
write!(f, "{{{} in {}}}", self.target, self.to)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StructuralEq for GuardType {
|
impl StructuralEq for GuardType {
|
||||||
fn structural_eq(&self, other: &Self) -> bool {
|
fn structural_eq(&self, other: &Self) -> bool {
|
||||||
self.var == other.var && self.to.structural_eq(&other.to)
|
self.target == other.target && self.to.structural_eq(&other.to)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GuardType {
|
impl GuardType {
|
||||||
pub fn new(var: Variable, to: Type) -> Self {
|
pub fn new(namespace: Str, target: CastTarget, to: Type) -> Self {
|
||||||
Self {
|
Self {
|
||||||
var,
|
namespace,
|
||||||
|
target,
|
||||||
to: Box::new(to),
|
to: Box::new(to),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1359,8 +1353,8 @@ impl HasType for Type {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn ref_mut_t(&mut self) -> &mut Type {
|
fn ref_mut_t(&mut self) -> Option<&mut Type> {
|
||||||
self
|
Some(self)
|
||||||
}
|
}
|
||||||
fn inner_ts(&self) -> Vec<Type> {
|
fn inner_ts(&self) -> Vec<Type> {
|
||||||
match self {
|
match self {
|
||||||
|
@ -3107,9 +3101,11 @@ impl Type {
|
||||||
proj_call(lhs, attr_name.clone(), args)
|
proj_call(lhs, attr_name.clone(), args)
|
||||||
}
|
}
|
||||||
Self::Structural(ty) => ty.derefine().structuralize(),
|
Self::Structural(ty) => ty.derefine().structuralize(),
|
||||||
Self::Guard(guard) => {
|
Self::Guard(guard) => Self::Guard(GuardType::new(
|
||||||
Self::Guard(GuardType::new(guard.var.clone(), guard.to.derefine()))
|
guard.namespace.clone(),
|
||||||
}
|
guard.target.clone(),
|
||||||
|
guard.to.derefine(),
|
||||||
|
)),
|
||||||
Self::Bounded { sub, sup } => Self::Bounded {
|
Self::Bounded { sub, sup } => Self::Bounded {
|
||||||
sub: Box::new(sub.derefine()),
|
sub: Box::new(sub.derefine()),
|
||||||
sup: Box::new(sup.derefine()),
|
sup: Box::new(sup.derefine()),
|
||||||
|
@ -3253,7 +3249,8 @@ impl Type {
|
||||||
}
|
}
|
||||||
Self::Structural(ty) => ty._replace(target, to).structuralize(),
|
Self::Structural(ty) => ty._replace(target, to).structuralize(),
|
||||||
Self::Guard(guard) => Self::Guard(GuardType::new(
|
Self::Guard(guard) => Self::Guard(GuardType::new(
|
||||||
guard.var.clone(),
|
guard.namespace,
|
||||||
|
guard.target.clone(),
|
||||||
guard.to._replace(target, to),
|
guard.to._replace(target, to),
|
||||||
)),
|
)),
|
||||||
Self::Bounded { sub, sup } => Self::Bounded {
|
Self::Bounded { sub, sup } => Self::Bounded {
|
||||||
|
@ -3315,7 +3312,11 @@ impl Type {
|
||||||
Self::Or(l, r) => l.normalize() | r.normalize(),
|
Self::Or(l, r) => l.normalize() | r.normalize(),
|
||||||
Self::Not(ty) => !ty.normalize(),
|
Self::Not(ty) => !ty.normalize(),
|
||||||
Self::Structural(ty) => ty.normalize().structuralize(),
|
Self::Structural(ty) => ty.normalize().structuralize(),
|
||||||
Self::Guard(guard) => Self::Guard(GuardType::new(guard.var, guard.to.normalize())),
|
Self::Guard(guard) => Self::Guard(GuardType::new(
|
||||||
|
guard.namespace,
|
||||||
|
guard.target,
|
||||||
|
guard.to.normalize(),
|
||||||
|
)),
|
||||||
Self::Bounded { sub, sup } => Self::Bounded {
|
Self::Bounded { sub, sup } => Self::Bounded {
|
||||||
sub: Box::new(sub.normalize()),
|
sub: Box::new(sub.normalize()),
|
||||||
sup: Box::new(sup.normalize()),
|
sup: Box::new(sup.normalize()),
|
||||||
|
|
|
@ -880,8 +880,8 @@ impl HasType for ValueObj {
|
||||||
fn ref_t(&self) -> &Type {
|
fn ref_t(&self) -> &Type {
|
||||||
panic!("cannot get reference of the const")
|
panic!("cannot get reference of the const")
|
||||||
}
|
}
|
||||||
fn ref_mut_t(&mut self) -> &mut Type {
|
fn ref_mut_t(&mut self) -> Option<&mut Type> {
|
||||||
panic!("cannot get mutable reference of the const")
|
None
|
||||||
}
|
}
|
||||||
/// その要素だけの集合型を返す、クラスが欲しい場合は.classで
|
/// その要素だけの集合型を返す、クラスが欲しい場合は.classで
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -216,8 +216,8 @@ impl HasType for VarInfo {
|
||||||
&self.t
|
&self.t
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn ref_mut_t(&mut self) -> &mut Type {
|
fn ref_mut_t(&mut self) -> Option<&mut Type> {
|
||||||
&mut self.t
|
Some(&mut self.t)
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn signature_t(&self) -> Option<&Type> {
|
fn signature_t(&self) -> Option<&Type> {
|
||||||
|
|
|
@ -10,3 +10,8 @@ j = json.loads "{ \"a\": [1] }"
|
||||||
assert j in {Str: Obj}
|
assert j in {Str: Obj}
|
||||||
assert j["a"] in Array(Int)
|
assert j["a"] in Array(Int)
|
||||||
assert j["a"] notin Array(Str)
|
assert j["a"] notin Array(Str)
|
||||||
|
_: Array(Int) = j["a"]
|
||||||
|
|
||||||
|
.f dic: {Str: Str or Array(Str)} =
|
||||||
|
assert dic["key"] in Str # Required to pass the check on the next line
|
||||||
|
assert dic["key"] in {"a", "b", "c"}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue