in lib/semantic.js [3146:3194]
visitAssign(ast, env) {
assert.equal(ast.type, 'assign');
if (ast.left.type === 'virtualVariable') {
this.checkVid(ast.left.vid, env);
} else if (ast.left.type === 'variable') {
this.checkId(ast.left.id, env);
} else if (ast.left.type === 'property') {
this.checkProperty(ast.left, env);
} else if (ast.left.type === 'map_access') {
let mainType;
if (ast.left.propertyPath) {
this.checkProperty(ast.left, env);
mainType = this.calculatePropertyType(ast.left, env);
} else {
this.checkId(ast.left.id, env);
mainType = this.getVariableType(ast.left.id, env);
}
if (mainType.type === 'map') {
if (!this.isStringType(ast.left.accessKey, env)) {
this.error(`The key expr type must be string type`, ast.left.accessKey);
}
} else if (mainType.type === 'array') {
ast.left.type = 'array_access';
if (!this.isNumberType(ast.left.accessKey, env)) {
this.error(`The key expr type must be number type`, ast.left.accessKey);
}
} else {
this.error(`the [] form only support map or array type`, ast.left.accessKey);
}
} else {
throw new Error('unimplemented');
}
const expected = this.getExprType(ast.left, env);
ast.left.inferred = expected;
this.visitExpr(ast.expr, env);
const actual = this.getExprType(ast.expr, env);
if (!isAssignable(expected, actual, ast.expr)) {
this.error(`can't assign ${display(actual)} to ${display(expected)}`, ast.expr);
}
if (expected.type === 'basic' && expected.name === 'readable') {
if (actual.type === 'basic' && actual.name === 'bytes' ||
actual.type === 'basic' && actual.name === 'string') {
ast.expr.needToReadable = true;
}
}
}