don't try to type-guess on list expressions in case

This commit is contained in:
2022-06-19 21:33:20 +00:00
parent d17098f732
commit 7b4c850511
3 changed files with 31 additions and 17 deletions

View File

@@ -102,7 +102,8 @@ class FieldForms {
var access = fieldAccess(formName, name, args[0]); var access = fieldAccess(formName, name, args[0]);
var type = Helpers.explicitType(args[0]); var type = Helpers.explicitType(args[0]);
k.typeHints.push({name: name, type: type}); if (type != null)
k.typeHints.push({name: name, type: type});
({ ({
name: name, name: name,

View File

@@ -173,7 +173,7 @@ class Helpers {
}; };
} }
var args = switch (argList.def) { var args:Array<FunctionArg> = switch (argList.def) {
case ListExp(funcArgs): case ListExp(funcArgs):
funcArgs.map(makeFuncArg); funcArgs.map(makeFuncArg);
case CallExp(_, _): case CallExp(_, _):
@@ -190,7 +190,8 @@ class Helpers {
}]; }];
for (v in vars) { for (v in vars) {
k.typeHints.push(v); if (v.type != null)
k.typeHints.push(v);
} }
var expr = if (body.length == 0) { var expr = if (body.length == 0) {
@@ -206,7 +207,8 @@ class Helpers {
} }
for (v in vars) { for (v in vars) {
k.typeHints.remove(v); if (v.type != null)
k.typeHints.remove(v);
} }
// To make function args immutable by default, we would use (let...) instead of (begin...) // To make function args immutable by default, we would use (let...) instead of (begin...)
@@ -217,7 +219,7 @@ class Helpers {
ret: if (name != null) Helpers.explicitType(name) else null, ret: if (name != null) Helpers.explicitType(name) else null,
args: args, args: args,
expr: expr expr: expr
} };
} }
// The name of this function is confusing--it actually makes a Haxe `case` expression, not a switch-case expression // The name of this function is confusing--it actually makes a Haxe `case` expression, not a switch-case expression

View File

@@ -204,7 +204,8 @@ class SpecialForms {
} }
for (v in varDefs) { for (v in varDefs) {
k.typeHints.push(v); if (v.type != null)
k.typeHints.push(v);
} }
var block = EBlock([ var block = EBlock([
@@ -213,7 +214,8 @@ class SpecialForms {
]).withMacroPosOf(wholeExp); ]).withMacroPosOf(wholeExp);
for (v in varDefs) { for (v in varDefs) {
k.typeHints.remove(v); if (v.type != null)
k.typeHints.remove(v);
} }
block; block;
@@ -322,16 +324,25 @@ class SpecialForms {
// On C#, C++, and HashLink, value types (specifically Float and Int) cannot be null, so they cannot be compared with null. // On C#, C++, and HashLink, value types (specifically Float and Int) cannot be null, so they cannot be compared with null.
// Therefore a null case doesn't need to be added--and will cause a compile failure if it is. // Therefore a null case doesn't need to be added--and will cause a compile failure if it is.
var canCompareNull = if (Context.defined('cs') || Context.defined('cpp') || Context.defined('hl')) { var canCompareNull = switch (args[0].def) {
switch (exp.typeof(k.typeHints)) { // don't try to type [multiple caseArgs]! It will never return!
case Success(TAbstract(ref, [])) if (["Int", "Float", "Bool"].indexOf(ref.get().name) != -1): case ListExp(_):
false; false;
case Failure(_): default:
KissError.warnFromExp(args[0], "Can't detect whether expression can be null-checked"); if (Context.defined('cs') || Context.defined('cpp') || Context.defined('hl')) {
false; var type = exp.typeof(k.typeHints);
default: true; switch (type) {
} case null:
} else true; false;
case Success(TAbstract(ref, [])) if (["Int", "Float", "Bool"].indexOf(ref.get().name) != -1):
false;
case Failure(_):
KissError.warnFromExp(args[0], "Can't detect whether expression can be null-checked");
false;
default: true;
}
} else true;
}
var cases = args.slice(1); var cases = args.slice(1);
// case also override's haxe's switch() behavior by refusing to match null values against <var> patterns. // case also override's haxe's switch() behavior by refusing to match null values against <var> patterns.