diff --git a/src/librustc_trans/trans/abi.rs b/src/librustc_trans/trans/abi.rs
index 192522214e6..39ecae41750 100644
--- a/src/librustc_trans/trans/abi.rs
+++ b/src/librustc_trans/trans/abi.rs
@@ -378,11 +378,27 @@ impl FnType {
         if abi == Abi::Rust || abi == Abi::RustCall ||
            abi == Abi::RustIntrinsic || abi == Abi::PlatformIntrinsic {
             let fixup = |arg: &mut ArgType| {
-                if !arg.ty.is_aggregate() {
+                let mut llty = arg.ty;
+
+                // Replace newtypes with their inner-most type.
+                while llty.kind() == llvm::TypeKind::Struct {
+                    let inner = llty.field_types();
+                    if inner.len() != 1 {
+                        break;
+                    }
+                    llty = inner[0];
+                }
+
+                if !llty.is_aggregate() {
                     // Scalars and vectors, always immediate.
+                    if llty != arg.ty {
+                        // Needs a cast as we've unpacked a newtype.
+                        arg.cast = Some(llty);
+                    }
                     return;
                 }
-                let size = llsize_of_real(ccx, arg.ty);
+
+                let size = llsize_of_real(ccx, llty);
                 if size > llsize_of_real(ccx, ccx.int_type()) {
                     arg.make_indirect(ccx);
                 } else if size > 0 {