Skip to content

Commit 6fce518

Browse files
fix: report error when generic method attempts to implement non-generic interface method
1 parent be8e56d commit 6fce518

File tree

3 files changed

+40
-1
lines changed

3 files changed

+40
-1
lines changed

src/resolver.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3063,7 +3063,14 @@ export class Resolver extends DiagnosticEmitter {
30633063
let boundPrototype = classInstance.getMember(unboundOverridePrototype.name);
30643064
if (boundPrototype) { // might have errored earlier and wasn't added
30653065
assert(boundPrototype.kind == ElementKind.FunctionPrototype);
3066-
overrideInstance = this.resolveFunction(<FunctionPrototype>boundPrototype, instance.typeArguments);
3066+
let boundFuncPrototype = <FunctionPrototype>boundPrototype;
3067+
let overrideTypeParams = boundFuncPrototype.typeParameterNodes;
3068+
let numOverrideTypeParams = overrideTypeParams ? overrideTypeParams.length : 0;
3069+
let baseTypeArgs = instance.typeArguments;
3070+
let numBaseTypeArgs = baseTypeArgs ? baseTypeArgs.length : 0;
3071+
if (numOverrideTypeParams == numBaseTypeArgs) {
3072+
overrideInstance = this.resolveFunction(boundFuncPrototype, baseTypeArgs);
3073+
}
30673074
}
30683075
}
30693076
if (overrideInstance) overrides.add(overrideInstance);
@@ -3439,6 +3446,20 @@ export class Resolver extends DiagnosticEmitter {
34393446
default: assert(false);
34403447
}
34413448
if (!member.is(CommonFlags.Abstract)) {
3449+
// A generic method cannot implement a non-generic interface method
3450+
// because monomorphization requires a concrete type to generate code,
3451+
// but virtual dispatch through the interface has no type arguments.
3452+
let ifaceMember = unimplemented.get(memberName);
3453+
if (ifaceMember
3454+
&& member.kind == ElementKind.FunctionPrototype
3455+
&& ifaceMember.kind == ElementKind.FunctionPrototype
3456+
) {
3457+
let memberTypeParams = (<FunctionPrototype>member).typeParameterNodes;
3458+
let ifaceTypeParams = (<FunctionPrototype>ifaceMember).typeParameterNodes;
3459+
let numMemberTypeParams = memberTypeParams ? memberTypeParams.length : 0;
3460+
let numIfaceTypeParams = ifaceTypeParams ? ifaceTypeParams.length : 0;
3461+
if (numMemberTypeParams != numIfaceTypeParams) continue;
3462+
}
34423463
unimplemented.delete(memberName);
34433464
}
34443465
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"asc_flags": [],
3+
"stderr": [
4+
"TS2515: Non-abstract class 'override-typeparam-mismatch/CC' does not implement inherited abstract member 'foo' from 'override-typeparam-mismatch/I'."
5+
]
6+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
interface I {
2+
foo(x: i32): i32;
3+
}
4+
5+
class CC implements I {
6+
foo<T>(x: i32): i32 {
7+
return x;
8+
}
9+
}
10+
11+
let c:I = new CC();
12+
c.foo(1);

0 commit comments

Comments
 (0)