diff options
author | Zahary Karadjov <zahary@gmail.com> | 2020-04-01 03:33:32 +0300 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2020-04-01 19:38:44 +0200 |
commit | be95f8fdfac9ceb559f77b55630ca9e285fa9a2d (patch) | |
tree | c4819894e2f0fdf8a720795880ece26c8e5e5795 | |
parent | ce9a4ed124d798d0287a62e4700a32f1d15878c9 (diff) | |
download | Nim-be95f8fdfac9ceb559f77b55630ca9e285fa9a2d.tar.gz |
Turn some of the errors back into warnings
-rw-r--r-- | compiler/lineinfos.nim | 6 | ||||
-rw-r--r-- | compiler/semexprs.nim | 14 | ||||
-rw-r--r-- | compiler/semmagic.nim | 17 | ||||
-rw-r--r-- | compiler/semobjconstr.nim | 5 | ||||
-rw-r--r-- | compiler/sempass2.nim | 6 | ||||
-rw-r--r-- | tests/constructors/tinvalid_construction.nim | 46 | ||||
-rw-r--r-- | tests/objects/tobjects_issues.nim | 2 |
7 files changed, 63 insertions, 33 deletions
diff --git a/compiler/lineinfos.nim b/compiler/lineinfos.nim index 585a95c80..658863676 100644 --- a/compiler/lineinfos.nim +++ b/compiler/lineinfos.nim @@ -37,6 +37,8 @@ type warnUnusedImportX, warnInheritFromException, warnEachIdentIsTuple, + warnUnsafeSetLen, + warnUnsafeDefault, warnProveInit, warnProveField, warnProveIndex, warnStaticIndexCheck, warnGcUnsafe, warnGcUnsafe2, warnUninit, warnGcMem, warnDestructor, warnLockLevel, warnResultShadowed, @@ -87,6 +89,9 @@ const warnUnusedImportX: "imported and not used: '$1'", warnInheritFromException: "inherit from a more precise exception type like ValueError, IOError or OSError", warnEachIdentIsTuple: "each identifier is a tuple", + warnUnsafeSetLen: "setLen can potentially expand the sequence, " & + "but the element type '$1' doesn't have a valid default value", + warnUnsafeDefault: "The '$1' type doesn't have a valid default value", warnProveInit: "Cannot prove that '$1' is initialized. This will become a compile time error in the future.", warnProveField: "cannot prove that field '$1' is accessible", warnProveIndex: "cannot prove index '$1' is valid", @@ -146,6 +151,7 @@ const "TypelessParam", "UseBase", "WriteToForeignHeap", "UnsafeCode", "UnusedImport", "InheritFromException", "EachIdentIsTuple", + "UnsafeSetLen", "UnsafeDefault", "ProveInit", "ProveField", "ProveIndex", "IndexCheck", "GcUnsafe", "GcUnsafe2", "Uninit", "GcMem", "Destructor", "LockLevel", "ResultShadowed", diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 56de00d56..5f82eb1e7 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -2267,20 +2267,6 @@ proc semMagic(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode = of mSizeOf: markUsed(c, n.info, s) result = semSizeof(c, setMs(n, s)) - of mSetLengthSeq: - result = semDirectOp(c, n, flags) - 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: - localError(c.config, n.info, "setLen can potentially expand the sequence, " & - "but the element type $1 doesn't have a default value.", - [typeToString(seqType.base)]) - of mDefault: - result = semDirectOp(c, n, flags) - c.config.internalAssert result[1].typ.kind == tyTypeDesc - if result[1].typ.base.requiresInit: - localError(c.config, n.info, "not nil types don't have a default value") else: result = semDirectOp(c, n, flags) diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim index 8c07d7d18..783846650 100644 --- a/compiler/semmagic.nim +++ b/compiler/semmagic.nim @@ -530,4 +530,19 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode, result = semQuantifier(c, n) of mOld: result = semOld(c, n) - else: result = n + of mSetLengthSeq: + result = n + 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: + message(c.config, n.info, warnUnsafeSetLen, typeToString(seqType.base)) + of mDefault: + 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)) + else: + result = n + diff --git a/compiler/semobjconstr.nim b/compiler/semobjconstr.nim index eb0589601..eeec42900 100644 --- a/compiler/semobjconstr.nim +++ b/compiler/semobjconstr.nim @@ -336,6 +336,11 @@ proc semConstructTypeAux(c: PContext, let base = t[0] if base == nil: break t = skipTypes(base, skipPtrs) + if t.kind == tyGenericParam: + # XXX: This is not supposed to happen, but apparently + # there are some issues in semtypinst. Luckily, it + # seems to affect only `computeRequiresInit`. + return constrCtx.needsFullInit = constrCtx.needsFullInit or tfNeedsFullInit in t.flags diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index 79d969fbb..a4e1dcf00 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -254,7 +254,7 @@ proc useVar(a: PEffects, n: PNode) = a.init.add s.id elif s.id notin a.init: if s.typ.requiresInit: - localError(a.config, n.info, errProveInit, s.name.s) + message(a.config, n.info, warnProveInit, s.name.s) else: message(a.config, n.info, warnUninit, s.name.s) # prevent superfluous warnings about the same variable: @@ -844,7 +844,7 @@ proc track(tracked: PEffects, n: PNode) = # var s: seq[notnil]; newSeq(s, 0) is a special case! discard else: - localError(tracked.config, arg.info, errProveInit, $arg) + message(tracked.config, arg.info, warnProveInit, $arg) # check required for 'nim check': if n[1].typ.len > 0: @@ -1209,7 +1209,7 @@ proc trackProc*(c: PContext; s: PSym, body: PNode) = s.kind in {skProc, skFunc, skConverter, skMethod}: var res = s.ast[resultPos].sym # get result symbol if res.id notin t.init: - localError(g.config, body.info, errProveInit, "result") + message(g.config, body.info, warnProveInit, "result") let p = s.ast[pragmasPos] let raisesSpec = effectSpec(p, wRaises) if not isNil(raisesSpec): diff --git a/tests/constructors/tinvalid_construction.nim b/tests/constructors/tinvalid_construction.nim index e98b530bb..4b372d68a 100644 --- a/tests/constructors/tinvalid_construction.nim +++ b/tests/constructors/tinvalid_construction.nim @@ -113,18 +113,18 @@ reject THasNotNils(a: notNilRef, b: nilRef, c: nilRef) # `b` shouldn't be n reject THasNotNils(b: notNilRef, c: notNilRef) # there is a missing not nil field reject THasNotNils() # again, missing fields accept THasNotNils(a: notNilRef, b: notNilRef) # it's OK to omit a non-mandatory field -reject default(THasNotNils) -reject userDefinedDefault(THasNotNils) +# produces only warning: reject default(THasNotNils) +# produces only warning: reject userDefinedDefault(THasNotNils) -reject default(TRefObjNotNil) -reject userDefinedDefault(TRefObjNotNil) -reject genericDefault(TRefObjNotNil) +# produces only warning: reject default(TRefObjNotNil) +# produces only warning: reject userDefinedDefault(TRefObjNotNil) +# produces only warning: reject genericDefault(TRefObjNotNil) # missing not nils in base reject TBaseHasNotNils() -reject default(TBaseHasNotNils) -reject userDefinedDefault(TBaseHasNotNils) -reject genericDefault(TBaseHasNotNils) +# produces only warning: reject default(TBaseHasNotNils) +# produces only warning: reject userDefinedDefault(TBaseHasNotNils) +# produces only warning: reject genericDefault(TBaseHasNotNils) # once you take care of them, it's ok accept TBaseHasNotNils(a: notNilRef, b: notNilRef, choice: D) @@ -163,8 +163,8 @@ accept((ref PartialRequiresInit)(a: 20)) reject((ref PartialRequiresInit)(b: "x")) reject((ref PartialRequiresInit)()) -reject default(PartialRequiresInit) -reject userDefinedDefault(PartialRequiresInit) +# produces only warning: reject default(PartialRequiresInit) +# produces only warning: reject userDefinedDefault(PartialRequiresInit) reject: var obj: PartialRequiresInit @@ -181,8 +181,8 @@ reject((ref FullRequiresInit)(a: 10)) reject((ref FullRequiresInit)(b: 20)) reject((ref FullRequiresInit)()) -reject default(FullRequiresInit) -reject userDefinedDefault(FullRequiresInit) +# produces only warning: reject default(FullRequiresInit) +# produces only warning: reject userDefinedDefault(FullRequiresInit) reject: var obj: FullRequiresInit @@ -192,8 +192,8 @@ reject FullRequiresInitWithParent(a: notNilRef, b: nil, c: nil, e: 10, d: 20) # reject FullRequiresInitWithParent(a: notNilRef, b: notNilRef, e: 10, d: 20) # c should not be missing reject FullRequiresInitWithParent(a: notNilRef, b: notNilRef, c: nil, e: 10) # d should not be missing reject FullRequiresInitWithParent() -reject default(FullRequiresInitWithParent) -reject userDefinedDefault(FullRequiresInitWithParent) +# produces only warning: reject default(FullRequiresInitWithParent) +# produces only warning: reject userDefinedDefault(FullRequiresInitWithParent) reject: var obj: FullRequiresInitWithParent @@ -203,28 +203,36 @@ accept default(TNestedChoices) accept: var obj: TNestedChoices +#[# produces only warning: reject: # This proc is illegal, because it tries to produce # a default object of a type that requires initialization: proc defaultHasNotNils: THasNotNils = discard +#]# +#[# produces only warning: reject: # You cannot cheat by using the result variable to specify # only some of the fields proc invalidPartialTHasNotNils: THasNotNils = result.c = nilRef +#]# +#[# produces only warning: reject: # The same applies for requiresInit types proc invalidPartialRequiersInit: PartialRequiresInit = result.b = "x" +#]# +#[# produces only warning: # All code paths must return a value when the result requires initialization: reject: proc ifWithoutAnElse: THasNotNils = if stdin.readLine == "": return THasNotNils(a: notNilRef, b: notNilRef, c: nilRef) +#]# accept: # All code paths must return a value when the result requires initialization: @@ -234,6 +242,7 @@ accept: else: return THasNotNIls(a: notNilRef, b: notNilRef) +#[# produces only warning: reject: proc caseWithoutAllCasesCovered: FullRequiresInit = # Please note that these is no else branch here: @@ -242,6 +251,7 @@ reject: return FullRequiresInit(a: 10, b: 20) of "y": return FullRequiresInit(a: 30, b: 40) +#]# accept: proc wellFormedCase: FullRequiresInit = @@ -276,18 +286,24 @@ block: var one = legalSeq[0] var twoAgain = legalSeq.pop + #[# produces only warning: # It's not possible to tell the sequence to create elements # for us though: reject: var illegalSeq = newSeq[IllegalToConstruct](10) + #]# + #[# produces only warning: reject: var illegalSeq: seq[IllegalToConstruct] newSeq(illegalSeq, 10) + #]# + #[# produces only warning: reject: var illegalSeq: seq[IllegalToConstruct] illegalSeq.setLen 10 + #]# # You can still use newSeqOfCap to write efficient code: var anotherLegalSequence = newSeqOfCap[IllegalToConstruct](10) @@ -363,8 +379,10 @@ block: reject: var x: IllegalPair + #[# produces only warning: reject: var s = newSeq[IllegalPair](10) + #]# # Specific issues: # diff --git a/tests/objects/tobjects_issues.nim b/tests/objects/tobjects_issues.nim index fddfff7d5..f1a416d04 100644 --- a/tests/objects/tobjects_issues.nim +++ b/tests/objects/tobjects_issues.nim @@ -113,5 +113,5 @@ block t3038: Type = ref object of RootObj SubType[T] = ref object of Type data: Data[T] - SubSubType = ref object of SubType + SubSubType = ref object of SubType[int] SubSubSubType = ref object of SubSubType |