This module implements the signature matching for resolving the call to overloaded procs, generic procs and operators.
Imports
-
../ast/ast, ../ast/astalgo, ../ast/types, ../ast/renderer, ../ast/idents, ../ast/trees, ../ast/lineinfos, ../ast/errorreporting, ../ast/errorhandling, ../modules/modulegraphs, ../modules/magicsys, ../front/msgs, ../front/options, semdata, semtypinst, lookups, lowerings, parampatterns, ../utils/debugutils, ../utils/idioms, ../ast/reports_sem, ../ast/report_enums, ../ast/reports
Types
TCandidate = object c*: PContext exactMatches*: int ## also misused to prefer iters over procs genericMatches: int ## also misused to prefer constraints subtypeMatches: int intConvMatches: int ## conversions to int are not as expensive convMatches: int state*: TCandidateState callee*: PType ## may not be nil! calleeSym*: PSym ## may be nil calleeScope*: int ## scope depth: ## is this a top-level symbol or a nested proc? call*: PNode ## modified call bindings*: TIdTable ## maps types to types 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. ## this is used to prevent instantiations. genericConverter*: bool ## true if a generic converter needs to ## be instantiated coerceDistincts*: bool ## this is an explicit coercion that can strip away ## a distrinct type typedescMatched*: bool isNoCall*: bool ## misused for generic type instantiations C[T] inferredTypes: seq[PType] ## inferred types during the current signature ## matching. they will be reset if the matching ## is not successful. may replace the bindings ## table in the future. inheritancePenalty: int ## to prefer closest father object type error*: SemCallMismatch
- Source Edit
TCandidateState = enum csEmpty, csMatch, csNoMatch
- Source Edit
TTypeRelFlag = enum trDontBind, trNoCovariance, trBindGenericParam ## bind tyGenericParam even with trDontBind
- Source Edit
TTypeRelFlags = set[TTypeRelFlag]
- Source Edit
Procs
proc argtypeMatches(c: PContext; f, a: PType; fromHlo = false): bool {. ...raises: [Exception, KeyError, ERecoverableError], tags: [RootEffect, ReadIOEffect].}
- Source Edit
proc cmpCandidates(a, b: TCandidate): int {....raises: [Exception], tags: [RootEffect].}
- Source Edit
proc cmpTypes(c: PContext; f, a: PType): TTypeRelation {. ...raises: [KeyError, Exception, ERecoverableError], tags: [RootEffect].}
- Source Edit
proc inferStaticParam(c: var TCandidate; lhs: PNode; rhs: BiggestInt): bool {. ...raises: [], tags: [].}
-
This is a simple integer arithimetic equation solver, capable of deriving the value of a static parameter in expressions such as (N + 5) / 2 = rhs
Preconditions:
- The input of this proc must be semantized
- all templates should be expanded
- aby constant folding possible should already be performed
- There must be exactly one unresolved static parameter
- Result:
- The proc will return true if the static types was successfully inferred. The result will be bound to the original static type in the TCandidate.
- The input of this proc must be semantized
proc initCallCandidate(ctx: PContext; c: var TCandidate; callee: PSym; calleeScope = -1) {....raises: [], tags: [].}
- Source Edit
proc initCandidate(ctx: PContext; c: var TCandidate; callee: PType) {. ...raises: [], tags: [].}
- Source Edit
proc instTypeBoundOp(c: PContext; dc: PSym; t: PType; info: TLineInfo; op: TTypeAttachedOp; col: int): PSym {.nosinks, ...raises: [Exception, ERecoverableError, KeyError], tags: [RootEffect].}
- Source Edit
proc matches(c: PContext; n, nOrig: PNode; m: var TCandidate) {. ...raises: [KeyError, Exception, ERecoverableError], tags: [RootEffect, ReadIOEffect, ReadDirEffect].}
- Source Edit
proc matchesGenericParams(c: PContext; args: PNode; m: var TCandidate) {. ...raises: [KeyError, Exception, ERecoverableError], tags: [RootEffect].}
-
Matches the provided generic arguments args (stored as a nkBracketExpr) against the candidate's generic parameters. Updates m with whether or not there was a match.
The arguments must strictly match the parameters -- them not being exactly equal means no match.
XXX: this strictness might be subject to change
Source Edit proc matchUserTypeClass(m: var TCandidate; ff, a: PType): PType {. ...raises: [Exception, ERecoverableError, KeyError], tags: [RootEffect].}
- Source Edit
proc newCallCandidate(ctx: PContext; callee: PSym; calleeScope = -1): TCandidate {. ...raises: [], tags: [].}
- Source Edit
proc newCandidate(ctx: PContext; callee: PType): TCandidate {....raises: [], tags: [].}
- Source Edit
proc paramTypesMatch(candidate: var TCandidate; formal, passed: PType; arg: PNode): PNode {. ...raises: [Exception, KeyError, ERecoverableError], tags: [RootEffect, ReadIOEffect].}
- Try to check a single argument for the candidate function call using provided formal parmameter and passed one. arg is a node that was passed from the callsite Source Edit
proc partialMatch(c: PContext; n, nOrig: PNode; m: var TCandidate) {. ...raises: [KeyError, Exception, ERecoverableError], tags: [RootEffect, ReadDirEffect, ReadIOEffect].}
- Source Edit
proc semFinishOperands(c: PContext; n: PNode) {....raises: [Exception], tags: [RootEffect].}
- Source Edit
proc toDebugCallableCandidate(c: TCandidate): DebugCallableCandidate {. ...raises: [], tags: [].}
- Source Edit
proc typeRel(c: var TCandidate; f, aOrig: PType; flags: TTypeRelFlags = {}): TTypeRelation {. ...raises: [KeyError, Exception, ERecoverableError], tags: [RootEffect].}
-
typeRel can be used to establish various relationships between types:
- When used with concrete types, it will check for type equivalence
- or a subtype relationship.
- When used with a concrete type against a type class (such as generic signature of a proc), it will check whether the concrete type is a member of the designated type class.
- When used with two type classes, it will check whether the types matching the first type class are a strict subset of the types matching the other. This allows us to compare the signatures of generic procs in order to give preferrence to the most specific one:
seq[seq[any]] is a strict subset of seq[any] and hence more specific.
Source Edit proc writeMatches(c: TCandidate) {....raises: [KeyError, Exception], tags: [ReadDirEffect, RootEffect].}
- Source Edit
Templates
template hasFauxMatch(c: TCandidate): bool
- Source Edit