mirror of
https://github.com/erg-lang/erg.git
synced 2025-10-03 05:54:33 +00:00
Fix sub_unify with class&trait
This commit is contained in:
parent
57da071ba8
commit
08e501f103
9 changed files with 60 additions and 39 deletions
|
@ -20,7 +20,7 @@ use Type::*;
|
||||||
|
|
||||||
use crate::context::cache::{SubtypePair, GLOBAL_TYPE_CACHE};
|
use crate::context::cache::{SubtypePair, GLOBAL_TYPE_CACHE};
|
||||||
use crate::context::eval::SubstContext;
|
use crate::context::eval::SubstContext;
|
||||||
use crate::context::instantiate::TyVarContext;
|
use crate::context::instantiate::TyVarInstContext;
|
||||||
use crate::context::{Context, TraitInstance, Variance};
|
use crate::context::{Context, TraitInstance, Variance};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
|
@ -619,8 +619,8 @@ impl Context {
|
||||||
}
|
}
|
||||||
(Quantified(l), Quantified(r)) => {
|
(Quantified(l), Quantified(r)) => {
|
||||||
// REVIEW: maybe this should be `unreachable`
|
// REVIEW: maybe this should be `unreachable`
|
||||||
let l_tv_ctx = TyVarContext::new(self.level, l.bounds.clone(), self);
|
let l_tv_ctx = TyVarInstContext::new(self.level, l.bounds.clone(), self);
|
||||||
let r_tv_ctx = TyVarContext::new(self.level, r.bounds.clone(), self);
|
let r_tv_ctx = TyVarInstContext::new(self.level, r.bounds.clone(), self);
|
||||||
let l_callable = self
|
let l_callable = self
|
||||||
.instantiate_t(
|
.instantiate_t(
|
||||||
l.unbound_callable.as_ref().clone(),
|
l.unbound_callable.as_ref().clone(),
|
||||||
|
@ -639,7 +639,7 @@ impl Context {
|
||||||
}
|
}
|
||||||
(Quantified(q), r) => {
|
(Quantified(q), r) => {
|
||||||
// REVIEW: maybe this should be `unreachable`
|
// REVIEW: maybe this should be `unreachable`
|
||||||
let tmp_tv_ctx = TyVarContext::new(self.level, q.bounds.clone(), self);
|
let tmp_tv_ctx = TyVarInstContext::new(self.level, q.bounds.clone(), self);
|
||||||
let q_callable = self
|
let q_callable = self
|
||||||
.instantiate_t(
|
.instantiate_t(
|
||||||
q.unbound_callable.as_ref().clone(),
|
q.unbound_callable.as_ref().clone(),
|
||||||
|
|
|
@ -24,7 +24,7 @@ use crate::ty::typaram::{OpKind, TyParam};
|
||||||
use crate::ty::value::ValueObj;
|
use crate::ty::value::ValueObj;
|
||||||
use crate::ty::{ConstSubr, HasType, Predicate, SubrKind, TyBound, Type, UserConstSubr, ValueArgs};
|
use crate::ty::{ConstSubr, HasType, Predicate, SubrKind, TyBound, Type, UserConstSubr, ValueArgs};
|
||||||
|
|
||||||
use crate::context::instantiate::TyVarContext;
|
use crate::context::instantiate::TyVarInstContext;
|
||||||
use crate::context::{ClassDefType, Context, ContextKind, RegistrationMode};
|
use crate::context::{ClassDefType, Context, ContextKind, RegistrationMode};
|
||||||
use crate::error::{EvalError, EvalErrors, EvalResult, SingleEvalResult, TyCheckResult};
|
use crate::error::{EvalError, EvalErrors, EvalResult, SingleEvalResult, TyCheckResult};
|
||||||
|
|
||||||
|
@ -172,7 +172,7 @@ impl<'c> SubstContext<'c> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn substitute(&self, quant_t: Type) -> TyCheckResult<Type> {
|
pub fn substitute(&self, quant_t: Type) -> TyCheckResult<Type> {
|
||||||
let tv_ctx = TyVarContext::new(self.ctx.level, self.bounds.clone(), self.ctx);
|
let tv_ctx = TyVarInstContext::new(self.ctx.level, self.bounds.clone(), self.ctx);
|
||||||
let inst = self.ctx.instantiate_t(quant_t, &tv_ctx, self.loc)?;
|
let inst = self.ctx.instantiate_t(quant_t, &tv_ctx, self.loc)?;
|
||||||
for param in inst.typarams() {
|
for param in inst.typarams() {
|
||||||
self.substitute_tp(¶m)?;
|
self.substitute_tp(¶m)?;
|
||||||
|
@ -425,7 +425,7 @@ impl Context {
|
||||||
Signature::Subr(subr) => {
|
Signature::Subr(subr) => {
|
||||||
let bounds =
|
let bounds =
|
||||||
self.instantiate_ty_bounds(&subr.bounds, RegistrationMode::Normal)?;
|
self.instantiate_ty_bounds(&subr.bounds, RegistrationMode::Normal)?;
|
||||||
Some(TyVarContext::new(self.level, bounds, self))
|
Some(TyVarInstContext::new(self.level, bounds, self))
|
||||||
}
|
}
|
||||||
Signature::Var(_) => None,
|
Signature::Var(_) => None,
|
||||||
};
|
};
|
||||||
|
@ -507,7 +507,7 @@ impl Context {
|
||||||
/// FIXME: grow
|
/// FIXME: grow
|
||||||
fn eval_const_lambda(&self, lambda: &Lambda) -> EvalResult<ValueObj> {
|
fn eval_const_lambda(&self, lambda: &Lambda) -> EvalResult<ValueObj> {
|
||||||
let bounds = self.instantiate_ty_bounds(&lambda.sig.bounds, RegistrationMode::Normal)?;
|
let bounds = self.instantiate_ty_bounds(&lambda.sig.bounds, RegistrationMode::Normal)?;
|
||||||
let tv_ctx = TyVarContext::new(self.level, bounds, self);
|
let tv_ctx = TyVarInstContext::new(self.level, bounds, self);
|
||||||
let mut non_default_params = Vec::with_capacity(lambda.sig.params.non_defaults.len());
|
let mut non_default_params = Vec::with_capacity(lambda.sig.params.non_defaults.len());
|
||||||
for sig in lambda.sig.params.non_defaults.iter() {
|
for sig in lambda.sig.params.non_defaults.iter() {
|
||||||
let pt =
|
let pt =
|
||||||
|
|
|
@ -1397,6 +1397,11 @@ impl Context {
|
||||||
Some(vec![ctx].into_iter().chain(sups))
|
Some(vec![ctx].into_iter().chain(sups))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn _get_super_traits(&self, typ: &Type) -> Option<impl Iterator<Item = Type>> {
|
||||||
|
self.get_nominal_type_ctx(typ)
|
||||||
|
.map(|ctx| ctx.super_traits.clone().into_iter())
|
||||||
|
}
|
||||||
|
|
||||||
/// if `typ` is a refinement type, include the base type (refine.t)
|
/// if `typ` is a refinement type, include the base type (refine.t)
|
||||||
pub(crate) fn get_super_classes(&self, typ: &Type) -> Option<impl Iterator<Item = Type>> {
|
pub(crate) fn get_super_classes(&self, typ: &Type) -> Option<impl Iterator<Item = Type>> {
|
||||||
self.get_nominal_type_ctx(typ).map(|ctx| {
|
self.get_nominal_type_ctx(typ).map(|ctx| {
|
||||||
|
|
|
@ -33,23 +33,23 @@ use RegistrationMode::*;
|
||||||
/// Context for instantiating a quantified type
|
/// Context for instantiating a quantified type
|
||||||
/// 量化型をインスタンス化するための文脈
|
/// 量化型をインスタンス化するための文脈
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct TyVarContext {
|
pub struct TyVarInstContext {
|
||||||
level: usize,
|
level: usize,
|
||||||
pub(crate) tyvar_instances: Dict<Str, Type>,
|
pub(crate) tyvar_instances: Dict<Str, Type>,
|
||||||
pub(crate) typaram_instances: Dict<Str, TyParam>,
|
pub(crate) typaram_instances: Dict<Str, TyParam>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for TyVarContext {
|
impl fmt::Display for TyVarInstContext {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"TyVarContext {{ tyvar_instances: {}, typaram_instances: {} }}",
|
"TyVarInstContext {{ tyvar_instances: {}, typaram_instances: {} }}",
|
||||||
self.tyvar_instances, self.typaram_instances,
|
self.tyvar_instances, self.typaram_instances,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TyVarContext {
|
impl TyVarInstContext {
|
||||||
pub fn new(level: usize, bounds: Set<TyBound>, ctx: &Context) -> Self {
|
pub fn new(level: usize, bounds: Set<TyBound>, ctx: &Context) -> Self {
|
||||||
let mut self_ = Self {
|
let mut self_ = Self {
|
||||||
level,
|
level,
|
||||||
|
@ -509,7 +509,7 @@ impl Context {
|
||||||
.ok()
|
.ok()
|
||||||
.map(|t| enum_unwrap!(t, Type::Subr));
|
.map(|t| enum_unwrap!(t, Type::Subr));
|
||||||
let bounds = self.instantiate_ty_bounds(&sig.bounds, PreRegister)?;
|
let bounds = self.instantiate_ty_bounds(&sig.bounds, PreRegister)?;
|
||||||
let tv_ctx = TyVarContext::new(self.level, bounds, self);
|
let tv_ctx = TyVarInstContext::new(self.level, bounds, self);
|
||||||
let mut non_defaults = vec![];
|
let mut non_defaults = vec![];
|
||||||
for (n, p) in sig.params.non_defaults.iter().enumerate() {
|
for (n, p) in sig.params.non_defaults.iter().enumerate() {
|
||||||
let opt_decl_t = opt_decl_sig_t
|
let opt_decl_t = opt_decl_sig_t
|
||||||
|
@ -558,7 +558,7 @@ impl Context {
|
||||||
&self,
|
&self,
|
||||||
sig: &ParamSignature,
|
sig: &ParamSignature,
|
||||||
opt_decl_t: Option<&ParamTy>,
|
opt_decl_t: Option<&ParamTy>,
|
||||||
tmp_tv_ctx: Option<&TyVarContext>,
|
tmp_tv_ctx: Option<&TyVarInstContext>,
|
||||||
mode: RegistrationMode,
|
mode: RegistrationMode,
|
||||||
) -> TyCheckResult<Type> {
|
) -> TyCheckResult<Type> {
|
||||||
let spec_t = if let Some(spec_with_op) = &sig.t_spec {
|
let spec_t = if let Some(spec_with_op) = &sig.t_spec {
|
||||||
|
@ -595,7 +595,7 @@ impl Context {
|
||||||
&self,
|
&self,
|
||||||
sig: &ParamSignature,
|
sig: &ParamSignature,
|
||||||
opt_decl_t: Option<&ParamTy>,
|
opt_decl_t: Option<&ParamTy>,
|
||||||
tmp_tv_ctx: Option<&TyVarContext>,
|
tmp_tv_ctx: Option<&TyVarInstContext>,
|
||||||
mode: RegistrationMode,
|
mode: RegistrationMode,
|
||||||
) -> TyCheckResult<ParamTy> {
|
) -> TyCheckResult<ParamTy> {
|
||||||
let t = self.instantiate_param_sig_t(sig, opt_decl_t, tmp_tv_ctx, mode)?;
|
let t = self.instantiate_param_sig_t(sig, opt_decl_t, tmp_tv_ctx, mode)?;
|
||||||
|
@ -618,7 +618,7 @@ impl Context {
|
||||||
&self,
|
&self,
|
||||||
predecl: &PreDeclTypeSpec,
|
predecl: &PreDeclTypeSpec,
|
||||||
opt_decl_t: Option<&ParamTy>,
|
opt_decl_t: Option<&ParamTy>,
|
||||||
tmp_tv_ctx: Option<&TyVarContext>,
|
tmp_tv_ctx: Option<&TyVarInstContext>,
|
||||||
) -> TyCheckResult<Type> {
|
) -> TyCheckResult<Type> {
|
||||||
match predecl {
|
match predecl {
|
||||||
ast::PreDeclTypeSpec::Simple(simple) => {
|
ast::PreDeclTypeSpec::Simple(simple) => {
|
||||||
|
@ -632,7 +632,7 @@ impl Context {
|
||||||
&self,
|
&self,
|
||||||
simple: &SimpleTypeSpec,
|
simple: &SimpleTypeSpec,
|
||||||
opt_decl_t: Option<&ParamTy>,
|
opt_decl_t: Option<&ParamTy>,
|
||||||
tmp_tv_ctx: Option<&TyVarContext>,
|
tmp_tv_ctx: Option<&TyVarInstContext>,
|
||||||
) -> TyCheckResult<Type> {
|
) -> TyCheckResult<Type> {
|
||||||
match &simple.name.inspect()[..] {
|
match &simple.name.inspect()[..] {
|
||||||
"_" | "Obj" => Ok(Type::Obj),
|
"_" | "Obj" => Ok(Type::Obj),
|
||||||
|
@ -740,7 +740,7 @@ impl Context {
|
||||||
&self,
|
&self,
|
||||||
p: &ParamTySpec,
|
p: &ParamTySpec,
|
||||||
opt_decl_t: Option<&ParamTy>,
|
opt_decl_t: Option<&ParamTy>,
|
||||||
tmp_tv_ctx: Option<&TyVarContext>,
|
tmp_tv_ctx: Option<&TyVarInstContext>,
|
||||||
mode: RegistrationMode,
|
mode: RegistrationMode,
|
||||||
) -> TyCheckResult<ParamTy> {
|
) -> TyCheckResult<ParamTy> {
|
||||||
let t = self.instantiate_typespec(&p.ty, opt_decl_t, tmp_tv_ctx, mode)?;
|
let t = self.instantiate_typespec(&p.ty, opt_decl_t, tmp_tv_ctx, mode)?;
|
||||||
|
@ -754,7 +754,7 @@ impl Context {
|
||||||
&self,
|
&self,
|
||||||
spec: &TypeSpec,
|
spec: &TypeSpec,
|
||||||
opt_decl_t: Option<&ParamTy>,
|
opt_decl_t: Option<&ParamTy>,
|
||||||
tmp_tv_ctx: Option<&TyVarContext>,
|
tmp_tv_ctx: Option<&TyVarInstContext>,
|
||||||
mode: RegistrationMode,
|
mode: RegistrationMode,
|
||||||
) -> TyCheckResult<Type> {
|
) -> TyCheckResult<Type> {
|
||||||
match spec {
|
match spec {
|
||||||
|
@ -897,7 +897,7 @@ impl Context {
|
||||||
fn instantiate_tp(
|
fn instantiate_tp(
|
||||||
&self,
|
&self,
|
||||||
quantified: TyParam,
|
quantified: TyParam,
|
||||||
tmp_tv_ctx: &TyVarContext,
|
tmp_tv_ctx: &TyVarInstContext,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
) -> TyCheckResult<TyParam> {
|
) -> TyCheckResult<TyParam> {
|
||||||
match quantified {
|
match quantified {
|
||||||
|
@ -950,7 +950,7 @@ impl Context {
|
||||||
// K('U) -> K(?U)
|
// K('U) -> K(?U)
|
||||||
else {
|
else {
|
||||||
let ctx = self.get_nominal_type_ctx(&t).unwrap();
|
let ctx = self.get_nominal_type_ctx(&t).unwrap();
|
||||||
let tv_ctx = TyVarContext::new(self.level, ctx.bounds(), self);
|
let tv_ctx = TyVarInstContext::new(self.level, ctx.bounds(), self);
|
||||||
let t = self.instantiate_t(*t, &tv_ctx, loc)?;
|
let t = self.instantiate_t(*t, &tv_ctx, loc)?;
|
||||||
Ok(TyParam::t(t))
|
Ok(TyParam::t(t))
|
||||||
}
|
}
|
||||||
|
@ -970,7 +970,7 @@ impl Context {
|
||||||
pub(crate) fn instantiate_t(
|
pub(crate) fn instantiate_t(
|
||||||
&self,
|
&self,
|
||||||
unbound: Type,
|
unbound: Type,
|
||||||
tmp_tv_ctx: &TyVarContext,
|
tmp_tv_ctx: &TyVarInstContext,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
) -> TyCheckResult<Type> {
|
) -> TyCheckResult<Type> {
|
||||||
match unbound {
|
match unbound {
|
||||||
|
@ -1121,7 +1121,7 @@ impl Context {
|
||||||
pub(crate) fn instantiate(&self, quantified: Type, callee: &hir::Expr) -> TyCheckResult<Type> {
|
pub(crate) fn instantiate(&self, quantified: Type, callee: &hir::Expr) -> TyCheckResult<Type> {
|
||||||
match quantified {
|
match quantified {
|
||||||
Quantified(quant) => {
|
Quantified(quant) => {
|
||||||
let tmp_tv_ctx = TyVarContext::new(self.level, quant.bounds, self);
|
let tmp_tv_ctx = TyVarInstContext::new(self.level, quant.bounds, self);
|
||||||
let t = self.instantiate_t(*quant.unbound_callable, &tmp_tv_ctx, callee.loc())?;
|
let t = self.instantiate_t(*quant.unbound_callable, &tmp_tv_ctx, callee.loc())?;
|
||||||
match &t {
|
match &t {
|
||||||
Type::Subr(subr) => {
|
Type::Subr(subr) => {
|
||||||
|
@ -1141,7 +1141,7 @@ impl Context {
|
||||||
// HACK: {op: |T|(T -> T) | op == F} => ?T -> ?T
|
// HACK: {op: |T|(T -> T) | op == F} => ?T -> ?T
|
||||||
Refinement(refine) if refine.t.is_quantified() => {
|
Refinement(refine) if refine.t.is_quantified() => {
|
||||||
let quant = enum_unwrap!(*refine.t, Type::Quantified);
|
let quant = enum_unwrap!(*refine.t, Type::Quantified);
|
||||||
let tmp_tv_ctx = TyVarContext::new(self.level, quant.bounds, self);
|
let tmp_tv_ctx = TyVarInstContext::new(self.level, quant.bounds, self);
|
||||||
let t = self.instantiate_t(*quant.unbound_callable, &tmp_tv_ctx, callee.loc())?;
|
let t = self.instantiate_t(*quant.unbound_callable, &tmp_tv_ctx, callee.loc())?;
|
||||||
match &t {
|
match &t {
|
||||||
Type::Subr(subr) => {
|
Type::Subr(subr) => {
|
||||||
|
|
|
@ -39,7 +39,7 @@ use ast::{DefId, VarName};
|
||||||
use erg_parser::ast;
|
use erg_parser::ast;
|
||||||
use erg_parser::token::Token;
|
use erg_parser::token::Token;
|
||||||
|
|
||||||
use crate::context::instantiate::{ConstTemplate, TyVarContext};
|
use crate::context::instantiate::{ConstTemplate, TyVarInstContext};
|
||||||
use crate::error::{SingleTyCheckResult, TyCheckError, TyCheckErrors, TyCheckResult};
|
use crate::error::{SingleTyCheckResult, TyCheckError, TyCheckErrors, TyCheckResult};
|
||||||
use crate::mod_cache::SharedModuleCache;
|
use crate::mod_cache::SharedModuleCache;
|
||||||
use crate::varinfo::{Mutability, ParamIdx, VarInfo, VarKind};
|
use crate::varinfo::{Mutability, ParamIdx, VarInfo, VarKind};
|
||||||
|
@ -380,7 +380,7 @@ pub struct Context {
|
||||||
pub(crate) patches: Dict<VarName, Context>,
|
pub(crate) patches: Dict<VarName, Context>,
|
||||||
pub(crate) mod_cache: Option<SharedModuleCache>,
|
pub(crate) mod_cache: Option<SharedModuleCache>,
|
||||||
pub(crate) py_mod_cache: Option<SharedModuleCache>,
|
pub(crate) py_mod_cache: Option<SharedModuleCache>,
|
||||||
pub(crate) tv_ctx: Option<TyVarContext>,
|
pub(crate) tv_ctx: Option<TyVarInstContext>,
|
||||||
pub(crate) level: usize,
|
pub(crate) level: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -840,7 +840,7 @@ impl Context {
|
||||||
name: &str,
|
name: &str,
|
||||||
kind: ContextKind,
|
kind: ContextKind,
|
||||||
vis: Visibility,
|
vis: Visibility,
|
||||||
tv_ctx: Option<TyVarContext>,
|
tv_ctx: Option<TyVarInstContext>,
|
||||||
) -> TyCheckResult<()> {
|
) -> TyCheckResult<()> {
|
||||||
let name = if vis.is_public() {
|
let name = if vis.is_public() {
|
||||||
format!("{parent}.{name}", parent = self.name)
|
format!("{parent}.{name}", parent = self.name)
|
||||||
|
|
|
@ -34,7 +34,7 @@ use Mutability::*;
|
||||||
use RegistrationMode::*;
|
use RegistrationMode::*;
|
||||||
use Visibility::*;
|
use Visibility::*;
|
||||||
|
|
||||||
use super::instantiate::TyVarContext;
|
use super::instantiate::TyVarInstContext;
|
||||||
use super::OperationKind;
|
use super::OperationKind;
|
||||||
|
|
||||||
impl Context {
|
impl Context {
|
||||||
|
@ -517,7 +517,7 @@ impl Context {
|
||||||
ast::Signature::Subr(sig) => {
|
ast::Signature::Subr(sig) => {
|
||||||
if sig.is_const() {
|
if sig.is_const() {
|
||||||
let bounds = self.instantiate_ty_bounds(&sig.bounds, PreRegister)?;
|
let bounds = self.instantiate_ty_bounds(&sig.bounds, PreRegister)?;
|
||||||
let tv_ctx = TyVarContext::new(self.level, bounds, self);
|
let tv_ctx = TyVarInstContext::new(self.level, bounds, self);
|
||||||
let vis = def.sig.vis();
|
let vis = def.sig.vis();
|
||||||
self.grow(__name__, ContextKind::Proc, vis, Some(tv_ctx))?;
|
self.grow(__name__, ContextKind::Proc, vis, Some(tv_ctx))?;
|
||||||
let (obj, const_t) = match self.eval_const_block(&def.body.block) {
|
let (obj, const_t) = match self.eval_const_block(&def.body.block) {
|
||||||
|
|
|
@ -9,7 +9,7 @@ use crate::ty::typaram::TyParam;
|
||||||
use crate::ty::{Predicate, TyBound, Type};
|
use crate::ty::{Predicate, TyBound, Type};
|
||||||
use Type::*;
|
use Type::*;
|
||||||
|
|
||||||
use crate::context::instantiate::TyVarContext;
|
use crate::context::instantiate::TyVarInstContext;
|
||||||
use crate::context::Context;
|
use crate::context::Context;
|
||||||
|
|
||||||
impl Context {
|
impl Context {
|
||||||
|
@ -54,7 +54,7 @@ impl Context {
|
||||||
let unbound_t = func1(t.clone(), t);
|
let unbound_t = func1(t.clone(), t);
|
||||||
let quantified = quant(unbound_t.clone(), bounds.clone());
|
let quantified = quant(unbound_t.clone(), bounds.clone());
|
||||||
println!("quantified : {quantified}");
|
println!("quantified : {quantified}");
|
||||||
let tv_ctx = TyVarContext::new(self.level + 1, bounds, self);
|
let tv_ctx = TyVarInstContext::new(self.level + 1, bounds, self);
|
||||||
println!("tv_ctx: {tv_ctx}");
|
println!("tv_ctx: {tv_ctx}");
|
||||||
let inst = self
|
let inst = self
|
||||||
.instantiate_t(unbound_t, &tv_ctx, Location::Unknown)
|
.instantiate_t(unbound_t, &tv_ctx, Location::Unknown)
|
||||||
|
|
|
@ -15,8 +15,7 @@ use crate::ty::value::ValueObj;
|
||||||
use crate::ty::{HasType, Predicate, TyBound, Type};
|
use crate::ty::{HasType, Predicate, TyBound, Type};
|
||||||
|
|
||||||
use crate::context::eval::SubstContext;
|
use crate::context::eval::SubstContext;
|
||||||
use crate::context::{Context, TyVarContext, Variance};
|
use crate::context::{Context, TyVarInstContext, Variance};
|
||||||
// use crate::context::instantiate::TyVarContext;
|
|
||||||
use crate::error::{SingleTyCheckResult, TyCheckError, TyCheckErrors, TyCheckResult};
|
use crate::error::{SingleTyCheckResult, TyCheckError, TyCheckErrors, TyCheckResult};
|
||||||
use crate::hir;
|
use crate::hir;
|
||||||
|
|
||||||
|
@ -81,7 +80,7 @@ impl Context {
|
||||||
// NOTE: `?T(<: TraitX) -> Int` should be `TraitX -> Int`
|
// NOTE: `?T(<: TraitX) -> Int` should be `TraitX -> Int`
|
||||||
// However, the current Erg cannot handle existential types, so it quantifies anyway
|
// However, the current Erg cannot handle existential types, so it quantifies anyway
|
||||||
/*if !maybe_unbound_t.return_t().unwrap().has_qvar() {
|
/*if !maybe_unbound_t.return_t().unwrap().has_qvar() {
|
||||||
let mut tv_ctx = TyVarContext::new(self.level, bounds.clone(), self);
|
let mut tv_ctx = TyVarInstContext::new(self.level, bounds.clone(), self);
|
||||||
let inst = Self::instantiate_t(
|
let inst = Self::instantiate_t(
|
||||||
maybe_unbound_t,
|
maybe_unbound_t,
|
||||||
&mut tv_ctx,
|
&mut tv_ctx,
|
||||||
|
@ -532,7 +531,7 @@ impl Context {
|
||||||
for inst in self.get_trait_impls(trait_).into_iter() {
|
for inst in self.get_trait_impls(trait_).into_iter() {
|
||||||
let sub_type = if inst.sub_type.has_qvar() {
|
let sub_type = if inst.sub_type.has_qvar() {
|
||||||
let sub_ctx = self.get_nominal_type_ctx(&inst.sub_type).unwrap();
|
let sub_ctx = self.get_nominal_type_ctx(&inst.sub_type).unwrap();
|
||||||
let tv_ctx = TyVarContext::new(self.level, sub_ctx.bounds(), self);
|
let tv_ctx = TyVarInstContext::new(self.level, sub_ctx.bounds(), self);
|
||||||
self.instantiate_t(inst.sub_type, &tv_ctx, Location::Unknown)
|
self.instantiate_t(inst.sub_type, &tv_ctx, Location::Unknown)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
} else {
|
} else {
|
||||||
|
@ -540,7 +539,7 @@ impl Context {
|
||||||
};
|
};
|
||||||
let sup_trait = if inst.sup_trait.has_qvar() {
|
let sup_trait = if inst.sup_trait.has_qvar() {
|
||||||
let sup_ctx = self.get_nominal_type_ctx(&inst.sup_trait).unwrap();
|
let sup_ctx = self.get_nominal_type_ctx(&inst.sup_trait).unwrap();
|
||||||
let tv_ctx = TyVarContext::new(self.level, sup_ctx.bounds(), self);
|
let tv_ctx = TyVarInstContext::new(self.level, sup_ctx.bounds(), self);
|
||||||
self.instantiate_t(inst.sup_trait, &tv_ctx, Location::Unknown)
|
self.instantiate_t(inst.sup_trait, &tv_ctx, Location::Unknown)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
} else {
|
} else {
|
||||||
|
@ -1470,7 +1469,24 @@ impl Context {
|
||||||
params: rps,
|
params: rps,
|
||||||
},
|
},
|
||||||
) => {
|
) => {
|
||||||
|
// e.g. Set(?T) <: Eq(Set(?T))
|
||||||
if ln != rn {
|
if ln != rn {
|
||||||
|
if let Some(sub_ctx) = self.get_nominal_type_ctx(maybe_sub) {
|
||||||
|
let subst_ctx = SubstContext::new(maybe_sub, self, loc);
|
||||||
|
for sup_trait in sub_ctx.super_traits.iter() {
|
||||||
|
let sup_trait = if sup_trait.has_qvar() {
|
||||||
|
subst_ctx.substitute(sup_trait.clone())?
|
||||||
|
} else {
|
||||||
|
sup_trait.clone()
|
||||||
|
};
|
||||||
|
if self.supertype_of(maybe_sup, &sup_trait) {
|
||||||
|
for (l_maybe_sub, r_maybe_sup) in sup_trait.typarams().iter().zip(rps.iter()) {
|
||||||
|
self.sub_unify_tp(l_maybe_sub, r_maybe_sup, None, loc, false)?;
|
||||||
|
}
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return Err(TyCheckErrors::from(TyCheckError::unification_error(
|
return Err(TyCheckErrors::from(TyCheckError::unification_error(
|
||||||
self.cfg.input.clone(),
|
self.cfg.input.clone(),
|
||||||
line!() as usize,
|
line!() as usize,
|
||||||
|
|
|
@ -26,7 +26,7 @@ use crate::ty::typaram::TyParam;
|
||||||
use crate::ty::value::{GenTypeObj, TypeKind, TypeObj, ValueObj};
|
use crate::ty::value::{GenTypeObj, TypeKind, TypeObj, ValueObj};
|
||||||
use crate::ty::{HasType, ParamTy, Type};
|
use crate::ty::{HasType, ParamTy, Type};
|
||||||
|
|
||||||
use crate::context::instantiate::TyVarContext;
|
use crate::context::instantiate::TyVarInstContext;
|
||||||
use crate::context::{
|
use crate::context::{
|
||||||
ClassDefType, Context, ContextKind, OperationKind, RegistrationMode, TraitInstance,
|
ClassDefType, Context, ContextKind, OperationKind, RegistrationMode, TraitInstance,
|
||||||
};
|
};
|
||||||
|
@ -785,7 +785,7 @@ impl ASTLowerer {
|
||||||
let bounds = self
|
let bounds = self
|
||||||
.ctx
|
.ctx
|
||||||
.instantiate_ty_bounds(&lambda.sig.bounds, RegistrationMode::Normal)?;
|
.instantiate_ty_bounds(&lambda.sig.bounds, RegistrationMode::Normal)?;
|
||||||
let tv_ctx = TyVarContext::new(self.ctx.level, bounds, &self.ctx);
|
let tv_ctx = TyVarInstContext::new(self.ctx.level, bounds, &self.ctx);
|
||||||
self.ctx.grow(&name, kind, Private, Some(tv_ctx))?;
|
self.ctx.grow(&name, kind, Private, Some(tv_ctx))?;
|
||||||
if let Err(errs) = self.ctx.assign_params(&lambda.sig.params, None) {
|
if let Err(errs) = self.ctx.assign_params(&lambda.sig.params, None) {
|
||||||
self.errs.extend(errs.into_iter());
|
self.errs.extend(errs.into_iter());
|
||||||
|
@ -869,7 +869,7 @@ impl ASTLowerer {
|
||||||
let bounds = self
|
let bounds = self
|
||||||
.ctx
|
.ctx
|
||||||
.instantiate_ty_bounds(&sig.bounds, RegistrationMode::Normal)?;
|
.instantiate_ty_bounds(&sig.bounds, RegistrationMode::Normal)?;
|
||||||
let tv_ctx = TyVarContext::new(self.ctx.level, bounds, &self.ctx);
|
let tv_ctx = TyVarInstContext::new(self.ctx.level, bounds, &self.ctx);
|
||||||
self.ctx.grow(&name, kind, vis, Some(tv_ctx))?;
|
self.ctx.grow(&name, kind, vis, Some(tv_ctx))?;
|
||||||
self.lower_subr_def(sig, def.body)
|
self.lower_subr_def(sig, def.body)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue