Skip to content
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
67 changes: 54 additions & 13 deletions src/compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7455,17 +7455,33 @@ export class Compiler extends DiagnosticEmitter {
switch (expression.literalKind) {
case LiteralKind.ARRAY: {
assert(!implicitlyNegate);
let classType = contextualType.classReference;
if (classType) {
if (classType.prototype == this.program.arrayPrototype) {
return this.compileArrayLiteral(
assert(classType.typeArguments)[0],
(<ArrayLiteralExpression>expression).elementExpressions,
constraints,
expression
);
let elementExpressions = (<ArrayLiteralExpression>expression).elementExpressions;

// Infer from first element in auto contexts
if (contextualType == Type.auto) {
return this.compileArrayLiteral(
Type.auto,
elementExpressions,
constraints,
expression
);
}

// Use contextual type if an array
if (contextualType.is(TypeFlags.REFERENCE)) {
let classType = contextualType.classReference;
if (classType) {
if (classType.prototype == this.program.arrayPrototype) {
return this.compileArrayLiteral(
assert(classType.typeArguments)[0],
elementExpressions,
constraints,
expression
);
}
}
}

this.error(
DiagnosticCode.The_type_argument_for_type_parameter_0_cannot_be_inferred_from_the_usage_Consider_specifying_the_type_arguments_explicitly,
expression.range, "T"
Expand Down Expand Up @@ -7544,17 +7560,42 @@ export class Compiler extends DiagnosticEmitter {
var module = this.module;
var program = this.program;
var arrayPrototype = assert(program.arrayPrototype);
var arrayInstance = assert(this.resolver.resolveClass(arrayPrototype, [ elementType ]));
var arrayBufferInstance = assert(program.arrayBufferInstance);
var arrayType = arrayInstance.type;
var flow = this.currentFlow;

// block those here so compiling expressions doesn't conflict
var tempThis = flow.getTempLocal(arrayType);
var tempThis = flow.getTempLocal(this.options.usizeType);
var tempDataStart = flow.getTempLocal(arrayBufferInstance.type);

// compile value expressions and find out whether all are constant
// infer common element type in auto contexts
var length = expressions.length;
if (elementType == Type.auto) {
for (let i = 0; i < length; ++i) {
let expression = expressions[i];
if (expression) {
let currentType = this.resolver.resolveExpression(expression, this.currentFlow, elementType);
if (!currentType) return module.unreachable();
if (elementType == Type.auto) elementType = currentType;
else if (currentType != elementType) {
let commonType = Type.commonDenominator(elementType, currentType, false);
if (commonType) elementType = commonType;
// otherwise triggers error further down
}
}
}
if (elementType /* still */ == Type.auto) {
this.error(
DiagnosticCode.The_type_argument_for_type_parameter_0_cannot_be_inferred_from_the_usage_Consider_specifying_the_type_arguments_explicitly,
reportNode.range, "T"
);
return module.unreachable();
}
}

var arrayInstance = assert(this.resolver.resolveClass(arrayPrototype, [ elementType ]));
var arrayType = arrayInstance.type;

// compile value expressions and find out whether all are constant
var values = new Array<ExpressionRef>(length);
var isStatic = true;
var nativeElementType = elementType.toNativeType();
Expand Down
5 changes: 5 additions & 0 deletions tests/compiler/infer-array.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"asc_flags": [
"--runtime none"
]
}
Loading