mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-28 17:04:41 +00:00
* Fix several float range issues * address the comments
This commit is contained in:
@@ -444,6 +444,7 @@ proc semAfterMacroCall(c: PContext, call, macroResult: PNode,
|
||||
|
||||
const
|
||||
errMissingGenericParamsForTemplate = "'$1' has unspecified generic parameters"
|
||||
errFloatToString = "cannot convert '$1' to '$2'"
|
||||
|
||||
proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym,
|
||||
flags: TExprFlags = {}): PNode =
|
||||
|
||||
@@ -513,6 +513,9 @@ proc changeType(c: PContext; n: PNode, newType: PType, check: bool) =
|
||||
if value < firstOrd(c.config, newType) or value > lastOrd(c.config, newType):
|
||||
localError(c.config, n.info, "cannot convert " & $value &
|
||||
" to " & typeToString(newType))
|
||||
of nkFloatLit..nkFloat64Lit:
|
||||
if check and not floatRangeCheck(n.floatVal, newType):
|
||||
localError(c.config, n.info, errFloatToString % [$n.floatVal, typeToString(newType)])
|
||||
else: discard
|
||||
n.typ = newType
|
||||
|
||||
|
||||
@@ -292,6 +292,8 @@ proc fitRemoveHiddenConv(c: PContext, typ: PType, n: PNode): PNode =
|
||||
result = newFloatNode(nkFloatLit, BiggestFloat r1.intVal)
|
||||
result.info = n.info
|
||||
result.typ = typ
|
||||
if not floatRangeCheck(result.floatVal, typ):
|
||||
localError(c.config, n.info, errFloatToString % [$n.floatVal, typeToString(typ)])
|
||||
else:
|
||||
changeType(c, r1, typ, check=true)
|
||||
result = r1
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
# this module does the semantic checking of type declarations
|
||||
# included from sem.nim
|
||||
|
||||
import math
|
||||
|
||||
const
|
||||
errStringOrIdentNodeExpected = "string or ident node expected"
|
||||
errStringLiteralExpected = "string literal expected"
|
||||
@@ -236,6 +238,10 @@ proc semRangeAux(c: PContext, n: PNode, prev: PType): PType =
|
||||
else:
|
||||
result.n.addSon semConstExpr(c, range[i])
|
||||
|
||||
if (result.n[0].kind in {nkFloatLit..nkFloat64Lit} and classify(result.n[0].floatVal) == fcNan) or
|
||||
(result.n[1].kind in {nkFloatLit..nkFloat64Lit} and classify(result.n[1].floatVal) == fcNan):
|
||||
localError(c.config, n.info, "NaN is not a valid start or end for a range")
|
||||
|
||||
if weakLeValue(result.n[0], result.n[1]) == impNo:
|
||||
localError(c.config, n.info, "range is empty")
|
||||
|
||||
|
||||
@@ -414,9 +414,10 @@ proc isConvertibleToRange(f, a: PType): bool =
|
||||
of tyUInt16: result = a.kind in {tyUInt8, tyUInt16, tyUInt}
|
||||
of tyUInt32: result = a.kind in {tyUInt8, tyUInt16, tyUInt32, tyUInt}
|
||||
else: result = false
|
||||
elif f.kind in {tyFloat..tyFloat128} and
|
||||
a.kind in {tyFloat..tyFloat128}:
|
||||
result = true
|
||||
elif f.kind in {tyFloat..tyFloat128}:
|
||||
# `isIntLit` is correct and should be used above as well, see PR:
|
||||
# https://github.com/nim-lang/Nim/pull/11197
|
||||
result = isIntLit(a) or a.kind in {tyFloat..tyFloat128}
|
||||
|
||||
proc handleFloatRange(f, a: PType): TTypeRelation =
|
||||
if a.kind == f.kind:
|
||||
|
||||
@@ -118,3 +118,14 @@ block:
|
||||
x3 = R32(4)
|
||||
|
||||
doAssert $x1 & $x2 & $x3 == "444"
|
||||
|
||||
block:
|
||||
var x1: range[0'f..1'f] = 1
|
||||
const x2: range[0'f..1'f] = 1
|
||||
var x5: range[0'f32..1'f32] = 1'f64
|
||||
const x6: range[0'f32..1'f32] = 1'f64
|
||||
|
||||
reject:
|
||||
const x: range[0'f..1'f] = 2'f
|
||||
reject:
|
||||
const x: range[0'f..1'f] = 2
|
||||
|
||||
Reference in New Issue
Block a user