Skip to content

Commit b0912eb

Browse files
jemcSeanTAllen
authored andcommitted
Type param constraints now respect default cap of the type.
Prior to this change, any type named in a type constraint would get an implicit cap of `#any` if no explicit cap was named. The exception to this rule is primitives, which will use an implicit cap of `val` in a type constraint (though I'm not sure why you'd ever use a primitive as a type constraint to begin with). In both cases, the default cap declared by the user in the type declaration was being ignored, and this is the only context where that happens, violating the principle of least surprise. I also don't think this deviation is documented anywhere. As a veteran pony programmer, this still surprises and annoys me regularly when I run into it; I commonly make this mistake and have to recompile with an explicit cap that matches my declared default cap. Furthermore, using #any as a type parameter constraint is rarely what you actually want (not constraining the cap at all turns out to not let you do very much), so it doesn't make much sense to be the implicit cap. To illustrate this, there isn't a single example of a type constraint having a final cap of `#any` in the standard library. The lines that have been affected by this change are all cases of using type intersections where only one of the terms was being used to constrain the cap. After this change the default cap declared by the user will be universally respected. This is a breaking change for anyone who is relying on this behaviour.
1 parent d5ab678 commit b0912eb

File tree

5 files changed

+7
-17
lines changed

5 files changed

+7
-17
lines changed

packages/collections/_test.pony

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -598,7 +598,7 @@ class \nodoc\ iso _TestSort is UnitTest
598598
[""; "%*&^*&^&"; "***"; "Hello"; "bar"; "f00"; "foo"; "foo"],
599599
[""; "Hello"; "foo"; "bar"; "foo"; "f00"; "%*&^*&^&"; "***"])
600600

601-
fun test_sort[A: (Comparable[A] val & Stringable)](
601+
fun test_sort[A: (Comparable[A] val & Stringable val)](
602602
h: TestHelper,
603603
sorted: Array[A],
604604
unsorted: Array[A])

packages/collections/persistent/map.pony

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use mut = "collections"
22

3-
type Map[K: (mut.Hashable val & Equatable[K]), V: Any #share] is
3+
type Map[K: (mut.Hashable val & Equatable[K] val), V: Any #share] is
44
HashMap[K, V, mut.HashEq[K]]
55
"""
66
A map that uses structural equality on the key.

packages/collections/persistent/set.pony

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use mut = "collections"
22

3-
type Set[A: (mut.Hashable val & Equatable[A])] is HashSet[A, mut.HashEq[A]]
3+
type Set[A: (mut.Hashable val & Equatable[A] val)] is HashSet[A, mut.HashEq[A]]
44

55
type SetIs[A: Any #share] is HashSet[A, mut.HashIs[A]]
66

packages/pony_test/test_helper.pony

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ class val TestHelper
159159
"""
160160
_check_eq[A]("eq", expect, actual, msg, loc)
161161

162-
fun _check_eq[A: (Equatable[A] #read & Stringable)]
162+
fun _check_eq[A: (Equatable[A] #read & Stringable #read)]
163163
(check: String, expect: A, actual: A, msg: String, loc: SourceLoc)
164164
: Bool
165165
=>
@@ -221,7 +221,7 @@ class val TestHelper
221221
"""
222222
_check_ne[A]("ne", not_expect, actual, msg, loc)
223223

224-
fun _check_ne[A: (Equatable[A] #read & Stringable)]
224+
fun _check_ne[A: (Equatable[A] #read & Stringable #read)]
225225
(check: String, not_expect: A, actual: A, msg: String, loc: SourceLoc)
226226
: Bool
227227
=>

src/libponyc/pass/names.c

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -217,18 +217,8 @@ static bool names_type(pass_opt_t* opt, ast_t** astp, ast_t* def)
217217

218218
if(tcap == TK_NONE)
219219
{
220-
if((opt->check.frame->constraint != NULL) ||
221-
(opt->check.frame->iftype_constraint != NULL))
222-
{
223-
// A primitive constraint is a val, otherwise #any.
224-
if(ast_id(def) == TK_PRIMITIVE)
225-
tcap = TK_VAL;
226-
else
227-
tcap = TK_CAP_ANY;
228-
} else {
229-
// Use the default capability.
230-
tcap = ast_id(def_cap);
231-
}
220+
// Use the default capability.
221+
tcap = ast_id(def_cap);
232222
}
233223

234224
ast_setid(cap, tcap);

0 commit comments

Comments
 (0)