not nil types are illegal to construct through default(T)

This commit is contained in:
Zahary Karadjov
2020-03-29 02:34:50 +02:00
committed by Andreas Rumpf
parent 1b570f2b18
commit f3be5a716f
2 changed files with 16 additions and 0 deletions

View File

@@ -2270,6 +2270,8 @@ proc semMagic(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode =
let typ = result[1].typ.base
if typ.kind == tyObject:
checkDefaultConstruction(c, typ, n.info)
elif typ.kind in {tyRef, tyPtr} and tfNotNil in typ.flags:
localError(c.config, n.info, "not nil types don't have a default value")
else:
result = semDirectOp(c, n, flags)

View File

@@ -17,6 +17,8 @@ type
THasNotNilsRef = ref THasNotNils
TRefObjNotNil = TRefObj not nil
TChoice = enum A, B, C, D, E, F
TBaseHasNotNils = object of THasNotNils
@@ -84,6 +86,9 @@ proc userDefinedDefault(T: typedesc): T =
# with constructing requiresInit types
discard
proc genericDefault(T: typedesc): T =
result = default(T)
accept TObj()
accept TObj(choice: A)
reject TObj(choice: A, bc: 10) # bc is in the wrong branch
@@ -102,9 +107,18 @@ accept THasNotNils(a: notNilRef, b: notNilRef, c: nilRef)
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)
reject default(TRefObjNotNil)
reject userDefinedDefault(TRefObjNotNil)
reject genericDefault(TRefObjNotNil)
# missing not nils in base
reject TBaseHasNotNils()
reject default(TBaseHasNotNils)
reject userDefinedDefault(TBaseHasNotNils)
reject genericDefault(TBaseHasNotNils)
# once you take care of them, it's ok
accept TBaseHasNotNils(a: notNilRef, b: notNilRef, choice: D)