Skip to content

Fix failing non-null checks #1151

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

Merged
merged 1 commit into from
Mar 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions src/compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2592,9 +2592,6 @@ export class Compiler extends DiagnosticEmitter {
var flow = this.currentFlow;
var returnType = flow.returnType;

// Remember that this flow returns
flow.set(FlowFlags.RETURNS | FlowFlags.TERMINATES);

var valueExpression = statement.value;
if (valueExpression) {
if (returnType == Type.void) {
Expand Down Expand Up @@ -2633,6 +2630,9 @@ export class Compiler extends DiagnosticEmitter {
}
flow.freeScopedLocals();

// Remember that this flow returns
flow.set(FlowFlags.RETURNS | FlowFlags.TERMINATES);

// If the last statement anyway, make it the block's return value
if (isLastInBody && expr != 0 && returnType != Type.void) {
if (!stmts.length) return expr;
Expand Down Expand Up @@ -5711,7 +5711,7 @@ export class Compiler extends DiagnosticEmitter {
target,
expr, // TODO: delay release above if possible?
this.currentType,
left,
right,
resolver.currentThisExpression,
resolver.currentElementExpression,
contextualType != Type.void
Expand Down Expand Up @@ -5850,12 +5850,13 @@ export class Compiler extends DiagnosticEmitter {

// compile the value and do the assignment
assert(targetType != Type.void);
var valueExpr = this.compileExpression(valueExpression, targetType, Constraints.CONV_IMPLICIT | Constraints.WILL_RETAIN);
var valueExpr = this.compileExpression(valueExpression, targetType, Constraints.WILL_RETAIN);
var valueType = this.currentType;
return this.makeAssignment(
target,
valueExpr,
this.currentType,
expression,
this.convertExpression(valueExpr, valueType, targetType, false, false, valueExpression),
valueType,
valueExpression,
thisExpression,
elementExpression,
contextualType != Type.void
Expand Down
63 changes: 38 additions & 25 deletions src/flow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -764,35 +764,48 @@ export class Flow {

this.flags = newFlags | (this.flags & FlowFlags.UNCHECKED_CONTEXT);

var leftLocalFlags = left.localFlags;
var numLeftLocalFlags = leftLocalFlags.length;
var rightLocalFlags = right.localFlags;
var numRightLocalFlags = rightLocalFlags.length;
var maxLocalFlags = max(numLeftLocalFlags, numRightLocalFlags);
var combinedFlags = new Array<LocalFlags>(maxLocalFlags);
for (let i = 0; i < maxLocalFlags; ++i) {
let leftFlags = i < numLeftLocalFlags ? leftLocalFlags[i] : 0;
let rightFlags = i < numRightLocalFlags ? rightLocalFlags[i] : 0;
let newFlags = leftFlags & rightFlags & (
LocalFlags.CONSTANT |
LocalFlags.WRAPPED |
LocalFlags.NONNULL |
LocalFlags.INITIALIZED
);
if (leftFlags & LocalFlags.RETAINED) {
if (rightFlags & LocalFlags.RETAINED) {
newFlags |= LocalFlags.RETAINED;
} else {
var thisLocalFlags = this.localFlags;
if (leftFlags & FlowFlags.TERMINATES) {
if (!(rightFlags & FlowFlags.TERMINATES)) {
let rightLocalFlags = right.localFlags;
for (let i = 0, k = rightLocalFlags.length; i < k; ++i) {
thisLocalFlags[i] = rightLocalFlags[i];
}
}
} else if (rightFlags & FlowFlags.TERMINATES) {
let leftLocalFlags = left.localFlags;
for (let i = 0, k = leftLocalFlags.length; i < k; ++i) {
thisLocalFlags[i] = leftLocalFlags[i];
}
} else {
let leftLocalFlags = left.localFlags;
let numLeftLocalFlags = leftLocalFlags.length;
let rightLocalFlags = right.localFlags;
let numRightLocalFlags = rightLocalFlags.length;
let maxLocalFlags = max(numLeftLocalFlags, numRightLocalFlags);
for (let i = 0; i < maxLocalFlags; ++i) {
let leftFlags = i < numLeftLocalFlags ? leftLocalFlags[i] : 0;
let rightFlags = i < numRightLocalFlags ? rightLocalFlags[i] : 0;
let newFlags = leftFlags & rightFlags & (
LocalFlags.CONSTANT |
LocalFlags.WRAPPED |
LocalFlags.NONNULL |
LocalFlags.INITIALIZED
);
if (leftFlags & LocalFlags.RETAINED) {
if (rightFlags & LocalFlags.RETAINED) {
newFlags |= LocalFlags.RETAINED;
} else {
newFlags |= LocalFlags.CONDITIONALLY_RETAINED;
}
} else if (rightFlags & LocalFlags.RETAINED) {
newFlags |= LocalFlags.CONDITIONALLY_RETAINED;
} else {
newFlags |= (leftFlags | rightFlags) & LocalFlags.CONDITIONALLY_RETAINED;
}
} else if (rightFlags & LocalFlags.RETAINED) {
newFlags |= LocalFlags.CONDITIONALLY_RETAINED;
} else {
newFlags |= (leftFlags | rightFlags) & LocalFlags.CONDITIONALLY_RETAINED;
thisLocalFlags[i] = newFlags;
}
combinedFlags[i] = newFlags;
}
this.localFlags = combinedFlags;
}

/** Tests if the specified flows have differing local states. */
Expand Down
8 changes: 0 additions & 8 deletions src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1296,7 +1296,6 @@ export class Parser extends DiagnosticEmitter {
if (!type) return null;
} else {
type = Node.createOmittedType(tn.range(tn.pos));
type = type!; // FIXME: WHY?
}
let initializer: Expression | null = null;
if (tn.skip(Token.EQUALS)) {
Expand Down Expand Up @@ -1423,7 +1422,6 @@ export class Parser extends DiagnosticEmitter {
returnType = Node.createOmittedType(
tn.range(tn.pos)
);
returnType = returnType!; // FIXME: WHY?
if (!isSetter) {
this.error(
DiagnosticCode.Type_expected,
Expand Down Expand Up @@ -1532,7 +1530,6 @@ export class Parser extends DiagnosticEmitter {
if (!returnType) return null;
} else {
returnType = Node.createOmittedType(tn.range(tn.pos));
returnType = returnType!; // FIXME: WHY?
}

if (arrowKind) {
Expand Down Expand Up @@ -2082,7 +2079,6 @@ export class Parser extends DiagnosticEmitter {
if (!returnType) return null;
} else {
returnType = Node.createOmittedType(tn.range(tn.pos));
returnType = returnType!; // FIXME: WHY?
if (!isSetter && name.kind != NodeKind.CONSTRUCTOR) {
this.error(
DiagnosticCode.Type_expected,
Expand Down Expand Up @@ -3543,7 +3539,6 @@ export class Parser extends DiagnosticEmitter {
return null;
}
inner = Node.createParenthesizedExpression(inner, tn.range(startPos, tn.pos));
inner = inner!; // FIXME: WHY?
return this.maybeParseCallExpression(tn, inner);
}
// ArrayLiteralExpression
Expand Down Expand Up @@ -3833,7 +3828,6 @@ export class Parser extends DiagnosticEmitter {
null,
tn.range(startPos, tn.pos)
);
expr = expr!; // FIXME: WHY?
expr = this.maybeParseCallExpression(tn, expr);
break;
}
Expand Down Expand Up @@ -3864,7 +3858,6 @@ export class Parser extends DiagnosticEmitter {
next,
tn.range(startPos, tn.pos)
);
expr = expr!; // FIXME: WHY?
expr = this.maybeParseCallExpression(tn, expr);
break;
}
Expand Down Expand Up @@ -3932,7 +3925,6 @@ export class Parser extends DiagnosticEmitter {
<IdentifierExpression>next,
tn.range(startPos, tn.pos)
);
expr = expr!; // FIXME: WHY?
} else {
let next = this.parseExpression(tn, nextPrecedence + 1);
if (!next) return null;
Expand Down