Repository files navigation

Objective: Improve Type Level Rust in the Rust 2024 Edition

TLDR: Demonstrate unhelpful compile failure errors with TypeNum

backlink to the issue in the main repo: rust-lang/rust#118676

please note: this is a small example

in my real use case, I also have HList (Cons/Nil Russian Doll) of TypeNums, so it's much worse!

Start Quick

clone, change directory, run tests:

gh repo clone bionicles/broadcastable &&cd broadcastable && cargo test

once you're inside, you can just run the tests

cargo test

Example of the Issue

Notice how these TypeNums are really hard to read:

┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
error[E0271]: type mismatch resolving `<UInt<UInt<UTerm, B1>, B0> as IsEqual<UInt<UTerm, B1>>>::Output == B1`
--> tests/ui/compatibility_fail.rs:7:27
|
7 | println!("Bound: {}", FailedAlready::bound());
| ^^^^^^^^^^^^^ expected `B0`, found `B1`|
= note: required for`typenum::Less` to implement `CompatibleBounds<UInt<UInt<UTerm, B1>, B0>, UInt<UInt<UTerm, B1>, B1>>`
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈

rustc displays full types even for complex nested types which represent abstractions (i.e. instead of U2 you see UInt<UInt<UTerm, B1>, B0>)

Workarounds Tried

  1. I tried using tnfilt from https://github.com/auxoncorp/tnfilt -- but it clobbers a lot of terminal style content like colors, which causes other issues with Rust compiler error readability in type-level programming

  2. I tried using compile_error! (https://doc.rust-lang.org/std/macro.compile_error.html) in the type Output = ... but unfortunately it always fails to compile which means we can't conditionally trigger compile_error! inside trait impls.

  3. dfdx (https://github.com/coreylowman/dfdx) does implement compile-time shape checking with const generics, however this approach only uses numerical values for the axis bounds, which doesn't align with the principles of Named Arrays (i.e. broadcast by axis names, not axis positions)

Motivations: Benefits of Type Level Linear Algebra

If this issue were fixed, then Rust could have clearly better alternatives to numpy/jax/pytorch/tensorflow etc, because we could detect "shape bugs" at compile time instead of running code and waiting to see if it crashes.

Also, since we could check broadcast alignment compatibility at compile time, the performance could dramatically improve, since the work could be done once and amortized over all the broadcasts during the runtime execution of the program

License: MIT or Apache 2.0, at your option.

See LICENSE_MIT and/or LICENSE_APACHE for details.

About

a SSCCE (short, self-contained, correct example) of unhelpful type-level Rust broadcast compile error messages

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

Objective: Improve Type Level Rust in the Rust 2024 Edition

TLDR: Demonstrate unhelpful compile failure errors with TypeNum

backlink to the issue in the main repo: rust-lang/rust#118676

please note: this is a small example

in my real use case, I also have HList (Cons/Nil Russian Doll) of TypeNums, so it's much worse!

Start Quick

clone, change directory, run tests:

gh repo clone bionicles/broadcastable &&cd broadcastable && cargo test

once you're inside, you can just run the tests

cargo test

Example of the Issue

Notice how these TypeNums are really hard to read:

┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
error[E0271]: type mismatch resolving `<UInt<UInt<UTerm, B1>, B0> as IsEqual<UInt<UTerm, B1>>>::Output == B1`
--> tests/ui/compatibility_fail.rs:7:27
|
7 | println!("Bound: {}", FailedAlready::bound());
| ^^^^^^^^^^^^^ expected `B0`, found `B1`|
= note: required for`typenum::Less` to implement `CompatibleBounds<UInt<UInt<UTerm, B1>, B0>, UInt<UInt<UTerm, B1>, B1>>`
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈

rustc displays full types even for complex nested types which represent abstractions (i.e. instead of U2 you see UInt<UInt<UTerm, B1>, B0>)

Workarounds Tried

  1. I tried using tnfilt from https://github.com/auxoncorp/tnfilt -- but it clobbers a lot of terminal style content like colors, which causes other issues with Rust compiler error readability in type-level programming

  2. I tried using compile_error! (https://doc.rust-lang.org/std/macro.compile_error.html) in the type Output = ... but unfortunately it always fails to compile which means we can't conditionally trigger compile_error! inside trait impls.

  3. dfdx (https://github.com/coreylowman/dfdx) does implement compile-time shape checking with const generics, however this approach only uses numerical values for the axis bounds, which doesn't align with the principles of Named Arrays (i.e. broadcast by axis names, not axis positions)

Motivations: Benefits of Type Level Linear Algebra

If this issue were fixed, then Rust could have clearly better alternatives to numpy/jax/pytorch/tensorflow etc, because we could detect "shape bugs" at compile time instead of running code and waiting to see if it crashes.

Also, since we could check broadcast alignment compatibility at compile time, the performance could dramatically improve, since the work could be done once and amortized over all the broadcasts during the runtime execution of the program

License: MIT or Apache 2.0, at your option.

See LICENSE_MIT and/or LICENSE_APACHE for details.

About

a SSCCE (short, self-contained, correct example) of unhelpful type-level Rust broadcast compile error messages

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Objective: Improve Type Level Rust in the Rust 2024 Edition

TLDR: Demonstrate unhelpful compile failure errors with TypeNum

backlink to the issue in the main repo: rust-lang/rust#118676

please note: this is a small example

in my real use case, I also have HList (Cons/Nil Russian Doll) of TypeNums, so it's much worse!

Start Quick

clone, change directory, run tests:

gh repo clone bionicles/broadcastable &&cd broadcastable && cargo test

once you're inside, you can just run the tests

cargo test

Example of the Issue

Notice how these TypeNums are really hard to read:

┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
error[E0271]: type mismatch resolving `<UInt<UInt<UTerm, B1>, B0> as IsEqual<UInt<UTerm, B1>>>::Output == B1`
--> tests/ui/compatibility_fail.rs:7:27
|
7 | println!("Bound: {}", FailedAlready::bound());
| ^^^^^^^^^^^^^ expected `B0`, found `B1`|
= note: required for`typenum::Less` to implement `CompatibleBounds<UInt<UInt<UTerm, B1>, B0>, UInt<UInt<UTerm, B1>, B1>>`
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈

rustc displays full types even for complex nested types which represent abstractions (i.e. instead of U2 you see UInt<UInt<UTerm, B1>, B0>)

Workarounds Tried

  1. I tried using tnfilt from https://github.com/auxoncorp/tnfilt -- but it clobbers a lot of terminal style content like colors, which causes other issues with Rust compiler error readability in type-level programming

  2. I tried using compile_error! (https://doc.rust-lang.org/std/macro.compile_error.html) in the type Output = ... but unfortunately it always fails to compile which means we can't conditionally trigger compile_error! inside trait impls.

  3. dfdx (https://github.com/coreylowman/dfdx) does implement compile-time shape checking with const generics, however this approach only uses numerical values for the axis bounds, which doesn't align with the principles of Named Arrays (i.e. broadcast by axis names, not axis positions)

Motivations: Benefits of Type Level Linear Algebra

If this issue were fixed, then Rust could have clearly better alternatives to numpy/jax/pytorch/tensorflow etc, because we could detect "shape bugs" at compile time instead of running code and waiting to see if it crashes.

Also, since we could check broadcast alignment compatibility at compile time, the performance could dramatically improve, since the work could be done once and amortized over all the broadcasts during the runtime execution of the program

License: MIT or Apache 2.0, at your option.

See LICENSE_MIT and/or LICENSE_APACHE for details.

About

a SSCCE (short, self-contained, correct example) of unhelpful type-level Rust broadcast compile error messages

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Objective: Improve Type Level Rust in the Rust 2024 Edition

TLDR: Demonstrate unhelpful compile failure errors with TypeNum

backlink to the issue in the main repo: rust-lang/rust#118676

please note: this is a small example

in my real use case, I also have HList (Cons/Nil Russian Doll) of TypeNums, so it's much worse!

Start Quick

clone, change directory, run tests:

gh repo clone bionicles/broadcastable &&cd broadcastable && cargo test

once you're inside, you can just run the tests

cargo test

Example of the Issue

Notice how these TypeNums are really hard to read:

┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
error[E0271]: type mismatch resolving `<UInt<UInt<UTerm, B1>, B0> as IsEqual<UInt<UTerm, B1>>>::Output == B1`
--> tests/ui/compatibility_fail.rs:7:27
|
7 | println!("Bound: {}", FailedAlready::bound());
| ^^^^^^^^^^^^^ expected `B0`, found `B1`|
= note: required for`typenum::Less` to implement `CompatibleBounds<UInt<UInt<UTerm, B1>, B0>, UInt<UInt<UTerm, B1>, B1>>`
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈

rustc displays full types even for complex nested types which represent abstractions (i.e. instead of U2 you see UInt<UInt<UTerm, B1>, B0>)

Workarounds Tried

  1. I tried using tnfilt from https://github.com/auxoncorp/tnfilt -- but it clobbers a lot of terminal style content like colors, which causes other issues with Rust compiler error readability in type-level programming

  2. I tried using compile_error! (https://doc.rust-lang.org/std/macro.compile_error.html) in the type Output = ... but unfortunately it always fails to compile which means we can't conditionally trigger compile_error! inside trait impls.

  3. dfdx (https://github.com/coreylowman/dfdx) does implement compile-time shape checking with const generics, however this approach only uses numerical values for the axis bounds, which doesn't align with the principles of Named Arrays (i.e. broadcast by axis names, not axis positions)

Motivations: Benefits of Type Level Linear Algebra

If this issue were fixed, then Rust could have clearly better alternatives to numpy/jax/pytorch/tensorflow etc, because we could detect "shape bugs" at compile time instead of running code and waiting to see if it crashes.

Also, since we could check broadcast alignment compatibility at compile time, the performance could dramatically improve, since the work could be done once and amortized over all the broadcasts during the runtime execution of the program

License: MIT or Apache 2.0, at your option.

See LICENSE_MIT and/or LICENSE_APACHE for details.

About

a SSCCE (short, self-contained, correct example) of unhelpful type-level Rust broadcast compile error messages

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

Objective: Improve Type Level Rust in the Rust 2024 Edition

TLDR: Demonstrate unhelpful compile failure errors with TypeNum

backlink to the issue in the main repo: rust-lang/rust#118676

please note: this is a small example

in my real use case, I also have HList (Cons/Nil Russian Doll) of TypeNums, so it's much worse!

Start Quick

clone, change directory, run tests:

gh repo clone bionicles/broadcastable &&cd broadcastable && cargo test

once you're inside, you can just run the tests

cargo test

Example of the Issue

Notice how these TypeNums are really hard to read:

┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
error[E0271]: type mismatch resolving `<UInt<UInt<UTerm, B1>, B0> as IsEqual<UInt<UTerm, B1>>>::Output == B1`
--> tests/ui/compatibility_fail.rs:7:27
|
7 | println!("Bound: {}", FailedAlready::bound());
| ^^^^^^^^^^^^^ expected `B0`, found `B1`|
= note: required for`typenum::Less` to implement `CompatibleBounds<UInt<UInt<UTerm, B1>, B0>, UInt<UInt<UTerm, B1>, B1>>`
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈

rustc displays full types even for complex nested types which represent abstractions (i.e. instead of U2 you see UInt<UInt<UTerm, B1>, B0>)

Workarounds Tried

  1. I tried using tnfilt from https://github.com/auxoncorp/tnfilt -- but it clobbers a lot of terminal style content like colors, which causes other issues with Rust compiler error readability in type-level programming

  2. I tried using compile_error! (https://doc.rust-lang.org/std/macro.compile_error.html) in the type Output = ... but unfortunately it always fails to compile which means we can't conditionally trigger compile_error! inside trait impls.

  3. dfdx (https://github.com/coreylowman/dfdx) does implement compile-time shape checking with const generics, however this approach only uses numerical values for the axis bounds, which doesn't align with the principles of Named Arrays (i.e. broadcast by axis names, not axis positions)

Motivations: Benefits of Type Level Linear Algebra

If this issue were fixed, then Rust could have clearly better alternatives to numpy/jax/pytorch/tensorflow etc, because we could detect "shape bugs" at compile time instead of running code and waiting to see if it crashes.

Also, since we could check broadcast alignment compatibility at compile time, the performance could dramatically improve, since the work could be done once and amortized over all the broadcasts during the runtime execution of the program

License: MIT or Apache 2.0, at your option.

See LICENSE_MIT and/or LICENSE_APACHE for details.

About

a SSCCE (short, self-contained, correct example) of unhelpful type-level Rust broadcast compile error messages

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Objective: Improve Type Level Rust in the Rust 2024 Edition

TLDR: Demonstrate unhelpful compile failure errors with TypeNum

backlink to the issue in the main repo: rust-lang/rust#118676

please note: this is a small example

in my real use case, I also have HList (Cons/Nil Russian Doll) of TypeNums, so it's much worse!

Start Quick

clone, change directory, run tests:

gh repo clone bionicles/broadcastable &&cd broadcastable && cargo test

once you're inside, you can just run the tests

cargo test

Example of the Issue

Notice how these TypeNums are really hard to read:

┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
error[E0271]: type mismatch resolving `<UInt<UInt<UTerm, B1>, B0> as IsEqual<UInt<UTerm, B1>>>::Output == B1`
--> tests/ui/compatibility_fail.rs:7:27
|
7 | println!("Bound: {}", FailedAlready::bound());
| ^^^^^^^^^^^^^ expected `B0`, found `B1`|
= note: required for`typenum::Less` to implement `CompatibleBounds<UInt<UInt<UTerm, B1>, B0>, UInt<UInt<UTerm, B1>, B1>>`
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈

rustc displays full types even for complex nested types which represent abstractions (i.e. instead of U2 you see UInt<UInt<UTerm, B1>, B0>)

Workarounds Tried

  1. I tried using tnfilt from https://github.com/auxoncorp/tnfilt -- but it clobbers a lot of terminal style content like colors, which causes other issues with Rust compiler error readability in type-level programming

  2. I tried using compile_error! (https://doc.rust-lang.org/std/macro.compile_error.html) in the type Output = ... but unfortunately it always fails to compile which means we can't conditionally trigger compile_error! inside trait impls.

  3. dfdx (https://github.com/coreylowman/dfdx) does implement compile-time shape checking with const generics, however this approach only uses numerical values for the axis bounds, which doesn't align with the principles of Named Arrays (i.e. broadcast by axis names, not axis positions)

Motivations: Benefits of Type Level Linear Algebra

If this issue were fixed, then Rust could have clearly better alternatives to numpy/jax/pytorch/tensorflow etc, because we could detect "shape bugs" at compile time instead of running code and waiting to see if it crashes.

Also, since we could check broadcast alignment compatibility at compile time, the performance could dramatically improve, since the work could be done once and amortized over all the broadcasts during the runtime execution of the program

License: MIT or Apache 2.0, at your option.

See LICENSE_MIT and/or LICENSE_APACHE for details.

About

a SSCCE (short, self-contained, correct example) of unhelpful type-level Rust broadcast compile error messages

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Objective: Improve Type Level Rust in the Rust 2024 Edition

TLDR: Demonstrate unhelpful compile failure errors with TypeNum

backlink to the issue in the main repo: rust-lang/rust#118676

please note: this is a small example

in my real use case, I also have HList (Cons/Nil Russian Doll) of TypeNums, so it's much worse!

Start Quick

clone, change directory, run tests:

gh repo clone bionicles/broadcastable &&cd broadcastable && cargo test

once you're inside, you can just run the tests

cargo test

Example of the Issue

Notice how these TypeNums are really hard to read:

┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
error[E0271]: type mismatch resolving `<UInt<UInt<UTerm, B1>, B0> as IsEqual<UInt<UTerm, B1>>>::Output == B1`
--> tests/ui/compatibility_fail.rs:7:27
|
7 | println!("Bound: {}", FailedAlready::bound());
| ^^^^^^^^^^^^^ expected `B0`, found `B1`|
= note: required for`typenum::Less` to implement `CompatibleBounds<UInt<UInt<UTerm, B1>, B0>, UInt<UInt<UTerm, B1>, B1>>`
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈

rustc displays full types even for complex nested types which represent abstractions (i.e. instead of U2 you see UInt<UInt<UTerm, B1>, B0>)

Workarounds Tried

  1. I tried using tnfilt from https://github.com/auxoncorp/tnfilt -- but it clobbers a lot of terminal style content like colors, which causes other issues with Rust compiler error readability in type-level programming

  2. I tried using compile_error! (https://doc.rust-lang.org/std/macro.compile_error.html) in the type Output = ... but unfortunately it always fails to compile which means we can't conditionally trigger compile_error! inside trait impls.

  3. dfdx (https://github.com/coreylowman/dfdx) does implement compile-time shape checking with const generics, however this approach only uses numerical values for the axis bounds, which doesn't align with the principles of Named Arrays (i.e. broadcast by axis names, not axis positions)

Motivations: Benefits of Type Level Linear Algebra

If this issue were fixed, then Rust could have clearly better alternatives to numpy/jax/pytorch/tensorflow etc, because we could detect "shape bugs" at compile time instead of running code and waiting to see if it crashes.

Also, since we could check broadcast alignment compatibility at compile time, the performance could dramatically improve, since the work could be done once and amortized over all the broadcasts during the runtime execution of the program

License: MIT or Apache 2.0, at your option.

See LICENSE_MIT and/or LICENSE_APACHE for details.

About

a SSCCE (short, self-contained, correct example) of unhelpful type-level Rust broadcast compile error messages

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

Objective: Improve Type Level Rust in the Rust 2024 Edition

TLDR: Demonstrate unhelpful compile failure errors with TypeNum

backlink to the issue in the main repo: rust-lang/rust#118676

please note: this is a small example

in my real use case, I also have HList (Cons/Nil Russian Doll) of TypeNums, so it's much worse!

Start Quick

clone, change directory, run tests:

gh repo clone bionicles/broadcastable &&cd broadcastable && cargo test

once you're inside, you can just run the tests

cargo test

Example of the Issue

Notice how these TypeNums are really hard to read:

┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
error[E0271]: type mismatch resolving `<UInt<UInt<UTerm, B1>, B0> as IsEqual<UInt<UTerm, B1>>>::Output == B1`
--> tests/ui/compatibility_fail.rs:7:27
|
7 | println!("Bound: {}", FailedAlready::bound());
| ^^^^^^^^^^^^^ expected `B0`, found `B1`|
= note: required for`typenum::Less` to implement `CompatibleBounds<UInt<UInt<UTerm, B1>, B0>, UInt<UInt<UTerm, B1>, B1>>`
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈

rustc displays full types even for complex nested types which represent abstractions (i.e. instead of U2 you see UInt<UInt<UTerm, B1>, B0>)

Workarounds Tried

  1. I tried using tnfilt from https://github.com/auxoncorp/tnfilt -- but it clobbers a lot of terminal style content like colors, which causes other issues with Rust compiler error readability in type-level programming

  2. I tried using compile_error! (https://doc.rust-lang.org/std/macro.compile_error.html) in the type Output = ... but unfortunately it always fails to compile which means we can't conditionally trigger compile_error! inside trait impls.

  3. dfdx (https://github.com/coreylowman/dfdx) does implement compile-time shape checking with const generics, however this approach only uses numerical values for the axis bounds, which doesn't align with the principles of Named Arrays (i.e. broadcast by axis names, not axis positions)

Motivations: Benefits of Type Level Linear Algebra

If this issue were fixed, then Rust could have clearly better alternatives to numpy/jax/pytorch/tensorflow etc, because we could detect "shape bugs" at compile time instead of running code and waiting to see if it crashes.

Also, since we could check broadcast alignment compatibility at compile time, the performance could dramatically improve, since the work could be done once and amortized over all the broadcasts during the runtime execution of the program

License: MIT or Apache 2.0, at your option.

See LICENSE_MIT and/or LICENSE_APACHE for details.

About

a SSCCE (short, self-contained, correct example) of unhelpful type-level Rust broadcast compile error messages

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages