Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Widening and non-widening computed enum types #52542

Merged
merged 6 commits into from
Feb 15, 2023
Merged

Widening and non-widening computed enum types #52542

merged 6 commits into from
Feb 15, 2023

Conversation

ahejlsberg
Copy link
Member

Fixes #52531.

@typescript-bot typescript-bot added Author: Team For Milestone Bug PRs that fix a bug with a specific milestone labels Feb 1, 2023
@ahejlsberg
Copy link
Member Author

@typescript-bot test this
@typescript-bot user test this inline
@typescript-bot run dt
@typescript-bot perf test faster
@typescript-bot test top100

@typescript-bot
Copy link
Collaborator

typescript-bot commented Feb 1, 2023

Heya @ahejlsberg, I've started to run the extended test suite on this PR at a84ac81. You can monitor the build here.

@typescript-bot
Copy link
Collaborator

typescript-bot commented Feb 1, 2023

Heya @ahejlsberg, I've started to run the abridged perf test suite on this PR at a84ac81. You can monitor the build here.

Update: The results are in!

@typescript-bot
Copy link
Collaborator

typescript-bot commented Feb 1, 2023

Heya @ahejlsberg, I've started to run the diff-based user code test suite on this PR at a84ac81. You can monitor the build here.

Update: The results are in!

@typescript-bot
Copy link
Collaborator

typescript-bot commented Feb 1, 2023

Heya @ahejlsberg, I've started to run the parallelized Definitely Typed test suite on this PR at a84ac81. You can monitor the build here.

@typescript-bot
Copy link
Collaborator

typescript-bot commented Feb 1, 2023

Heya @ahejlsberg, I've started to run the diff-based top-repos suite on this PR at a84ac81. You can monitor the build here.

Update: The results are in!

@typescript-bot
Copy link
Collaborator

@ahejlsberg Here are the results of running the user test suite comparing main and refs/pull/52542/merge:

Everything looks good!

@typescript-bot
Copy link
Collaborator

@ahejlsberg
The results of the perf run you requested are in!

Here they are:

Comparison Report - main..52542

