Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
4012b77
fix(types): stop var/const arrow hoisting placeholder from tripping T…
nickna Jul 6, 2026
18d8c67
test(conformance): update baseline — subtypingWithCallSignatures2/3/4…
nickna Jul 6, 2026
fd89120
fix(types): fix swapped-branch bug in ternary common-type selection
nickna Jul 6, 2026
9330164
fix(types): relate namespace/module types structurally in IsCompatibl…
nickna Jul 6, 2026
aadabac
test(conformance): update baseline — 3 more tests now pass
nickna Jul 6, 2026
857af4c
fix(types): add TS2464 computed-property-name validation, type Symbol…
nickna Jul 6, 2026
adfe251
test(conformance): update baseline — symbolProperty3/52/54 now pass
nickna Jul 6, 2026
0130fb4
fix(types): detect duplicate well-known-symbol object-literal keys an…
nickna Jul 6, 2026
f0bee95
test(conformance): update baseline — symbolProperty36/44 now pass
nickna Jul 6, 2026
4aa5bf5
fix(types): validate overloads for computed well-known-symbol class m…
nickna Jul 6, 2026
495a4ce
test(conformance): update baseline — symbolProperty39/42/43 now pass
nickna Jul 6, 2026
f255347
fix(types): flag a class accessor that collides with a same-named method
nickna Jul 6, 2026
1e7cc8b
test(conformance): update baseline — symbolDeclarationEmit12 now passes
nickna Jul 6, 2026
c15c43d
fix(types): fix swapped-branch bug in nullish-coalescing common-type …
nickna Jul 6, 2026
32ff032
fix(types): validate well-known-symbol interface members against a sy…
nickna Jul 6, 2026
1e013dc
test(conformance): update baseline — symbolProperty17 now passes
nickna Jul 6, 2026
df055f6
fix(types): validate symbol operands in in/for-in/delete/new and inte…
nickna Jul 9, 2026
fa46f5c
test(conformance): update baseline — symbolType2/3/13/14/20 now pass
nickna Jul 9, 2026
990cd22
fix(types): flag a class used before its declaration in an extends cl…
nickna Jul 9, 2026
8c77595
test(conformance): update baseline — symbolProperty33 now passes
nickna Jul 9, 2026
0425498
fix(types): match symbol-keyed class fields structurally + assign obj…
nickna Jul 9, 2026
a50114c
test(conformance): update baseline — symbolProperty9/10/11/12 now pass
nickna Jul 9, 2026
fe054a7
fix(types): reject an interface extending two bases with a non-identi…
nickna Jul 9, 2026
3558c79
test(conformance): update baseline — symbolProperty35 now passes
nickna Jul 9, 2026
402d53b
fix(types): validate class symbol-keyed members against a symbol inde…
nickna Jul 9, 2026
264d87a
test(conformance): update baseline — symbolProperty30/32 now pass
nickna Jul 9, 2026
8b1efd4
fix(types): accept a boolean argument to BigInt()
nickna Jul 9, 2026
a312fe8
fix(types): relate an unconstrained type parameter to a no-required-m…
nickna Jul 9, 2026
2312d94
test(conformance): update baseline — constructBigint + subtypingWithO…
nickna Jul 9, 2026
a532c22
fix(types): reject a plain-symbol computed class field name (TS1166)
nickna Jul 9, 2026
0b7b754
fix(types): report TS2538 when indexing with a function-typed key
nickna Jul 9, 2026
bde494a
test(conformance): update baseline — symbolProperty7/53 now pass
nickna Jul 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Parsing/AST.cs
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,9 @@ public record While(Expr Condition, Stmt Body) : Stmt;
public record For(Stmt? Initializer, Expr? Condition, Expr? Increment, Stmt Body) : Stmt;
public record DoWhile(Stmt Body, Expr Condition) : Stmt;
public record ForOf(Token Variable, string? TypeAnnotation, Expr Iterable, Stmt Body, bool IsAsync = false) : Stmt;
public record ForIn(Token Variable, string? TypeAnnotation, Expr Object, Stmt Body) : Stmt;
// IsDeclaration distinguishes `for (var x in o)` (a fresh binding) from `for (x in o)`
// (assignment to an existing lvalue) — the latter's target type is validated (TS2405).
public record ForIn(Token Variable, string? TypeAnnotation, Expr Object, Stmt Body, bool IsDeclaration = true) : Stmt;
public record If(Expr Condition, Stmt ThenBranch, Stmt? ElseBranch) : Stmt;
public record Print(Expr Expr) : Stmt; // Temporary for console.log
public record Break(Token Keyword, Token? Label = null) : Stmt;
Expand Down
2 changes: 1 addition & 1 deletion Parsing/Parser.Statements.cs
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ private Stmt ForStatement()
Stmt body = Statement();
if (isOfLoop)
return new Stmt.ForOf(varName, null, rhs, body, isAsync);
return new Stmt.ForIn(varName, null, rhs, body);
return new Stmt.ForIn(varName, null, rhs, body, IsDeclaration: false);
}

// Traditional for loop without let/const
Expand Down
68 changes: 34 additions & 34 deletions SharpTS.TypeScriptConformance/baselines/interpreted.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ tests/cases/conformance/es2019/importMeta/importMetaNarrowing.ts Fail
tests/cases/conformance/es2020/bigintMissingES2019.ts Pass
tests/cases/conformance/es2020/bigintMissingES2020.ts Pass
tests/cases/conformance/es2020/bigintMissingESNext.ts Pass
tests/cases/conformance/es2020/constructBigint.ts Fail
tests/cases/conformance/es2020/constructBigint.ts Pass
tests/cases/conformance/es2020/es2020IntlAPIs.ts Fail
tests/cases/conformance/es2020/intlNumberFormatES2020.ts Pass
tests/cases/conformance/es2020/localesObjectArgument.ts Pass
Expand Down Expand Up @@ -71,7 +71,7 @@ tests/cases/conformance/es2023/intlNumberFormatES5UseGrouping.ts Fail
tests/cases/conformance/es6/Symbols/symbolDeclarationEmit1.ts Pass
tests/cases/conformance/es6/Symbols/symbolDeclarationEmit10.ts Pass
tests/cases/conformance/es6/Symbols/symbolDeclarationEmit11.ts Pass
tests/cases/conformance/es6/Symbols/symbolDeclarationEmit12.ts Fail
tests/cases/conformance/es6/Symbols/symbolDeclarationEmit12.ts Pass
tests/cases/conformance/es6/Symbols/symbolDeclarationEmit13.ts Pass
tests/cases/conformance/es6/Symbols/symbolDeclarationEmit14.ts Pass
tests/cases/conformance/es6/Symbols/symbolDeclarationEmit2.ts Pass
Expand All @@ -83,14 +83,14 @@ tests/cases/conformance/es6/Symbols/symbolDeclarationEmit7.ts Pass
tests/cases/conformance/es6/Symbols/symbolDeclarationEmit8.ts Pass
tests/cases/conformance/es6/Symbols/symbolDeclarationEmit9.ts Pass
tests/cases/conformance/es6/Symbols/symbolProperty1.ts Pass
tests/cases/conformance/es6/Symbols/symbolProperty10.ts Fail
tests/cases/conformance/es6/Symbols/symbolProperty11.ts Fail
tests/cases/conformance/es6/Symbols/symbolProperty12.ts Fail
tests/cases/conformance/es6/Symbols/symbolProperty10.ts Pass
tests/cases/conformance/es6/Symbols/symbolProperty11.ts Pass
tests/cases/conformance/es6/Symbols/symbolProperty12.ts Pass
tests/cases/conformance/es6/Symbols/symbolProperty13.ts Pass
tests/cases/conformance/es6/Symbols/symbolProperty14.ts Pass
tests/cases/conformance/es6/Symbols/symbolProperty15.ts Pass
tests/cases/conformance/es6/Symbols/symbolProperty16.ts Pass
tests/cases/conformance/es6/Symbols/symbolProperty17.ts Fail
tests/cases/conformance/es6/Symbols/symbolProperty17.ts Pass
tests/cases/conformance/es6/Symbols/symbolProperty18.ts Pass
tests/cases/conformance/es6/Symbols/symbolProperty19.ts Pass
tests/cases/conformance/es6/Symbols/symbolProperty2.ts Pass
Expand All @@ -104,23 +104,23 @@ tests/cases/conformance/es6/Symbols/symbolProperty26.ts Pass
tests/cases/conformance/es6/Symbols/symbolProperty27.ts Pass
tests/cases/conformance/es6/Symbols/symbolProperty28.ts Pass
tests/cases/conformance/es6/Symbols/symbolProperty29.ts Pass
tests/cases/conformance/es6/Symbols/symbolProperty3.ts Fail
tests/cases/conformance/es6/Symbols/symbolProperty30.ts Fail
tests/cases/conformance/es6/Symbols/symbolProperty3.ts Pass
tests/cases/conformance/es6/Symbols/symbolProperty30.ts Pass
tests/cases/conformance/es6/Symbols/symbolProperty31.ts Pass
tests/cases/conformance/es6/Symbols/symbolProperty32.ts Fail
tests/cases/conformance/es6/Symbols/symbolProperty33.ts Fail
tests/cases/conformance/es6/Symbols/symbolProperty32.ts Pass
tests/cases/conformance/es6/Symbols/symbolProperty33.ts Pass
tests/cases/conformance/es6/Symbols/symbolProperty34.ts Fail
tests/cases/conformance/es6/Symbols/symbolProperty35.ts Fail
tests/cases/conformance/es6/Symbols/symbolProperty36.ts Fail
tests/cases/conformance/es6/Symbols/symbolProperty35.ts Pass
tests/cases/conformance/es6/Symbols/symbolProperty36.ts Pass
tests/cases/conformance/es6/Symbols/symbolProperty37.ts TypeCheckError
tests/cases/conformance/es6/Symbols/symbolProperty38.ts Pass
tests/cases/conformance/es6/Symbols/symbolProperty39.ts Fail
tests/cases/conformance/es6/Symbols/symbolProperty39.ts Pass
tests/cases/conformance/es6/Symbols/symbolProperty4.ts Pass
tests/cases/conformance/es6/Symbols/symbolProperty40.ts Pass
tests/cases/conformance/es6/Symbols/symbolProperty41.ts Pass
tests/cases/conformance/es6/Symbols/symbolProperty42.ts Fail
tests/cases/conformance/es6/Symbols/symbolProperty43.ts Fail
tests/cases/conformance/es6/Symbols/symbolProperty44.ts Fail
tests/cases/conformance/es6/Symbols/symbolProperty42.ts Pass
tests/cases/conformance/es6/Symbols/symbolProperty43.ts Pass
tests/cases/conformance/es6/Symbols/symbolProperty44.ts Pass
tests/cases/conformance/es6/Symbols/symbolProperty45.ts Pass
tests/cases/conformance/es6/Symbols/symbolProperty46.ts Fail
tests/cases/conformance/es6/Symbols/symbolProperty47.ts Fail
Expand All @@ -129,9 +129,9 @@ tests/cases/conformance/es6/Symbols/symbolProperty49.ts Pass
tests/cases/conformance/es6/Symbols/symbolProperty5.ts Pass
tests/cases/conformance/es6/Symbols/symbolProperty50.ts Pass
tests/cases/conformance/es6/Symbols/symbolProperty51.ts Pass
tests/cases/conformance/es6/Symbols/symbolProperty52.ts Skipped:lib-drift
tests/cases/conformance/es6/Symbols/symbolProperty53.ts Fail
tests/cases/conformance/es6/Symbols/symbolProperty54.ts Fail
tests/cases/conformance/es6/Symbols/symbolProperty52.ts Pass
tests/cases/conformance/es6/Symbols/symbolProperty53.ts Pass
tests/cases/conformance/es6/Symbols/symbolProperty54.ts Pass
tests/cases/conformance/es6/Symbols/symbolProperty55.ts Fail
tests/cases/conformance/es6/Symbols/symbolProperty56.ts Pass
tests/cases/conformance/es6/Symbols/symbolProperty57.ts Pass
Expand All @@ -140,23 +140,23 @@ tests/cases/conformance/es6/Symbols/symbolProperty59.ts Fail
tests/cases/conformance/es6/Symbols/symbolProperty6.ts Pass
tests/cases/conformance/es6/Symbols/symbolProperty60.ts Pass
tests/cases/conformance/es6/Symbols/symbolProperty61.ts Fail
tests/cases/conformance/es6/Symbols/symbolProperty7.ts Fail
tests/cases/conformance/es6/Symbols/symbolProperty7.ts Pass
tests/cases/conformance/es6/Symbols/symbolProperty8.ts Pass
tests/cases/conformance/es6/Symbols/symbolProperty9.ts Fail
tests/cases/conformance/es6/Symbols/symbolProperty9.ts Pass
tests/cases/conformance/es6/Symbols/symbolType1.ts Fail
tests/cases/conformance/es6/Symbols/symbolType10.ts Pass
tests/cases/conformance/es6/Symbols/symbolType11.ts Pass
tests/cases/conformance/es6/Symbols/symbolType12.ts Pass
tests/cases/conformance/es6/Symbols/symbolType13.ts Fail
tests/cases/conformance/es6/Symbols/symbolType14.ts Fail
tests/cases/conformance/es6/Symbols/symbolType13.ts Pass
tests/cases/conformance/es6/Symbols/symbolType14.ts Pass
tests/cases/conformance/es6/Symbols/symbolType15.ts Fail
tests/cases/conformance/es6/Symbols/symbolType16.ts Pass
tests/cases/conformance/es6/Symbols/symbolType17.ts Pass
tests/cases/conformance/es6/Symbols/symbolType18.ts Pass
tests/cases/conformance/es6/Symbols/symbolType19.ts Pass
tests/cases/conformance/es6/Symbols/symbolType2.ts Fail
tests/cases/conformance/es6/Symbols/symbolType20.ts Fail
tests/cases/conformance/es6/Symbols/symbolType3.ts Fail
tests/cases/conformance/es6/Symbols/symbolType2.ts Pass
tests/cases/conformance/es6/Symbols/symbolType20.ts Pass
tests/cases/conformance/es6/Symbols/symbolType3.ts Pass
tests/cases/conformance/es6/Symbols/symbolType4.ts Pass
tests/cases/conformance/es6/Symbols/symbolType5.ts Pass
tests/cases/conformance/es6/Symbols/symbolType6.ts Pass
Expand Down Expand Up @@ -247,17 +247,17 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotA
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/nullIsSubtypeOfEverythingButUndefined.ts Pass
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/stringLiteralTypeIsSubtypeOfString.ts Fail
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfAny.ts Pass
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameter.ts Fail
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameter.ts Pass
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts Pass
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints2.ts Fail
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints3.ts Fail
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts Fail
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints2.ts Pass
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints3.ts Pass
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts Pass
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts Fail
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts Pass
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithCallSignatures.ts Pass
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithCallSignatures2.ts Fail
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithCallSignatures3.ts Fail
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithCallSignatures4.ts Fail
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithCallSignatures2.ts Pass
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithCallSignatures3.ts Pass
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithCallSignatures4.ts Pass
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithCallSignaturesA.ts Pass
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithCallSignaturesWithOptionalParameters.ts Pass
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithCallSignaturesWithRestParameters.ts Pass
Expand Down Expand Up @@ -288,7 +288,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembersOptionality2.ts Pass
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembersOptionality3.ts Pass
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembersOptionality4.ts Pass
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithOptionalProperties.ts Fail
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithOptionalProperties.ts Pass
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithStringIndexer.ts Pass
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithStringIndexer2.ts Pass
tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithStringIndexer3.ts Pass
Expand Down
6 changes: 4 additions & 2 deletions TypeSystem/TypeChecker.Calls.cs
Original file line number Diff line number Diff line change
Expand Up @@ -417,9 +417,11 @@ private bool TryCheckBuiltinCall(Expr.Call call, out TypeInfo result)
throw new TypeCheckException("BigInt() requires exactly one argument.", tsCode: "TS2554");
}
var argType = CheckExpr(call.Arguments[0]);
if (!IsNumber(argType) && !IsString(argType) && !IsBigInt(argType) && argType is not TypeInfo.Any)
// BigInt's parameter type is `string | number | bigint | boolean` (a boolean coerces to 0n/1n).
bool isBoolean = argType is TypeInfo.Primitive { Type: TokenType.TYPE_BOOLEAN } or TypeInfo.BooleanLiteral;
if (!IsNumber(argType) && !IsString(argType) && !IsBigInt(argType) && !isBoolean && argType is not TypeInfo.Any)
{
throw new TypeCheckException($"BigInt() argument must be a number, string, or bigint, got '{argType}'.", tsCode: "TS2345");
throw new TypeCheckException($"BigInt() argument must be a number, string, bigint, or boolean, got '{argType}'.", tsCode: "TS2345");
}
{ result = new TypeInfo.BigInt(); return true; }
}
Expand Down
9 changes: 7 additions & 2 deletions TypeSystem/TypeChecker.Compatibility.Helpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -784,7 +784,8 @@ private Dictionary<string, TypeInfo> CollectGenericClassMembers(TypeInfo.Generic
/// generic type arguments substituted. Returns false for branded or member-less/index-less targets
/// (those stay nominal).
/// </summary>
private bool StructurallyAssignableToClassTarget(TypeInfo targetResolved, TypeInfo source)
private bool StructurallyAssignableToClassTarget(TypeInfo targetResolved, TypeInfo source,
bool emptyTargetAcceptsObjectSource = false)
{
Dictionary<string, TypeInfo> members;
bool hasIndex;
Expand Down Expand Up @@ -813,7 +814,11 @@ private bool StructurallyAssignableToClassTarget(TypeInfo targetResolved, TypeIn
default:
return false;
}
if (members.Count == 0 && !hasIndex) return false;
// A member-less, index-less unbranded target is structurally `{}`. For class-vs-class this
// stays nominal (caller passes false, preserving subclass-safety), but an object-like source
// (interface value / record) IS assignable to `{}` — that's the emptyTargetAcceptsObjectSource
// path, so `interface I → empty class C` no longer spuriously fails.
if (members.Count == 0 && !hasIndex) return emptyTargetAcceptsObjectSource;
return CheckStructuralCompatibility(members, source) && IndexSignaturesSatisfied(indexCarrier, source);
}

Expand Down
17 changes: 16 additions & 1 deletion TypeSystem/TypeChecker.Compatibility.Relations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,22 @@ private bool TryRelateTypeParameters(TypeInfo expected, TypeInfo actual, out boo
return true;
}
var apparent = ApparentTypeOf(actualTpOnly);
result = apparent != null && IsCompatible(expected, apparent);
if (apparent == null)
{
// An unconstrained type parameter has no apparent (constraint) type. tsc still relates
// it to a target that requires NO members — an all-optional / empty object type — its
// "subtyping assumes transitivity for optional properties (99% case)" allowance. It is
// NOT assignable to a primitive, `object`, or any target with a required member.
result = expected switch
{
TypeInfo.Record rec => HasNoRequiredMembers(rec),
TypeInfo.Interface itf => !itf.HasIndexSignature && !itf.IsCallable && !itf.IsConstructable
&& itf.GetAllMembers().All(m => itf.GetAllOptionalMembers().Contains(m.Key)),
_ => false
};
return true;
}
result = IsCompatible(expected, apparent);
return true;
}
result = false;
Expand Down
19 changes: 18 additions & 1 deletion TypeSystem/TypeChecker.Compatibility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,23 @@ private bool IsCompatibleCore(TypeInfo expected, TypeInfo actual)
if (!_strictNullChecks && actual is TypeInfo.Null or TypeInfo.Undefined)
return expected is not TypeInfo.Never;

