Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tests: organize lang spec and generic related tests #1175

Open
wants to merge 16 commits into
base: devel
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions tests/lang/s02_core/README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
# What Belongs Here?

This is the core of the language, but prior to the higher level features, this
would be what one might use to write a bootstrap Nim compiler which does not
possess all the features of Nim.
would be what one might use to write a basic bootstrap Nimskull compiler for a
barebones/basic Nimskull (no generics, metaprogramming, effects, etc).

- User-defined data types - generic, regular types, inheritance
- inline iterators
- procedures - `func`, `proc` and `converter`. Overload resolution rules for generic
and regular procedures. Methods
- elaboration of evaluation order
- user-defined data types - concrete types and basic parametric polymorphism
- procedures - overload resolution

Everything below doesn't belong in the core:
- iterators
- Effect and exception tracking system
- Templates
- Macros and macro API
- Macros
2 changes: 2 additions & 0 deletions tests/lang/s02_core/s02_procedures/sample_types_import.nim
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
## Example type definitions to be used in the procedure calls.

# TODO no imports in this section of tests

type
ImRange = range[0 .. 10]
ImArray = array[3, int]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# TODO no includes in this section of tests
7 changes: 7 additions & 0 deletions tests/lang/s02_core/s02_procedures/t02_argument_passing.nim
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ Covers the multitude of ways you can pass arguments to procedures.
'''
"""

# TODO: break things out as more advanced sections:
# - variadics should be their own spec
# - variadic with conversion, is yet more complicated
# - syntax: separate dot call rewrites
# - named arguments
# - default arguments


block different_number_of_arguments:
## Procedures can accept zero or more arguments.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ being passed to the called procedure. If derived object is passed, correct `.Sup
be used to achieve desired behavior.

'''
knownIssue: "varargs cannot pass polymorphic derived types"

"""

var invalidAssings: seq[string]
Expand All @@ -34,58 +32,15 @@ block regular_types:

try:
test(Base())

except ObjectAssignmentDefect:
invalidAssings.add "Base()"

try:
test(Base(), Derived1())

except ObjectAssignmentDefect:
invalidAssings.add "Base(), Derived1()"

try:
test(Derived1(), Derived2())

except ObjectAssignmentDefect:
invalidAssings.add "Derived1(), Derived2()"


block:
type
Base[T] = object of RootObj
value: T
Derived1[T] = object of Base[T]
Derived2[T] = object of Base[T]


proc implRegular[T](a, b, c: Base[T]): string =
result.add $a.value
result.add $b.value
result.add $c.value

proc implVarargs[T](x: varargs[Base[T]]): string =
discard
# result = ""
# for c in x:
# result.add $c.value

doAssert implRegular(
Derived2[int](value: 2),
Derived1[int](value: 4),
Base[int](value: 3)
) == "243", "Passing subtypes using regular arguments works correctly"

try:
doAssert implVarargs(
Derived2[int](value: 2),
Derived1[int](value: 4),
Base[int](value: 3)
) == "243", "Passing subtypes via varargs must work the same way as mutliple arguments"

except ObjectAssignmentdefect:
invalidAssings.add "Derived1, Derived, Base"


doAssert invalidAssings.len == 0, "Failed object assignment for " & $invalidAssings.len &
" cases - " & $invalidAssings
91 changes: 4 additions & 87 deletions tests/lang/s02_core/s02_procedures/t03_overload_core.nim
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
discard """
description: '''
Specification of the core overloading resolution algorithm with examples
'''