Metric main 52542 Delta Best Worst
Angular - node (v16.17.1, x64)
Memory used 359,200k (± 0.01%) 359,222k (± 0.00%) +22k (+ 0.01%) 359,196k 359,241k
Parse Time 4.19s (± 0.39%) 4.18s (± 0.20%) -0.01s (- 0.20%) 4.17s 4.19s
Bind Time 1.22s (± 0.67%) 1.22s (± 0.62%) -0.01s (- 0.41%) 1.21s 1.23s
Check Time 9.42s (± 0.53%) 9.42s (± 0.48%) +0.00s (+ 0.04%) 9.37s 9.49s
Emit Time 8.08s (± 0.29%) 8.07s (± 0.34%) -0.01s (- 0.12%) 8.04s 8.11s
Total Time 22.91s (± 0.32%) 22.89s (± 0.28%) -0.02s (- 0.07%) 22.80s 22.98s
Compiler-Unions - node (v16.17.1, x64)
Memory used 194,197k (± 0.02%) 194,179k (± 0.02%) -18k (- 0.01%) 194,121k 194,224k
Parse Time 1.80s (± 1.34%) 1.81s (± 0.23%) +0.01s (+ 0.28%) 1.80s 1.81s
Bind Time 0.84s (± 0.89%) 0.85s (± 0.61%) +0.01s (+ 0.59%) 0.84s 0.85s
Check Time 10.36s (± 0.43%) 10.40s (± 0.41%) +0.04s (+ 0.42%) 10.33s 10.46s
Emit Time 3.07s (± 0.97%) 3.04s (± 0.57%) -0.03s (- 0.87%) 3.02s 3.06s
Total Time 16.07s (± 0.33%) 16.10s (± 0.38%) +0.03s (+ 0.22%) 16.02s 16.19s
Monaco - node (v16.17.1, x64)
Memory used 343,250k (± 0.01%) 343,626k (± 0.01%) +376k (+ 0.11%) 343,600k 343,680k
Parse Time 3.17s (± 0.94%) 3.20s (± 1.06%) +0.03s (+ 1.00%) 3.17s 3.26s
Bind Time 1.12s (± 0.49%) 1.12s (± 0.46%) +0.00s (+ 0.15%) 1.11s 1.12s
Check Time 7.75s (± 0.41%) 7.76s (± 0.57%) +0.02s (+ 0.24%) 7.69s 7.81s
Emit Time 4.53s (± 0.68%) 4.53s (± 0.70%) +0.00s (+ 0.04%) 4.49s 4.58s
Total Time 16.55s (± 0.24%) 16.61s (± 0.45%) +0.06s (+ 0.35%) 16.53s 16.74s
TFS - node (v16.17.1, x64)
Memory used 299,770k (± 0.01%) 299,784k (± 0.00%) +14k (+ 0.00%) 299,770k 299,805k
Parse Time 2.50s (± 1.63%) 2.48s (± 0.97%) -0.02s (- 1.00%) 2.45s 2.51s
Bind Time 1.26s (± 0.65%) 1.26s (± 0.67%) -0.00s (- 0.13%) 1.24s 1.26s
Check Time 7.19s (± 0.38%) 7.20s (± 0.33%) +0.01s (+ 0.16%) 7.17s 7.24s
Emit Time 4.23s (± 0.61%) 4.23s (± 0.60%) -0.00s (- 0.08%) 4.20s 4.27s
Total Time 15.18s (± 0.30%) 15.16s (± 0.30%) -0.02s (- 0.12%) 15.09s 15.21s
material-ui - node (v16.17.1, x64)
Memory used 476,052k (± 0.02%) 476,118k (± 0.02%) +66k (+ 0.01%) 476,021k 476,207k
Parse Time 3.71s (± 0.24%) 3.73s (± 0.43%) +0.02s (+ 0.49%) 3.72s 3.76s
Bind Time 1.02s (± 0.40%) 1.02s (± 0.40%) +0.00s (+ 0.33%) 1.02s 1.03s
Check Time 18.11s (± 0.24%) 18.07s (± 0.35%) -0.04s (- 0.21%) 18.00s 18.17s
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) 0.00s ( NaN%) 0.00s 0.00s
Total Time 22.84s (± 0.20%) 22.82s (± 0.32%) -0.02s (- 0.07%) 22.74s 22.95s
xstate - node (v16.17.1, x64)
Memory used 546,305k (± 0.02%) 546,297k (± 0.02%) -8k (- 0.00%) 546,179k 546,483k
Parse Time 4.78s (± 0.48%) 4.77s (± 0.54%) -0.01s (- 0.28%) 4.74s 4.81s
Bind Time 1.78s (± 5.02%) 1.80s (± 3.97%) +0.02s (+ 1.12%) 1.66s 1.85s
Check Time 3.03s (± 3.33%) 3.01s (± 2.52%) -0.03s (- 0.93%) 2.96s 3.16s
Emit Time 0.09s (± 5.53%) 0.10s (± 4.15%) +0.00s (+ 5.36%) 0.09s 0.10s
Total Time 9.70s (± 0.14%) 9.67s (± 0.38%) -0.02s (- 0.24%) 9.61s 9.71s
System
Machine Namets-ci-ubuntu
Platformlinux 5.4.0-135-generic
Architecturex64
Available Memory16 GB
Available Memory15 GB
CPUs4 × Intel(R) Core(TM) i7-4770 CPU @ 3.40GHz
Hosts
  • node (v16.17.1, x64)
Scenarios
  • Angular - node (v16.17.1, x64)
  • Compiler-Unions - node (v16.17.1, x64)
  • Monaco - node (v16.17.1, x64)
  • TFS - node (v16.17.1, x64)
  • material-ui - node (v16.17.1, x64)
  • xstate - node (v16.17.1, x64)
Benchmark Name Iterations
Current 52542 6
Baseline main 6

Developer Information:

Download Benchmark

@typescript-bot
Copy link
Collaborator

Heya @ahejlsberg, I've run the RWC suite on this PR - assuming you're on the TS core team, you can view the resulting diff here.

@typescript-bot
Copy link
Collaborator

@ahejlsberg Here are the results of running the top-repos suite comparing main and refs/pull/52542/merge:

Everything looks good!

}
return type;
}

