fix semFinishOperands for bracket expressions [backport:2.0] (#23571)

fixes #23568, fixes #23310

In #23091 `semFinishOperands` was changed to not be called for `mArrGet`
and `mArrPut`, presumably in preparation for #23188 (not sure why it was
needed in #23091, maybe they got mixed together), since the compiler
handles these later and needs the first argument to not be completely
"typed" since brackets can serve as explicit generic instantiations in
which case the first argument would have to be an unresolved generic
proc (not accepted by `finishOperand`).

In this PR we just make it so `mArrGet` and `mArrPut` specifically skip
calling `finishOperand` on the first argument. This way the generic
arguments in the explicit instantiation get typed, but not the
unresolved generic proc.

(cherry picked from commit 09bd9d0b19)
This commit is contained in:
metagn
2024-05-08 18:35:26 +03:00
committed by narimiran
parent 526e48b2ed
commit 5cecd81a05
2 changed files with 32 additions and 7 deletions

View File

@@ -1012,10 +1012,14 @@ proc finishOperand(c: PContext, a: PNode): PNode =
localError(c.config, a.info, err)
considerGenSyms(c, result)
proc semFinishOperands(c: PContext; n: PNode) =
proc semFinishOperands(c: PContext; n: PNode; isBracketExpr = false) =
# this needs to be called to ensure that after overloading resolution every
# argument has been sem'checked:
for i in 1..<n.len:
# argument has been sem'checked
# skip the first argument for operands of `[]` since it may be an unresolved
# generic proc, which is handled in semMagic
let start = 1 + ord(isBracketExpr)
for i in start..<n.len:
n[i] = finishOperand(c, n[i])
proc afterCallActions(c: PContext; n, orig: PNode, flags: TExprFlags; expectedType: PType = nil): PNode =
@@ -1038,10 +1042,7 @@ proc afterCallActions(c: PContext; n, orig: PNode, flags: TExprFlags; expectedTy
of skMacro: result = semMacroExpr(c, result, orig, callee, flags, expectedType)
of skTemplate: result = semTemplateExpr(c, result, callee, flags, expectedType)
else:
if callee.magic notin {mArrGet, mArrPut, mNBindSym}:
# calls to `[]` can be explicit generic instantiations,
# don't sem every operand now, leave it to semmagic
semFinishOperands(c, result)
semFinishOperands(c, result, isBracketExpr = callee.magic in {mArrGet, mArrPut})
activate(c, result)
fixAbstractType(c, result)
analyseIfAddressTakenInCall(c, result)

View File

@@ -0,0 +1,24 @@
block: # issue #23568
type G[T] = object
j: T
proc s[T](u: int) = discard
proc s[T]() = discard
proc c(e: int | int): G[G[G[int]]] = s[G[G[int]]]()
discard c(0)
import std/options
block: # issue #23310
type
BID = string or uint64
Future[T] = ref object of RootObj
internalValue: T
InternalRaisesFuture[T] = ref object of Future[T]
proc newInternalRaisesFutureImpl[T](): InternalRaisesFuture[T] =
let fut = InternalRaisesFuture[T]()
template newFuture[T](): auto =
newInternalRaisesFutureImpl[T]()
proc problematic(blockId: BID): Future[Option[seq[int]]] =
let resultFuture = newFuture[Option[seq[int]]]()
return resultFuture
let x = problematic("latest")