fixing type variables in loops

This commit is contained in:
Jakub Doka 2024-11-11 09:06:34 +01:00
parent b6274f3455
commit 3c35557872
No known key found for this signature in database
GPG key ID: C6E9A89936B8C143
4 changed files with 75 additions and 4 deletions

View file

@ -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}

View file

@ -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,

View file

@ -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<ty::Id> {
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;

View file

@ -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(())