Skip to content

Preserve Class<T> type arguments#1763

Closed
RushikeshGandhmal wants to merge 1 commit into
apple:mainfrom
RushikeshGandhmal:fix/1729-preserve-class-type-args
Closed

Preserve Class<T> type arguments#1763
RushikeshGandhmal wants to merge 1 commit into
apple:mainfrom
RushikeshGandhmal:fix/1729-preserve-class-type-args

Conversation

@RushikeshGandhmal

Copy link
Copy Markdown

Fixes #1729

Previously, Class<T> was explicitly erased to Class during type resolution, so C is Class<A> could not be distinguished from C is Class<B>.

This change introduces a ClassValueTypeNode that:

  • preserves the type argument through type resolution and runtime checks
  • validates class values by requiring the represented class to be a subclass of the type argument
  • rejects invalid concrete type arguments such as unions, nullables, constrained types, parameterized types, and modules
  • still allows type variables like Class<Type> used in stdlib generic signatures

A regression test is added covering:

  • positive cases (C is Class<A> vs Class<B>)
  • aliases to class types and alias-preserving generics
  • exported schema preservation
  • stdlib compatibility with type variables
  • rejection of invalid Class<T> arguments

Previously, `Class<T>` was explicitly erased to `Class` during type
resolution, so type checks like `C is Class<A>` could not distinguish
between `A` and `B`.

Replace the erasure with a dedicated `ClassValueTypeNode` that keeps
the type argument and validates it at runtime. Class values now pass
type checks only when their represented class is a subclass of the
type argument.

Also reject invalid `Class<T>` arguments such as unions, nullables,
constrained types, parameterized types, and modules with a clear error
message.

Fixes apple#1729.
@RushikeshGandhmal
RushikeshGandhmal force-pushed the fix/1729-preserve-class-type-args branch from 0d3e01f to a13c7f2 Compare July 12, 2026 13:42
@RushikeshGandhmal

Copy link
Copy Markdown
Author

Hi @bioball -- this is a more substantial type-system fix for #1729. I kept the change focused on Class resolution and used the existing ValidatingObjectSlotTypeNode pattern for validation. The regression test covers both the new semantics and the stdlib compatibility case. Thanks for taking a look!

@HT154

HT154 commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

This appears to be a duplicate of #1698. If you have input on this change, I would encourage you to discuss there so we can avoid splitting the discussion.

@RushikeshGandhmal

Copy link
Copy Markdown
Author

Thanks for pointing this out. I missed #1698, and after comparing the implementations I agree that #1763 overlaps it. I’ll close this PR and move the additional schema-export observation and regression test to #1698 so the discussion stays in one place.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Class<T> is always type-erased to Class

2 participants