.forbids pragma: defining forbidden tags (#20050)
* .forbids pragma: defining illegal effects for proc types This patch intends to define the opposite of the .tags pragma: a way to define effects which are not allowed in a proc. * updated documentation and changelogs for the forbids pragma * renamed notTagEffects to forbiddenEffects * corrected issues of forbids pragma the forbids pragma didn't handle simple restrictions properly and it also had issues with subtyping * removed incorrect character from changelog * added test to cover the interaction of methods and the forbids pragma * covering the interaction of the tags and forbids pragmas * updated manual about the forbids pragma * removed useless statement * corrected the subtyping of proc types using the forbids pragma * updated manual for the forbids pragma * updated documentations for forbids pragma * updated nim docs * updated docs with rsttester.nim * regenerated documentation * updated rst docs * Update changelog.md Co-authored-by: ringabout <43030857+ringabout@users.noreply.github.com> * updated changelog * corrected typo Co-authored-by: ringabout <43030857+ringabout@users.noreply.github.com>
This commit is contained in:
parent
62b81d7f10
commit
efd5c571bf
24 changed files with 405 additions and 71 deletions
|
|
@ -1372,6 +1372,13 @@ proc compatibleEffectsAux(se, re: PNode): bool =
|
|||
return false
|
||||
result = true
|
||||
|
||||
proc hasIncompatibleEffect(se, re: PNode): bool =
|
||||
if re.isNil: return false
|
||||
for r in items(re):
|
||||
for s in items(se):
|
||||
if safeInheritanceDiff(r.typ, s.typ) != high(int):
|
||||
return true
|
||||
|
||||
type
|
||||
EffectsCompat* = enum
|
||||
efCompat
|
||||
|
|
@ -1381,6 +1388,7 @@ type
|
|||
efTagsUnknown
|
||||
efLockLevelsDiffer
|
||||
efEffectsDelayed
|
||||
efTagsIllegal
|
||||
|
||||
proc compatibleEffects*(formal, actual: PType): EffectsCompat =
|
||||
# for proc type compatibility checking:
|
||||
|
|
@ -1414,6 +1422,14 @@ proc compatibleEffects*(formal, actual: PType): EffectsCompat =
|
|||
if not res:
|
||||
#if tfEffectSystemWorkaround notin actual.flags:
|
||||
return efTagsDiffer
|
||||
|
||||
let sn = spec[forbiddenEffects]
|
||||
if not isNil(sn) and sn.kind != nkArgList:
|
||||
if 0 == real.len:
|
||||
return efTagsUnknown
|
||||
elif hasIncompatibleEffect(sn, real[tagEffects]):
|
||||
return efTagsIllegal
|
||||
|
||||
if formal.lockLevel.ord < 0 or
|
||||
actual.lockLevel.ord <= formal.lockLevel.ord:
|
||||
|
||||
|
|
@ -1627,6 +1643,8 @@ proc typeMismatch*(conf: ConfigRef; info: TLineInfo, formal, actual: PType, n: P
|
|||
msg.add "\nlock levels differ"
|
||||
of efEffectsDelayed:
|
||||
msg.add "\n.effectsOf annotations differ"
|
||||
of efTagsIllegal:
|
||||
msg.add "\n.notTag catched an illegal effect"
|
||||
localError(conf, info, msg)
|
||||
|
||||
proc isTupleRecursive(t: PType, cycleDetector: var IntSet): bool =
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue