Skip to content

Commit 3e92dee

Browse files
committed
Merge worker-7
2 parents d24cf5c + 5eb1ade commit 3e92dee

1 file changed

Lines changed: 12 additions & 8 deletions

File tree

wasm/src/solver/subtype.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -290,9 +290,10 @@ impl<'a, R: TypeResolver> SubtypeChecker<'a, R> {
290290
// =========================================================================
291291

292292
if self.depth > 100 {
293-
// Recursion too deep - return provisional true to prevent stack overflow
294-
// This is a safety measure for deeply nested or expanding recursive types
295-
return SubtypeResult::Provisional;
293+
// Recursion too deep - return false to be conservative and prevent stack overflow
294+
// This ensures complex generics don't silently accept invalid code
295+
// Note: This differs from coinductive cycle detection which returns Provisional
296+
return SubtypeResult::False;
296297
}
297298

298299
// =========================================================================
@@ -510,9 +511,11 @@ impl<'a, R: TypeResolver> SubtypeChecker<'a, R> {
510511
(None, Some(_)) => {
511512
return SubtypeResult::False;
512513
}
513-
// Both unconstrained - they both act like unknown, so they're compatible
514+
// Both unconstrained - different type parameters are not guaranteed compatible
515+
// T <: U is only sound if we know T = U (handled above by name check)
516+
// Two different unconstrained parameters could be instantiated to incompatible types
514517
(None, None) => {
515-
return SubtypeResult::True;
518+
return SubtypeResult::False;
516519
}
517520
}
518521
}
@@ -524,9 +527,10 @@ impl<'a, R: TypeResolver> SubtypeChecker<'a, R> {
524527
}
525528

526529
// Unconstrained type parameter acts like `unknown` (top type)
527-
// It is assignable to any type (but not vice versa)
528-
// Since we're checking `source <: target`, unknown <: anything is TRUE
529-
SubtypeResult::True
530+
// Since unknown is a TOP type: T <: unknown is TRUE, but unknown <: T is FALSE
531+
// An unconstrained type param as source cannot be assigned to a concrete target
532+
// because the param could be instantiated to an incompatible type
533+
SubtypeResult::False
530534
}
531535

532536
// object keyword accepts any non-primitive type

0 commit comments

Comments
 (0)