Skip to content

Commit

Permalink
remove fauxMatch for tyFromExpr, remove tyProxy and tyUnknown aliases (
Browse files Browse the repository at this point in the history
…#24018)

updated version of #22193

After #22029 and the followups #23983 and #24005 which fixed issues with
it, `tyFromExpr` no longer match any proc params in generic type bodies
but delay all non-matching calls until the type is instantiated.
Previously the mechanism `fauxMatch` was used to pretend that any
failing match against `tyFromExpr` actually matched, but prevented the
instantiation of the type until later.

Since this mechanism is not needed anymore for `tyFromExpr`, it is now
only used for `tyError` to prevent cascading errors and changed to a
bool field for simplicity. A change in `semtypes` was also needed to
prevent calling `fitNode` on default param values resolving to type
`tyFromExpr` in generic procs for params with non-generic types, as this
would try to coerce the expression into a concrete type when it can't be
instantiated yet.

The aliases `tyProxy` and `tyUnknown` for `tyError` and `tyFromExpr` are
also removed for uniformity.
  • Loading branch information
metagn authored Aug 28, 2024
1 parent ea7c2a4 commit d3af51e
Show file tree
Hide file tree
Showing 15 changed files with 31 additions and 39 deletions.
7 changes: 2 additions & 5 deletions compiler/ast.nim
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,8 @@ type
tyUncheckedArray
# An array with boundaries [0,+∞]

tyProxy # used as errornous type (for idetools)
tyError # used as erroneous type (for idetools)
# as an erroneous node should match everything

tyBuiltInTypeClass
# Type such as the catch-all object, tuple, seq, etc
Expand Down Expand Up @@ -276,10 +277,6 @@ static:
const
tyPureObject* = tyTuple
GcTypeKinds* = {tyRef, tySequence, tyString}
tyError* = tyProxy # as an errornous node should match everything
tyUnknown* = tyFromExpr

tyUnknownTypes* = {tyError, tyFromExpr}

tyTypeClasses* = {tyBuiltInTypeClass, tyCompositeTypeClass,
tyUserTypeClass, tyUserTypeClassInst,
Expand Down
2 changes: 1 addition & 1 deletion compiler/ccgreset.nim
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ proc specializeResetT(p: BProc, accessor: Rope, typ: PType) =
raiseAssert "unexpected set type kind"
of tyNone, tyEmpty, tyNil, tyUntyped, tyTyped, tyGenericInvocation,
tyGenericParam, tyOrdinal, tyOpenArray, tyForward, tyVarargs,
tyUncheckedArray, tyProxy, tyBuiltInTypeClass, tyUserTypeClass,
tyUncheckedArray, tyError, tyBuiltInTypeClass, tyUserTypeClass,
tyUserTypeClassInst, tyCompositeTypeClass, tyAnd, tyOr, tyNot,
tyAnything, tyStatic, tyFromExpr, tyConcept, tyVoid, tyIterable:
discard
Expand Down
2 changes: 1 addition & 1 deletion compiler/expanddefaults.nim
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ proc expandDefault(t: PType; info: TLineInfo): PNode =
of tyString:
result = newZero(t, info, nkStrLit)
of tyNone, tyEmpty, tyUntyped, tyTyped, tyTypeDesc,
tyNil, tyGenericInvocation, tyProxy, tyBuiltInTypeClass,
tyNil, tyGenericInvocation, tyError, tyBuiltInTypeClass,
tyUserTypeClass, tyUserTypeClassInst, tyCompositeTypeClass,
tyAnd, tyOr, tyNot, tyAnything, tyConcept, tyIterable, tyForward:
result = newZero(t, info, nkEmpty) # bug indicator
2 changes: 1 addition & 1 deletion compiler/jsgen.nim
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ proc mapType(typ: PType): TJSTypeKind =
of tyPointer:
# treat a tyPointer like a typed pointer to an array of bytes
result = etyBaseIndex
of tyRange, tyDistinct, tyOrdinal, tyProxy, tyLent:
of tyRange, tyDistinct, tyOrdinal, tyError, tyLent:
# tyLent is no-op as JS has pass-by-reference semantics
result = mapType(skipModifier t)
of tyInt..tyInt64, tyUInt..tyUInt64, tyEnum, tyChar: result = etyInt
Expand Down
2 changes: 1 addition & 1 deletion compiler/liftdestructors.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1040,7 +1040,7 @@ proc fillBody(c: var TLiftCtx; t: PType; body, x, y: PNode) =
else:
discard "cannot copy openArray"

of tyFromExpr, tyProxy, tyBuiltInTypeClass, tyUserTypeClass,
of tyFromExpr, tyError, tyBuiltInTypeClass, tyUserTypeClass,
tyUserTypeClassInst, tyCompositeTypeClass, tyAnd, tyOr, tyNot, tyAnything,
tyGenericParam, tyGenericBody, tyNil, tyUntyped, tyTyped,
tyTypeDesc, tyGenericInvocation, tyForward, tyStatic:
Expand Down
8 changes: 4 additions & 4 deletions compiler/semcall.nim
Original file line number Diff line number Diff line change
Expand Up @@ -696,12 +696,12 @@ proc semResolvedCall(c: PContext, x: var TCandidate,
markUsed(c, info, finalCallee)
onUse(info, finalCallee)
assert finalCallee.ast != nil
if x.hasFauxMatch:
if x.matchedErrorType:
result = x.call
result[0] = newSymNode(finalCallee, getCallLineInfo(result[0]))
if containsGenericType(result.typ) or x.fauxMatch == tyUnknown:
result.typ = newTypeS(x.fauxMatch, c)
if result.typ.kind == tyError: incl result.typ.flags, tfCheckedForDestructor
if containsGenericType(result.typ):
result.typ = newTypeS(tyError, c)
incl result.typ.flags, tfCheckedForDestructor
return
let gp = finalCallee.ast[genericParamsPos]
if gp.isGenericParams:
Expand Down
2 changes: 1 addition & 1 deletion compiler/semstmts.nim
Original file line number Diff line number Diff line change
Expand Up @@ -2859,7 +2859,7 @@ proc semStmtList(c: PContext, n: PNode, flags: TExprFlags, expectedType: PType =
let verdict = semConstExpr(c, n[i])
if verdict == nil or verdict.kind != nkIntLit or verdict.intVal == 0:
localError(c.config, result.info, "concept predicate failed")
of tyUnknown: continue
of tyFromExpr: continue
else: discard
if n[i].typ == c.enforceVoidContext: #or usesResult(n[i]):
voidContext = true
Expand Down
2 changes: 1 addition & 1 deletion compiler/semtypes.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1385,7 +1385,7 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
typ = newTypeS(tyTypeDesc, c, newTypeS(tyNone, c))
typ.flags.incl tfCheckedForDestructor

else:
elif def.typ.kind != tyFromExpr:
# if def.typ != nil and def.typ.kind != tyNone:
# example code that triggers it:
# proc sort[T](cmp: proc(a, b: T): int = cmp)
Expand Down
23 changes: 9 additions & 14 deletions compiler/sigmatch.nim
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ type
magic*: TMagic # magic of operation
baseTypeMatch: bool # needed for conversions from T to openarray[T]
# for example
fauxMatch*: TTypeKind # the match was successful only due to the use
# of error or wildcard (unknown) types.
matchedErrorType*: bool # match is considered successful after matching
# error type to avoid cascading errors
# this is used to prevent instantiations.
genericConverter*: bool # true if a generic converter needs to
# be instantiated
Expand Down Expand Up @@ -101,8 +101,6 @@ const
proc markUsed*(c: PContext; info: TLineInfo, s: PSym; checkStyle = true)
proc markOwnerModuleAsUsed*(c: PContext; s: PSym)

template hasFauxMatch*(c: TCandidate): bool = c.fauxMatch != tyNone

proc initCandidateAux(ctx: PContext,
callee: PType): TCandidate {.inline.} =
result = TCandidate(c: ctx, exactMatches: 0, subtypeMatches: 0,
Expand Down Expand Up @@ -813,7 +811,7 @@ proc matchUserTypeClass*(m: var TCandidate; ff, a: PType): PType =
param.typ.flags.incl tfInferrableStatic
else:
param.ast = typ.n
of tyUnknown:
of tyFromExpr:
param = paramSym skVar
param.typ = typ.exactReplica
#copyType(typ, c.idgen, typ.owner)
Expand Down Expand Up @@ -1971,7 +1969,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
if aOrig != nil:
put(c, f, aOrig)
result = isGeneric
of tyProxy:
of tyError:
result = isEqual
of tyFromExpr:
# fix the expression, so it contains the already instantiated types
Expand Down Expand Up @@ -2037,7 +2035,7 @@ proc implicitConv(kind: TNodeKind, f: PType, arg: PNode, m: TCandidate,
c: PContext): PNode =
result = newNodeI(kind, arg.info)
if containsGenericType(f):
if not m.hasFauxMatch:
if not m.matchedErrorType:
result.typ = getInstantiatedType(c, arg, m, f).skipTypes({tySink})
else:
result.typ = errorType(c)
Expand Down Expand Up @@ -2329,13 +2327,10 @@ proc paramTypesMatchAux(m: var TCandidate, f, a: PType,
result = implicitConv(nkHiddenSubConv, f, arg, m, c)
of isNone:
# do not do this in ``typeRel`` as it then can't infer T in ``ref T``:
if a.kind in {tyProxy, tyUnknown}:
if a.kind == tyUnknown and c.inGenericContext > 0:
# don't bother with fauxMatch mechanism in generic type,
# reject match, typechecking will be delayed to instantiation
return nil
if a.kind == tyFromExpr: return nil
elif a.kind == tyError:
inc(m.genericMatches)
m.fauxMatch = a.kind
m.matchedErrorType = true
return arg
elif a.kind == tyVoid and f.matchesVoidProc and argOrig.kind == nkStmtList:
# lift do blocks without params to lambdas
Expand Down Expand Up @@ -2505,7 +2500,7 @@ proc setSon(father: PNode, at: int, son: PNode) =
# we are allowed to modify the calling node in the 'prepare*' procs:
proc prepareOperand(c: PContext; formal: PType; a: PNode): PNode =
if formal.kind == tyUntyped and formal.len != 1:
# {tyTypeDesc, tyUntyped, tyTyped, tyProxy}:
# {tyTypeDesc, tyUntyped, tyTyped, tyError}:
# a.typ == nil is valid
result = a
elif a.typ.isNil:
Expand Down
2 changes: 1 addition & 1 deletion compiler/typeallowed.nim
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
result = typeAllowedNode(marker, t.n, kind, c, flags)
of tyEmpty:
if kind in {skVar, skLet}: result = t
of tyProxy:
of tyError:
# for now same as error node; we say it's a valid type as it should
# prevent cascading errors:
result = nil
Expand Down
4 changes: 2 additions & 2 deletions compiler/types.nim
Original file line number Diff line number Diff line change
Expand Up @@ -776,7 +776,7 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =

proc firstOrd*(conf: ConfigRef; t: PType): Int128 =
case t.kind
of tyBool, tyChar, tySequence, tyOpenArray, tyString, tyVarargs, tyProxy:
of tyBool, tyChar, tySequence, tyOpenArray, tyString, tyVarargs, tyError:
result = Zero
of tySet, tyVar: result = firstOrd(conf, t.elementType)
of tyArray: result = firstOrd(conf, t.indexType)
Expand Down Expand Up @@ -909,7 +909,7 @@ proc lastOrd*(conf: ConfigRef; t: PType): Int128 =
result = lastOrd(conf, skipModifier(t))
of tyUserTypeClasses:
result = lastOrd(conf, last(t))
of tyProxy: result = Zero
of tyError: result = Zero
of tyOrdinal:
if t.hasElementType: result = lastOrd(conf, skipModifier(t))
else:
Expand Down
2 changes: 1 addition & 1 deletion compiler/vmdeps.nim
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ proc mapTypeToAstX(cache: IdentCache; t: PType; info: TLineInfo;
of tyUInt32: result = atomicType("uint32", mUInt32)
of tyUInt64: result = atomicType("uint64", mUInt64)
of tyVarargs: result = mapTypeToBracket("varargs", mVarargs, t, info)
of tyProxy: result = atomicType("error", mNone)
of tyError: result = atomicType("error", mNone)
of tyBuiltInTypeClass:
result = mapTypeToBracket("builtinTypeClass", mNone, t, info)
of tyUserTypeClass, tyUserTypeClassInst:
Expand Down
2 changes: 1 addition & 1 deletion lib/system/hti.nim
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ type
tyOwned, tyUnused1, tyUnused2,
tyVarargsHidden,
tyUncheckedArray,
tyProxyHidden,
tyErrorHidden,
tyBuiltInTypeClassHidden,
tyUserTypeClassHidden,
tyUserTypeClassInstHidden,
Expand Down
6 changes: 3 additions & 3 deletions tests/generics/tstatic_constrained.nim
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ but expected: <T: float or string, Y>
tstatic_constrained.nim(44, 22) Error: cannot instantiate MyOtherType [type declared in tstatic_constrained.nim(30, 5)]
got: <typedesc[int], int literal(10)>
but expected: <T: float or string, Y>
tstatic_constrained.nim(44, 31) Error: object constructor needs an object type [proxy]
tstatic_constrained.nim(44, 31) Error: object constructor needs an object type [error]
tstatic_constrained.nim(44, 31) Error: expression '' has no type (or is ambiguous)
tstatic_constrained.nim(45, 22) Error: cannot instantiate MyOtherType [type declared in tstatic_constrained.nim(30, 5)]
got: <typedesc[byte], uint8>
but expected: <T: float or string, Y>
tstatic_constrained.nim(45, 22) Error: cannot instantiate MyOtherType [type declared in tstatic_constrained.nim(30, 5)]
got: <typedesc[byte], uint8>
but expected: <T: float or string, Y>
tstatic_constrained.nim(45, 34) Error: object constructor needs an object type [proxy]
tstatic_constrained.nim(45, 34) Error: object constructor needs an object type [error]
tstatic_constrained.nim(45, 34) Error: expression '' has no type (or is ambiguous)
tstatic_constrained.nim(77, 14) Error: cannot instantiate MyType [type declared in tstatic_constrained.nim(71, 5)]
got: <typedesc[float], float64>
Expand Down Expand Up @@ -76,4 +76,4 @@ block:
b: MyType[string, "hello"]
c: MyType[float, 10d]
d: MyOtherType[MyOtherConstraint[float],MyOtherConstraint[float]()]
e: MyOtherType[MyOtherConstraint[int], MyOtherConstraint[int]()]
e: MyOtherType[MyOtherConstraint[int], MyOtherConstraint[int]()]
4 changes: 2 additions & 2 deletions tests/types/tinheritgenericparameter.nim
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ discard """
nimout:'''
tinheritgenericparameter.nim(36, 15) Error: Cannot inherit from: 'MyObject'
tinheritgenericparameter.nim(36, 15) Error: Cannot inherit from: 'MyObject'
tinheritgenericparameter.nim(36, 23) Error: object constructor needs an object type [proxy]
tinheritgenericparameter.nim(36, 23) Error: object constructor needs an object type [error]
tinheritgenericparameter.nim(36, 23) Error: expression '' has no type (or is ambiguous)
tinheritgenericparameter.nim(37, 15) Error: Cannot inherit from: 'int'
tinheritgenericparameter.nim(37, 15) Error: Cannot inherit from: 'int'
tinheritgenericparameter.nim(37, 23) Error: object constructor needs an object type [proxy]
tinheritgenericparameter.nim(37, 23) Error: object constructor needs an object type [error]
tinheritgenericparameter.nim(37, 23) Error: expression '' has no type (or is ambiguous)
'''
"""
Expand Down

0 comments on commit d3af51e

Please sign in to comment.