Skip to content

Commit 2f8eda8

Browse files
committed
Add interface version canonicalization
1 parent e362068 commit 2f8eda8

File tree

1 file changed

+37
-6
lines changed

1 file changed

+37
-6
lines changed

design/mvp/Explainer.md

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ sort ::= core <core:sort>
294294
| type
295295
| component
296296
| instance
297-
inlineexport ::= (export <exportname> <sortidx>)
297+
inlineexport ::= (export <exportname> <fullversion>? <sortidx>)
298298
```
299299
Because component-level function, type and instance definitions are different
300300
than core-level function, type and instance definitions, they are put into
@@ -574,8 +574,8 @@ instancedecl ::= core-prefix(<core:type>)
574574
| <alias>
575575
| <exportdecl>
576576
| <value> 🪙
577-
importdecl ::= (import <importname> bind-id(<externdesc>))
578-
exportdecl ::= (export <exportname> bind-id(<externdesc>))
577+
importdecl ::= (import <importname> <fullversion>? bind-id(<externdesc>))
578+
exportdecl ::= (export <exportname> <fullversion>? bind-id(<externdesc>))
579579
externdesc ::= (<sort> (type <u32>) )
580580
| core-prefix(<core:moduletype>)
581581
| <functype>
@@ -2242,8 +2242,9 @@ the identifier `$x`). In the case of exports, the `<id>?` right after the
22422242
preceding definition being exported (e.g., `(export $x "x" (func $f))` binds a
22432243
new identifier `$x`).
22442244
```ebnf
2245-
import ::= (import "<importname>" bind-id(<externdesc>))
2246-
export ::= (export <id>? "<exportname>" <sortidx> <externdesc>?)
2245+
import ::= (import "<importname>" <fullversion>? bind-id(<externdesc>))
2246+
export ::= (export <id>? "<exportname>" <fullversion>? <sortidx> <externdesc>?)
2247+
fullversion ::= (fullversion <valid semver>)
22472248
```
22482249
All import names are required to be [strongly-unique]. Separately, all export
22492250
names are also required to be [strongly-unique]. The rest of the grammar for
@@ -2283,10 +2284,13 @@ words ::= <word>
22832284
| <words> '-' <word>
22842285
projection ::= '/' <label>
22852286
version ::= '@' <valid semver>
2287+
| '@' [1-9] [0-9]*
2288+
| '@0.' [1-9] [0-9]*
22862289
depname ::= 'unlocked-dep=<' <pkgnamequery> '>'
22872290
| 'locked-dep=<' <pkgname> '>' ( ',' <hashname> )?
22882291
pkgnamequery ::= <pkgpath> <verrange>?
2289-
pkgname ::= <pkgpath> <version>?
2292+
pkgname ::= <pkgpath> <pkgversion>?
2293+
pkgversion ::= '@' <valid semver>
22902294
pkgpath ::= <namespace> <words>
22912295
| <namespace>+ <words> <projection>* 🪺
22922296
verrange ::= '@*'
@@ -2379,6 +2383,33 @@ interpreted with the same [semantics][SemVerRange]. (Mostly this
23792383
interpretation is the usual SemVer-spec-defined ordering, but note the
23802384
particular behavior of pre-release tags.)
23812385

2386+
The `version` production used in `interfacename`s accepts both `valid semver`
2387+
and "canonicalized interface versions" which can be constructed from a `valid
2388+
semver` as follows:
2389+
2390+
- An input version is split into `<major>.<minor>.<patch>`, with any trailing
2391+
`-<prerelease>` or `+<build>` field discarded.
2392+
- The canonicalized interface version is:
2393+
- if `major` and `minor` are `0`:
2394+
- `0.0.<patch>`
2395+
- otherwise, if `major` is `0`:
2396+
- `0.<minor>`
2397+
- otherwise:
2398+
- `<major>`
2399+
2400+
This canonicalization, when used in conjunction with interface consumers and
2401+
implementations that follow SemVer compatibility, allows the matching of
2402+
compatible imports and exports that differ only in "insignificant" (from a
2403+
SemVer semantics perspective) parts of their version numbers. For example, an
2404+
implementation of `a:b/[email protected]` should be compatible with a consumer of
2405+
`a:b/[email protected]`; version canonicalization would produce the identical interface
2406+
name `a:b/[email protected]` for both of these versions.
2407+
2408+
When a component producer canonicalizes an interface version the original
2409+
version should be preserved in imports / exports in the `fullversion` field.
2410+
This gives component runtimes and other tools access to the original version for
2411+
error messages, documentation, and other development purposes.
2412+
23822413
The `plainname` production captures several language-neutral syntactic hints
23832414
that allow bindings generators to produce more idiomatic bindings in their
23842415
target language. At the top-level, a `plainname` allows functions to be

0 commit comments

Comments
 (0)