fix arithemtic promotions for UFCS / parameters

This commit is contained in:
WebFreak001 2023-05-16 22:42:28 +02:00 committed by Jan Jurzitza
parent cdf4b56eb3
commit efd8743c9e
16 changed files with 180 additions and 9 deletions

View File

@ -32,7 +32,7 @@ struct TokenCursorResult
// https://dlang.org/spec/type.html#implicit-conversions // https://dlang.org/spec/type.html#implicit-conversions
enum string[string] INTEGER_PROMOTIONS = [ enum string[string] INTEGER_PROMOTIONS = [
"bool": "int", "bool": "byte",
"byte": "int", "byte": "int",
"ubyte": "int", "ubyte": "int",
"short": "int", "short": "int",
@ -40,6 +40,15 @@ enum string[string] INTEGER_PROMOTIONS = [
"char": "int", "char": "int",
"wchar": "int", "wchar": "int",
"dchar": "uint", "dchar": "uint",
// found in test case extra/tc_ufcs_all_kinds:
"int": "float",
"uint": "float",
"long": "float",
"ulong": "float",
"float": "double",
"double": "real",
]; ];
enum MAX_NUMBER_OF_MATCHING_RUNS = 50; enum MAX_NUMBER_OF_MATCHING_RUNS = 50;
@ -273,11 +282,60 @@ private bool willImplicitBeUpcasted(scope ref const(DSymbol) incomingSymbolType,
private bool typeWillBeUpcastedTo(string from, string to) private bool typeWillBeUpcastedTo(string from, string to)
{ {
if (auto promotionType = from in INTEGER_PROMOTIONS) while (true)
return *promotionType == to; {
if (typeWillIntegerUpcastedTo(from, to))
return true;
if (from.typeIsFloating && to.typeIsFloating)
return true;
if (auto promotionType = from in INTEGER_PROMOTIONS)
{
if (*promotionType == to)
return true;
from = *promotionType;
}
else
return false; return false;
} }
}
private bool typeWillIntegerUpcastedTo(string from, string to)
{
int fromIntSize = getIntegerTypeSize(from);
int toIntSize = getIntegerTypeSize(to);
return fromIntSize != 0 && toIntSize != 0 && fromIntSize <= toIntSize;
}
private int getIntegerTypeSize(string type)
{
switch (type)
{
// ordered by subjective frequency of use, since the compiler may use that
// for optimization.
case "int", "uint": return 4;
case "long", "ulong": return 8;
case "byte", "ubyte": return 1;
case "short", "ushort": return 2;
case "dchar": return 4;
case "wchar": return 2;
case "char": return 1;
default: return 0;
}
}
private bool typeIsFloating(string type)
{
switch (type)
{
case "float":
case "double":
case "real":
return true;
default:
return false;
}
}
bool isNonConstrainedTemplate(scope ref const(DSymbol) symbolType) bool isNonConstrainedTemplate(scope ref const(DSymbol) symbolType)
{ {
@ -303,21 +361,24 @@ private bool typeMatchesWith(scope ref const(DSymbol) incomingSymbolType, scope
return incomingSymbolType is significantSymbolType return incomingSymbolType is significantSymbolType
|| isNonConstrainedTemplate(incomingSymbolType) || isNonConstrainedTemplate(incomingSymbolType)
|| matchesWithTypeOfArray(incomingSymbolType, significantSymbolType) || matchesWithTypeOfArray(incomingSymbolType, significantSymbolType)
|| matchesWithTypeOfPointer(incomingSymbolType, significantSymbolType) || matchesWithTypeOfPointer(incomingSymbolType, significantSymbolType);
|| willImplicitBeUpcasted(incomingSymbolType, significantSymbolType);
} }
private bool matchSymbolType(const(DSymbol)* incomingSymbolType, const(DSymbol)* significantSymbolType) { private bool matchSymbolType(const(DSymbol)* firstParameter, const(DSymbol)* significantSymbolType) {
auto currentSignificantSymbolType = significantSymbolType; auto currentSignificantSymbolType = significantSymbolType;
uint numberOfRetries = 0; uint numberOfRetries = 0;
do do
{ {
if (typeMatchesWith(*incomingSymbolType, *currentSignificantSymbolType)){ if (typeMatchesWith(*firstParameter.type, *currentSignificantSymbolType)) {
return true; return true;
} }
if (!(firstParameter.parameterIsRef || firstParameter.parameterIsOut)
&& willImplicitBeUpcasted(*firstParameter.type, *currentSignificantSymbolType))
return true;
if (currentSignificantSymbolType.aliasThisSymbols.empty || currentSignificantSymbolType is currentSignificantSymbolType.aliasThisSymbols.front){ if (currentSignificantSymbolType.aliasThisSymbols.empty || currentSignificantSymbolType is currentSignificantSymbolType.aliasThisSymbols.front){
return false; return false;
} }
@ -351,7 +412,7 @@ bool isCallableWithArg(const(DSymbol)* incomingSymbol, const(DSymbol)* beforeDot
if (incomingSymbol.kind is CompletionKind.functionName && !incomingSymbol.functionParameters.empty && incomingSymbol.functionParameters.front.type) if (incomingSymbol.kind is CompletionKind.functionName && !incomingSymbol.functionParameters.empty && incomingSymbol.functionParameters.front.type)
{ {
return matchSymbolType(incomingSymbol.functionParameters.front.type, beforeDotType); return matchSymbolType(incomingSymbol.functionParameters.front, beforeDotType);
} }
return false; return false;
} }

View File

@ -6,5 +6,18 @@ max k
min k min k
sizeof k sizeof k
someBool F someBool F
someByte F
someChar F
someDchar F
someDouble F
someFloat F
someInt F someInt F
someLong F
someReal F
someShort F
someUbyte F
someUint F
someUlong F
someUshort F
someWchar F
stringof k stringof k

View File

@ -6,5 +6,17 @@ max k
min k min k
sizeof k sizeof k
someByte F someByte F
someChar F
someDchar F
someDouble F
someFloat F
someInt F someInt F
someLong F
someReal F
someShort F
someUbyte F
someUint F
someUlong F
someUshort F
someWchar F
stringof k stringof k

View File

@ -5,6 +5,18 @@ mangleof k
max k max k
min k min k
sizeof k sizeof k
someByte F
someChar F someChar F
someDchar F
someDouble F
someFloat F
someInt F someInt F
someLong F
someReal F
someShort F
someUbyte F
someUint F
someUlong F
someUshort F
someWchar F
stringof k stringof k

View File

@ -6,5 +6,11 @@ max k
min k min k
sizeof k sizeof k
someDchar F someDchar F
someDouble F
someFloat F
someInt F
someLong F
someReal F
someUint F someUint F
someUlong F
stringof k stringof k

View File

@ -15,4 +15,6 @@ min_normal k
nan k nan k
sizeof k sizeof k
someDouble F someDouble F
someFloat F
someReal F
stringof k stringof k

View File

@ -14,5 +14,7 @@ min_exp k
min_normal k min_normal k
nan k nan k
sizeof k sizeof k
someDouble F
someFloat F someFloat F
someReal F
stringof k stringof k

View File

@ -5,5 +5,12 @@ mangleof k
max k max k
min k min k
sizeof k sizeof k
someDchar F
someDouble F
someFloat F
someInt F someInt F
someLong F
someReal F
someUint F
someUlong F
stringof k stringof k

View File

@ -5,5 +5,9 @@ mangleof k
max k max k
min k min k
sizeof k sizeof k
someDouble F
someFloat F
someLong F someLong F
someReal F
someUlong F
stringof k stringof k

View File

@ -14,5 +14,7 @@ min_exp k
min_normal k min_normal k
nan k nan k
sizeof k sizeof k
someDouble F
someFloat F
someReal F someReal F
stringof k stringof k

View File

@ -5,6 +5,15 @@ mangleof k
max k max k
min k min k
sizeof k sizeof k
someDchar F
someDouble F
someFloat F
someInt F someInt F
someLong F
someReal F
someShort F someShort F
someUint F
someUlong F
someUshort F
someWchar F
stringof k stringof k

View File

@ -5,6 +5,18 @@ mangleof k
max k max k
min k min k
sizeof k sizeof k
someByte F
someChar F
someDchar F
someDouble F
someFloat F
someInt F someInt F
someLong F
someReal F
someShort F
someUbyte F someUbyte F
someUint F
someUlong F
someUshort F
someWchar F
stringof k stringof k

View File

@ -5,5 +5,12 @@ mangleof k
max k max k
min k min k
sizeof k sizeof k
someDchar F
someDouble F
someFloat F
someInt F
someLong F
someReal F
someUint F someUint F
someUlong F
stringof k stringof k

View File

@ -5,5 +5,9 @@ mangleof k
max k max k
min k min k
sizeof k sizeof k
someDouble F
someFloat F
someLong F
someReal F
someUlong F someUlong F
stringof k stringof k

View File

@ -5,6 +5,15 @@ mangleof k
max k max k
min k min k
sizeof k sizeof k
someDchar F
someDouble F
someFloat F
someInt F someInt F
someLong F
someReal F
someShort F
someUint F
someUlong F
someUshort F someUshort F
someWchar F
stringof k stringof k

View File

@ -5,6 +5,15 @@ mangleof k
max k max k
min k min k
sizeof k sizeof k
someDchar F
someDouble F
someFloat F
someInt F someInt F
someLong F
someReal F
someShort F
someUint F
someUlong F
someUshort F
someWchar F someWchar F
stringof k stringof k