function getRegularTypeOfLiteralType(type: Type): Type {
return type.flags & TypeFlags.Literal ? (type as LiteralType).regularType :
return type.flags & TypeFlags.Freshable ? (type as FreshableType).regularType :
type.flags & TypeFlags.Union ? ((type as UnionType).regularType || ((type as UnionType).regularType = mapType(type, getRegularTypeOfLiteralType) as UnionType)) :
type;
}

function isFreshLiteralType(type: Type) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

perhaps this "family" of functions could be renamed now? they all (isFreshLiteralType, getRegularTypeOfLiteralType, getFreshTypeOfLiteralType, getRegularTypeOfLiteralType) mention "literal" type but now they will also handle enums and enums are not literal types

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, but isFreshFreshableType and getFreshTypeOfFreshableType are pretty awful. 😮

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, can't argue that 😅 OTOH, those names would be more correct - they sound a little bit weird at first but if we focus on their meaning, it makes sense.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fresh type of bel-air!

I suppose it could be argued that Enum.A is an “enum literal”, even if it’s not a literal in the grammatical sense. The compiler is treating it as one in a way by giving it its own nominal type (Enum)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main problem from my PoV, is that "literal" is already used in the codebase and it often doesn't include enums:

Literal = StringLiteral | NumberLiteral | BigIntLiteral | BooleanLiteral,

I see now though that EnumLiteral also exist so maybe it isn't a big deal.

@ahejlsberg
Copy link
Member Author

Tests and performance all look good.

Copy link
Member

@weswigham weswigham left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think since these are freshable now, we need a declaration emit test that validates we write out initializers for the fresh variant in declaration emit, eg,

declare function computed(x: number): number;

enum E {
    A = computed(0),
    B = computed(1),
    C = computed(2),
    D = computed(3),
}

export class A {
  prop = E.A;
}

needs to emit

export declare class A {
  prop = E.A;
}

rather than

export class A {
  prop: E;
}

(and that needs to not read back in as an error in a declaration file if it does right now, since it does serve a semantic purpose - preserving freshness)

@ahejlsberg
Copy link
Member Author

I think since these are freshable now, we need a declaration emit test that validates we write out initializers for the fresh variant in declaration emit

Agreed, though your example wouldn't validate that since class properties are mutable locations and their inferred types are always widened. But we should have an example of a const declaration with a fresh enum initializer.


class C {
p1 = E.B;
p2 = E.B as const;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A readonly p3 = E.B would be another good addition, since that one should be like a const declaration, iirc.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed.

@@ -6028,7 +6028,8 @@ export const enum TypeFlags {
/** @internal */
Nullable = Undefined | Null,
Literal = StringLiteral | NumberLiteral | BigIntLiteral | BooleanLiteral,
Unit = Literal | UniqueESSymbol | Nullable,
Unit = Enum | Literal | UniqueESSymbol | Nullable,
Freshable = Enum | Literal,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Freshable = Enum | Literal,
/** @internal */
Freshable = Enum | Literal,

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I intended for this to be public.

Comment on lines -6125 to +6128
/** @internal */
export interface FreshableIntrinsicType extends IntrinsicType {
freshType: IntrinsicType; // Fresh version of type
regularType: IntrinsicType; // Regular version of type
export interface FreshableType extends Type {
freshType: FreshableType; // Fresh version of type
regularType: FreshableType; // Regular version of type
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was this intended to be public API now?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes.


// String literal types (TypeFlags.StringLiteral)
// Numeric literal types (TypeFlags.NumberLiteral)
// BigInt literal types (TypeFlags.BigIntLiteral)
export interface LiteralType extends Type {
export interface LiteralType extends FreshableType {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could technically still keep FreshableType if you left the members in place.

export interface LiteralType extends FreshableType {}
export interface LiteralType {
    freshType: LiteralType;
    regularType: LiteralType;

@ahejlsberg
Copy link
Member Author

I think all feedback has been addressed, can I get another review please?

@ahejlsberg ahejlsberg merged commit 7d00bb0 into main Feb 15, 2023
@ahejlsberg ahejlsberg deleted the fix52531 branch February 15, 2023 00:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Author: Team For Milestone Bug PRs that fix a bug with a specific milestone
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

Type inference for declared enum member assignment
7 participants