<p dir="auto">For small structs/enums (size &lt;= <code class="notranslate">uint</code>) we currently prefer to pass them as immediate values (good) but unlike clang we don't "cast" them to an appropriately sized integer type but pass them around as first class aggregates (not so good).</p>
<p dir="auto">While LLVM supports the usage of FCAs, the optimizations largely depend on them being torn apart again, and that doesn't always work so great. The latest issue about that was <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="52702410" data-permission-text="Title is private" data-url="https://github.com/rust-lang/rust/issues/20149" data-hovercard-type="issue" data-hovercard-url="/rust-lang/rust/issues/20149/hovercard" href="https://github.com/rust-lang/rust/issues/20149">#20149</a> for which I opted to patch LLVM to have it handle some basic store-to-load that involves FCA.</p>
<p dir="auto">That led to the following email, in which Chandler Carruth suggests that we move away from using FCAs as much as possible: <a href="http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20141229/250758.html" rel="nofollow">http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20141229/250758.html</a></p>
<p dir="auto">AFAICT this would leave us with two choices:</p>
<ul dir="auto">
<li>Make all type that end up as structs or arrays in LLVM IR non-immediate</li>
</ul>
<p dir="auto">or</p>
<ul dir="auto">
<li>Do as clang does and convert small structs to an appropriately sized integer type when using them as SSA values</li>
</ul>
<p dir="auto">(Some) Related tickets are <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="52702410" data-permission-text="Title is private" data-url="https://github.com/rust-lang/rust/issues/20149" data-hovercard-type="issue" data-hovercard-url="/rust-lang/rust/issues/20149/hovercard" href="https://github.com/rust-lang/rust/issues/20149">#20149</a> <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="40305051" data-permission-text="Title is private" data-url="https://github.com/rust-lang/rust/issues/16506" data-hovercard-type="issue" data-hovercard-url="/rust-lang/rust/issues/16506/hovercard" href="https://github.com/rust-lang/rust/issues/16506">#16506</a> <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="32760457" data-permission-text="Title is private" data-url="https://github.com/rust-lang/rust/issues/13927" data-hovercard-type="issue" data-hovercard-url="/rust-lang/rust/issues/13927/hovercard" href="https://github.com/rust-lang/rust/issues/13927">#13927</a><br>
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> <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/thestinger/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/thestinger">@thestinger</a> <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/eddyb/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/eddyb">@eddyb</a> <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/erickt/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/erickt">@erickt</a> <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/Aatch/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/Aatch">@Aatch</a> <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/luqmana/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/luqmana">@luqmana</a></p>
<p dir="auto"><em>Version of Rust</em>: rustc 0.13.0-nightly (<a class="commit-link" data-hovercard-type="commit" data-hovercard-url="https://github.com/rust-lang/rust/commit/c89417130f042c58adc60012e7cddc4ef70b70b9/hovercard" href="https://github.com/rust-lang/rust/commit/c89417130f042c58adc60012e7cddc4ef70b70b9"><tt>c894171</tt></a> 2015-01-02 21:56:13 +0000)<br>
<em>Operating system</em>: Linux 3.16.0-4-686-pae <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="227519" data-permission-text="Title is private" data-url="https://github.com/rust-lang/rust/issues/1" data-hovercard-type="issue" data-hovercard-url="/rust-lang/rust/issues/1/hovercard" href="https://github.com/rust-lang/rust/issues/1">#1</a> SMP Debian 3.16.7-ckt2-1 (2014-12-08) i686 GNU/Linux</p>
<p dir="auto">When the associated <code class="notranslate">Target</code> type is not defined in an <code class="notranslate">impl Deref</code>, this leads to an internal compiler error.</p>
<p dir="auto">Here is an example:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="#![feature(associated_types)]
use std::ops::Deref;

struct Wrapper {
    inner: int
}

impl Deref for Wrapper {
    //type Target = int;
    fn deref(&amp;self) -&gt; &amp;int {
        &amp;self.inner
    }
}

fn main() {
}"><pre class="notranslate"><code class="notranslate">#![feature(associated_types)]
use std::ops::Deref;

struct Wrapper {
    inner: int
}

impl Deref for Wrapper {
    //type Target = int;
    fn deref(&amp;self) -&gt; &amp;int {
        &amp;self.inner
    }
}

fn main() {
}
</code></pre></div>
<p dir="auto">Error message from the compiler:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="src/main.rs:10:5: 12:6 error: internal compiler error: impl `VtableImpl(impl_def_id=DefId { krate: 0, node: 10 }:Wrapper.Deref, substs=Substs[types=[[];[];[]], regions=[[];[];[]]], nested=[[];[];[]])` did not contain projection for `Obligation(predicate=&lt;Wrapper as TraitRef(Wrapper, core::ops::Deref)&gt;::Target,depth=0)`
src/main.rs:10     fn deref(&amp;self) -&gt; &amp;int {
src/main.rs:11         &amp;self.inner
src/main.rs:12     }
note: the compiler unexpectedly panicked. this is a bug.
note: we would appreciate a bug report: http://doc.rust-lang.org/complement-bugreport.html
note: run with `RUST_BACKTRACE=1` for a backtrace"><pre class="notranslate"><code class="notranslate">src/main.rs:10:5: 12:6 error: internal compiler error: impl `VtableImpl(impl_def_id=DefId { krate: 0, node: 10 }:Wrapper.Deref, substs=Substs[types=[[];[];[]], regions=[[];[];[]]], nested=[[];[];[]])` did not contain projection for `Obligation(predicate=&lt;Wrapper as TraitRef(Wrapper, core::ops::Deref)&gt;::Target,depth=0)`
src/main.rs:10     fn deref(&amp;self) -&gt; &amp;int {
src/main.rs:11         &amp;self.inner
src/main.rs:12     }
note: the compiler unexpectedly panicked. this is a bug.
note: we would appreciate a bug report: http://doc.rust-lang.org/complement-bugreport.html
note: run with `RUST_BACKTRACE=1` for a backtrace
</code></pre></div>
<p dir="auto">Backtrace:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="thread 'rustc' panicked at 'Box&lt;Any&gt;', /home/rustbuild/src/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libsyntax/diagnostic.rs:123

stack backtrace:
   1: 0xb7383f20 - sys::backtrace::write::h6d0a4417f4e5c493sit
   2: 0xb73a8770 - failure::on_fail::h17e5357971ef1fadTuz
   3: 0xb7310d00 - rt::unwind::begin_unwind_inner::h81966bf04c2cd1f4y9y
   4: 0xb389edb0 - rt::unwind::begin_unwind::h12436254939101185090
   5: 0xb389ed20 - diagnostic::SpanHandler::span_bug::h64fa6f5fbd27e941zFF
   6: 0xb6326a10 - middle::traits::project::project_type::h85510b9af23c51a6UQP
   7: 0xb6323b00 - middle::traits::project::opt_normalize_projection_type::h16b6e65a2aa8a5c1XIP
   8: 0xb6312320 - middle::traits::project::normalize_projection_type::h4e3c940bec71651byHP
   9: 0xb6324ea0 - middle::traits::project::AssociatedTypeNormalizer&lt;'a, 'b, 'tcx&gt;.TypeFolder&lt;'tcx&gt;::fold_ty::h3cbce0725be04edf9FP
  10: 0xb6324ea0 - middle::traits::project::AssociatedTypeNormalizer&lt;'a, 'b, 'tcx&gt;.TypeFolder&lt;'tcx&gt;::fold_ty::h3cbce0725be04edf9FP
  11: 0xb6dc4600 - middle::ty_fold::ty..FnSig&lt;'tcx&gt;.TypeFoldable&lt;'tcx&gt;::fold_with::h10991263838617593069
  12: 0xb6e58690 - check::assoc::normalize_associated_types_in::h9980513805539501870
  13: 0xb6e4eae0 - check::compare_impl_method::h37df9bd14bbfe837q4j
  14: 0xb6e3aed0 - check::check_item::hda7b1175944bf853SGj
  15: 0xb6ff1830 - check_crate::unboxed_closure.39847
  16: 0xb6fec070 - check_crate::h5a3950962091692dVlx
  17: 0xb76bf8b0 - driver::phase_3_run_analysis_passes::hf1b11de46876f77cTva
  18: 0xb76ad980 - driver::compile_input::h567277daca5fdd24wba
  19: 0xb777fa80 - thunk::F.Invoke&lt;A, R&gt;::invoke::h14467627679629470429
  20: 0xb777e890 - rt::unwind::try::try_fn::h7264457252665277252
  21: 0xb7418c90 - rust_try_inner
  22: 0xb7418c60 - rust_try
  23: 0xb777ebd0 - thunk::F.Invoke&lt;A, R&gt;::invoke::h428659666485879903
  24: 0xb73956c0 - sys::thread::thread_start::haeae5d792ecbddcdy8v
  25: 0xb36c4e30 - start_thread
  26: 0xb71eddf2 - clone
  27:        0x0 - &lt;unknown&gt;"><pre class="notranslate"><code class="notranslate">thread 'rustc' panicked at 'Box&lt;Any&gt;', /home/rustbuild/src/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libsyntax/diagnostic.rs:123

stack backtrace:
   1: 0xb7383f20 - sys::backtrace::write::h6d0a4417f4e5c493sit
   2: 0xb73a8770 - failure::on_fail::h17e5357971ef1fadTuz
   3: 0xb7310d00 - rt::unwind::begin_unwind_inner::h81966bf04c2cd1f4y9y
   4: 0xb389edb0 - rt::unwind::begin_unwind::h12436254939101185090
   5: 0xb389ed20 - diagnostic::SpanHandler::span_bug::h64fa6f5fbd27e941zFF
   6: 0xb6326a10 - middle::traits::project::project_type::h85510b9af23c51a6UQP
   7: 0xb6323b00 - middle::traits::project::opt_normalize_projection_type::h16b6e65a2aa8a5c1XIP
   8: 0xb6312320 - middle::traits::project::normalize_projection_type::h4e3c940bec71651byHP
   9: 0xb6324ea0 - middle::traits::project::AssociatedTypeNormalizer&lt;'a, 'b, 'tcx&gt;.TypeFolder&lt;'tcx&gt;::fold_ty::h3cbce0725be04edf9FP
  10: 0xb6324ea0 - middle::traits::project::AssociatedTypeNormalizer&lt;'a, 'b, 'tcx&gt;.TypeFolder&lt;'tcx&gt;::fold_ty::h3cbce0725be04edf9FP
  11: 0xb6dc4600 - middle::ty_fold::ty..FnSig&lt;'tcx&gt;.TypeFoldable&lt;'tcx&gt;::fold_with::h10991263838617593069
  12: 0xb6e58690 - check::assoc::normalize_associated_types_in::h9980513805539501870
  13: 0xb6e4eae0 - check::compare_impl_method::h37df9bd14bbfe837q4j
  14: 0xb6e3aed0 - check::check_item::hda7b1175944bf853SGj
  15: 0xb6ff1830 - check_crate::unboxed_closure.39847
  16: 0xb6fec070 - check_crate::h5a3950962091692dVlx
  17: 0xb76bf8b0 - driver::phase_3_run_analysis_passes::hf1b11de46876f77cTva
  18: 0xb76ad980 - driver::compile_input::h567277daca5fdd24wba
  19: 0xb777fa80 - thunk::F.Invoke&lt;A, R&gt;::invoke::h14467627679629470429
  20: 0xb777e890 - rt::unwind::try::try_fn::h7264457252665277252
  21: 0xb7418c90 - rust_try_inner
  22: 0xb7418c60 - rust_try
  23: 0xb777ebd0 - thunk::F.Invoke&lt;A, R&gt;::invoke::h428659666485879903
  24: 0xb73956c0 - sys::thread::thread_start::haeae5d792ecbddcdy8v
  25: 0xb36c4e30 - start_thread
  26: 0xb71eddf2 - clone
  27:        0x0 - &lt;unknown&gt;
</code></pre></div>