diff --git a/src/common/bit_field.h b/src/common/bit_field.h
index 66689f398dbe86375b8c469cd24dfae09288e572..600e0c70c9fff099e5f161377a67206cfeb08185 100644
--- a/src/common/bit_field.h
+++ b/src/common/bit_field.h
@@ -115,29 +115,24 @@ template<std::size_t position, std::size_t bits, typename T>
 struct BitField
 {
 private:
-    // This constructor might be considered ambiguous:
-    // Would it initialize the storage or just the bitfield?
-    // Hence, delete it. Use the assignment operator to set bitfield values!
-    BitField(T val) = delete;
+    // We hide the copy assigment operator here, because the default copy
+    // assignment would copy the full storage value, rather than just the bits
+    // relevant to this particular bit field.
+    // We don't delete it because we want BitField to be trivially copyable.
+    BitField& operator=(const BitField&) = default;
 
 public:
+    // This constructor and assignment operator might be considered ambiguous:
+    // Would they initialize the storage or just the bitfield?
+    // Hence, delete them. Use the Assign method to set bitfield values!
+    BitField(T val) = delete;
+    BitField& operator=(T val) = delete;
+
     // Force default constructor to be created
     // so that we can use this within unions
     BitField() = default;
 
-    // We explicitly delete the copy assigment operator here, because the
-    // default copy assignment would copy the full storage value, rather than
-    // just the bits relevant to this particular bit field.
-    BitField& operator=(const BitField&) = delete;
-
-    FORCE_INLINE BitField& operator=(T val)
-    {
-        Assign(val);
-        return *this;
-    }
-
-    FORCE_INLINE operator T() const
-    {
+    FORCE_INLINE operator T() const {
         return Value();
     }
 
@@ -145,8 +140,7 @@ public:
         storage = (storage & ~GetMask()) | (((StorageType)value << position) & GetMask());
     }
 
-    FORCE_INLINE T Value() const
-    {
+    FORCE_INLINE T Value() const {
         if (std::numeric_limits<T>::is_signed)
         {
             std::size_t shift = 8 * sizeof(T)-bits;
@@ -159,8 +153,7 @@ public:
     }
 
     // TODO: we may want to change this to explicit operator bool() if it's bug-free in VS2015
-    FORCE_INLINE bool ToBool() const
-    {
+    FORCE_INLINE bool ToBool() const {
         return Value() != 0;
     }
 
@@ -176,8 +169,7 @@ private:
     // Unsigned version of StorageType
     typedef typename std::make_unsigned<StorageType>::type StorageTypeU;
 
-    FORCE_INLINE StorageType GetMask() const
-    {
+    FORCE_INLINE StorageType GetMask() const {
         return (((StorageTypeU)~0) >> (8 * sizeof(T)-bits)) << position;
     }
 
@@ -189,6 +181,10 @@ private:
     static_assert(position < 8 * sizeof(T), "Invalid position");
     static_assert(bits <= 8 * sizeof(T), "Invalid number of bits");
     static_assert(bits > 0, "Invalid number of bits");
-    static_assert(std::is_standard_layout<T>::value, "Invalid base type");
+    static_assert(std::is_pod<T>::value, "Invalid base type");
 };
 #pragma pack()
+
+#if (__GNUC__ >= 5) || defined __clang__ || defined _MSC_VER
+static_assert(std::is_trivially_copyable<BitField<0, 1, u32>>::value, "BitField must be trivially copyable");
+#endif
diff --git a/src/common/emu_window.cpp b/src/common/emu_window.cpp
index b69b05cb9a25a9ce56fc5df41655b4df78b948ad..b2807354a5b51d5d643ae5202b736935ec7879a9 100644
--- a/src/common/emu_window.cpp
+++ b/src/common/emu_window.cpp
@@ -55,14 +55,14 @@ void EmuWindow::TouchPressed(unsigned framebuffer_x, unsigned framebuffer_y) {
         (framebuffer_layout.bottom_screen.bottom - framebuffer_layout.bottom_screen.top);
 
     touch_pressed = true;
-    pad_state.touch = 1;
+    pad_state.touch.Assign(1);
 }
 
 void EmuWindow::TouchReleased() {
     touch_pressed = false;
     touch_x = 0;
     touch_y = 0;
-    pad_state.touch = 0;
+    pad_state.touch.Assign(0);
 }
 
 void EmuWindow::TouchMoved(unsigned framebuffer_x, unsigned framebuffer_y) {
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp
index d148efde2a836763a82f155ea8cdd73a12f70e2a..16eb972fb4cd6144328f2892feac440c1dcd2655 100644
--- a/src/core/hle/kernel/process.cpp
+++ b/src/core/hle/kernel/process.cpp
@@ -35,7 +35,7 @@ SharedPtr<Process> Process::Create(SharedPtr<CodeSet> code_set) {
 
     process->codeset = std::move(code_set);
     process->flags.raw = 0;
-    process->flags.memory_region = MemoryRegion::APPLICATION;
+    process->flags.memory_region.Assign(MemoryRegion::APPLICATION);
     Memory::InitLegacyAddressSpace(process->vm_manager);
 
     return process;
diff --git a/src/core/hle/result.h b/src/core/hle/result.h
index ea3abb5f6cd12490946aa2812eee40b1ecca6557..0fce5988bd2e18bf471c5692ac00febfbbb2d1bf 100644
--- a/src/core/hle/result.h
+++ b/src/core/hle/result.h
@@ -193,10 +193,10 @@ union ResultCode {
     explicit ResultCode(u32 raw) : raw(raw) {}
     ResultCode(ErrorDescription description_, ErrorModule module_,
             ErrorSummary summary_, ErrorLevel level_) : raw(0) {
-        description = description_;
-        module = module_;
-        summary = summary_;
-        level = level_;
+        description.Assign(description_);
+        module.Assign(module_);
+        summary.Assign(summary_);
+        level.Assign(level_);
     }
 
     ResultCode& operator=(const ResultCode& o) { raw = o.raw; return *this; }
diff --git a/src/core/hle/service/cfg/cfg.cpp b/src/core/hle/service/cfg/cfg.cpp
index 633fe19eb97e1c83916de10bc1d64346c6f827b3..7556aa6a5e2382c4ae94c9b80c14c68896e6ab71 100644
--- a/src/core/hle/service/cfg/cfg.cpp
+++ b/src/core/hle/service/cfg/cfg.cpp
@@ -293,8 +293,8 @@ ResultCode DeleteConfigNANDSaveFile() {
 
 ResultCode UpdateConfigNANDSavegame() {
     FileSys::Mode mode = {};
-    mode.write_flag = 1;
-    mode.create_flag = 1;
+    mode.write_flag.Assign(1);
+    mode.create_flag.Assign(1);
 
     FileSys::Path path("config");
 
@@ -405,7 +405,7 @@ void Init() {
 
     FileSys::Path config_path("config");
     FileSys::Mode open_mode = {};
-    open_mode.read_flag = 1;
+    open_mode.read_flag.Assign(1);
 
     auto config_result = Service::FS::OpenFileFromArchive(*archive_result, config_path, open_mode);
 
diff --git a/src/core/hle/service/gsp_gpu.cpp b/src/core/hle/service/gsp_gpu.cpp
index 98b11c798991b6415f4425ac869273894578532f..5838b6d7109e73953e12f39f8f4e8a20d43e9773 100644
--- a/src/core/hle/service/gsp_gpu.cpp
+++ b/src/core/hle/service/gsp_gpu.cpp
@@ -347,7 +347,7 @@ void SignalInterrupt(InterruptId interrupt_id) {
             FrameBufferUpdate* info = GetFrameBufferInfo(thread_id, screen_id);
             if (info->is_dirty) {
                 SetBufferSwap(screen_id, info->framebuffer_info[info->index]);
-                info->is_dirty = false;
+                info->is_dirty.Assign(false);
             }
         }
     }
@@ -499,7 +499,7 @@ static void SetLcdForceBlack(Service::Interface* self) {
 
     // Since data is already zeroed, there is no need to explicitly set
     // the color to black (all zero).
-    data.is_enabled = enable_black;
+    data.is_enabled.Assign(enable_black);
 
     LCD::Write(HW::VADDR_LCD + 4 * LCD_REG_INDEX(color_fill_top), data.raw); // Top LCD
     LCD::Write(HW::VADDR_LCD + 4 * LCD_REG_INDEX(color_fill_bottom), data.raw); // Bottom LCD
@@ -521,7 +521,7 @@ static void TriggerCmdReqQueue(Service::Interface* self) {
             ExecuteCommand(command_buffer->commands[i], thread_id);
 
             // Indicates that command has completed
-            command_buffer->number_commands = command_buffer->number_commands - 1;
+            command_buffer->number_commands.Assign(command_buffer->number_commands - 1);
         }
     }
 
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 0bed0ce368e6903852d00ea23fcb773d14c314f4..11d7e69a1f2d974f849fd89235e41da124f28ed7 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -105,7 +105,7 @@ void Update() {
     bool pressed = false;
 
     std::tie(touch_entry->x, touch_entry->y, pressed) = VideoCore::g_emu_window->GetTouchState();
-    touch_entry->valid = pressed ? 1 : 0;
+    touch_entry->valid.Assign(pressed ? 1 : 0);
 
     // TODO(bunnei): We're not doing anything with offset 0xA8 + 0x18 of HID SharedMemory, which
     // supposedly is "Touch-screen entry, which contains the raw coordinate data prior to being
diff --git a/src/core/hle/service/ptm/ptm.cpp b/src/core/hle/service/ptm/ptm.cpp
index 22c1093ff887fa42c6a7bef31ef3ec90377caec9..6bdee4d9eb91951a4ce4abaef9a73c0acfb54311 100644
--- a/src/core/hle/service/ptm/ptm.cpp
+++ b/src/core/hle/service/ptm/ptm.cpp
@@ -110,8 +110,8 @@ void Init() {
 
         FileSys::Path gamecoin_path("gamecoin.dat");
         FileSys::Mode open_mode = {};
-        open_mode.write_flag = 1;
-        open_mode.create_flag = 1;
+        open_mode.write_flag.Assign(1);
+        open_mode.create_flag.Assign(1);
         // Open the file and write the default gamecoin information
         auto gamecoin_result = Service::FS::OpenFileFromArchive(*archive_result, gamecoin_path, open_mode);
         if (gamecoin_result.Succeeded()) {
diff --git a/src/core/hle/service/soc_u.cpp b/src/core/hle/service/soc_u.cpp
index 822b093f4392f70e11bc9fb38c328d646236bde1..e603bf79496b87a88c25f23a5195ff84697ba875 100644
--- a/src/core/hle/service/soc_u.cpp
+++ b/src/core/hle/service/soc_u.cpp
@@ -178,17 +178,17 @@ struct CTRPollFD {
         static Events TranslateTo3DS(u32 input_event) {
             Events ev = {};
             if (input_event & POLLIN)
-                ev.pollin = 1;
+                ev.pollin.Assign(1);
             if (input_event & POLLPRI)
-                ev.pollpri = 1;
+                ev.pollpri.Assign(1);
             if (input_event & POLLHUP)
-                ev.pollhup = 1;
+                ev.pollhup.Assign(1);
             if (input_event & POLLERR)
-                ev.pollerr = 1;
+                ev.pollerr.Assign(1);
             if (input_event & POLLOUT)
-                ev.pollout = 1;
+                ev.pollout.Assign(1);
             if (input_event & POLLNVAL)
-                ev.pollnval = 1;
+                ev.pollnval.Assign(1);
             return ev;
         }
 
diff --git a/src/core/hw/gpu.cpp b/src/core/hw/gpu.cpp
index 4bd3a632da94d20a4a471646db987236ab86d3cb..c603105869525d2d8c121c20dcdc83d60743abad 100644
--- a/src/core/hw/gpu.cpp
+++ b/src/core/hw/gpu.cpp
@@ -146,8 +146,8 @@ inline void Write(u32 addr, const T data) {
 
             // Reset "trigger" flag and set the "finish" flag
             // NOTE: This was confirmed to happen on hardware even if "address_start" is zero.
-            config.trigger = 0;
-            config.finished = 1;
+            config.trigger.Assign(0);
+            config.finished.Assign(1);
         }
         break;
     }
@@ -444,16 +444,16 @@ void Init() {
     framebuffer_sub.address_left1  = 0x1848F000;
     framebuffer_sub.address_left2  = 0x184C7800;
 
-    framebuffer_top.width = 240;
-    framebuffer_top.height = 400;
+    framebuffer_top.width.Assign(240);
+    framebuffer_top.height.Assign(400);
     framebuffer_top.stride = 3 * 240;
-    framebuffer_top.color_format = Regs::PixelFormat::RGB8;
+    framebuffer_top.color_format.Assign(Regs::PixelFormat::RGB8);
     framebuffer_top.active_fb = 0;
 
-    framebuffer_sub.width = 240;
-    framebuffer_sub.height = 320;
+    framebuffer_sub.width.Assign(240);
+    framebuffer_sub.height.Assign(320);
     framebuffer_sub.stride = 3 * 240;
-    framebuffer_sub.color_format = Regs::PixelFormat::RGB8;
+    framebuffer_sub.color_format.Assign(Regs::PixelFormat::RGB8);
     framebuffer_sub.active_fb = 0;
 
     last_skip_frame = false;
diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp
index 5dfedfe311ee877a6e1c2506408e41f1189156bb..ed20057b5e35000a9149b09b888a4c41391f4507 100644
--- a/src/video_core/command_processor.cpp
+++ b/src/video_core/command_processor.cpp
@@ -429,7 +429,7 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) {
                           uniform.w.ToFloat32());
 
                 // TODO: Verify that this actually modifies the register!
-                uniform_setup.index = uniform_setup.index + 1;
+                uniform_setup.index.Assign(uniform_setup.index + 1);
             }
             break;
         }
@@ -478,7 +478,7 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) {
             ASSERT_MSG(lut_config.index < 256, "lut_config.index exceeded maximum value of 255!");
 
             g_state.lighting.luts[lut_config.type][lut_config.index].raw = value;
-            lut_config.index = lut_config.index + 1;
+            lut_config.index.Assign(lut_config.index + 1);
             break;
         }
 
diff --git a/src/video_core/debug_utils/debug_utils.cpp b/src/video_core/debug_utils/debug_utils.cpp
index 4f66dbd658f78446beb5c559077e079398cd06b3..6e6fd7335f14b14bfa3ddb35b4a6123f2ce19bb8 100644
--- a/src/video_core/debug_utils/debug_utils.cpp
+++ b/src/video_core/debug_utils/debug_utils.cpp
@@ -201,11 +201,11 @@ void DumpShader(const std::string& filename, const Regs::ShaderConfig& config, c
 
                     if (it == output_info_table.end()) {
                         output_info_table.emplace_back();
-                        output_info_table.back().type = type;
-                        output_info_table.back().component_mask = component_mask;
-                        output_info_table.back().id = i;
+                        output_info_table.back().type.Assign(type);
+                        output_info_table.back().component_mask.Assign(component_mask);
+                        output_info_table.back().id.Assign(i);
                     } else {
-                        it->component_mask = it->component_mask | component_mask;
+                        it->component_mask.Assign(it->component_mask | component_mask);
                     }
                 } catch (const std::out_of_range& ) {
                     DEBUG_ASSERT_MSG(false, "Unknown output attribute mapping");