diff --git a/crates/els/completion.rs b/crates/els/completion.rs index 8b2dc3b6..36bc078c 100644 --- a/crates/els/completion.rs +++ b/crates/els/completion.rs @@ -444,6 +444,7 @@ impl Server { &self, uri: &NormalizedUrl, arg_pt: Option, + already_appeared: &mut Set, ) -> Vec { let mut comps = vec![]; for mod_ctx in self.get_neighbor_ctxs(uri) { @@ -451,6 +452,9 @@ impl Server { if vi.vis.is_private() { continue; } + if already_appeared.contains(&name.inspect()[..]) { + continue; + } let Some(path) = vi.def_loc.module.as_ref() else { continue; }; @@ -474,6 +478,7 @@ impl Server { }]); item.insert_text = Some(name.inspect().trim_end_matches('\0').to_string()); item.filter_text = Some(name.inspect().to_string()); + already_appeared.insert(name.inspect().to_string()); comps.push(item); } } @@ -621,7 +626,7 @@ impl Server { self.comp_cache.insert("".into(), comps.clone()); result.extend(comps); } - result.extend(self.neighbor_completion(&uri, arg_pt)); + self.neighbor_completion(&uri, arg_pt, &mut already_appeared); } send_log(format!("completion items: {}", result.len()))?; Ok(Some(CompletionResponse::Array(result))) diff --git a/crates/erg_compiler/context/register.rs b/crates/erg_compiler/context/register.rs index 40e5d8a0..dae7a10f 100644 --- a/crates/erg_compiler/context/register.rs +++ b/crates/erg_compiler/context/register.rs @@ -2277,7 +2277,13 @@ impl Context { guard: GuardType, overwritten: &mut Vec<(VarName, VarInfo)>, ) -> TyCheckResult<()> { - if let Variable::Var(name, _) = &guard.var { + 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 diff --git a/crates/erg_compiler/lower.rs b/crates/erg_compiler/lower.rs index b40a1979..6ea09360 100644 --- a/crates/erg_compiler/lower.rs +++ b/crates/erg_compiler/lower.rs @@ -50,11 +50,15 @@ use crate::{feature_error, unreachable_error}; use VisibilityModifier::*; -pub fn acc_to_variable(acc: &ast::Accessor) -> Option { +pub fn acc_to_variable(namespace: Str, acc: &ast::Accessor) -> Option { match acc { - ast::Accessor::Ident(ident) => Some(Variable::Var(ident.inspect().clone(), ident.loc())), + ast::Accessor::Ident(ident) => Some(Variable::Var { + namespace, + name: ident.inspect().clone(), + loc: ident.loc(), + }), ast::Accessor::Attr(attr) => Some(Variable::attr( - expr_to_variable(&attr.obj)?, + expr_to_variable(namespace, &attr.obj)?, attr.ident.inspect().clone(), attr.loc(), )), @@ -62,9 +66,9 @@ pub fn acc_to_variable(acc: &ast::Accessor) -> Option { } } -pub fn expr_to_variable(expr: &ast::Expr) -> Option { +pub fn expr_to_variable(namespace: Str, expr: &ast::Expr) -> Option { match expr { - ast::Expr::Accessor(acc) => acc_to_variable(acc), + ast::Expr::Accessor(acc) => acc_to_variable(namespace, acc), _ => None, } } @@ -743,9 +747,9 @@ impl ASTLowerer { fn get_guard_type(&self, op: &Token, lhs: &ast::Expr, rhs: &ast::Expr) -> Option { let var = if op.kind == TokenKind::ContainsOp { - expr_to_variable(rhs)? + expr_to_variable(self.module.context.name.clone(), rhs)? } else { - expr_to_variable(lhs)? + expr_to_variable(self.module.context.name.clone(), lhs)? }; match op.kind { // l in T -> T contains l diff --git a/crates/erg_compiler/ty/mod.rs b/crates/erg_compiler/ty/mod.rs index 07da43b9..727083fd 100644 --- a/crates/erg_compiler/ty/mod.rs +++ b/crates/erg_compiler/ty/mod.rs @@ -756,7 +756,11 @@ pub enum Variable { name: Str, loc: Location, }, - Var(Str, Location), + Var { + namespace: Str, + name: Str, + loc: Location, + }, Attr { receiver: Box, attr: Str, @@ -768,7 +772,7 @@ impl fmt::Display for Variable { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { 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}"), } } @@ -778,7 +782,7 @@ impl Locational for Variable { fn loc(&self) -> Location { match self { Self::Param { loc, .. } => *loc, - Self::Var(_, loc) => *loc, + Self::Var { loc, .. } => *loc, Self::Attr { loc, .. } => *loc, } }