about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-02-17 14:27:28 +0000
committerbors <bors@rust-lang.org>2023-02-17 14:27:28 +0000
commitf722b24eb9ea35a7cc187a1cb5c50d4d324f5855 (patch)
tree821e87562b0d14d209fae8d39ed8fc417d6d459e
parentf4f5fc3e5cc70b7a43bf7b518c455f3d9bada9e3 (diff)
parentae5473c9699eaf1998c414e0a8884383bb9ddcc3 (diff)
downloadrust-f722b24eb9ea35a7cc187a1cb5c50d4d324f5855.tar.gz
rust-f722b24eb9ea35a7cc187a1cb5c50d4d324f5855.zip
Auto merge of #108159 - matthiaskrgr:rollup-5k2j7cx, r=matthiaskrgr
Rollup of 6 pull requests

Successful merges:

 - #107592 (Default `repr(C)` enums to `c_int` size)
 - #107956 (Copy `bin/*` and `lib/*.dylib` files to `stage0-sysroot`)
 - #108126 (fix a line, and do a consistency fix)
 - #108144 (Add compiler-errors to a few more triagebot groups)
 - #108149 (typo)
 - #108154 (`BasicBlock::new(0)` -> `START_BLOCK` [no functional changes])

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_abi/src/lib.rs4
-rw-r--r--compiler/rustc_codegen_llvm/src/consts.rs4
-rw-r--r--compiler/rustc_codegen_ssa/src/lib.rs2
-rw-r--r--compiler/rustc_const_eval/src/transform/promote_consts.rs2
-rw-r--r--compiler/rustc_middle/src/middle/codegen_fn_attrs.rs3
-rw-r--r--compiler/rustc_middle/src/mir/visit.rs6
-rw-r--r--compiler/rustc_mir_transform/src/dest_prop.rs6
-rw-r--r--compiler/rustc_mir_transform/src/generator.rs6
-rw-r--r--compiler/rustc_mir_transform/src/inline.rs2
-rw-r--r--compiler/rustc_mir_transform/src/simplify.rs2
-rw-r--r--compiler/rustc_target/src/spec/armebv7r_none_eabi.rs2
-rw-r--r--compiler/rustc_target/src/spec/armebv7r_none_eabihf.rs2
-rw-r--r--compiler/rustc_target/src/spec/armv4t_none_eabi.rs2
-rw-r--r--compiler/rustc_target/src/spec/armv7a_none_eabi.rs2
-rw-r--r--compiler/rustc_target/src/spec/armv7a_none_eabihf.rs2
-rw-r--r--compiler/rustc_target/src/spec/armv7r_none_eabi.rs2
-rw-r--r--compiler/rustc_target/src/spec/armv7r_none_eabihf.rs2
-rw-r--r--compiler/rustc_target/src/spec/hexagon_unknown_linux_musl.rs2
-rw-r--r--compiler/rustc_target/src/spec/mod.rs30
-rw-r--r--compiler/rustc_target/src/spec/thumb_base.rs2
-rw-r--r--compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs2
-rw-r--r--src/bootstrap/compile.rs66
-rw-r--r--tests/ui/repr/16-bit-repr-c-enum.rs52
-rw-r--r--triagebot.toml4
24 files changed, 167 insertions, 42 deletions
diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs
index c88a60c62b9..aa3a666b0b2 100644
--- a/compiler/rustc_abi/src/lib.rs
+++ b/compiler/rustc_abi/src/lib.rs
@@ -171,7 +171,9 @@ pub struct TargetDataLayout {
 
     pub instruction_address_space: AddressSpace,
 
-    /// Minimum size of #[repr(C)] enums (default I32 bits)
+    /// Minimum size of #[repr(C)] enums (default c_int::BITS, usually 32)
+    /// Note: This isn't in LLVM's data layout string, it is `short_enum`
+    /// so the only valid spec for LLVM is c_int::BITS or 8
     pub c_enum_min_size: Integer,
 }
 
diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs
index 92629aa18d4..9116e71beac 100644
--- a/compiler/rustc_codegen_llvm/src/consts.rs
+++ b/compiler/rustc_codegen_llvm/src/consts.rs
@@ -521,7 +521,7 @@ impl<'ll> StaticMethods for CodegenCx<'ll, '_> {
 
                 // The semantics of #[used] in Rust only require the symbol to make it into the
                 // object file. It is explicitly allowed for the linker to strip the symbol if it
