From 18b5fb256d4647efa6a64df451d37129d36e96f3 Mon Sep 17 00:00:00 2001 From: Nikolay Nikolov Date: Mon, 15 Jan 2024 19:36:03 +0200 Subject: [PATCH] + show the inferred exception list (as part of the type) for functions that don't have an explicit `.raises` pragma (#23193) --- compiler/suggest.nim | 2 +- compiler/types.nim | 22 ++++++++++++++++++--- nimsuggest/tests/tdef1.nim | 6 +++--- nimsuggest/tests/tdot4.nim | 2 +- nimsuggest/tests/tinclude.nim | 2 +- nimsuggest/tests/tsug_pragmas.nim | 10 +++++----- nimsuggest/tests/tsug_template.nim | 2 +- nimsuggest/tests/tuse.nim | 8 ++++---- nimsuggest/tests/tv3.nim | 2 +- nimsuggest/tests/tv3_forward_definition.nim | 18 ++++++++--------- nimsuggest/tests/tv3_globalSymbols.nim | 8 ++++---- nimsuggest/tests/tv3_outline.nim | 14 ++++++------- nimsuggest/tests/twithin_macro.nim | 4 ++-- nimsuggest/tests/twithin_macro_prefix.nim | 2 +- 14 files changed, 59 insertions(+), 43 deletions(-) diff --git a/compiler/suggest.nim b/compiler/suggest.nim index 5eb2c03ab62db..720418466e4cb 100644 --- a/compiler/suggest.nim +++ b/compiler/suggest.nim @@ -172,7 +172,7 @@ proc symToSuggest*(g: ModuleGraph; s: PSym, isLocal: bool, section: IdeCmd, info if section == ideInlayHints: result.forth = typeToString(s.typ, preferInlayHint) else: - result.forth = typeToString(s.typ) + result.forth = typeToString(s.typ, preferInferredEffects) else: result.forth = "" when defined(nimsuggest) and not defined(noDocgen) and not defined(leanCompiler): diff --git a/compiler/types.nim b/compiler/types.nim index 04f953f79d1cb..8c447ddbfbae2 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -31,6 +31,7 @@ type # most useful, shows: symbol + resolved symbols if it differs, e.g.: # tuple[a: MyInt{int}, b: float] preferInlayHint, + preferInferredEffects, TTypeRelation* = enum # order is important! isNone, isConvertible, @@ -477,7 +478,7 @@ const "void", "iterable"] const preferToResolveSymbols = {preferName, preferTypeName, preferModuleInfo, - preferGenericArg, preferResolved, preferMixed, preferInlayHint} + preferGenericArg, preferResolved, preferMixed, preferInlayHint, preferInferredEffects} template bindConcreteTypeToUserTypeClass*(tc, concrete: PType) = tc.add concrete @@ -530,7 +531,7 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string = result = t.sym.name.s if prefer == preferMixed and result != t.sym.name.s: result = t.sym.name.s & "{" & result & "}" - elif prefer in {preferName, preferTypeName, preferInlayHint} or t.sym.owner.isNil: + elif prefer in {preferName, preferTypeName, preferInlayHint, preferInferredEffects} or t.sym.owner.isNil: # note: should probably be: {preferName, preferTypeName, preferGenericArg} result = t.sym.name.s if t.kind == tyGenericParam and t.genericParamHasConstraints: @@ -723,6 +724,7 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string = result.add(')') if t.returnType != nil: result.add(": " & typeToString(t.returnType)) var prag = if t.callConv == ccNimCall and tfExplicitCallConv notin t.flags: "" else: $t.callConv + var hasImplicitRaises = false if not isNil(t.owner) and not isNil(t.owner.ast) and (t.owner.ast.len - 1) >= pragmasPos: let pragmasNode = t.owner.ast[pragmasPos] let raisesSpec = effectSpec(pragmasNode, wRaises) @@ -730,13 +732,27 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string = addSep(prag) prag.add("raises: ") prag.add($raisesSpec) - + hasImplicitRaises = true if tfNoSideEffect in t.flags: addSep(prag) prag.add("noSideEffect") if tfThread in t.flags: addSep(prag) prag.add("gcsafe") + if not hasImplicitRaises and prefer == preferInferredEffects and not isNil(t.owner) and not isNil(t.owner.typ) and not isNil(t.owner.typ.n) and (t.owner.typ.n.len > 0): + let effects = t.owner.typ.n[0] + if effects.kind == nkEffectList and effects.len == effectListLen: + var inferredRaisesStr = "" + let effs = effects[exceptionEffects] + if not isNil(effs): + for eff in items(effs): + if not isNil(eff): + addSep(inferredRaisesStr) + inferredRaisesStr.add($eff.typ) + addSep(prag) + prag.add("raises: [") + prag.add(inferredRaisesStr) + prag.add("]") if prag.len != 0: result.add("{." & prag & ".}") of tyVarargs: result = typeToStr[t.kind] % typeToString(t.elementType) diff --git a/nimsuggest/tests/tdef1.nim b/nimsuggest/tests/tdef1.nim index 46d7c0b5d716e..49265bbc13857 100644 --- a/nimsuggest/tests/tdef1.nim +++ b/nimsuggest/tests/tdef1.nim @@ -1,11 +1,11 @@ discard """ $nimsuggest --tester $file >def $1 -def;;skProc;;tdef1.hello;;proc (): string{.noSideEffect, gcsafe.};;$file;;11;;5;;"Return hello";;100 +def;;skProc;;tdef1.hello;;proc (): string{.noSideEffect, gcsafe, raises: [].};;$file;;11;;5;;"Return hello";;100 >def $2 -def;;skProc;;tdef1.hello;;proc (): string{.noSideEffect, gcsafe.};;$file;;11;;5;;"Return hello";;100 +def;;skProc;;tdef1.hello;;proc (): string{.noSideEffect, gcsafe, raises: [].};;$file;;11;;5;;"Return hello";;100 >def $2 -def;;skProc;;tdef1.hello;;proc (): string{.noSideEffect, gcsafe.};;$file;;11;;5;;"Return hello";;100 +def;;skProc;;tdef1.hello;;proc (): string{.noSideEffect, gcsafe, raises: [].};;$file;;11;;5;;"Return hello";;100 """ proc hel#[!]#lo(): string = diff --git a/nimsuggest/tests/tdot4.nim b/nimsuggest/tests/tdot4.nim index 8681d045add70..f2c6c765f5919 100644 --- a/nimsuggest/tests/tdot4.nim +++ b/nimsuggest/tests/tdot4.nim @@ -15,7 +15,7 @@ discard """ $nimsuggest --tester --maxresults:2 $file >sug $1 sug;;skProc;;tdot4.main;;proc (inp: string): string;;$file;;6;;5;;"";;100;;None -sug;;skFunc;;mstrutils.replace;;proc (s: string, sub: string, by: string): string{.noSideEffect, gcsafe.};;*fixtures/mstrutils.nim;;9;;5;;"this is a test version of strutils.replace, it simply returns `by`";;100;;None +sug;;skFunc;;mstrutils.replace;;proc (s: string, sub: string, by: string): string{.noSideEffect, gcsafe, raises: [].};;*fixtures/mstrutils.nim;;9;;5;;"this is a test version of strutils.replace, it simply returns `by`";;100;;None """ # TODO - determine appropriate behaviour for further suggest output and test it diff --git a/nimsuggest/tests/tinclude.nim b/nimsuggest/tests/tinclude.nim index 66726f907ef21..f5cbabf053445 100644 --- a/nimsuggest/tests/tinclude.nim +++ b/nimsuggest/tests/tinclude.nim @@ -11,7 +11,7 @@ go() discard """ $nimsuggest --tester $file >def $path/tinclude.nim:7:14 -def;;skProc;;minclude_import.create;;proc (greeting: string, subject: string): Greet{.noSideEffect, gcsafe.};;*fixtures/minclude_include.nim;;3;;5;;"";;100 +def;;skProc;;minclude_import.create;;proc (greeting: string, subject: string): Greet{.noSideEffect, gcsafe, raises: [].};;*fixtures/minclude_include.nim;;3;;5;;"";;100 >def $path/fixtures/minclude_include.nim:3:71 def;;skType;;minclude_types.Greet;;Greet;;*fixtures/minclude_types.nim;;4;;2;;"";;100 >def $path/fixtures/minclude_include.nim:3:71 diff --git a/nimsuggest/tests/tsug_pragmas.nim b/nimsuggest/tests/tsug_pragmas.nim index 03a9cba4c67f3..ce9c4e8f8dca4 100644 --- a/nimsuggest/tests/tsug_pragmas.nim +++ b/nimsuggest/tests/tsug_pragmas.nim @@ -18,23 +18,23 @@ $nimsuggest --tester $file >sug $1 sug;;skTemplate;;fooBar4;;;;$file;;4;;8;;"";;100;;Prefix sug;;skTemplate;;tsug_pragmas.fooBar1;;template ();;$file;;1;;9;;"";;100;;Prefix -sug;;skMacro;;tsug_pragmas.fooBar3;;macro (x: untyped){.noSideEffect, gcsafe.};;$file;;3;;6;;"";;50;;Prefix +sug;;skMacro;;tsug_pragmas.fooBar3;;macro (x: untyped){.noSideEffect, gcsafe, raises: [].};;$file;;3;;6;;"";;50;;Prefix >sug $2 sug;;skTemplate;;fooBar4;;;;$file;;4;;8;;"";;100;;Prefix sug;;skTemplate;;tsug_pragmas.fooBar1;;template ();;$file;;1;;9;;"";;100;;Prefix -sug;;skMacro;;tsug_pragmas.fooBar3;;macro (x: untyped){.noSideEffect, gcsafe.};;$file;;3;;6;;"";;50;;Prefix +sug;;skMacro;;tsug_pragmas.fooBar3;;macro (x: untyped){.noSideEffect, gcsafe, raises: [].};;$file;;3;;6;;"";;50;;Prefix >sug $3 sug;;skTemplate;;fooBar4;;;;$file;;4;;8;;"";;100;;Prefix sug;;skTemplate;;tsug_pragmas.fooBar1;;template ();;$file;;1;;9;;"";;100;;Prefix -sug;;skMacro;;tsug_pragmas.fooBar3;;macro (x: untyped){.noSideEffect, gcsafe.};;$file;;3;;6;;"";;50;;Prefix +sug;;skMacro;;tsug_pragmas.fooBar3;;macro (x: untyped){.noSideEffect, gcsafe, raises: [].};;$file;;3;;6;;"";;50;;Prefix >sug $4 sug;;skTemplate;;fooBar4;;;;$file;;4;;8;;"";;100;;Prefix sug;;skTemplate;;tsug_pragmas.fooBar1;;template ();;$file;;1;;9;;"";;100;;Prefix -sug;;skMacro;;tsug_pragmas.fooBar3;;macro (x: untyped){.noSideEffect, gcsafe.};;$file;;3;;6;;"";;50;;Prefix +sug;;skMacro;;tsug_pragmas.fooBar3;;macro (x: untyped){.noSideEffect, gcsafe, raises: [].};;$file;;3;;6;;"";;50;;Prefix >sug $5 sug;;skTemplate;;fooBar4;;;;$file;;4;;8;;"";;100;;Prefix sug;;skTemplate;;tsug_pragmas.fooBar1;;template ();;$file;;1;;9;;"";;100;;Prefix -sug;;skMacro;;tsug_pragmas.fooBar3;;macro (x: untyped){.noSideEffect, gcsafe.};;$file;;3;;6;;"";;50;;Prefix +sug;;skMacro;;tsug_pragmas.fooBar3;;macro (x: untyped){.noSideEffect, gcsafe, raises: [].};;$file;;3;;6;;"";;50;;Prefix """ diff --git a/nimsuggest/tests/tsug_template.nim b/nimsuggest/tests/tsug_template.nim index a2558c81c7331..da494d279d896 100644 --- a/nimsuggest/tests/tsug_template.nim +++ b/nimsuggest/tests/tsug_template.nim @@ -6,7 +6,7 @@ tmp#[!]# discard """ $nimsuggest --tester $file >sug $1 -sug;;skMacro;;tsug_template.tmpb;;macro (){.noSideEffect, gcsafe.};;$file;;2;;6;;"";;100;;Prefix +sug;;skMacro;;tsug_template.tmpb;;macro (){.noSideEffect, gcsafe, raises: [].};;$file;;2;;6;;"";;100;;Prefix sug;;skConverter;;tsug_template.tmpc;;converter ();;$file;;3;;10;;"";;100;;Prefix sug;;skTemplate;;tsug_template.tmpa;;template ();;$file;;1;;9;;"";;100;;Prefix """ diff --git a/nimsuggest/tests/tuse.nim b/nimsuggest/tests/tuse.nim index deaf81ef2ec68..7c1d1ad0c800f 100644 --- a/nimsuggest/tests/tuse.nim +++ b/nimsuggest/tests/tuse.nim @@ -14,9 +14,9 @@ proc #[!]#someProc*() = discard """ $nimsuggest --tester $file >use $1 -def;;skProc;;tuse.someProc;;proc (){.noSideEffect, gcsafe.};;$file;;9;;5;;"";;100 -use;;skProc;;tuse.someProc;;proc (){.noSideEffect, gcsafe.};;$file;;12;;0;;"";;100 +def;;skProc;;tuse.someProc;;proc (){.noSideEffect, gcsafe, raises: [].};;$file;;9;;5;;"";;100 +use;;skProc;;tuse.someProc;;proc (){.noSideEffect, gcsafe, raises: [].};;$file;;12;;0;;"";;100 >use $2 -def;;skProc;;tuse.someProc;;proc (){.noSideEffect, gcsafe.};;$file;;9;;5;;"";;100 -use;;skProc;;tuse.someProc;;proc (){.noSideEffect, gcsafe.};;$file;;12;;0;;"";;100 +def;;skProc;;tuse.someProc;;proc (){.noSideEffect, gcsafe, raises: [].};;$file;;9;;5;;"";;100 +use;;skProc;;tuse.someProc;;proc (){.noSideEffect, gcsafe, raises: [].};;$file;;12;;0;;"";;100 """ diff --git a/nimsuggest/tests/tv3.nim b/nimsuggest/tests/tv3.nim index fd736a1d8cc80..80e51e3644918 100644 --- a/nimsuggest/tests/tv3.nim +++ b/nimsuggest/tests/tv3.nim @@ -19,7 +19,7 @@ def skField tv3.Foo.bar string $file 5 4 "" 100 >sug $1 sug skField bar string $file 5 4 "" 100 Prefix >globalSymbols test -def skProc tv3.test proc (f: Foo){.gcsafe.} $file 7 5 "" 100 +def skProc tv3.test proc (f: Foo){.gcsafe, raises: [].} $file 7 5 "" 100 >globalSymbols Foo def skType tv3.Foo Foo $file 4 2 "" 100 >def $2 diff --git a/nimsuggest/tests/tv3_forward_definition.nim b/nimsuggest/tests/tv3_forward_definition.nim index 392e019ff910e..7a16ea331c249 100644 --- a/nimsuggest/tests/tv3_forward_definition.nim +++ b/nimsuggest/tests/tv3_forward_definition.nim @@ -7,17 +7,17 @@ let a = de#[!]#mo() discard """ $nimsuggest --v3 --tester $file >use $1 -use skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe.} $file 1 5 "" 100 -def skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe.} $file 3 5 "" 100 -use skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe.} $file 5 8 "" 100 +use skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe, raises: [].} $file 1 5 "" 100 +def skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe, raises: [].} $file 3 5 "" 100 +use skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe, raises: [].} $file 5 8 "" 100 >use $2 -use skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe.} $file 1 5 "" 100 -def skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe.} $file 3 5 "" 100 -use skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe.} $file 5 8 "" 100 +use skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe, raises: [].} $file 1 5 "" 100 +def skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe, raises: [].} $file 3 5 "" 100 +use skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe, raises: [].} $file 5 8 "" 100 >declaration $1 -declaration skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe.} $file 3 5 "" 100 +declaration skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe, raises: [].} $file 3 5 "" 100 >declaration $2 -declaration skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe.} $file 1 5 "" 100 +declaration skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe, raises: [].} $file 1 5 "" 100 >declaration $3 -declaration skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe.} $file 1 5 "" 100 +declaration skProc tv3_forward_definition.demo proc (): int{.noSideEffect, gcsafe, raises: [].} $file 1 5 "" 100 """ diff --git a/nimsuggest/tests/tv3_globalSymbols.nim b/nimsuggest/tests/tv3_globalSymbols.nim index f965a07aa9c13..c3bb9933b6cbc 100644 --- a/nimsuggest/tests/tv3_globalSymbols.nim +++ b/nimsuggest/tests/tv3_globalSymbols.nim @@ -7,8 +7,8 @@ proc BBtokenA(): int = 5 discard """ $nimsuggest --v3 --tester $file >globalSymbols token -def skProc tv3_globalSymbols.token proc (): int{.noSideEffect, gcsafe.} $file 4 5 "" 100 -def skProc tv3_globalSymbols.tokenA proc (): int{.noSideEffect, gcsafe.} $file 3 5 "" 100 -def skProc tv3_globalSymbols.Btoken proc (): int{.noSideEffect, gcsafe.} $file 2 5 "" 100 -def skProc tv3_globalSymbols.BBtokenA proc (): int{.noSideEffect, gcsafe.} $file 5 5 "" 100 +def skProc tv3_globalSymbols.token proc (): int{.noSideEffect, gcsafe, raises: [].} $file 4 5 "" 100 +def skProc tv3_globalSymbols.tokenA proc (): int{.noSideEffect, gcsafe, raises: [].} $file 3 5 "" 100 +def skProc tv3_globalSymbols.Btoken proc (): int{.noSideEffect, gcsafe, raises: [].} $file 2 5 "" 100 +def skProc tv3_globalSymbols.BBtokenA proc (): int{.noSideEffect, gcsafe, raises: [].} $file 5 5 "" 100 """ diff --git a/nimsuggest/tests/tv3_outline.nim b/nimsuggest/tests/tv3_outline.nim index 6370948d9a4e3..518620c871167 100644 --- a/nimsuggest/tests/tv3_outline.nim +++ b/nimsuggest/tests/tv3_outline.nim @@ -33,13 +33,13 @@ outline skType tv3_outline.FooEnum FooEnum $file 6 2 "" 100 6 31 outline skEnumField tv3_outline.FooEnum.value1 FooEnum $file 6 17 "" 100 6 23 outline skEnumField tv3_outline.FooEnum.value2 FooEnum $file 6 25 "" 100 6 31 outline skType tv3_outline.FooPrivate FooPrivate $file 7 2 "" 100 8 22 -outline skMacro tv3_outline.m macro (arg: untyped): untyped{.noSideEffect, gcsafe.} $file 10 6 "" 100 10 40 +outline skMacro tv3_outline.m macro (arg: untyped): untyped{.noSideEffect, gcsafe, raises: [].} $file 10 6 "" 100 10 40 outline skTemplate tv3_outline.t template (arg: untyped): untyped $file 11 9 "" 100 11 43 -outline skProc tv3_outline.p proc (){.noSideEffect, gcsafe.} $file 12 5 "" 100 12 24 -outline skConverter tv3_outline.c converter (s: string): int{.noSideEffect, gcsafe.} $file 14 10 "" 100 14 37 -outline skFunc tv3_outline.f proc (){.noSideEffect, gcsafe.} $file 16 5 "" 100 16 24 +outline skProc tv3_outline.p proc (){.noSideEffect, gcsafe, raises: [].} $file 12 5 "" 100 12 24 +outline skConverter tv3_outline.c converter (s: string): int{.noSideEffect, gcsafe, raises: [].} $file 14 10 "" 100 14 37 +outline skFunc tv3_outline.f proc (){.noSideEffect, gcsafe, raises: [].} $file 16 5 "" 100 16 24 outline skConst tv3_outline.con int literal(2) $file 20 6 "" 100 20 13 -outline skProc tv3_outline.outer proc (){.noSideEffect, gcsafe.} $file 22 5 "" 100 23 24 -outline skProc tv3_outline.outer.inner proc (){.noSideEffect, gcsafe.} $file 23 7 "" 100 23 24 -outline skProc tv3_outline.procWithLocal proc (){.noSideEffect, gcsafe.} $file 25 5 "" 100 26 16 +outline skProc tv3_outline.outer proc (){.noSideEffect, gcsafe, raises: [].} $file 22 5 "" 100 23 24 +outline skProc tv3_outline.outer.inner proc (){.noSideEffect, gcsafe, raises: [].} $file 23 7 "" 100 23 24 +outline skProc tv3_outline.procWithLocal proc (){.noSideEffect, gcsafe, raises: [].} $file 25 5 "" 100 26 16 """ diff --git a/nimsuggest/tests/twithin_macro.nim b/nimsuggest/tests/twithin_macro.nim index d79dae1be009c..98d58381f0fbf 100644 --- a/nimsuggest/tests/twithin_macro.nim +++ b/nimsuggest/tests/twithin_macro.nim @@ -45,7 +45,7 @@ $nimsuggest --tester --maxresults:5 $file >sug $1 sug;;skField;;age;;int;;$file;;6;;6;;"";;100;;None sug;;skField;;name;;string;;$file;;5;;6;;"";;100;;None -sug;;skMethod;;twithin_macro.age_human_yrs;;proc (self: Animal): int;;$file;;8;;9;;"";;100;;None -sug;;skMethod;;twithin_macro.vocalize;;proc (self: Animal): string;;$file;;7;;9;;"";;100;;None +sug;;skMethod;;twithin_macro.age_human_yrs;;proc (self: Animal): int{.raises: [].};;$file;;8;;9;;"";;100;;None +sug;;skMethod;;twithin_macro.vocalize;;proc (self: Animal): string{.raises: [].};;$file;;7;;9;;"";;100;;None sug;;skMethod;;twithin_macro.vocalize;;proc (self: Rabbit): string;;$file;;23;;9;;"";;100;;None """ diff --git a/nimsuggest/tests/twithin_macro_prefix.nim b/nimsuggest/tests/twithin_macro_prefix.nim index dd38108183d61..e89c8b94231d1 100644 --- a/nimsuggest/tests/twithin_macro_prefix.nim +++ b/nimsuggest/tests/twithin_macro_prefix.nim @@ -44,5 +44,5 @@ discard """ $nimsuggest --tester $file >sug $1 sug;;skField;;age;;int;;$file;;6;;6;;"";;100;;Prefix -sug;;skMethod;;twithin_macro_prefix.age_human_yrs;;proc (self: Animal): int;;$file;;8;;9;;"";;100;;Prefix +sug;;skMethod;;twithin_macro_prefix.age_human_yrs;;proc (self: Animal): int{.raises: [].};;$file;;8;;9;;"";;100;;Prefix """