mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-28 20:14:45 +00:00
fix: nested module bug
This commit is contained in:
parent
20b1993714
commit
a6e7a39753
8 changed files with 62 additions and 28 deletions
|
@ -46,6 +46,13 @@ impl PartialEq<str> for Str {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PartialEq<&str> for Str {
|
||||||
|
#[inline]
|
||||||
|
fn eq(&self, other: &&str) -> bool {
|
||||||
|
self[..] == other[..]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl PartialEq<String> for Str {
|
impl PartialEq<String> for Str {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn eq(&self, other: &String) -> bool {
|
fn eq(&self, other: &String) -> bool {
|
||||||
|
|
|
@ -205,7 +205,7 @@ impl Context {
|
||||||
.or_else(|| self.get_param_kv(name))
|
.or_else(|| self.get_param_kv(name))
|
||||||
.or_else(|| self.decls.get_key_value(name))
|
.or_else(|| self.decls.get_key_value(name))
|
||||||
.or_else(|| self.future_defined_locals.get_key_value(name))
|
.or_else(|| self.future_defined_locals.get_key_value(name))
|
||||||
.or_else(|| self.get_outer().and_then(|ctx| ctx.get_var_kv(name)))
|
.or_else(|| self.get_outer_scope().and_then(|ctx| ctx.get_var_kv(name)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_param_kv(&self, name: &str) -> Option<(&VarName, &VarInfo)> {
|
fn get_param_kv(&self, name: &str) -> Option<(&VarName, &VarInfo)> {
|
||||||
|
@ -234,7 +234,10 @@ impl Context {
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
})
|
})
|
||||||
.or_else(|| self.get_outer().and_then(|ctx| ctx.get_method_kv(name)))
|
.or_else(|| {
|
||||||
|
self.get_outer_scope()
|
||||||
|
.and_then(|ctx| ctx.get_method_kv(name))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_singular_ctxs_by_hir_expr(
|
pub fn get_singular_ctxs_by_hir_expr(
|
||||||
|
@ -622,7 +625,7 @@ impl Context {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if acc_kind.is_local() {
|
if acc_kind.is_local() {
|
||||||
if let Some(parent) = self.get_outer().or_else(|| self.get_builtins()) {
|
if let Some(parent) = self.get_outer_scope().or_else(|| self.get_builtins()) {
|
||||||
return parent.rec_get_var_info(ident, acc_kind, input, namespace);
|
return parent.rec_get_var_info(ident, acc_kind, input, namespace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -681,7 +684,7 @@ impl Context {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if acc_kind.is_local() {
|
if acc_kind.is_local() {
|
||||||
if let Some(parent) = self.get_outer().or_else(|| self.get_builtins()) {
|
if let Some(parent) = self.get_outer_scope().or_else(|| self.get_builtins()) {
|
||||||
return parent.rec_get_decl_info(ident, acc_kind, input, namespace);
|
return parent.rec_get_decl_info(ident, acc_kind, input, namespace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1133,7 +1136,8 @@ impl Context {
|
||||||
if &self.name[..] == name {
|
if &self.name[..] == name {
|
||||||
Some(self)
|
Some(self)
|
||||||
} else {
|
} else {
|
||||||
self.get_outer().and_then(|p| p.get_same_name_context(name))
|
self.get_outer_scope()
|
||||||
|
.and_then(|p| p.get_same_name_context(name))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2395,7 +2399,7 @@ impl Context {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO: dependent type widening
|
// TODO: dependent type widening
|
||||||
if let Some(parent) = self.get_outer().or_else(|| self.get_builtins()) {
|
if let Some(parent) = self.get_outer_scope_or_builtins() {
|
||||||
parent._get_const_attr(obj, name, namespace)
|
parent._get_const_attr(obj, name, namespace)
|
||||||
} else {
|
} else {
|
||||||
Err(TyCheckError::no_attr_error(
|
Err(TyCheckError::no_attr_error(
|
||||||
|
@ -2998,7 +3002,7 @@ impl Context {
|
||||||
} else {
|
} else {
|
||||||
set! {}
|
set! {}
|
||||||
};
|
};
|
||||||
if let Some(outer) = self.get_outer().or_else(|| self.get_builtins()) {
|
if let Some(outer) = self.get_outer_scope_or_builtins() {
|
||||||
current.union(&outer.get_simple_trait_impls(trait_))
|
current.union(&outer.get_simple_trait_impls(trait_))
|
||||||
} else {
|
} else {
|
||||||
current
|
current
|
||||||
|
@ -3006,7 +3010,7 @@ impl Context {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn all_patches(&self) -> Vec<&Context> {
|
pub(crate) fn all_patches(&self) -> Vec<&Context> {
|
||||||
if let Some(outer) = self.get_outer().or_else(|| self.get_builtins()) {
|
if let Some(outer) = self.get_outer_scope_or_builtins() {
|
||||||
[outer.all_patches(), self.patches.values().collect()].concat()
|
[outer.all_patches(), self.patches.values().collect()].concat()
|
||||||
} else {
|
} else {
|
||||||
self.patches.values().collect()
|
self.patches.values().collect()
|
||||||
|
@ -3052,7 +3056,7 @@ impl Context {
|
||||||
return Some(val);
|
return Some(val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(outer) = self.get_outer().or_else(|| self.get_builtins()) {
|
if let Some(outer) = self.get_outer_scope_or_builtins() {
|
||||||
outer.rec_get_const_obj(name)
|
outer.rec_get_const_obj(name)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -3062,7 +3066,7 @@ impl Context {
|
||||||
pub(crate) fn _rec_get_const_param_defaults(&self, name: &str) -> Option<&Vec<ConstTemplate>> {
|
pub(crate) fn _rec_get_const_param_defaults(&self, name: &str) -> Option<&Vec<ConstTemplate>> {
|
||||||
if let Some(impls) = self.const_param_defaults.get(name) {
|
if let Some(impls) = self.const_param_defaults.get(name) {
|
||||||
Some(impls)
|
Some(impls)
|
||||||
} else if let Some(outer) = self.get_outer().or_else(|| self.get_builtins()) {
|
} else if let Some(outer) = self.get_outer_scope_or_builtins() {
|
||||||
outer._rec_get_const_param_defaults(name)
|
outer._rec_get_const_param_defaults(name)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -3075,7 +3079,7 @@ impl Context {
|
||||||
Some(mono(self.name.clone()))
|
Some(mono(self.name.clone()))
|
||||||
} else if let ContextKind::PatchMethodDefs(t) = &self.kind {
|
} else if let ContextKind::PatchMethodDefs(t) = &self.kind {
|
||||||
Some(t.clone())
|
Some(t.clone())
|
||||||
} else if let Some(outer) = self.get_outer() {
|
} else if let Some(outer) = self.get_outer_scope() {
|
||||||
outer.rec_get_self_t()
|
outer.rec_get_self_t()
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -3149,7 +3153,7 @@ impl Context {
|
||||||
let name = self.erg_to_py_names.get(name).map_or(name, |s| &s[..]);
|
let name = self.erg_to_py_names.get(name).map_or(name, |s| &s[..]);
|
||||||
if let Some(ctx) = self.mono_types.get(name) {
|
if let Some(ctx) = self.mono_types.get(name) {
|
||||||
Some(ctx)
|
Some(ctx)
|
||||||
} else if let Some(outer) = self.get_outer().or_else(|| self.get_builtins()) {
|
} else if let Some(outer) = self.get_outer_scope_or_builtins() {
|
||||||
outer.rec_local_get_mono_type(name)
|
outer.rec_local_get_mono_type(name)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -3161,7 +3165,7 @@ impl Context {
|
||||||
let name = self.erg_to_py_names.get(name).map_or(name, |s| &s[..]);
|
let name = self.erg_to_py_names.get(name).map_or(name, |s| &s[..]);
|
||||||
if let Some(ctx) = self.poly_types.get(name) {
|
if let Some(ctx) = self.poly_types.get(name) {
|
||||||
Some(ctx)
|
Some(ctx)
|
||||||
} else if let Some(outer) = self.get_outer().or_else(|| self.get_builtins()) {
|
} else if let Some(outer) = self.get_outer_scope_or_builtins() {
|
||||||
outer.rec_local_get_poly_type(name)
|
outer.rec_local_get_poly_type(name)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -3260,7 +3264,7 @@ impl Context {
|
||||||
value
|
value
|
||||||
.as_type(self)
|
.as_type(self)
|
||||||
.and_then(|typ_obj| self.get_nominal_type_ctx(typ_obj.typ()))
|
.and_then(|typ_obj| self.get_nominal_type_ctx(typ_obj.typ()))
|
||||||
} else if let Some(outer) = self.get_outer().or_else(|| self.get_builtins()) {
|
} else if let Some(outer) = self.get_outer_scope_or_builtins() {
|
||||||
outer.rec_local_get_type(name)
|
outer.rec_local_get_type(name)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -3270,7 +3274,7 @@ impl Context {
|
||||||
pub(crate) fn rec_get_patch(&self, name: &str) -> Option<&Context> {
|
pub(crate) fn rec_get_patch(&self, name: &str) -> Option<&Context> {
|
||||||
if let Some(ctx) = self.patches.get(name) {
|
if let Some(ctx) = self.patches.get(name) {
|
||||||
Some(ctx)
|
Some(ctx)
|
||||||
} else if let Some(outer) = self.get_outer().or_else(|| self.get_builtins()) {
|
} else if let Some(outer) = self.get_outer_scope_or_builtins() {
|
||||||
outer.rec_get_patch(name)
|
outer.rec_get_patch(name)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -3278,7 +3282,7 @@ impl Context {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn rec_get_guards(&self) -> Vec<&GuardType> {
|
pub(crate) fn rec_get_guards(&self) -> Vec<&GuardType> {
|
||||||
if let Some(outer) = self.get_outer() {
|
if let Some(outer) = self.get_outer_scope() {
|
||||||
[self.guards.iter().collect(), outer.rec_get_guards()].concat()
|
[self.guards.iter().collect(), outer.rec_get_guards()].concat()
|
||||||
} else {
|
} else {
|
||||||
self.guards.iter().collect()
|
self.guards.iter().collect()
|
||||||
|
@ -3393,7 +3397,7 @@ impl Context {
|
||||||
if let Some(candidates) = self.method_to_classes.get(attr.inspect()) {
|
if let Some(candidates) = self.method_to_classes.get(attr.inspect()) {
|
||||||
return self.get_attr_type(receiver, attr, candidates, namespace);
|
return self.get_attr_type(receiver, attr, candidates, namespace);
|
||||||
}
|
}
|
||||||
if let Some(outer) = self.get_outer().or_else(|| self.get_builtins()) {
|
if let Some(outer) = self.get_outer_scope_or_builtins() {
|
||||||
outer.get_attr_type_by_name(receiver, attr, namespace)
|
outer.get_attr_type_by_name(receiver, attr, namespace)
|
||||||
} else {
|
} else {
|
||||||
Triple::None
|
Triple::None
|
||||||
|
|
|
@ -637,7 +637,7 @@ impl fmt::Display for Context {
|
||||||
impl ContextProvider for Context {
|
impl ContextProvider for Context {
|
||||||
fn dir(&self) -> Dict<&VarName, &VarInfo> {
|
fn dir(&self) -> Dict<&VarName, &VarInfo> {
|
||||||
let mut vars = self.type_dir(self);
|
let mut vars = self.type_dir(self);
|
||||||
if let Some(outer) = self.get_outer() {
|
if let Some(outer) = self.get_outer_scope() {
|
||||||
vars.guaranteed_extend(outer.dir());
|
vars.guaranteed_extend(outer.dir());
|
||||||
} else if let Some(builtins) = self.get_builtins() {
|
} else if let Some(builtins) = self.get_builtins() {
|
||||||
vars.guaranteed_extend(builtins.locals.iter());
|
vars.guaranteed_extend(builtins.locals.iter());
|
||||||
|
@ -1125,10 +1125,25 @@ impl Context {
|
||||||
String::from(&self.name[..])
|
String::from(&self.name[..])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// use `get_outer_scope` for getting the outer scope
|
||||||
pub(crate) fn get_outer(&self) -> Option<&Context> {
|
pub(crate) fn get_outer(&self) -> Option<&Context> {
|
||||||
self.outer.as_ref().map(|x| x.as_ref())
|
self.outer.as_ref().map(|x| x.as_ref())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// If both `self` and `outer` are modules, returns `None` because the outer namespace is different from the current context
|
||||||
|
pub(crate) fn get_outer_scope(&self) -> Option<&Context> {
|
||||||
|
let outer = self.get_outer()?;
|
||||||
|
if outer.name != "<builtins>" && outer.kind.is_module() && self.kind.is_module() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(outer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn get_outer_scope_or_builtins(&self) -> Option<&Context> {
|
||||||
|
self.get_outer_scope().or_else(|| self.get_builtins())
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn get_mut_outer(&mut self) -> Option<&mut Context> {
|
pub(crate) fn get_mut_outer(&mut self) -> Option<&mut Context> {
|
||||||
self.outer.as_mut().map(|x| x.as_mut())
|
self.outer.as_mut().map(|x| x.as_mut())
|
||||||
}
|
}
|
||||||
|
@ -1423,7 +1438,7 @@ impl Context {
|
||||||
pub fn current_true_function_ctx(&self) -> Option<&Context> {
|
pub fn current_true_function_ctx(&self) -> Option<&Context> {
|
||||||
if self.kind.is_subr() && self.current_control_flow().is_none() {
|
if self.kind.is_subr() && self.current_control_flow().is_none() {
|
||||||
Some(self)
|
Some(self)
|
||||||
} else if let Some(outer) = self.get_outer() {
|
} else if let Some(outer) = self.get_outer_scope() {
|
||||||
outer.current_true_function_ctx()
|
outer.current_true_function_ctx()
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
|
@ -70,7 +70,7 @@ impl Context {
|
||||||
return Some((name, vi));
|
return Some((name, vi));
|
||||||
}
|
}
|
||||||
if is_const {
|
if is_const {
|
||||||
let outer = self.get_outer().or_else(|| self.get_builtins())?;
|
let outer = self.get_outer_scope_or_builtins()?;
|
||||||
outer.registered_info(name, is_const)
|
outer.registered_info(name, is_const)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
use erg_common::consts::PYTHON_MODE;
|
use erg_common::consts::PYTHON_MODE;
|
||||||
|
use erg_common::error::Location;
|
||||||
use erg_common::traits::{Locational, Runnable, Stream};
|
use erg_common::traits::{Locational, Runnable, Stream};
|
||||||
use erg_common::{enum_unwrap, fn_name, log, set, Str, Triple};
|
use erg_common::{enum_unwrap, fn_name, log, set, Str, Triple};
|
||||||
|
|
||||||
|
@ -129,8 +130,15 @@ impl<A: ASTBuildable> GenericASTLowerer<A> {
|
||||||
.module
|
.module
|
||||||
.context
|
.context
|
||||||
.registered_info(&name, def.sig.is_const())
|
.registered_info(&name, def.sig.is_const())
|
||||||
.is_some()
|
.is_some_and(|(_, vi)| {
|
||||||
&& def.sig.vis().is_private()
|
!vi.kind.is_builtin()
|
||||||
|
&& vi.def_loc
|
||||||
|
!= self.module.context.absolutize(
|
||||||
|
def.sig
|
||||||
|
.ident()
|
||||||
|
.map_or(Location::Unknown, |ident| ident.loc()),
|
||||||
|
)
|
||||||
|
})
|
||||||
{
|
{
|
||||||
return Err(LowerErrors::from(LowerError::reassign_error(
|
return Err(LowerErrors::from(LowerError::reassign_error(
|
||||||
self.cfg().input.clone(),
|
self.cfg().input.clone(),
|
||||||
|
|
|
@ -2514,7 +2514,7 @@ impl<A: ASTBuildable> GenericASTLowerer<A> {
|
||||||
let (unverified_names, mut errors) = if let Some(typ_ctx) = self
|
let (unverified_names, mut errors) = if let Some(typ_ctx) = self
|
||||||
.module
|
.module
|
||||||
.context
|
.context
|
||||||
.get_outer()
|
.get_outer_scope()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.get_nominal_type_ctx(&impl_trait)
|
.get_nominal_type_ctx(&impl_trait)
|
||||||
{
|
{
|
||||||
|
|
|
@ -540,10 +540,10 @@ impl Predicate {
|
||||||
|
|
||||||
pub fn substitute(self, var: &str, tp: &TyParam) -> Self {
|
pub fn substitute(self, var: &str, tp: &TyParam) -> Self {
|
||||||
match self {
|
match self {
|
||||||
Self::Equal { lhs, .. } if &lhs == var => Self::eq(lhs, tp.clone()),
|
Self::Equal { lhs, .. } if lhs == var => Self::eq(lhs, tp.clone()),
|
||||||
Self::GreaterEqual { lhs, .. } if &lhs == var => Self::ge(lhs, tp.clone()),
|
Self::GreaterEqual { lhs, .. } if lhs == var => Self::ge(lhs, tp.clone()),
|
||||||
Self::LessEqual { lhs, .. } if &lhs == var => Self::le(lhs, tp.clone()),
|
Self::LessEqual { lhs, .. } if lhs == var => Self::le(lhs, tp.clone()),
|
||||||
Self::NotEqual { lhs, .. } if &lhs == var => Self::ne(lhs, tp.clone()),
|
Self::NotEqual { lhs, .. } if lhs == var => Self::ne(lhs, tp.clone()),
|
||||||
Self::Equal { lhs, rhs } => Self::eq(lhs, rhs.substitute(var, tp)),
|
Self::Equal { lhs, rhs } => Self::eq(lhs, rhs.substitute(var, tp)),
|
||||||
Self::GreaterEqual { lhs, rhs } => Self::ge(lhs, rhs.substitute(var, tp)),
|
Self::GreaterEqual { lhs, rhs } => Self::ge(lhs, rhs.substitute(var, tp)),
|
||||||
Self::LessEqual { lhs, rhs } => Self::le(lhs, rhs.substitute(var, tp)),
|
Self::LessEqual { lhs, rhs } => Self::le(lhs, rhs.substitute(var, tp)),
|
||||||
|
|
|
@ -1449,7 +1449,7 @@ impl TyParam {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn substitute(self, var: &str, to: &TyParam) -> TyParam {
|
pub fn substitute(self, var: &str, to: &TyParam) -> TyParam {
|
||||||
if self.qual_name().is_some_and(|n| &n == var) {
|
if self.qual_name().is_some_and(|n| n == var) {
|
||||||
return to.clone();
|
return to.clone();
|
||||||
}
|
}
|
||||||
match self {
|
match self {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue