diff --git a/design/mvp/Explainer.md b/design/mvp/Explainer.md index 3e7f8c95..1502f8ca 100644 --- a/design/mvp/Explainer.md +++ b/design/mvp/Explainer.md @@ -2833,7 +2833,8 @@ within the same scope. To determine whether two names (defined as sequences of [Unicode Scalar Values]) are **strongly-unique**: 1. Canonicalize each name: - 1. Lowercase all the `acronym`s (uppercase letters) in the name. + 1. Remove all hyphens and lowercase all the `acronym`s (uppercase letters) in + the name. 2. If the name is `[method]l.l` or `[static]l.l` for some `label` `l`, replace the name with `l` (e.g. `[method]foo.foo` becomes `foo`). 3. If the name has any `[...]` annotation prefix other than `[constructor]`, @@ -2842,10 +2843,13 @@ Values]) are **strongly-unique**: unequal. Thus, the following set of names are strongly-unique and can thus all be imports (or exports) of the same component (or component type or instance type): -* `foo`, `foo-bar`, `[constructor]foo`, `[method]foo.bar`, `[static]foo.baz`, `foo:bar/baz` +* `foo`, `foo-bar`, `[constructor]foo`, `[method]foo.bar`, `[static]foo.baz`, + `foo:bar/baz` but attempting to add *any* of the following names would be a validation error: -* `foo`, `FOO`, `foo-BAR`, `[constructor]FOO`, `[method]foo.BAR`, `[static]foo.bar`, `[method]foo.baz`, `[method]foo.foo`, `[static]foo-BAR.FOO-bar`, `foo:bar/BAZ` +* `foo`, `FOO`, `foo-BAR`, `foobar`, `foob-ar`, `[constructor]FOO`, + `[method]foo.BAR`, `[static]foo.bar`, `[method]foo.baz`, `[method]foo.foo`, + `[static]foobar.FOOBAR`, `foo:bar/BAZ` The purpose of steps 1.2 and 1.3 is to play nice with constructors: in many languages, constructors are the only item that can have the same name as the class. diff --git a/test/validation/kebab.wast b/test/validation/kebab.wast index 478677ac..90de3354 100644 --- a/test/validation/kebab.wast +++ b/test/validation/kebab.wast @@ -1,14 +1,12 @@ ;; Validation of kebab-case plain names and `ns:pkg/iface` extern names, and -;; case-insensitive uniqueness of import/export names. +;; case-insensitive and hyphen-insensitive uniqueness of import/export names. (component (component (import "a" (func)) (import "a1" (func)) - (import "a-1" (func)) (import "a-1-b-2-c-3" (func)) (import "B" (func)) (import "B1" (func)) - (import "B-1" (func)) (import "B-1-C-2-D-3" (func)) (import "a11-B11-123-ABC-abc" (func)) (import "ns-1-a:b-1-c/D-2" (func)) @@ -117,7 +115,7 @@ (import "DOWn" (instance))) "`DOWn` is not in kebab case") -;; import/export names must be unique, compared case-insensitively +;; import/export names must be unique, compared case- and hyphen-insensitively (assert_invalid (component (import "f" (func $f)) @@ -148,3 +146,28 @@ (export "foo-BAR-baz" (func)) (export "FOO-bar-BAZ" (func))))) "export name `FOO-bar-BAZ` conflicts with previous name `foo-BAR-baz`") +(assert_invalid + (component + (import "foo-bar" (func)) + (import "foobar" (func))) + "import name `foobar` conflicts with previous name `foo-bar`") +(assert_invalid + (component + (import "foo-bar" (func)) + (import "FOOBAR" (func))) + "import name `FOOBAR` conflicts with previous name `foo-bar`") +(assert_invalid + (component + (import "foo-bar" (func)) + (import "FOOB-ar" (func))) + "import name `foob-ar` conflicts with previous name `foo-bar`") +(assert_invalid + (component + (import "foo-bar" (type (sub resource))) + (import "[static]foo-bar.FO-ob-AR" (func))) + "import name `[static]foo-bar.FO-ob-AR` conflicts with previous name `foo-bar`") +(assert_invalid + (component + (import "foo-bar" (type $t (sub resource))) + (import "[method]foo-bar.foobar" (func (param "self" (borrow $t))))) + "import name `[method]foo-bar.foobar` conflicts with previous name `foo-bar`")