diff options
author | metagn <metagngn@gmail.com> | 2024-08-28 21:46:36 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-08-28 20:46:36 +0200 |
commit | d3af51e3ce968076bb3331087806312c0faba054 (patch) | |
tree | 9a3321b4f3691c851ef68d1d82ed364c3d7ec78b | |
parent | ea7c2a440976b2757a780680a08f29c3ce0914e0 (diff) | |
download | Nim-d3af51e3ce968076bb3331087806312c0faba054.tar.gz |
remove fauxMatch for tyFromExpr, remove tyProxy and tyUnknown aliases (#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.
-rw-r--r-- | compiler/ast.nim | 7 | ||||
-rw-r--r-- | compiler/ccgreset.nim | 2 | ||||
-rw-r--r-- | compiler/expanddefaults.nim | 2 | ||||
-rw-r--r-- | compiler/jsgen.nim | 2 | ||||
-rw-r--r-- | compiler/liftdestructors.nim | 2 | ||||
-rw-r--r-- | compiler/semcall.nim | 8 | ||||
-rw-r--r-- | compiler/semstmts.nim | 2 | ||||
-rw-r--r-- | compiler/semtypes.nim | 2 | ||||
-rw-r--r-- | compiler/sigmatch.nim | 23 | ||||
-rw-r--r-- | compiler/typeallowed.nim | 2 | ||||
-rw-r--r-- | compiler/types.nim | 4 | ||||
-rw-r--r-- | compiler/vmdeps.nim | 2 | ||||
-rw-r--r-- | lib/system/hti.nim | 2 | ||||
-rw-r--r-- | tests/generics/tstatic_constrained.nim | 6 | ||||
-rw-r--r-- | tests/types/tinheritgenericparameter.nim | 4 |
15 files changed, 31 insertions, 39 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim index d0d4f8db3..db6cd9761 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -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 @@ -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, diff --git a/compiler/ccgreset.nim b/compiler/ccgreset.nim index 29791afdc..6caeb8084 100644 --- a/compiler/ccgreset.nim +++ b/compiler/ccgreset.nim @@ -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 diff --git a/compiler/expanddefaults.nim b/compiler/expanddefaults.nim index c121f5dea..c520d8849 100644 --- a/compiler/expanddefaults.nim +++ b/compiler/expanddefaults.nim @@ -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 diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index 657994b0d..d6310d584 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -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 diff --git a/compiler/liftdestructors.nim b/compiler/liftdestructors.nim index 0bbaf3b33..2cf8afb62 100644 --- a/compiler/liftdestructors.nim +++ b/compiler/liftdestructors.nim @@ -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: diff --git a/compiler/semcall.nim b/compiler/semcall.nim index 7040c1ac6..14e8591ba 100644 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -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: diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 185441815..be60b093d 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -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 diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 2a5b6c751..292558b5b 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -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) diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 1650e8598..89b66b524 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -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 @@ -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, @@ -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) @@ -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 @@ -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) @@ -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 @@ -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: diff --git a/compiler/typeallowed.nim b/compiler/typeallowed.nim index 2f757bb62..39193a42d 100644 --- a/compiler/typeallowed.nim +++ b/compiler/typeallowed.nim @@ -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 diff --git a/compiler/types.nim b/compiler/types.nim index 9dbbc3b8b..786fe0b0c 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -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) @@ -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: diff --git a/compiler/vmdeps.nim b/compiler/vmdeps.nim index e293ab7b2..5f9a2b5bc 100644 --- a/compiler/vmdeps.nim +++ b/compiler/vmdeps.nim @@ -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: diff --git a/lib/system/hti.nim b/lib/system/hti.nim index 9acaae88b..a26aff982 100644 --- a/lib/system/hti.nim +++ b/lib/system/hti.nim @@ -59,7 +59,7 @@ type tyOwned, tyUnused1, tyUnused2, tyVarargsHidden, tyUncheckedArray, - tyProxyHidden, + tyErrorHidden, tyBuiltInTypeClassHidden, tyUserTypeClassHidden, tyUserTypeClassInstHidden, diff --git a/tests/generics/tstatic_constrained.nim b/tests/generics/tstatic_constrained.nim index 3c9201548..d356b9d1c 100644 --- a/tests/generics/tstatic_constrained.nim +++ b/tests/generics/tstatic_constrained.nim @@ -8,7 +8,7 @@ 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> @@ -16,7 +16,7 @@ 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> @@ -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]()] \ No newline at end of file + e: MyOtherType[MyOtherConstraint[int], MyOtherConstraint[int]()] diff --git a/tests/types/tinheritgenericparameter.nim b/tests/types/tinheritgenericparameter.nim index c88c50b7b..d0d313635 100644 --- a/tests/types/tinheritgenericparameter.nim +++ b/tests/types/tinheritgenericparameter.nim @@ -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) ''' """ |