Skip to content

Commit

Permalink
a bit ugly but works
Browse files Browse the repository at this point in the history
  • Loading branch information
metagn committed Aug 19, 2024
1 parent 53620f5 commit 1f419c4
Show file tree
Hide file tree
Showing 7 changed files with 31 additions and 56 deletions.
7 changes: 0 additions & 7 deletions compiler/sem.nim
Original file line number Diff line number Diff line change
Expand Up @@ -501,13 +501,6 @@ const

proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym,
flags: TExprFlags = {}; expectedType: PType = nil): PNode =
if c.inGenericContext > 0 and n.findUnresolvedStatic != nil:
# in generic type body, typed macros using unresolved statics
# can only be instantiated when the generic type is instantiated
result = semGenericStmt(c, n)
result.typ = makeTypeFromExpr(c, result.copyTree)
return

rememberExpansion(c, nOrig.info, sym)
pushInfoContext(c.config, nOrig.info, sym.detailedInfo)

Expand Down
6 changes: 5 additions & 1 deletion compiler/semcall.nim
Original file line number Diff line number Diff line change
Expand Up @@ -701,7 +701,7 @@ proc semResolvedCall(c: PContext, x: var TCandidate,
else:
c.inheritBindings(x, expectedType)
finalCallee = generateInstance(c, x.calleeSym, x.bindings, n.info)
elif c.inGenericContext == 0 or n.findUnresolvedStatic == nil:
else:
# For macros and templates, the resolved generic params
# are added as normal params.
# This is not done with unresolved static arguments, as typed macros
Expand Down Expand Up @@ -747,6 +747,10 @@ proc semOverloadedCall(c: PContext, n, nOrig: PNode,
var errors: CandidateErrors = @[] # if efExplain in flags: @[] else: nil
var r = resolveOverloads(c, n, nOrig, filter, flags, errors, efExplain in flags)
if r.state == csMatch:
if c.inGenericContext > 0 and r.matchedUnresolvedStatic:
result = semGenericStmt(c, n)
result.typ = makeTypeFromExpr(c, result.copyTree)
return
# this may be triggered, when the explain pragma is used
if errors.len > 0:
let (_, candidates) = presentFailedCandidates(c, n, errors)
Expand Down
7 changes: 0 additions & 7 deletions compiler/semexprs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,6 @@ const

proc semTemplateExpr(c: PContext, n: PNode, s: PSym,
flags: TExprFlags = {}; expectedType: PType = nil): PNode =
if c.inGenericContext > 0 and n.findUnresolvedStatic != nil:
# in generic type body, typed templates using unresolved statics
# can only be instantiated when the generic type is instantiated
result = semGenericStmt(c, n)
result.typ = makeTypeFromExpr(c, result.copyTree)
return

rememberExpansion(c, n.info, s)
let info = getCallLineInfo(n)
markUsed(c, info, s)
Expand Down
10 changes: 7 additions & 3 deletions compiler/sigmatch.nim
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ type
inheritancePenalty: int
firstMismatch*: MismatchInfo # mismatch info for better error messages
diagnosticsEnabled*: bool
matchedUnresolvedStatic*: bool

TTypeRelFlag* = enum
trDontBind
Expand Down Expand Up @@ -1216,6 +1217,9 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
return isGeneric
else: discard

if aOrig.kind == tyStatic and aOrig.n == nil:
c.matchedUnresolvedStatic = true

case f.kind
of tyEnum:
if a.kind == f.kind and sameEnumTypes(f, a): result = isEqual
Expand Down Expand Up @@ -1858,6 +1862,8 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
let prev = idTableGet(c.bindings, f)
if prev == nil:
if aOrig.kind == tyStatic:
if c.c.inGenericContext > 0 and aOrig.n == nil:
result = isNone
if f.base.kind notin {tyNone, tyGenericParam}:
result = typeRel(c, f.base, a, flags)
if result != isNone and f.n != nil:
Expand Down Expand Up @@ -1913,9 +1919,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
# proc foo(T: typedesc, x: T)
# when `f` is an unresolved typedesc, `a` could be any
# type, so we should not perform this check earlier
if c.c.inGenericContext > 0 and
a.skipTypes({tyTypeDesc}).kind == tyGenericParam#[ and
not (c.calleeSym != nil and c.calleeSym.kind in {skMacro, skTemplate})]#:
if c.c.inGenericContext > 0 and a.containsGenericType:
# generic type bodies can sometimes compile call expressions
# prevent unresolved generic parameters from being passed to procs as
# typedesc parameters
Expand Down
38 changes: 0 additions & 38 deletions tests/generics/tmacrotype.nim

This file was deleted.

18 changes: 18 additions & 0 deletions tests/generics/tuninstantiatedgenericcalls.nim
Original file line number Diff line number Diff line change
Expand Up @@ -221,3 +221,21 @@ block:
doAssert b.fixed1 is int
doAssert b.fixed2 is float
doAssert b.unknown is int

import std/sequtils

block: # version of #23432 with `typed`, don't delay instantiation
type
Future[T] = object
InternalRaisesFuture[T, E] = object
macro Raising[T](F: typedesc[Future[T]], E: varargs[typed]): untyped =
let raises = nnkTupleConstr.newTree(E.mapIt(it))
nnkBracketExpr.newTree(
ident "InternalRaisesFuture",
nnkDotExpr.newTree(F, ident"T"),
raises
)
type X[E] = Future[void].Raising(E)
proc f(x: X) = discard
var v: Future[void].Raising([ValueError])
f(v)
1 change: 1 addition & 0 deletions tests/iter/titertypedesc.nim
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
discard """
joinable: false # fails to #23977
output: '''0
(id: 0)
@[]
Expand Down

0 comments on commit 1f419c4

Please sign in to comment.