<p dir="auto">Basically the idea here is to support shuffling for SIMD types in a way that can be easily lowered to IR (LLVM's <code class="notranslate">shufflevector</code> requires the mask be a vector of constants, so an intrinsic function is out of the question), however I image this sugar could extend to tuples with multiple types.</p>
<p dir="auto">Some examples:</p>
<div class="highlight highlight-source-rust notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="let vec = (1.0f32, 2.0f32, 3.0f32, 4.0f32);
let all_x = vec -&gt; (0, 0, 0, 0);
assert_eq!(all_x, (1.0f32, 1.0f32, 1.0f32, 1.0f32));
let single_x = vec -&gt; (0);
assert_eq!(single_x, (1.0f32));

let mut vec = vec;
vec &lt;- (0) = 5.0f32; // set x only
vec &lt;- (1, 2) = (6.0f32, 7.0f32) // set y &amp; z
assert_eq!(vec, (5.0f32, 6.0f32, 7.0f32, 4.0f32));

let vec = vec;
// the mask may be arbitrarily long:
assert_eq!(vec -&gt; (0, 1, 2, 3, 0), (5.0f32, 6.0f32, 7.0f32, 4.0f32, 5.0f32));

// leaves vec unchanged
let functional_update = vec -&gt; (0, 1, 3) .. (0.5f32, 1.0f32, 10.0f32);
// functional_update would take it's type from vec
assert_eq!(vec, (5.0f32, 6.0f32, 7.0f32, 4.0f32));
assert_eq!(functional_update, (0.5f32, 1.0f32, 7.0f32, 10.0f32));"><pre class="notranslate"><span class="pl-k">let</span> vec = <span class="pl-kos">(</span><span class="pl-c1">1.0f32</span><span class="pl-kos">,</span> <span class="pl-c1">2.0f32</span><span class="pl-kos">,</span> <span class="pl-c1">3.0f32</span><span class="pl-kos">,</span> <span class="pl-c1">4.0f32</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-k">let</span> all_x = <span class="pl-en">vec</span> -&gt; <span class="pl-kos">(</span><span class="pl-c1">0</span><span class="pl-kos">,</span> <span class="pl-c1">0</span><span class="pl-kos">,</span> <span class="pl-c1">0</span><span class="pl-kos">,</span> <span class="pl-c1">0</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-en">assert_eq</span><span class="pl-en">!</span><span class="pl-kos">(</span>all_x, <span class="pl-kos">(</span><span class="pl-c1">1.0f32</span>, <span class="pl-c1">1.0f32</span>, <span class="pl-c1">1.0f32</span>, <span class="pl-c1">1.0f32</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-k">let</span> single_x = <span class="pl-en">vec</span> -&gt; <span class="pl-kos">(</span><span class="pl-c1">0</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-en">assert_eq</span><span class="pl-en">!</span><span class="pl-kos">(</span>single_x, <span class="pl-kos">(</span><span class="pl-c1">1.0f32</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

<span class="pl-k">let</span> <span class="pl-k">mut</span> vec = vec<span class="pl-kos">;</span>
vec &lt;- <span class="pl-kos">(</span><span class="pl-c1">0</span><span class="pl-kos">)</span> = <span class="pl-c1">5.0f32</span><span class="pl-kos">;</span> <span class="pl-c">// set x only</span>
vec &lt;- <span class="pl-kos">(</span><span class="pl-c1">1</span><span class="pl-kos">,</span> <span class="pl-c1">2</span><span class="pl-kos">)</span> = <span class="pl-kos">(</span><span class="pl-c1">6.0f32</span><span class="pl-kos">,</span> <span class="pl-c1">7.0f32</span><span class="pl-kos">)</span> <span class="pl-c">// set y &amp; z</span>
<span class="pl-en">assert_eq</span><span class="pl-en">!</span><span class="pl-kos">(</span>vec, <span class="pl-kos">(</span><span class="pl-c1">5.0f32</span>, <span class="pl-c1">6.0f32</span>, <span class="pl-c1">7.0f32</span>, <span class="pl-c1">4.0f32</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

<span class="pl-k">let</span> vec = vec<span class="pl-kos">;</span>
<span class="pl-c">// the mask may be arbitrarily long:</span>
<span class="pl-en">assert_eq</span><span class="pl-en">!</span><span class="pl-kos">(</span>vec -&gt; <span class="pl-kos">(</span><span class="pl-c1">0</span>, <span class="pl-c1">1</span>, <span class="pl-c1">2</span>, <span class="pl-c1">3</span>, <span class="pl-c1">0</span><span class="pl-kos">)</span>, <span class="pl-kos">(</span><span class="pl-c1">5.0f32</span>, <span class="pl-c1">6.0f32</span>, <span class="pl-c1">7.0f32</span>, <span class="pl-c1">4.0f32</span>, <span class="pl-c1">5.0f32</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

<span class="pl-c">// leaves vec unchanged</span>
<span class="pl-k">let</span> functional_update = <span class="pl-en">vec</span> -&gt; <span class="pl-kos">(</span><span class="pl-c1">0</span><span class="pl-kos">,</span> <span class="pl-c1">1</span><span class="pl-kos">,</span> <span class="pl-c1">3</span><span class="pl-kos">)</span> .. <span class="pl-kos">(</span><span class="pl-c1">0.5f32</span><span class="pl-kos">,</span> <span class="pl-c1">1.0f32</span><span class="pl-kos">,</span> <span class="pl-c1">10.0f32</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-c">// functional_update would take it's type from vec</span>
<span class="pl-en">assert_eq</span><span class="pl-en">!</span><span class="pl-kos">(</span>vec, <span class="pl-kos">(</span><span class="pl-c1">5.0f32</span>, <span class="pl-c1">6.0f32</span>, <span class="pl-c1">7.0f32</span>, <span class="pl-c1">4.0f32</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-en">assert_eq</span><span class="pl-en">!</span><span class="pl-kos">(</span>functional_update, <span class="pl-kos">(</span><span class="pl-c1">0.5f32</span>, <span class="pl-c1">1.0f32</span>, <span class="pl-c1">7.0f32</span>, <span class="pl-c1">10.0f32</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<p dir="auto">A couple of things would need to be disallowed, however:</p>
<div class="highlight highlight-source-rust notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="// continuing from above
let mut vec = vec;
// 1. no duplicate assignments/functional updates:
vec &lt;- (0, 0) = (..);
let _ = vec -&gt; (0, 1, 2, 3, 0) .. (..);
// 2. no out-of-bounds:
vec &lt;- (5, 9000) = (..);
let _ = vec -&gt; (5, 9001);
let _ = vec -&gt; (5, 9002) .. (..);
let _ = vec -&gt; (0, 1, 2, 3, 4) .. (..);
// 3. all mask values must be a const expr:
let mut non_const_expr = 15;
vec &lt;- (non_const_expr) = (..);
let _ = vec -&gt; (non_const_expr) .. (..);
let _ = vec -&gt; (non_const_expr);
// 4. mismatched tuple sizes:
vec &lt;- (0, 1) = (0.0f32, 0.0f32, 0.0f32);
let _ = vec -&gt; (0) .. (0.0f32, 0.0f32);"><pre class="notranslate"><span class="pl-c">// continuing from above</span>
<span class="pl-k">let</span> <span class="pl-k">mut</span> vec = vec<span class="pl-kos">;</span>
<span class="pl-c">// 1. no duplicate assignments/functional updates:</span>
vec &lt;- <span class="pl-kos">(</span><span class="pl-c1">0</span><span class="pl-kos">,</span> <span class="pl-c1">0</span><span class="pl-kos">)</span> = <span class="pl-kos">(</span>..<span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-k">let</span> _ = <span class="pl-en">vec</span> -&gt; <span class="pl-kos">(</span><span class="pl-c1">0</span><span class="pl-kos">,</span> <span class="pl-c1">1</span><span class="pl-kos">,</span> <span class="pl-c1">2</span><span class="pl-kos">,</span> <span class="pl-c1">3</span><span class="pl-kos">,</span> <span class="pl-c1">0</span><span class="pl-kos">)</span> .. <span class="pl-kos">(</span>..<span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-c">// 2. no out-of-bounds:</span>
vec &lt;- <span class="pl-kos">(</span><span class="pl-c1">5</span><span class="pl-kos">,</span> <span class="pl-c1">9000</span><span class="pl-kos">)</span> = <span class="pl-kos">(</span>..<span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-k">let</span> _ = <span class="pl-en">vec</span> -&gt; <span class="pl-kos">(</span><span class="pl-c1">5</span><span class="pl-kos">,</span> <span class="pl-c1">9001</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-k">let</span> _ = <span class="pl-en">vec</span> -&gt; <span class="pl-kos">(</span><span class="pl-c1">5</span><span class="pl-kos">,</span> <span class="pl-c1">9002</span><span class="pl-kos">)</span> .. <span class="pl-kos">(</span>..<span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-k">let</span> _ = <span class="pl-en">vec</span> -&gt; <span class="pl-kos">(</span><span class="pl-c1">0</span><span class="pl-kos">,</span> <span class="pl-c1">1</span><span class="pl-kos">,</span> <span class="pl-c1">2</span><span class="pl-kos">,</span> <span class="pl-c1">3</span><span class="pl-kos">,</span> <span class="pl-c1">4</span><span class="pl-kos">)</span> .. <span class="pl-kos">(</span>..<span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-c">// 3. all mask values must be a const expr:</span>
<span class="pl-k">let</span> <span class="pl-k">mut</span> non_const_expr = <span class="pl-c1">15</span><span class="pl-kos">;</span>
vec &lt;- <span class="pl-kos">(</span>non_const_expr<span class="pl-kos">)</span> = <span class="pl-kos">(</span>..<span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-k">let</span> _ = <span class="pl-en">vec</span> -&gt; <span class="pl-kos">(</span>non_const_expr<span class="pl-kos">)</span> .. <span class="pl-kos">(</span>..<span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-k">let</span> _ = <span class="pl-en">vec</span> -&gt; <span class="pl-kos">(</span>non_const_expr<span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-c">// 4. mismatched tuple sizes:</span>
vec &lt;- <span class="pl-kos">(</span><span class="pl-c1">0</span><span class="pl-kos">,</span> <span class="pl-c1">1</span><span class="pl-kos">)</span> = <span class="pl-kos">(</span><span class="pl-c1">0.0f32</span><span class="pl-kos">,</span> <span class="pl-c1">0.0f32</span><span class="pl-kos">,</span> <span class="pl-c1">0.0f32</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-k">let</span> _ = <span class="pl-en">vec</span> -&gt; <span class="pl-kos">(</span><span class="pl-c1">0</span><span class="pl-kos">)</span> .. <span class="pl-kos">(</span><span class="pl-c1">0.0f32</span><span class="pl-kos">,</span> <span class="pl-c1">0.0f32</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<p dir="auto">AIUI, the notation would be:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="tuple_mask : '(' integer [ ',' integer ] * ')' ;
tuple_expr : '(' expr [ ',' expr ] * ')' |
             tuple_expr &quot;-&gt;&quot; tuple_mask [ &quot;..&quot; tuple_expr ] ? ;"><pre class="notranslate"><code class="notranslate">tuple_mask : '(' integer [ ',' integer ] * ')' ;
tuple_expr : '(' expr [ ',' expr ] * ')' |
             tuple_expr "-&gt;" tuple_mask [ ".." tuple_expr ] ? ;
</code></pre></div>
<p dir="auto">I'm willing to write this myself, but I'd like some consensus/feedback regarding ze sugar I've used.</p>
<p dir="auto">cc <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/alexcrichton/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/alexcrichton">@alexcrichton</a>. It looks like we have a lot of duplicated code with <a href="https://github.com/rust-lang/rust/blob/master/src/libcore/fmt/float.rs">libcore/fmt/float.rs</a> and <a href="https://github.com/rust-lang/rust/blob/master/src/libstd/num/strconv.rs#L261">std::num::strconv::float_to_str_bytes_common</a>. Can this code be merged?</p>