-                // is dead, which means we are allowed use `llvm.compiler.used` instead of
+                // is dead, which means we are allowed to use `llvm.compiler.used` instead of
                 // `llvm.used` here.
                 //
                 // Additionally, https://reviews.llvm.org/D97448 in LLVM 13 started emitting unique
@@ -532,7 +532,7 @@ impl<'ll> StaticMethods for CodegenCx<'ll, '_> {
                 // That said, we only ever emit these when compiling for ELF targets, unless
                 // `#[used(compiler)]` is explicitly requested. This is to avoid similar breakage
                 // on other targets, in particular MachO targets have *their* static constructor
-                // lists broken if `llvm.compiler.used` is emitted rather than llvm.used. However,
+                // lists broken if `llvm.compiler.used` is emitted rather than `llvm.used`. However,
                 // that check happens when assigning the `CodegenFnAttrFlags` in `rustc_hir_analysis`,
                 // so we don't need to take care of it here.
                 self.add_compiler_used_global(g);
diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs
index d5530c47680..7d51cee307e 100644
--- a/compiler/rustc_codegen_ssa/src/lib.rs
+++ b/compiler/rustc_codegen_ssa/src/lib.rs
@@ -13,7 +13,7 @@
 
 //! This crate contains codegen code that is used by all codegen backends (LLVM and others).
 //! The backend-agnostic functions of this crate use functions defined in various traits that
-//! have to be implemented by each backends.
+//! have to be implemented by each backend.
 
 #[macro_use]
 extern crate rustc_macros;
diff --git a/compiler/rustc_const_eval/src/transform/promote_consts.rs b/compiler/rustc_const_eval/src/transform/promote_consts.rs
index 7009d3b38ae..19367d708ee 100644
--- a/compiler/rustc_const_eval/src/transform/promote_consts.rs
+++ b/compiler/rustc_const_eval/src/transform/promote_consts.rs
@@ -898,7 +898,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
         assert_eq!(self.new_block(), START_BLOCK);
         self.visit_rvalue(
             &mut rvalue,
-            Location { block: BasicBlock::new(0), statement_index: usize::MAX },
+            Location { block: START_BLOCK, statement_index: usize::MAX },
         );
 
         let span = self.promoted.span;
diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
index bea884c856a..c4601a1fb41 100644
--- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
+++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
@@ -91,7 +91,8 @@ bitflags! {
         /// the MIR `InstrumentCoverage` pass and not added to the coverage map
         /// during codegen.
         const NO_COVERAGE               = 1 << 15;
-        /// `#[used(linker)]`: indicates that LLVM nor the linker can eliminate this function.
+        /// `#[used(linker)]`:
+        /// indicates that neither LLVM nor the linker will eliminate this function.
         const USED_LINKER               = 1 << 16;
         /// `#[rustc_deallocator]`: a hint to LLVM that the function only deallocates memory.
         const DEALLOCATOR               = 1 << 17;
diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs
index 3ddac5e11fb..443c1b2d261 100644
--- a/compiler/rustc_middle/src/mir/visit.rs
+++ b/compiler/rustc_middle/src/mir/visit.rs
@@ -323,7 +323,7 @@ macro_rules! make_mir_visitor {
                     self.visit_source_scope($(& $mutability)? *parent_scope);
                 }
                 if let Some((callee, callsite_span)) = inlined {
-                    let location = START_BLOCK.start_location();
+                    let location = Location::START;
 
                     self.visit_span($(& $mutability)? *callsite_span);
 
@@ -837,7 +837,7 @@ macro_rules! make_mir_visitor {
                 } = var_debug_info;
 
                 self.visit_source_info(source_info);
-                let location = START_BLOCK.start_location();
+                let location = Location::START;
                 match value {
                     VarDebugInfoContents::Const(c) => self.visit_constant(c, location),
                     VarDebugInfoContents::Place(place) =>
@@ -1026,7 +1026,7 @@ macro_rules! super_body {
         $self.visit_span($(& $mutability)? $body.span);
 
         for const_ in &$($mutability)? $body.required_consts {
-            let location = START_BLOCK.start_location();
+            let location = Location::START;
             $self.visit_constant(const_, location);
         }
     }
diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs
index 5c5baa68e58..2e481b97278 100644
--- a/compiler/rustc_mir_transform/src/dest_prop.rs
+++ b/compiler/rustc_mir_transform/src/dest_prop.rs
@@ -136,8 +136,8 @@ use rustc_index::bit_set::BitSet;
 use rustc_middle::mir::visit::{MutVisitor, PlaceContext, Visitor};
 use rustc_middle::mir::{dump_mir, PassWhere};
 use rustc_middle::mir::{
-    traversal, BasicBlock, Body, InlineAsmOperand, Local, LocalKind, Location, Operand, Place,
-    Rvalue, Statement, StatementKind, TerminatorKind,
+    traversal, Body, InlineAsmOperand, Local, LocalKind, Location, Operand, Place, Rvalue,
+    Statement, StatementKind, TerminatorKind,
 };
 use rustc_middle::ty::TyCtxt;
 use rustc_mir_dataflow::impls::MaybeLiveLocals;
@@ -468,7 +468,7 @@ impl<'a, 'body, 'alloc, 'tcx> FilterInformation<'a, 'body, 'alloc, 'tcx> {
             // to reuse the allocation.
             write_info: write_info_alloc,
             // Doesn't matter what we put here, will be overwritten before being used
-            at: Location { block: BasicBlock::from_u32(0), statement_index: 0 },
+            at: Location::START,
         };
         this.internal_filter_liveness();
     }
diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs
index 35c6037fa29..dc5f88f24f8 100644
--- a/compiler/rustc_mir_transform/src/generator.rs
+++ b/compiler/rustc_mir_transform/src/generator.rs
@@ -487,7 +487,7 @@ fn transform_async_context<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
 
     let get_context_def_id = tcx.require_lang_item(LangItem::GetContext, None);
 
-    for bb in BasicBlock::new(0)..body.basic_blocks.next_index() {
+    for bb in START_BLOCK..body.basic_blocks.next_index() {
         let bb_data = &body[bb];
         if bb_data.is_cleanup {
             continue;
@@ -1255,7 +1255,7 @@ fn create_generator_resume_function<'tcx>(
     use rustc_middle::mir::AssertKind::{ResumedAfterPanic, ResumedAfterReturn};
 
     // Jump to the entry point on the unresumed
-    cases.insert(0, (UNRESUMED, BasicBlock::new(0)));
+    cases.insert(0, (UNRESUMED, START_BLOCK));
 
     // Panic when resumed on the returned or poisoned state
     let generator_kind = body.generator_kind().unwrap();
@@ -1481,7 +1481,7 @@ impl<'tcx> MirPass<'tcx> for StateTransform {
 
         // When first entering the generator, move the resume argument into its new local.
         let source_info = SourceInfo::outermost(body.span);
-        let stmts = &mut body.basic_blocks_mut()[BasicBlock::new(0)].statements;
+        let stmts = &mut body.basic_blocks_mut()[START_BLOCK].statements;
         stmts.insert(
             0,
             Statement {
diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs
index 44b94f1c1a5..8c6b0463a73 100644
--- a/compiler/rustc_mir_transform/src/inline.rs
+++ b/compiler/rustc_mir_transform/src/inline.rs
@@ -96,7 +96,7 @@ fn inline<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> bool {
         history: Vec::new(),
         changed: false,
     };
-    let blocks = BasicBlock::new(0)..body.basic_blocks.next_index();
+    let blocks = START_BLOCK..body.basic_blocks.next_index();
     this.process_blocks(body, blocks);
     this.changed
 }
diff --git a/compiler/rustc_mir_transform/src/simplify.rs b/compiler/rustc_mir_transform/src/simplify.rs
index ced97b2c788..9ef55c558c6 100644
--- a/compiler/rustc_mir_transform/src/simplify.rs
+++ b/compiler/rustc_mir_transform/src/simplify.rs
@@ -496,7 +496,7 @@ impl UsedLocals {
         self.increment = false;
 
         // The location of the statement is irrelevant.
-        let location = Location { block: START_BLOCK, statement_index: 0 };
+        let location = Location::START;
         self.visit_statement(statement, location);
     }
 
diff --git a/compiler/rustc_target/src/spec/armebv7r_none_eabi.rs b/compiler/rustc_target/src/spec/armebv7r_none_eabi.rs
index 8c65d6afcc1..f6f46aac4c3 100644
--- a/compiler/rustc_target/src/spec/armebv7r_none_eabi.rs
+++ b/compiler/rustc_target/src/spec/armebv7r_none_eabi.rs
@@ -19,7 +19,7 @@ pub fn target() -> Target {
             max_atomic_width: Some(32),
             emit_debug_gdb_scripts: false,
             // GCC and Clang default to 8 for arm-none here
-            c_enum_min_bits: 8,
+            c_enum_min_bits: Some(8),
             ..Default::default()
         },
     }
diff --git a/compiler/rustc_target/src/spec/armebv7r_none_eabihf.rs b/compiler/rustc_target/src/spec/armebv7r_none_eabihf.rs
index 7013bc60d16..9608efe8bcf 100644
--- a/compiler/rustc_target/src/spec/armebv7r_none_eabihf.rs
+++ b/compiler/rustc_target/src/spec/armebv7r_none_eabihf.rs
@@ -20,7 +20,7 @@ pub fn target() -> Target {
             max_atomic_width: Some(32),
             emit_debug_gdb_scripts: false,
             // GCC and Clang default to 8 for arm-none here
-            c_enum_min_bits: 8,
+            c_enum_min_bits: Some(8),
             ..Default::default()
         },
     }
diff --git a/compiler/rustc_target/src/spec/armv4t_none_eabi.rs b/compiler/rustc_target/src/spec/armv4t_none_eabi.rs
index 7ac1aab3b43..28b109889e9 100644
--- a/compiler/rustc_target/src/spec/armv4t_none_eabi.rs
+++ b/compiler/rustc_target/src/spec/armv4t_none_eabi.rs
@@ -49,7 +49,7 @@ pub fn target() -> Target {
             // from thumb_base, rust-lang/rust#44993.
             emit_debug_gdb_scripts: false,
             // from thumb_base, apparently gcc/clang give enums a minimum of 8 bits on no-os targets
-            c_enum_min_bits: 8,
+            c_enum_min_bits: Some(8),
             ..Default::default()
         },
     }
diff --git a/compiler/rustc_target/src/spec/armv7a_none_eabi.rs b/compiler/rustc_target/src/spec/armv7a_none_eabi.rs
index 4e20fb32569..d59de86a230 100644
--- a/compiler/rustc_target/src/spec/armv7a_none_eabi.rs
+++ b/compiler/rustc_target/src/spec/armv7a_none_eabi.rs
@@ -27,7 +27,7 @@ pub fn target() -> Target {
         max_atomic_width: Some(64),
         panic_strategy: PanicStrategy::Abort,
         emit_debug_gdb_scripts: false,
-        c_enum_min_bits: 8,
+        c_enum_min_bits: Some(8),
         ..Default::default()
     };
     Target {
diff --git a/compiler/rustc_target/src/spec/armv7a_none_eabihf.rs b/compiler/rustc_target/src/spec/armv7a_none_eabihf.rs
index ae70129ae51..8cdf3c36ba2 100644
--- a/compiler/rustc_target/src/spec/armv7a_none_eabihf.rs
+++ b/compiler/rustc_target/src/spec/armv7a_none_eabihf.rs
@@ -19,7 +19,7 @@ pub fn target() -> Target {
         panic_strategy: PanicStrategy::Abort,
         emit_debug_gdb_scripts: false,
         // GCC and Clang default to 8 for arm-none here
-        c_enum_min_bits: 8,
+        c_enum_min_bits: Some(8),
         ..Default::default()
     };
     Target {
diff --git a/compiler/rustc_target/src/spec/armv7r_none_eabi.rs b/compiler/rustc_target/src/spec/armv7r_none_eabi.rs
index 25f301ccce7..5225abf44fc 100644
--- a/compiler/rustc_target/src/spec/armv7r_none_eabi.rs
+++ b/compiler/rustc_target/src/spec/armv7r_none_eabi.rs
@@ -18,7 +18,7 @@ pub fn target() -> Target {
             max_atomic_width: Some(32),
             emit_debug_gdb_scripts: false,
             // GCC and Clang default to 8 for arm-none here
-            c_enum_min_bits: 8,
+            c_enum_min_bits: Some(8),
             ..Default::default()
         },
     }
diff --git a/compiler/rustc_target/src/spec/armv7r_none_eabihf.rs b/compiler/rustc_target/src/spec/armv7r_none_eabihf.rs
index 40449759dd3..9a35e04617f 100644
--- a/compiler/rustc_target/src/spec/armv7r_none_eabihf.rs
+++ b/compiler/rustc_target/src/spec/armv7r_none_eabihf.rs
@@ -19,7 +19,7 @@ pub fn target() -> Target {
             max_atomic_width: Some(32),
             emit_debug_gdb_scripts: false,
             // GCC and Clang default to 8 for arm-none here
-            c_enum_min_bits: 8,
+            c_enum_min_bits: Some(8),
             ..Default::default()
         },
     }
diff --git a/compiler/rustc_target/src/spec/hexagon_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/hexagon_unknown_linux_musl.rs
index 3aad05eb271..4c6ab5f5ae4 100644
--- a/compiler/rustc_target/src/spec/hexagon_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/hexagon_unknown_linux_musl.rs
@@ -11,7 +11,7 @@ pub fn target() -> Target {
     base.has_rpath = true;
     base.linker_flavor = LinkerFlavor::Unix(Cc::Yes);
 
-    base.c_enum_min_bits = 8;
+    base.c_enum_min_bits = Some(8);
 
     Target {
         llvm_target: "hexagon-unknown-linux-musl".into(),
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index bc1920e3424..ef60956a617 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -1344,10 +1344,18 @@ impl Target {
             });
         }
 
-        dl.c_enum_min_size = match Integer::from_size(Size::from_bits(self.c_enum_min_bits)) {
-            Ok(bits) => bits,
-            Err(err) => return Err(TargetDataLayoutErrors::InvalidBitsSize { err }),
-        };
+        dl.c_enum_min_size = self
+            .c_enum_min_bits
+            .map_or_else(
+                || {
+                    self.c_int_width
+                        .parse()
+                        .map_err(|_| String::from("failed to parse c_int_width"))
+                },
+                Ok,
+            )
+            .and_then(|i| Integer::from_size(Size::from_bits(i)))
+            .map_err(|err| TargetDataLayoutErrors::InvalidBitsSize { err })?;
 
         Ok(dl)
     }
@@ -1701,8 +1709,8 @@ pub struct TargetOptions {
     /// If present it's a default value to use for adjusting the C ABI.
     pub default_adjusted_cabi: Option<Abi>,
 
-    /// Minimum number of bits in #[repr(C)] enum. Defaults to 32.
-    pub c_enum_min_bits: u64,
+    /// Minimum number of bits in #[repr(C)] enum. Defaults to the size of c_int
+    pub c_enum_min_bits: Option<u64>,
 
     /// Whether or not the DWARF `.debug_aranges` section should be generated.
     pub generate_arange_section: bool,
@@ -1935,7 +1943,7 @@ impl Default for TargetOptions {
             supported_split_debuginfo: Cow::Borrowed(&[SplitDebuginfo::Off]),
             supported_sanitizers: SanitizerSet::empty(),
             default_adjusted_cabi: None,
-            c_enum_min_bits: 32,
+            c_enum_min_bits: None,
             generate_arange_section: true,
             supports_stack_protector: true,
             entry_name: "main".into(),
@@ -2122,12 +2130,6 @@ impl Target {
                     base.$key_name = s;
                 }
             } );
-            ($key_name:ident, u64) => ( {
-                let name = (stringify!($key_name)).replace("_", "-");
-                if let Some(s) = obj.remove(&name).and_then(|j| Json::as_u64(&j)) {
-                    base.$key_name = s;
-                }
-            } );
             ($key_name:ident, u32) => ( {
                 let name = (stringify!($key_name)).replace("_", "-");
                 if let Some(s) = obj.remove(&name).and_then(|b| b.as_u64()) {
@@ -2496,6 +2498,7 @@ impl Target {
 
         key!(is_builtin, bool);
         key!(c_int_width = "target-c-int-width");
+        key!(c_enum_min_bits, Option<u64>); // if None, matches c_int_width
         key!(os);
         key!(env);
         key!(abi);
@@ -2591,7 +2594,6 @@ impl Target {
         key!(supported_split_debuginfo, falliable_list)?;
         key!(supported_sanitizers, SanitizerSet)?;
         key!(default_adjusted_cabi, Option<Abi>)?;
-        key!(c_enum_min_bits, u64);
         key!(generate_arange_section, bool);
         key!(supports_stack_protector, bool);
         key!(entry_name);
diff --git a/compiler/rustc_target/src/spec/thumb_base.rs b/compiler/rustc_target/src/spec/thumb_base.rs
index 000766c57ce..4dcf47fe465 100644
--- a/compiler/rustc_target/src/spec/thumb_base.rs
+++ b/compiler/rustc_target/src/spec/thumb_base.rs
@@ -53,7 +53,7 @@ pub fn opts() -> TargetOptions {
         frame_pointer: FramePointer::Always,
         // ARM supports multiple ABIs for enums, the linux one matches the default of 32 here
         // but any arm-none or thumb-none target will be defaulted to 8 on GCC and clang
-        c_enum_min_bits: 8,
+        c_enum_min_bits: Some(8),
         ..Default::default()
     }
 }
diff --git a/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs b/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs
index 5a3e4c88d3a..e3734932f88 100644
--- a/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs
+++ b/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs
@@ -55,7 +55,7 @@ pub fn target() -> Target {
             // suggested from thumb_base, rust-lang/rust#44993.
             emit_debug_gdb_scripts: false,
             // suggested from thumb_base, with no-os gcc/clang use 8-bit enums
-            c_enum_min_bits: 8,
+            c_enum_min_bits: Some(8),
             frame_pointer: FramePointer::MayOmit,
 
             main_needs_argc_argv: false,
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index 07c0d2233ca..97a1102e3c5 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -445,6 +445,72 @@ impl Step for StdLink {
         let libdir = builder.sysroot_libdir(target_compiler, target);
         let hostdir = builder.sysroot_libdir(target_compiler, compiler.host);
         add_to_sysroot(builder, &libdir, &hostdir, &libstd_stamp(builder, compiler, target));
+
+        if compiler.stage == 0 {
+            // special handling for stage0, to make `rustup toolchain link` and `x dist --stage 0`
+            // work for stage0-sysroot
+            let sysroot = builder.out.join(&compiler.host.triple).join("stage0-sysroot");
+
+            let host_lib_dir = builder.initial_rustc.ancestors().nth(2).unwrap().join("lib");
+            let host_bin_dir = builder.out.join(&builder.initial_rustc.parent().unwrap());
+            let host_codegen_backends =
+                host_lib_dir.join("rustlib").join(&compiler.host.triple).join("codegen-backends");
+            let sysroot_bin_dir = sysroot.join("bin");
+            let sysroot_lib_dir = sysroot.join("lib");
+            let sysroot_codegen_backends = builder.sysroot_codegen_backends(compiler);
+
+            // Create the `bin` directory in stage0-sysroot
+            t!(fs::create_dir_all(&sysroot_bin_dir));
+
+            // copy bin files from `builder.initial_rustc/./` to `stage0-sysroot/bin`
+            if let Ok(files) = fs::read_dir(&host_bin_dir) {
+                for file in files {
+                    let file = t!(file);
+                    if file.file_name() == "rustfmt" {
+                        // This is when `rustc` and `cargo` are set in `config.toml`
+                        if !file.path().starts_with(&builder.out) {
+                            builder.copy(
+                                &file.path().into_boxed_path(),
+                                &sysroot_bin_dir.join(file.file_name()),
+                            );
+                        } else {
+                            builder.copy(
+                                &builder
+                                    .out
+                                    .join(&compiler.host.triple)
+                                    .join("rustfmt/bin/rustfmt"),
+                                &sysroot_bin_dir.join(file.file_name()),
+                            );
+                        }
+                    } else {
+                        builder.copy(
+                            &file.path().into_boxed_path(),
+                            &sysroot_bin_dir.join(file.file_name()),
+                        );
+                    }
+                }
+            }
+
+            // copy dylib files from `builder.initial_rustc/../lib/*` while excluding the `rustlib` directory to `stage0-sysroot/lib`
+            if let Ok(files) = fs::read_dir(&host_lib_dir) {
+                for file in files {
+                    let file = t!(file);
+                    let path = file.path();
+                    if path.is_file()
+                        && is_dylib(&file.file_name().into_string().unwrap())
+                        && !path.starts_with(sysroot_lib_dir.join("rustlib").into_boxed_path())
+                    {
+                        builder.copy(&path, &sysroot_lib_dir.join(path.file_name().unwrap()));
+                    }
+                }
+            }
+
+            t!(fs::create_dir_all(&sysroot_codegen_backends));
+            // copy `codegen-backends` from `host_lib_dir/rustlib/codegen_backends` to `stage0-sysroot/lib/rustlib/host-triple/codegen-backends` if it exists.
+            if host_codegen_backends.exists() {
+                builder.cp_r(&host_codegen_backends, &sysroot_codegen_backends);
+            }
+        }
     }
 }
 
diff --git a/tests/ui/repr/16-bit-repr-c-enum.rs b/tests/ui/repr/16-bit-repr-c-enum.rs
new file mode 100644
index 00000000000..2acfde4be46
--- /dev/null
+++ b/tests/ui/repr/16-bit-repr-c-enum.rs
@@ -0,0 +1,52 @@
+// build-pass
+// revisions: avr msp430
+//
+// [avr] needs-llvm-components: avr
+// [avr] compile-flags: --target=avr-unknown-gnu-atmega328 --crate-type=rlib
+// [msp430] needs-llvm-components: msp430
+// [msp430] compile-flags: --target=msp430-none-elf --crate-type=rlib
+#![feature(no_core, lang_items, intrinsics, staged_api)]
+#![no_core]
+#![crate_type = "lib"]
+#![stable(feature = "", since = "")]
+#![allow(dead_code)]
+
+// Test that the repr(C) attribute doesn't break compilation
+// Previous bad assumption was that 32-bit enum default width is fine on msp430, avr
+// But the width of the C int on these platforms is 16 bits, and C enums <= C int range
+// so we want no more than that, usually. This resulted in errors like
+// "layout decided on a larger discriminant type (I32) than typeck (I16)"
+#[repr(C)]
+enum Foo {
+    Bar,
+}
+
+extern "rust-intrinsic" {
+    #[stable(feature = "", since = "")]
+    #[rustc_const_stable(feature = "", since = "")]
+    #[rustc_safe_intrinsic]
+    fn size_of<T>() -> usize;
+}
+
+#[lang="sized"]
+trait Sized {}
+#[lang="copy"]
+trait Copy {}
+
+const EXPECTED: usize = 2;
+const ACTUAL: usize = size_of::<Foo>();
+// Validate that the size is indeed 16 bits, to match this C static_assert:
+/**
+```c
+#include <assert.h>
+enum foo {
+    BAR
+};
+int main(void)
+{
+    /* passes on msp430-elf-gcc */
+    static_assert(sizeof(enum foo) == 2);
+}
+```
+*/
+const _: [(); EXPECTED] = [(); ACTUAL];
diff --git a/triagebot.toml b/triagebot.toml
index 8a9d9403366..7a26457ab04 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -538,6 +538,7 @@ diagnostics = [
     "@TaKO8Ki",
 ]
 parser = [
+    "@compiler-errors",
     "@davidtwco",
     "@nnethercote",
     "@petrochenkov",
@@ -567,6 +568,7 @@ borrowck = [
     "@pnkfelix",
 ]
 ast_lowering = [
+    "@compiler-errors",
     "@spastorino",
 ]
 fallback = [
@@ -630,7 +632,7 @@ style-team = [
 "/src/stage0.json" =                         ["bootstrap"]
 "/tests/ui" =                                ["compiler"]
 "/src/tools/cargo" =                         ["@ehuss", "@joshtriplett"]
-"/src/tools/compiletest" =                   ["bootstrap", "@wesleywiser", "@oli-obk"]
+"/src/tools/compiletest" =                   ["bootstrap", "@wesleywiser", "@oli-obk", "@compiler-errors"]
 "/src/tools/linkchecker" =                   ["@ehuss"]
 "/src/tools/rust-installer" =                ["bootstrap"]
 "/src/tools/rustbook" =                      ["@ehuss"]