Commit 6521988
committed
Add "&" intersection types, "|" union operator, and "[...]" precedence override
Adds three related type-tag syntax elements:
- `&` (intersection, closes #1644): `Foo & Bar` means a value must
satisfy both `Foo` and `Bar`, matching Solargraph's syntax
(castwide/solargraph#1231). Legal in every position a type can appear,
and always binds tighter than the union or slot separator around it,
matching RBS's documented precedence. Renders as "both a Foo and a
Bar" (or "all of a Foo, a Bar, and a Baz" for 3+), to avoid reading
like two separate values.
- `|` (union, closes #1699): marks a union - a value matching any of the
listed types. Some type lists already mean a union without it (the top
level, a hash's key/value lists, `[...]`, and `Array<...>`/`Set<...>`),
so `,` and `|` land on the same result there. Elsewhere, each
comma-separated item is a distinct, positional type parameter instead
(a fixed-order list like `Array(...)`, or `<...>` for a name other than
`Array`/`Set`) - there, `|` groups alternatives within a single one of
them: `Array(Foo | Bar, Baz)` is a 2-element Array whose first element
is a Foo or a Bar, and `Result<Success | Failure, Other>` is a Result
whose first type parameter is a Success or a Failure.
- `[...]` (closes #1699): used the same way parentheses are in algebra,
to override the default order of operations - e.g. to use a union as
one conjunct of an intersection, which otherwise has no way to mark
where the union ends: `[Foo | Bar] & Baz`.
Also documents three pre-existing but previously undocumented anonymous
shorthand forms - `<A>`, `(A)`, `{A=>B}` - where the leading type name can
be omitted and defaults to `Array`/`Hash` (see #1701), and stops
`Foo<A, B>` from always being read as a union: `<...>`'s type parameters
are conventionally used both ways - a homogeneous collection's implicit
union of element type(s) (`Array<String, Symbol>`), or a class's
distinct, positional type parameters (`Result<Success, Failure>`).
`Array`/`Set` (and any name with a single type parameter) keep the union
reading; `Hash<K, V>` gets its own dedicated key/value rendering matching
`Hash{K=>V}`; anything else with 2+ parameters reads neutrally ("a Result
with type parameters (a Success, a Failure)"). This choice is made
entirely by `CollectionType#to_s` at render time - the parser always
treats `<...>` the same way it already treats `(...)` (`,` separates
positional type parameters, `|` groups alternatives within one of them),
with no name-specific knowledge at all.
Full rules and examples are in the new "Operator Precedence" and
"Overriding the Order of Operations" sections of `docs/Tags.md`, and the
rewritten "Parameterized Types"/"Union Operator" sections.
Test plan:
- `bundle exec rspec spec/tags/types_explainer_spec.rb` - specs for
`IntersectionType`/`GroupType`/`CollectionType#to_s`, parser-level
precedence/error cases, and end-to-end `.explain` examples.
- `bundle exec rspec` - full suite green (2830 examples, 0 failures).1 parent 1f6bac2 commit 6521988
4 files changed
Lines changed: 704 additions & 24 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
3 | 25 | | |
4 | 26 | | |
5 | 27 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
169 | 169 | | |
170 | 170 | | |
171 | 171 | | |
172 | | - | |
| 172 | + | |
173 | 173 | | |
174 | 174 | | |
175 | | - | |
| 175 | + | |
176 | 176 | | |
177 | 177 | | |
178 | | - | |
179 | | - | |
180 | | - | |
181 | | - | |
182 | | - | |
183 | | - | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
184 | 195 | | |
185 | 196 | | |
186 | 197 | | |
| |||
194 | 205 | | |
195 | 206 | | |
196 | 207 | | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
197 | 223 | | |
198 | 224 | | |
199 | | - | |
| 225 | + | |
200 | 226 | | |
201 | 227 | | |
202 | 228 | | |
| |||
222 | 248 | | |
223 | 249 | | |
224 | 250 | | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
225 | 254 | | |
226 | 255 | | |
227 | 256 | | |
228 | 257 | | |
229 | 258 | | |
230 | 259 | | |
231 | 260 | | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
232 | 319 | | |
233 | 320 | | |
234 | 321 | | |
| |||
0 commit comments