From 3c35557872654d6c563725e2965dc2603819bcaf Mon Sep 17 00:00:00 2001 From: Jakub Doka Date: Mon, 11 Nov 2024 09:06:34 +0100 Subject: [PATCH] fixing type variables in loops --- lang/README.md | 20 +++++++++++ lang/src/lib.rs | 5 ++- lang/src/son.rs | 19 +++++++++-- lang/tests/son_tests_generic_type_mishap.txt | 35 ++++++++++++++++++++ 4 files changed, 75 insertions(+), 4 deletions(-) create mode 100644 lang/tests/son_tests_generic_type_mishap.txt diff --git a/lang/README.md b/lang/README.md index f5c9729..695d936 100644 --- a/lang/README.md +++ b/lang/README.md @@ -615,6 +615,26 @@ main := fn(): uint { ### Purely Testing Examples +#### generic_type_mishap +```hb +opaque := fn($Expr: type, ptr: ^?Expr): void { +} + +process := fn($Expr: type): void { + optional := @as(?Expr, null) + timer := 1000 + loop if timer > 0 { + opaque(Expr, &optional) + if optional != null return { + } + timer -= 1 + } + return +} + +main := fn(): void process(uint) +``` + #### storing_into_nullable_struct ```hb StructA := struct {b: StructB, c: ^uint, d: uint} diff --git a/lang/src/lib.rs b/lang/src/lib.rs index 5a41744..bd6120a 100644 --- a/lang/src/lib.rs +++ b/lang/src/lib.rs @@ -1032,7 +1032,10 @@ trait TypeParser { let Some((expr @ Expr::BinOp { left, right, .. }, name)) = f.find_decl(id) else { return match id { - Ok(_) => ty::Id::NEVER, + Ok(_) => { + debug_assert_eq!(from_file, file); + self.report(file, pos, "somehow this was not found") + } Err("main") => self.report( from_file, pos, diff --git a/lang/src/son.rs b/lang/src/son.rs index eb73dbe..c45179e 100644 --- a/lang/src/son.rs +++ b/lang/src/son.rs @@ -2022,6 +2022,12 @@ struct Variable { impl Variable { fn new(id: Ident, ty: ty::Id, ptr: bool, value: Nid, nodes: &mut Nodes) -> Self { + if value == NEVER { + if ty == ty::Id::NEVER { + panic!(); + } + } + Self { id, ty, ptr, value: StrongRef::new(value, nodes) } } @@ -3400,7 +3406,7 @@ impl<'a> Codegen<'a> { }); for var in self.ci.scope.vars.iter_mut().skip(self.ci.inline_var_base) { - if !var.ptr { + if !var.ptr && var.value() != NEVER { var.set_value(VOID, &mut self.ci.nodes); } } @@ -4331,7 +4337,7 @@ impl<'a> Codegen<'a> { self.ci.nodes.basic_blocks(); self.ci.nodes.graphviz(self.ty_display(ty::Id::VOID)); } else { - self.ci.nodes.graphviz_in_browser(self.ty_display(ty::Id::VOID)); + //self.ci.nodes.graphviz_in_browser(self.ty_display(ty::Id::VOID)); } self.errors.borrow().len() == prev_err_len @@ -4664,7 +4670,13 @@ impl TypeParser for Codegen<'_> { } fn find_local_ty(&mut self, ident: Ident) -> Option { - self.ci.scope.vars.iter().rfind(|v| (v.id == ident && v.value() == NEVER)).map(|v| v.ty) + self.ci + .scope + .vars + .iter() + .rfind(|v| (v.id == ident && v.value() == NEVER)) + .map(|v| v.ty) + .inspect(|&ty| debug_assert_ne!(ty, ty::Id::NEVER)) } } @@ -4743,6 +4755,7 @@ mod tests { fb_driver; // Purely Testing Examples; + generic_type_mishap; storing_into_nullable_struct; scheduling_block_did_dirty; null_check_returning_small_global; diff --git a/lang/tests/son_tests_generic_type_mishap.txt b/lang/tests/son_tests_generic_type_mishap.txt new file mode 100644 index 0000000..ab5bb18 --- /dev/null +++ b/lang/tests/son_tests_generic_type_mishap.txt @@ -0,0 +1,35 @@ +main: + ADDI64 r254, r254, -8d + ST r31, r254, 0a, 8h + JAL r31, r0, :process + LD r31, r254, 0a, 8h + ADDI64 r254, r254, 8d + JALA r0, r31, 0a +opaque: + JALA r0, r31, 0a +process: + ADDI64 r254, r254, -64d + ST r31, r254, 16a, 48h + LI64 r32, 0d + LI64 r33, 1000d + ADDI64 r34, r254, 0d + LI8 r35, 0b + ST r35, r254, 0a, 1h + 4: JGTU r33, r32, :0 + JMP :1 + 0: CP r2, r34 + JAL r31, r0, :opaque + LD r36, r254, 0a, 1h + ANDI r36, r36, 255d + ANDI r35, r35, 255d + JEQ r36, r35, :2 + JMP :3 + 2: ADDI64 r33, r33, -1d + 1: JMP :4 + 3: LD r31, r254, 16a, 48h + ADDI64 r254, r254, 64d + JALA r0, r31, 0a +timed out +code size: 272 +ret: 0 +status: Ok(())