diff --git a/compiler/sem.nim b/compiler/sem.nim index 3392db7a9da0..c70cf412b598 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -710,10 +710,7 @@ proc defaultNodeField(c: PContext, a: PNode, aTyp: PType, checkDefault: bool): P else: result = nil of tyRange: - if c.graph.config.isDefined("nimPreviewRangeDefault"): - result = firstRange(c.config, aTypSkip) - else: - result = nil + result = firstRange(c.config, aTypSkip) else: result = nil diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim index 0ad6117813a6..af9ccde85093 100644 --- a/compiler/semmagic.nim +++ b/compiler/semmagic.nim @@ -580,12 +580,18 @@ proc semPrivateAccess(c: PContext, n: PNode): PNode = c.currentScope.allowPrivateAccess.add t.sym result = newNodeIT(nkEmpty, n.info, getSysType(c.graph, n.info, tyVoid)) -proc checkDefault(c: PContext, n: PNode): PNode = +proc checkDefault(c: PContext, n: PNode; isDefault: bool): PNode = result = n c.config.internalAssert result[1].typ.kind == tyTypeDesc let constructed = result[1].typ.base - if constructed.requiresInit: - message(c.config, n.info, warnUnsafeDefault, typeToString(constructed)) + # allows simple range types because they now have a valid default value + if constructed.requiresInit and constructed.skipTypes({tyGenericInst}).kind != tyRange: + # TODO: sorts out `nimPreviewRangeDefault` with `ranges` in the future + # TODO: be lenient with views and notnil types for now + if isDefault and c.config.features * {views, notnil} == {}: + localError(c.config, n.info, "The '$1' type doesn't have a valid default value" % typeToString(constructed)) + else: + message(c.config, n.info, warnUnsafeDefault, typeToString(constructed)) proc magicsAfterOverloadResolution(c: PContext, n: PNode, flags: TExprFlags; expectedType: PType = nil): PNode = @@ -672,16 +678,18 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode, let seqType = result[1].typ.skipTypes({tyPtr, tyRef, # in case we had auto-dereferencing tyVar, tyGenericInst, tyOwned, tySink, tyAlias, tyUserTypeClassInst}) - if seqType.kind == tySequence and seqType.base.requiresInit: + if seqType.kind == tySequence and seqType.base.requiresInit and + seqType.base.skipTypes({tyGenericInst}).kind != tyRange: + # allows simple range types because they now have a valid default value message(c.config, n.info, warnUnsafeSetLen, typeToString(seqType.base)) of mDefault: - result = checkDefault(c, n) + result = checkDefault(c, n, true) let typ = result[^1].typ.skipTypes({tyTypeDesc}) let defaultExpr = defaultNodeField(c, result[^1], typ, false) if defaultExpr != nil: result = defaultExpr of mZeroDefault: - result = checkDefault(c, n) + result = checkDefault(c, n, false) of mIsolate: if not checkIsolate(n[1]): localError(c.config, n.info, "expression cannot be isolated: " & $n[1]) diff --git a/tests/errmsgs/t25116.nim b/tests/errmsgs/t25116.nim new file mode 100644 index 000000000000..611a1bda4c37 --- /dev/null +++ b/tests/errmsgs/t25116.nim @@ -0,0 +1,9 @@ +discard """ + errormsg: "The 'RI' type doesn't have a valid default value" +""" + + +type RI {.requiresInit.} = object + v: int + +var v = default(RI) # should be flagged as invalid \ No newline at end of file