Use context free expression types in evolving array checking and cache context free type (#26585)

* Use context free expression types in evolving array checking and cache context free type

* Simplify second test

* Low max depth a tad just so node 8 wont stack out

* By request make flow control a round number
This commit is contained in:
Wesley Wigham 2018-08-22 16:17:42 -07:00 committed by GitHub
parent 194ffb3449
commit 5e8b63cd1d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 6277 additions and 4 deletions

View File

@ -14433,8 +14433,8 @@ namespace ts {
return resultType;
function getTypeAtFlowNode(flow: FlowNode): FlowType {
if (flowDepth === 2500) {
// We have made 2500 recursive invocations. To avoid overflowing the call stack we report an error
if (flowDepth === 2000) {
// We have made 2000 recursive invocations. To avoid overflowing the call stack we report an error
// and disable further control flow analysis in the containing function or module body.
flowAnalysisDisabled = true;
reportFlowControlError(reference);
@ -14574,7 +14574,8 @@ namespace ts {
}
}
else {
const indexType = getTypeOfExpression((<ElementAccessExpression>node.left).argumentExpression);
// We must get the context free expression type so as to not recur in an uncached fashion on the LHS (which causes exponential blowup in compile time)
const indexType = getContextFreeTypeOfExpression((<ElementAccessExpression>node.left).argumentExpression);
if (isTypeAssignableToKind(indexType, TypeFlags.NumberLike)) {
evolvedType = addEvolvingArrayElementType(evolvedType, node.right);
}
@ -21720,9 +21721,13 @@ namespace ts {
* It sets the contextual type of the node to any before calling getTypeOfExpression.
*/
function getContextFreeTypeOfExpression(node: Expression) {
const links = getNodeLinks(node);
if (links.contextFreeType) {
return links.contextFreeType;
}
const saveContextualType = node.contextualType;
node.contextualType = anyType;
const type = getTypeOfExpression(node);
const type = links.contextFreeType = checkExpression(node, CheckMode.SkipContextSensitive);
node.contextualType = saveContextualType;
return type;
}

View File

@ -0,0 +1,158 @@
=== tests/cases/compiler/foo.js ===
// repro from #26031
function build() {
>build : Symbol(build, Decl(foo.js, 0, 0))
var arr = [];
>arr : Symbol(arr, Decl(foo.js, 2, 7))
arr[arr.length] = 'value';
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>arr.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
arr[arr.length] = 'value';
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>arr.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
arr[arr.length] = 'value';
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>arr.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
arr[arr.length] = 'value';
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>arr.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
arr[arr.length] = 'value';
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>arr.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
arr[arr.length] = 'value';
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>arr.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
arr[arr.length] = 'value';
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>arr.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
arr[arr.length] = 'value';
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>arr.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
arr[arr.length] = 'value';
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>arr.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
arr[arr.length] = 'value';
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>arr.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
arr[arr.length] = 'value';
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>arr.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
arr[arr.length] = 'value';
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>arr.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
arr[arr.length] = 'value';
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>arr.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
arr[arr.length] = 'value';
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>arr.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
arr[arr.length] = 'value';
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>arr.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
arr[arr.length] = 'value';
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>arr.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
arr[arr.length] = 'value';
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>arr.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
arr[arr.length] = 'value';
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>arr.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
arr[arr.length] = 'value';
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>arr.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
arr[arr.length] = 'value';
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>arr.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
arr[arr.length] = 'value';
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>arr.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
arr[arr.length] = 'value';
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>arr.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
arr[arr.length] = 'value';
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>arr.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
arr[arr.length] = 'value';
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>arr.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
arr[arr.length] = 'value';
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>arr.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
>arr : Symbol(arr, Decl(foo.js, 2, 7))
>length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
}

View File

@ -0,0 +1,234 @@
=== tests/cases/compiler/foo.js ===
// repro from #26031
function build() {
>build : () => void
var arr = [];
>arr : any[]
>[] : undefined[]
arr[arr.length] = 'value';
>arr[arr.length] = 'value' : "value"
>arr[arr.length] : any
>arr : any[]
>arr.length : number
>arr : any[]
>length : number
>'value' : "value"
arr[arr.length] = 'value';
>arr[arr.length] = 'value' : "value"
>arr[arr.length] : any
>arr : any[]
>arr.length : number
>arr : any[]
>length : number
>'value' : "value"
arr[arr.length] = 'value';
>arr[arr.length] = 'value' : "value"
>arr[arr.length] : any
>arr : any[]
>arr.length : number
>arr : any[]
>length : number
>'value' : "value"
arr[arr.length] = 'value';
>arr[arr.length] = 'value' : "value"
>arr[arr.length] : any
>arr : any[]
>arr.length : number
>arr : any[]
>length : number
>'value' : "value"
arr[arr.length] = 'value';
>arr[arr.length] = 'value' : "value"
>arr[arr.length] : any
>arr : any[]
>arr.length : number
>arr : any[]
>length : number
>'value' : "value"
arr[arr.length] = 'value';
>arr[arr.length] = 'value' : "value"
>arr[arr.length] : any
>arr : any[]
>arr.length : number
>arr : any[]
>length : number
>'value' : "value"
arr[arr.length] = 'value';
>arr[arr.length] = 'value' : "value"
>arr[arr.length] : any
>arr : any[]
>arr.length : number
>arr : any[]
>length : number
>'value' : "value"
arr[arr.length] = 'value';
>arr[arr.length] = 'value' : "value"
>arr[arr.length] : any
>arr : any[]
>arr.length : number
>arr : any[]
>length : number
>'value' : "value"
arr[arr.length] = 'value';
>arr[arr.length] = 'value' : "value"
>arr[arr.length] : any
>arr : any[]
>arr.length : number
>arr : any[]
>length : number
>'value' : "value"
arr[arr.length] = 'value';
>arr[arr.length] = 'value' : "value"
>arr[arr.length] : any
>arr : any[]
>arr.length : number
>arr : any[]
>length : number
>'value' : "value"
arr[arr.length] = 'value';
>arr[arr.length] = 'value' : "value"
>arr[arr.length] : any
>arr : any[]
>arr.length : number
>arr : any[]
>length : number
>'value' : "value"
arr[arr.length] = 'value';
>arr[arr.length] = 'value' : "value"
>arr[arr.length] : any
>arr : any[]
>arr.length : number
>arr : any[]
>length : number
>'value' : "value"
arr[arr.length] = 'value';
>arr[arr.length] = 'value' : "value"
>arr[arr.length] : any
>arr : any[]
>arr.length : number
>arr : any[]
>length : number
>'value' : "value"
arr[arr.length] = 'value';
>arr[arr.length] = 'value' : "value"
>arr[arr.length] : any
>arr : any[]
>arr.length : number
>arr : any[]
>length : number
>'value' : "value"
arr[arr.length] = 'value';
>arr[arr.length] = 'value' : "value"
>arr[arr.length] : any
>arr : any[]
>arr.length : number
>arr : any[]
>length : number
>'value' : "value"
arr[arr.length] = 'value';
>arr[arr.length] = 'value' : "value"
>arr[arr.length] : any
>arr : any[]
>arr.length : number
>arr : any[]
>length : number
>'value' : "value"
arr[arr.length] = 'value';
>arr[arr.length] = 'value' : "value"
>arr[arr.length] : any
>arr : any[]
>arr.length : number
>arr : any[]
>length : number
>'value' : "value"
arr[arr.length] = 'value';
>arr[arr.length] = 'value' : "value"
>arr[arr.length] : any
>arr : any[]
>arr.length : number
>arr : any[]
>length : number
>'value' : "value"
arr[arr.length] = 'value';
>arr[arr.length] = 'value' : "value"
>arr[arr.length] : any
>arr : any[]
>arr.length : number
>arr : any[]
>length : number
>'value' : "value"
arr[arr.length] = 'value';
>arr[arr.length] = 'value' : "value"
>arr[arr.length] : any
>arr : any[]
>arr.length : number
>arr : any[]
>length : number
>'value' : "value"
arr[arr.length] = 'value';
>arr[arr.length] = 'value' : "value"
>arr[arr.length] : any
>arr : any[]
>arr.length : number
>arr : any[]
>length : number
>'value' : "value"
arr[arr.length] = 'value';
>arr[arr.length] = 'value' : "value"
>arr[arr.length] : any
>arr : any[]
>arr.length : number
>arr : any[]
>length : number
>'value' : "value"
arr[arr.length] = 'value';
>arr[arr.length] = 'value' : "value"
>arr[arr.length] : any
>arr : any[]
>arr.length : number
>arr : any[]
>length : number
>'value' : "value"
arr[arr.length] = 'value';
>arr[arr.length] = 'value' : "value"
>arr[arr.length] : any
>arr : any[]
>arr.length : number
>arr : any[]
>length : number
>'value' : "value"
arr[arr.length] = 'value';
>arr[arr.length] = 'value' : "value"
>arr[arr.length] : any
>arr : any[]
>arr.length : number
>arr : any[]
>length : number
>'value' : "value"
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,35 @@
// @allowJs: true
// @checkJs: true
// @noEmit: true
// @target: es6
// @filename: foo.js
// repro from #26031
function build() {
var arr = [];
arr[arr.length] = 'value';
arr[arr.length] = 'value';
arr[arr.length] = 'value';
arr[arr.length] = 'value';
arr[arr.length] = 'value';
arr[arr.length] = 'value';
arr[arr.length] = 'value';
arr[arr.length] = 'value';
arr[arr.length] = 'value';
arr[arr.length] = 'value';
arr[arr.length] = 'value';
arr[arr.length] = 'value';
arr[arr.length] = 'value';
arr[arr.length] = 'value';
arr[arr.length] = 'value';
arr[arr.length] = 'value';
arr[arr.length] = 'value';
arr[arr.length] = 'value';
arr[arr.length] = 'value';
arr[arr.length] = 'value';
arr[arr.length] = 'value';
arr[arr.length] = 'value';
arr[arr.length] = 'value';
arr[arr.length] = 'value';
arr[arr.length] = 'value';
}

View File

@ -0,0 +1,320 @@
// @allowJs: true
// @checkJs: true
// @noEmit: true
// @filename: foo.js
// Looking at this test and thinking "that's silly, nobody would write code like that" and thinking it's OK to break this test?
// You'd be wrong - https://raw.githubusercontent.com/archilogic-com/3dio-js/master/build/3dio.js and plenty of other codebases
// have js code exactly like this! This pattern (even at this size!) with a few more embellishments is a common way to encode
// polygons or verticies into a buffer from a formulaic object definition! So while this is a lot more regular than a real piece
// of code, this is still representative of a common pattern.
function build() {
let i = 0;
const arr = [];
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
arr[i++] = arr[i] + 1;
return arr;
}
const a = build();