Skip to content

Commit cfcdaba

Browse files
committed
Merge worker-8
2 parents 181040c + 7fe1b2a commit cfcdaba

2 files changed

Lines changed: 23 additions & 0 deletions

File tree

wasm/src/solver/compat.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ pub struct CompatChecker<'a, R: TypeResolver = NoopResolver> {
2222
strict_null_checks: bool,
2323
no_unchecked_indexed_access: bool,
2424
exact_optional_property_types: bool,
25+
/// When true, enables additional strict subtype checking rules for lib.d.ts
26+
strict_subtype_checking: bool,
2527
cache: FxHashMap<(TypeId, TypeId), bool>,
2628
}
2729

@@ -36,6 +38,7 @@ impl<'a> CompatChecker<'a, NoopResolver> {
3638
strict_null_checks: true,
3739
no_unchecked_indexed_access: false,
3840
exact_optional_property_types: false,
41+
strict_subtype_checking: false,
3942
cache: FxHashMap::default(),
4043
}
4144
}
@@ -52,6 +55,7 @@ impl<'a, R: TypeResolver> CompatChecker<'a, R> {
5255
strict_null_checks: true,
5356
no_unchecked_indexed_access: false,
5457
exact_optional_property_types: false,
58+
strict_subtype_checking: false,
5559
cache: FxHashMap::default(),
5660
}
5761
}
@@ -91,6 +95,18 @@ impl<'a, R: TypeResolver> CompatChecker<'a, R> {
9195
}
9296

9397
/// Configure strict mode for `any` propagation.
98+
99+
/// Configure strict subtype checking mode for lib.d.ts type checking.
100+
///
101+
/// When enabled, applies additional strictness rules that reject borderline
102+
/// cases allowed by TypeScript's legacy behavior. This includes disabling
103+
/// method bivariance for soundness.
104+
pub fn set_strict_subtype_checking(&mut self, strict: bool) {
105+
if self.strict_subtype_checking != strict {
106+
self.strict_subtype_checking = strict;
107+
self.cache.clear();
108+
}
109+
}
94110
///
95111
/// When strict mode is enabled, `any` does NOT silence structural mismatches.
96112
/// This means the type checker will still report errors even when `any` is involved,
@@ -235,6 +251,8 @@ impl<'a, R: TypeResolver> CompatChecker<'a, R> {
235251
self.subtype.exact_optional_property_types = self.exact_optional_property_types;
236252
self.subtype.strict_null_checks = self.strict_null_checks;
237253
self.subtype.no_unchecked_indexed_access = self.no_unchecked_indexed_access;
254+
// In strict mode, disable method bivariance for soundness
255+
self.subtype.disable_method_bivariance = self.strict_subtype_checking;
238256
}
239257

240258
fn violates_weak_type(&self, source: TypeId, target: TypeId) -> bool {

wasm/src/solver/subtype.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,9 @@ pub struct SubtypeChecker<'a, R: TypeResolver = NoopResolver> {
174174
pub no_unchecked_indexed_access: bool,
175175
/// Whether to enforce weak type detection (optional-only targets require overlap).
176176
pub enforce_weak_types: bool,
177+
// When true, disables method bivariance (methods use contravariance).
178+
// Default: false (methods are bivariant in TypeScript for compatibility).
179+
pub disable_method_bivariance: bool,
177180
}
178181

179182
impl<'a> SubtypeChecker<'a, NoopResolver> {
@@ -193,6 +196,7 @@ impl<'a> SubtypeChecker<'a, NoopResolver> {
193196
strict_null_checks: true,
194197
no_unchecked_indexed_access: false,
195198
enforce_weak_types: true, // Enable to catch weak type violations (TS2559)
199+
disable_method_bivariance: false,
196200
}
197201
}
198202
}
@@ -213,6 +217,7 @@ impl<'a, R: TypeResolver> SubtypeChecker<'a, R> {
213217
strict_null_checks: true,
214218
no_unchecked_indexed_access: false,
215219
enforce_weak_types: true, // Enable to catch weak type violations (TS2559)
220+
disable_method_bivariance: false,
216221
}
217222
}
218223

0 commit comments

Comments
 (0)