···2626 functions, constants, module names, and `as` patterns.
2727 ([Giacomo Cavalieri](https://github.com/giacomocavalieri))
28282929+- The compiler now generates singleton values for variants with no fields on the
3030+ JavaScript target, allowing for faster comparison in most cases.
3131+ ([Surya Rose](https://github.com/GearsDatapacks))
3232+2933### Build tool
30343135- The build tool now generates Hexdocs URLs using the new format of
···1212 },
1313 format::break_block,
1414 javascript::{
1515+ TypeVariant,
1516 expression::{eco_string_int, string},
1617 maybe_escape_property,
1718 },
···274275/// Here we will first need to check that the list is not empty:
275276///
276277/// ```js
277277-/// if (value instanceOf $NonEmptyList) {
278278+/// if (value instanceof $NonEmptyList) {
278279/// // ...
279280/// } else {
280281/// return [];
···288289/// first item of the list, so we need to actually create a variable for it:
289290///
290291/// ```js
291291-/// if (value instanceOf $NonEmptyList) {
292292+/// if (value instanceof $NonEmptyList) {
292293/// let $ = value.head;
293294/// if ($ === 1) {
294295/// // ...
···13381339 // Some variants like `Bool` and `Result` are special cased and checked
13391340 // in a different way from all other variants.
13401341 RuntimeCheck::Variant { match_, .. } if variable.type_.is_bool() => {
13411341- match match_.name().as_str() {
13421342+ match match_.used_name().as_str() {
13421343 "True" => value.to_doc(),
13431344 _ => docvec!["!", value],
13441345 }
13451346 }
1346134713471347- RuntimeCheck::Variant { match_, index, .. } => {
13481348+ RuntimeCheck::Variant {
13491349+ match_,
13501350+ index,
13511351+ fields,
13521352+ ..
13531353+ } => {
13481354 if variable.type_.is_result() && match_.module().is_none() {
13491355 if *index == 0 {
13501356 self.expression_generator.tracker.ok_used = true;
···13581364 .map(|module| eco_format!("${module}."))
13591365 .unwrap_or_default();
1360136613611361- docvec![value, " instanceof ", qualification, match_.name()]
13671367+ // If this variant has no fields, register it as being used
13681368+ // so that we know to import it.
13691369+ if fields.is_empty()
13701370+ && let Some((package, module, type_name)) =
13711371+ variable.type_.named_type_name_and_package()
13721372+ {
13731373+ _ = self
13741374+ .expression_generator
13751375+ .tracker
13761376+ .variants_used_in_instanceof
13771377+ .insert(TypeVariant {
13781378+ package,
13791379+ module,
13801380+ type_name,
13811381+ name: match_.variant_name(),
13821382+ });
13831383+ }
13841384+13851385+ docvec![value, " instanceof ", qualification, match_.used_name()]
13621386 }
1363138713641388 RuntimeCheck::NonEmptyList { .. } => {
···14141515----- COMPILED JAVASCRIPT
1616import * as $other_module from "../../package/other_module.mjs";
1717-import { A as B } from "../../package/other_module.mjs";
1717+import { A as B, T$A$const as T$B$const } from "../../package/other_module.mjs";
18181919export function func() {
2020- let $ = new B();
2020+ let $ = T$B$const;
2121 let x = $;
2222 if (x instanceof B) {
2323 return true;
···2020import { Ok as Y, CustomType as $CustomType, isEqual } from "../gleam.mjs";
21212222export class Ok extends $CustomType {}
2323-export const X$Ok = () => new Ok();
2323+export const X$Ok$const = new Ok();
2424+export const X$Ok = () => X$Ok$const;
2425export const X$isOk = (value) => value instanceof Ok;
25262627export function func() {
···1717import { Ok as Y, CustomType as $CustomType } from "../gleam.mjs";
18181919export class Ok extends $CustomType {}
2020-export const X$Ok = () => new Ok();
2020+export const X$Ok$const = new Ok();
2121+export const X$Ok = () => X$Ok$const;
2122export const X$isOk = (value) => value instanceof Ok;
22232324export const y = (var0) => { return new Y(var0); };
···11+---
22+source: compiler-core/src/javascript/tests/custom_types.rs
33+expression: "\nimport wibble.{Wibble as Wobble}\n\npub fn main() {\n let x = Wobble\n x == Wobble\n}\n"
44+---
55+----- SOURCE CODE
66+-- wibble.gleam
77+pub type Wibble { Wibble Wobble }
88+99+-- main.gleam
1010+1111+import wibble.{Wibble as Wobble}
1212+1313+pub fn main() {
1414+ let x = Wobble
1515+ x == Wobble
1616+}
1717+1818+1919+----- COMPILED JAVASCRIPT
2020+import * as $wibble from "../wibble.mjs";
2121+import { Wibble as Wobble, Wibble$Wibble$const as Wibble$Wobble$const } from "../wibble.mjs";
2222+2323+export function main() {
2424+ let x = Wibble$Wobble$const;
2525+ return x instanceof Wobble;
2626+}
···13131414----- COMPILED JAVASCRIPT
1515import * as $a from "../../package/a.mjs";
1616-import { A } from "../../package/a.mjs";
1616+import { A$A$const } from "../../package/a.mjs";
17171818export function main() {
1919- return new A();
1919+ return A$A$const;
2020}
···1818import * as $other from "../other.mjs";
19192020export function main() {
2121- return new $other.One();
2121+ return $other.One$One$const;
2222}
···1616import * as $other from "../other.mjs";
17171818export function main() {
1919- return new $other.Two();
1919+ return $other.One$Two$const;
2020}
···14141515----- COMPILED JAVASCRIPT
1616import * as $other from "../other.mjs";
1717-import { Two } from "../other.mjs";
1717+import { One$Two$const } from "../other.mjs";
18181919export function main() {
2020- return new Two();
2020+ return One$Two$const;
2121}
···14141515----- COMPILED JAVASCRIPT
1616import * as $other from "../other.mjs";
1717-import { Two as Three } from "../other.mjs";
1717+import { One$Two$const as One$Three$const } from "../other.mjs";
18181919export function main() {
2020- return new Three();
2020+ return One$Three$const;
2121}
···4141}
42424343export function main() {
4444- wibble(new A(), new B(), new C(), new D());
4545- wibble(new A(), new B(), new C(), new D());
4646- wibble(new A(), new B(), new C(), new D());
4747- wibble(new A(), new B(), new C(), new D());
4848- wibble(new A(), new B(), new C(), new D());
4949- wibble(new A(), new B(), new C(), new D());
5050- wibble(new A(), new B(), new C(), new D());
5151- return wibble(new A(), new B(), new C(), new D());
4444+ wibble(A$A$const, B$B$const, C$C$const, D$D$const);
4545+ wibble(A$A$const, B$B$const, C$C$const, D$D$const);
4646+ wibble(A$A$const, B$B$const, C$C$const, D$D$const);
4747+ wibble(A$A$const, B$B$const, C$C$const, D$D$const);
4848+ wibble(A$A$const, B$B$const, C$C$const, D$D$const);
4949+ wibble(A$A$const, B$B$const, C$C$const, D$D$const);
5050+ wibble(A$A$const, B$B$const, C$C$const, D$D$const);
5151+ return wibble(A$A$const, B$B$const, C$C$const, D$D$const);
5252}
···439439 let definition = if constructors.is_empty() {
440440 if let Some((module, external_name, _location)) = external_javascript {
441441 let member = Member {
442442- name: external_name.to_doc(),
442442+ name: external_name.clone(),
443443 alias: Some(eco_format!("{name}$").to_doc()),
444444 };
445445 imports.register_export(eco_format!("{name}$"));
···7373 }
7474}
75757676-export class Empty extends List {}
7777-export const List$Empty = () => new Empty();
7676+export class Empty extends List { }
7777+export const List$Empty$const = new Empty();
7878+export const List$Empty = () => List$Empty$const;
7879export const List$isEmpty = (value) => value instanceof Empty;
79808081export class NonEmpty extends List {
···575576 return new BitArray(segment);
576577 }
577578578578- return new BitArray(new Uint8Array(/** @type {number[]} */ (segments)));
579579+ return new BitArray(new Uint8Array(/** @type {number[]} */(segments)));
579580 }
580581581582 // Count the total number of bits and check if all segments are numbers, i.e.
···597598 // If all segments are numbers then pass the segments array directly to the
598599 // Uint8Array constructor
599600 if (areAllSegmentsNumbers) {
600600- return new BitArray(new Uint8Array(/** @type {number[]} */ (segments)));
601601+ return new BitArray(new Uint8Array(/** @type {number[]} */(segments)));
601602 }
602603603604 // Pack the segments into a Uint8Array
···14581459 try {
14591460 if (a.equals(b)) continue;
14601461 else return false;
14611461- } catch {}
14621462+ } catch { }
14621463 }
1463146414641465 let [keys, get] = getters(a);