description: '''
Specification of the core overloading resolution algorithm with examples
'''
"""



# TODO: breakout `convertors` into their own section, not part of the core

## In a call `p(args)` the routine `p` that matches best is selected.
## If multiple routines match equally well, the ambiguity is reported
Expand Down Expand Up @@ -87,44 +85,6 @@ block subtype_match:
doAssert impl(C()) == "matched subtype B"
doAssert impl(B()) == "matched subtype B"


block most_specific_generic_wins:
## If multiple overloaded procedures are present, most specific is
## always selected.

block qualifier:
## `ref`, `ptr` and other type qualifiers are counted as a part of
## the generic procedure definition.

proc gen[T](x: var ref ref T): string = "var ref ref T"
proc gen[T](x: ref ref T): string = "ref ref T"
proc gen[T](x: ref T): string = "ref T"
proc gen[T](x: T): string = "T"

var v: ref ref int = nil
doAssert gen(v) == "var ref ref T"
doAssert gen((ref ref int)(nil)) == "ref ref T"
doAssert gen((ref int)(nil)) == "ref T"
doAssert gen(nil) == "T"


# QUESTION - it is not possible to select less generic overload?
# doAssert gen[ref ref ref ref int](nil) == "ref T"

block regular:
## The rule also applied to regular generic types
proc gen[T](x: var seq[seq[T]]): string = "var seq seq T"
proc gen[T](x: seq[seq[T]]): string = "seq seq T"
proc gen[T](x: seq[T]): string = "seq T"
proc gen[T](x: T): string = "T"

var v: seq[seq[int]]
doAssert gen(v) == "var seq seq T"
doAssert gen(newSeq[seq[int]]()) == "seq seq T"
doAssert gen(newSeq[int]()) == "seq T"
doAssert gen(nil) == "T"


block conversion_match:
## Conversion match: a is convertible to f, possibly via a user defined converter.

Expand All @@ -151,49 +111,6 @@ block consider_all_arguments:
## it leads to the "ambiguous overload" error -
## :idx:`t03_overload_core_ambiguous_fail.nim`

block generic_vs_subtype:
## Generic overloading match comes before subtype relation match, so maybe code
## like this would seem unexpected.
#
# Example taken from the https://github.com/nim-lang/Nim/issues/18314
#
type
A = ref object of RootObj
B = ref object of A
C = ref object of B

block regular_procs:
proc impl[T: A](a: T): string = "matched generic"
proc impl(b: B): string = "matched subtype B"

## subtype vs generic - wins generic
doAssert impl(C()) == "matched generic"

## generic vs exact match - wins exact match
doAssert impl(B()) == "matched subtype B"

block subtype_constaints_for_generic:
## When subtype is used as a constraint for the generic parameter it
## functions the same way as if it was written directly in the argument.

type
A = ref object of RootObj
B1 = ref object of A
B2 = ref object of A

proc impl[T](a: T): string = "T"
proc impl[T: A](a: T): string = "A"
proc impl[T: B1](a: T): string = "B1"
proc impl[T: B2](a: T): string = "B2"
proc impl[T: B1 | B2](a: T): string = "B1|B2"

doAssert impl(B1()) == "B1"
doAssert impl(B2()) == "B2"

## Note that `B1 | B2` is not reported as an ambiguous overload since constaints
## with alternatives have a lower precedence compared to the simple `SomeType`.


## Conveter must be defined on the toplevel - it is only used in the `varargs_overloading`
## example

Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
discard """
description: '''
Rejects valid code, or this part of the overload resolution is underspecified.

`ref object` in definition is handled differently from `ref T` in the argument
when overload resolution is considered.
'''
knownIssue: "ref object is not a proper subtype"
errormsg: "Error: type mismatch: got <ref Derived>"

description: '''
`ref object` in a definition is handled differently from `ref T` in an
argument when overload resolution is considered.
'''
knownIssue: '''
Rejects valid code or this part of the overload resolution is
underspecified.
'''
"""

# When fixed should be added back to the core overload resolution, "subtype" section
# When fixed should be added back to overload resolution with inheritance
block subtype_ref_object:
block no_qualifier:
## Identical to previous example, but used here to highlight lack of
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
discard """
description: '''
Identical number of matches in each argument overload category leads to an
ambiguous overload error.
'''
errormsg: "ambiguous call; both t01_overload_core_ambiguous_fail.impl2(exact: uint8, conv: string) [proc declared in t01_overload_core_ambiguous_fail.nim(13, 6)] and t01_overload_core_ambiguous_fail.impl2(conv: string, exact: uint8) [proc declared in t01_overload_core_ambiguous_fail.nim(14, 6)] match for: (uint8, uint8)"
"""

# TODO: this is a converter related test and should not be in s02_core

converter toString(i8: uint8): string = $i8

proc impl2(exact: uint8, conv: string): string = "exact+conv"
proc impl2(conv: string, exact: uint8): string = "widen+widen"

doAssert impl2(0u8, 0u8) == "exact+conv"

This file was deleted.

2 changes: 1 addition & 1 deletion tests/lang/s02_core/s08_evaluation_order/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This section contains tests for inter- and intra-evaluation-order of
expressions and their sub-expressions.

The tests document where and how effects of expression are observable --
without effectful expression (i.e., expression that do more than just return
without effectful expression (i.e., expression that do more than just return
a value), order of evaluation would not matter.

## Assumptions
Expand Down
8 changes: 8 additions & 0 deletions tests/lang/s03_templating/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# What Belongs Here?

Introduction of templating facilities into the language, primarily `template`
routines, their calling, and interaction with overloads. Including `typed` and
`untyped` parameters and inline iterator support.

TODO:
- figure out if `include` should be in this section or perhaps earlier
10 changes: 10 additions & 0 deletions tests/lang/s04_parapoly/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# What Belongs Here?

Support for Parametric Polymorphism (parapoly), or generics. This has
implications for data types and procedures. This is exclusive of implicit
generics/type parameters, but includes first class iterators.

TODO:
- confirm if first class iterators should be here, combined with another
section, or separated into their own thing.
- would this be better if we moved this whole section after module_system?
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
discard """
description: '''
Using user-defined typeclass in argument type works differently compared
to the explicitly written type alternatrives.
'''

errormsg: "type mismatch: got <float, int>"
description: '''
Using user-defined typeclass in argument type works differently compared
to the explicitly written type alternatrives.
'''
errormsg: "type mismatch: got <float, int>"
"""


Expand All @@ -29,7 +28,6 @@ block:
proc aliasedTypeAlts(a, b: distinct Typeclass) = discard
aliasedTypeAlts(float(2.0), int(2))


block:
type Typeclass = int or float

Expand Down
Loading
Loading