mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-04 12:07:51 +00:00
don't allow instantiations resolving to generic body types (#24273)
fixes #24091, refs #24092
Any instantiations resolving to a generic body type now gives an error.
Due to #24092, this does not error in cases like matching against `type
M` in generics because generic body type symbols are just not
instantiated. But this prevents parameters with type `type M` from being
used, although there doesn't seem to be any code which does this. Just
in case such code exists, we still allow `typedesc` types resolving to
generic body types.
(cherry picked from commit 2f904535d0)
This commit is contained in:
@@ -53,7 +53,9 @@ iterator instantiateGenericParamList(c: PContext, n: PNode, pt: LayeredIdTable):
|
||||
if q.typ.kind != tyCompositeTypeClass:
|
||||
localError(c.config, a.info, errCannotInstantiateX % s.name.s)
|
||||
t = errorType(c)
|
||||
elif t.kind in {tyGenericParam, tyConcept, tyFromExpr}:
|
||||
elif t.kind in {tyGenericParam, tyConcept, tyFromExpr} or
|
||||
# generic body types are accepted as typedesc arguments
|
||||
(t.kind == tyGenericBody and q.typ.kind != tyTypeDesc):
|
||||
localError(c.config, a.info, errCannotInstantiateX % q.name.s)
|
||||
t = errorType(c)
|
||||
elif isUnresolvedStatic(t) and (q.typ.kind == tyStatic or
|
||||
|
||||
9
tests/generics/tgenericbodyreturn1.nim
Normal file
9
tests/generics/tgenericbodyreturn1.nim
Normal file
@@ -0,0 +1,9 @@
|
||||
discard """
|
||||
errormsg: "cannot instantiate: 'T'"
|
||||
file: "system.nim"
|
||||
"""
|
||||
|
||||
# issue #24091
|
||||
|
||||
type M[V] = object
|
||||
echo default(M)
|
||||
11
tests/generics/tgenericbodyreturn2.nim
Normal file
11
tests/generics/tgenericbodyreturn2.nim
Normal file
@@ -0,0 +1,11 @@
|
||||
discard """
|
||||
errormsg: "cannot instantiate: 'T'"
|
||||
file: "system.nim"
|
||||
"""
|
||||
|
||||
# issue #24091
|
||||
|
||||
type M[V] = object
|
||||
type Foo = object # notice not generic
|
||||
x: typeof(default(M))
|
||||
echo Foo() # ()
|
||||
13
tests/generics/tgenericbodyreturn3.nim
Normal file
13
tests/generics/tgenericbodyreturn3.nim
Normal file
@@ -0,0 +1,13 @@
|
||||
discard """
|
||||
errormsg: "cannot instantiate: 'ShouldNotResolve'"
|
||||
"""
|
||||
|
||||
# issue #24091
|
||||
|
||||
type Generic[U] = object
|
||||
proc foo[ShouldNotResolve](x: typedesc[ShouldNotResolve]): ShouldNotResolve =
|
||||
echo ShouldNotResolve # Generic
|
||||
echo declared(result) # true
|
||||
echo typeof(result) # Generic
|
||||
echo typeof(foo(Generic)) # void
|
||||
foo(Generic)
|
||||
@@ -421,17 +421,17 @@ block: # issue #24090
|
||||
doAssert a.x is M[int]
|
||||
var b: Foo[float]
|
||||
doAssert b.x is M[float]
|
||||
# related to #24091:
|
||||
doAssert not (compiles do:
|
||||
type Bar[T] = object
|
||||
x: typeof(M()) # actually fails here immediately
|
||||
var bar: Bar[int])
|
||||
# ideally fails here immediately since the inside of `typeof` does not
|
||||
# depend on an unresolved parameter
|
||||
# but if typechecking gets too lazy, then we need to instantiate to error
|
||||
x: typeof(M()))
|
||||
doAssert not (compiles do:
|
||||
type Bar[T] = object
|
||||
x: typeof(default(M))
|
||||
var bar: Bar[int]
|
||||
# gives "undeclared identifier x" because of #24091,
|
||||
# normally it should fail in the line above
|
||||
echo bar.x)
|
||||
# again, ideally fails here immediately
|
||||
x: typeof(default(M)))
|
||||
proc foo[T: M](x: T = default(T)) = discard x
|
||||
foo[M[int]]()
|
||||
doAssert not compiles(foo())
|
||||
|
||||
Reference in New Issue
Block a user