Skip to content

Commit 2aac7bd

Browse files
committed
Improve type checking
TODO: add better error messages
1 parent 83839cd commit 2aac7bd

File tree

5 files changed

+129
-3
lines changed

5 files changed

+129
-3
lines changed

src/program.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2769,6 +2769,11 @@ export class FunctionPrototype extends DeclaredElement {
27692769
lookup(name: string): Element | null {
27702770
return this.parent.lookup(name);
27712771
}
2772+
2773+
equals(func: FunctionPrototype): bool {
2774+
return this.functionTypeNode.equals(func.functionTypeNode) &&
2775+
TypeNode.arrayEquals(func.typeParameterNodes, this.typeParameterNodes);
2776+
}
27722777
}
27732778

27742779
/** A resolved function. */
@@ -3381,7 +3386,7 @@ export class Class extends TypedElement {
33813386
/** Tests if a value of this class type is assignable to a target of the specified class type. */
33823387
isAssignableTo(target: Class): bool {
33833388
var current: Class | null = this;
3384-
if (target.kind == ElementKind.INTERFACE) {
3389+
if (target.kind == ElementKind.INTERFACE) {
33853390
return (<Interface>target).checkClass(this);
33863391
}
33873392
do if (current == target) return true;
@@ -3666,8 +3671,11 @@ export class Interface extends Class { // FIXME
36663671
}
36673672

36683673
checkClass(_class: Class): bool {
3669-
return this.methods.reduce<bool>((acc, ifunc) =>
3670-
(this.getFunc(_class, ifunc) != null ) && acc, true);
3674+
return this.methods.reduce<bool>((acc, ifunc) => {
3675+
let func = this.getFunc(_class, ifunc);
3676+
if (func == null) return false;
3677+
return ifunc.equals(func) && acc;
3678+
}, true);
36713679
}
36723680

36733681
private getFunc(_class: Class, ifunc: FunctionPrototype): FunctionPrototype | null {
File renamed without changes.
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
(module
2+
(type $FUNCSIG$vi (func (param i32)))
3+
(type $FUNCSIG$v (func))
4+
(type $FUNCSIG$i (func (result i32)))
5+
(memory $0 0)
6+
(global $~lib/rt/stub/startOffset (mut i32) (i32.const 0))
7+
(global $~lib/rt/stub/offset (mut i32) (i32.const 0))
8+
(global $interface-fail/aFoo (mut i32) (i32.const 0))
9+
(export "memory" (memory $0))
10+
(start $start)
11+
(func $~lib/rt/stub/maybeGrowMemory (; 0 ;) (type $FUNCSIG$vi) (param $0 i32)
12+
(local $1 i32)
13+
(local $2 i32)
14+
local.get $0
15+
memory.size
16+
local.tee $2
17+
i32.const 16
18+
i32.shl
19+
local.tee $1
20+
i32.gt_u
21+
if
22+
local.get $2
23+
local.get $0
24+
local.get $1
25+
i32.sub
26+
i32.const 65535
27+
i32.add
28+
i32.const -65536
29+
i32.and
30+
i32.const 16
31+
i32.shr_u
32+
local.tee $1
33+
local.get $2
34+
local.get $1
35+
i32.gt_s
36+
select
37+
memory.grow
38+
i32.const 0
39+
i32.lt_s
40+
if
41+
local.get $1
42+
memory.grow
43+
i32.const 0
44+
i32.lt_s
45+
if
46+
unreachable
47+
end
48+
end
49+
end
50+
local.get $0
51+
global.set $~lib/rt/stub/offset
52+
)
53+
(func $~lib/rt/stub/__alloc (; 1 ;) (type $FUNCSIG$i) (result i32)
54+
(local $0 i32)
55+
(local $1 i32)
56+
global.get $~lib/rt/stub/offset
57+
i32.const 16
58+
i32.add
59+
local.tee $1
60+
i32.const 16
61+
i32.add
62+
call $~lib/rt/stub/maybeGrowMemory
63+
local.get $1
64+
i32.const 16
65+
i32.sub
66+
local.tee $0
67+
i32.const 16
68+
i32.store
69+
local.get $0
70+
i32.const -1
71+
i32.store offset=4
72+
local.get $0
73+
i32.const 4
74+
i32.store offset=8
75+
local.get $0
76+
i32.const 4
77+
i32.store offset=12
78+
local.get $1
79+
)
80+
(func $start (; 2 ;) (type $FUNCSIG$v)
81+
(local $0 i32)
82+
i32.const 16
83+
global.set $~lib/rt/stub/startOffset
84+
i32.const 16
85+
global.set $~lib/rt/stub/offset
86+
call $~lib/rt/stub/__alloc
87+
local.tee $0
88+
i32.const 41
89+
i32.store
90+
local.get $0
91+
global.set $interface-fail/aFoo
92+
)
93+
(func $null (; 3 ;) (type $FUNCSIG$v)
94+
nop
95+
)
96+
)

tests/compiler/interface-fail.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
2+
interface IFoo {
3+
foo(i: i32): i32;
4+
}
5+
6+
class BadFoo implements IFoo {
7+
i: i32 = 41;
8+
9+
foo(i: i32): string {
10+
return "hello";
11+
}
12+
13+
faa(i: i32, i2: i32): i32 {
14+
return i + i2;
15+
}
16+
17+
}
18+
19+
20+
const aFoo: IFoo = new BadFoo();
21+
22+

tests/compiler/interface-fail.untouched.wat

Whitespace-only changes.

0 commit comments

Comments
 (0)