// Namespace/module types (typeof someNamespace / typeof import(...)) have no dedicated
// relation anywhere below, so two structurally-identical namespaces — even the exact same
// one referenced twice, e.g. `true ? af : null` vs `true ? null : af` — fell through to the
// generic `return false` at the bottom, making a namespace type spuriously incompatible with
// ITSELF. Relate them structurally, like an object/record: every member `expected` exposes
// must exist on `actual` with a compatible type.
if (expected is TypeInfo.Namespace expNs && actual is TypeInfo.Namespace actNs)
{
return expNs.Types.All(kv => actNs.Types.TryGetValue(kv.Key, out var t) && IsCompatible(kv.Value, t))
&& expNs.Values.All(kv => actNs.Values.TryGetValue(kv.Key, out var v) && IsCompatible(kv.Value, v));
}
if (expected is TypeInfo.Module expMod && actual is TypeInfo.Module actMod)
{
return expMod.Exports.All(kv => actMod.Exports.TryGetValue(kv.Key, out var v) && IsCompatible(kv.Value, v))
&& (expMod.DefaultExport is null || (actMod.DefaultExport is not null && IsCompatible(expMod.DefaultExport, actMod.DefaultExport)));
}

// Expand recursive type aliases lazily
if (expected is TypeInfo.RecursiveTypeAlias expectedRTA)
{
Expand Down Expand Up @@ -970,7 +987,7 @@ actualIG.GenericDefinition is TypeInfo.GenericClass gc2 &&
// interface/record) are handled by the structural paths below.
if (expected is TypeInfo.Instance targetInst &&
actual is TypeInfo.Interface or TypeInfo.Record &&
StructurallyAssignableToClassTarget(targetInst.ResolvedClassType, actual))
StructurallyAssignableToClassTarget(targetInst.ResolvedClassType, actual, emptyTargetAcceptsObjectSource: true))
{
return true;
}
Expand Down
Loading
Loading