Skip to content

Scoping and overload resolution #5

Open
@Araq

Description

@Araq

This issue aims to be a more precise description about how Nim's scoping rules and overloading interact and also how syntactic constructions should be resolved. The current implementation does not follow these rules, but should unless experiments show how the rules outlined here can be improved in order to match the reality so that most Nim code out there continues to work as before.

Affected code in the compiler:

  • semexprs.nim
  • semcalls.nim
  • sigmatch.nim

Simple call

For a call expression f(args) first a set of candidates C(f)
is created. Candidates are symbols in the current scope that are callable.
A routine (proc, template, macro, iterator, etc.) is callable. Variables
are callable if they have the type proc. Types are also considered callable.

Named parameters inside args lead to a further filtering step within overload
solution. Then for C(f) the overload resolution is performed as described in the manual.

Module call

For a call expression module.f(args) first a set of candidates C(f) is created. Candidates are symbols in the current "module" that are callable. A routine (proc, template, macro, iterator, etc.) is callable. Variables are callable if they have the type proc.

Note: In a first analysis step it is to be decided whether module can be interpreted as a module identifier. Variables can shadow a module name.

Simple call with explicit generic instantiation

f[a](args) Candidate set as before, but further filtered against generic routines which have the right number of generic parameters. Only if this set is empty, it is interpreted as array indexing followed by the call notation ().

module.f[a](args): Analogous to the "Module call" case.

Object call

obj.f(args)

Condition: obj cannot be interpreted as a module identifier.
Condition: obj.f does not have a field f or field f is not of type proc.

Rewrite rule: obj.f(args) --> f(obj, args)

Impossible: obj.f[T](args), instead the notation obj.f[:T](args) needs to be used. obj.f[:T](args) is rewritten to f[T](obj, args).

Object call without ()

obj.f

Condition: obj cannot be interpreted as a module identifier.
Condition: obj.f does not have a field f or field f is not of type proc.

Rewrite rule: obj.f --> f(obj)

Array indexing without ()

x[args]:

x is only converted to a symchoice if there is not
variable (or let or const) of this name.

Rule: Prefer generic instantiation if possible. Otherwise interpret the
expression as [](x, args)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions