Skip to content

Commit 4380ae2

Browse files
committed
fix(let-impl): improve scope resolution and LSP type checking
- Fix incorrect module scope resolution for `let impl` statements - Ensure LSP type-checks all `if let impl` branch bodies regardless of compile-time result Previously: - `let impl` statements incorrectly searched for implementations in wrong modules - LSP would skip type-checking `if let impl` branch bodies when compile-time result was false
1 parent 1a2bc02 commit 4380ae2

File tree

6 files changed

+27
-6
lines changed

6 files changed

+27
-6
lines changed

src/ast/ctx.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1118,6 +1118,25 @@ impl<'a, 'ctx> Ctx<'a> {
11181118
res
11191119
}
11201120

1121+
pub fn try_run_in_type_mod<'b, R, F: FnMut(&mut Ctx<'a>, &PLType) -> R>(
1122+
&'b mut self,
1123+
ty: &PLType,
1124+
mut f: F,
1125+
) -> R {
1126+
match ty {
1127+
PLType::Struct(sttype) => {
1128+
self.run_in_type_mod(sttype, |ctx, tp| f(ctx, &PLType::Struct(tp.clone())))
1129+
}
1130+
PLType::Trait(sttype) => {
1131+
self.run_in_type_mod(sttype, |ctx, tp| f(ctx, &PLType::Struct(tp.clone())))
1132+
}
1133+
PLType::Union(union_type) => {
1134+
self.run_in_type_mod(union_type, |ctx, tp| f(ctx, &PLType::Union(tp.clone())))
1135+
}
1136+
_ => f(self, ty),
1137+
}
1138+
}
1139+
11211140
/// # run_in_type_mod
11221141
///
11231142
/// it executes the function f under the module of the custom_type

src/ast/node/cast.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -671,7 +671,9 @@ impl Node for ImplCastNode {
671671
let mut satisfy_bound = true;
672672
for t in &t {
673673
if let PLType::Trait(trait_ty) = &*t.borrow() {
674-
if !ty.borrow().implements_trait(trait_ty, ctx) {
674+
if ctx.try_run_in_type_mod(&ty.borrow(), |ctx, ty| {
675+
!ty.implements_trait(trait_ty, ctx)
676+
}) {
675677
satisfy_bound = false;
676678
break;
677679
}

src/ast/node/control.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ impl Node for IfNode {
154154
let mut then_terminator = TerminatorEnum::None;
155155
// emit the code inside a child context because it belongs to a sub-block
156156
let mut child = ctx.new_child(self.then.range().start, builder);
157-
if !skip_body {
157+
if !skip_body || matches!(builder, BuilderEnum::NoOp(_)) {
158158
if let Some(mut def) = gen_def {
159159
def.emit(&mut child, builder)?;
160160
}

src/ast/pltype.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -520,7 +520,6 @@ impl PLType {
520520

521521
pub fn implements_trait(&self, tp: &STType, ctx: &Ctx) -> bool {
522522
let name = &self.get_full_elm_name_without_generic();
523-
524523
match self {
525524
PLType::Struct(s) => s.implements_trait(tp, ctx),
526525
PLType::Union(u) => u.implements_trait(tp, ctx),

src/ast/pltype/method.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -265,8 +265,9 @@ pub trait TraitImplAbleWithGeneric: Generic + TraitImplAble {
265265
false
266266
}
267267
fn implements_trait(&self, tp: &STType, ctx: &Ctx) -> bool {
268-
if tp.path == ctx.plmod.path {
269-
let plmod = &ctx.plmod;
268+
let origin_mod = unsafe { ctx.origin_mod.as_ref().unwrap() };
269+
if tp.path == origin_mod.path {
270+
let plmod = origin_mod;
270271
if self.implements_trait_curr_mod(tp, plmod) {
271272
return true;
272273
}

test/test/std_test.pi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ pub async fn test_delay() Task<()> {
209209

210210
use std::json::encode::encode;
211211
use std::cols::hashtable;
212+
use std::json::encode::JSONSerializable;
212213

213214
pub fn test_json() void {
214215
let nested = JSONObj{
@@ -222,7 +223,6 @@ pub fn test_json() void {
222223
let table = hashtable::new_hash_table(10 as u64, 0 as u64);
223224
table.insert(1, "abc");
224225
table.insert(2, "bcd");
225-
table.to_json();
226226
re = encode(table);
227227
println!(re);
228228
// hash table is special, it's directly encoded as json object

0 commit comments

Comments
 (0)