Change:
Building Firefox for the thumbv7neon-linux-androideabi and i686-linux-android fails with a rust compiler crash: I wish I could give something more detailed, but I haven't had the time to try to yet. I however identified the regression to come from (Enable ScalarReplacementOfAggregates in optimized builds) and building with avoids the crash.
Duplicate of
going to close as such. thanks for reporting !

Discussion:
bx.store(place.llval, alloca.llval, alloca.align); // Point the debug info to `*alloca` for the current variable <del> bx.dbg_var_addr(dbg_var, dbg_loc, alloca.llval, Size::ZERO, &[Size::ZERO], None); </del> <ins> bx.dbg_var_addr( dbg_var, dbg_loc, alloca.llval, Size::ZERO, &[Size::ZERO], var.fragment, ); </ins> } else { <del> bx.dbg_var_addr(dbg_var, dbg_loc, base.llval, direct_offset, &indirect_offsets, None); </del> <ins> bx.dbg_var_addr( dbg_var, dbg_loc, base.llval, direct_offset, &indirect_offsets, var.fragment, ); </ins> } }

} let place = fragment.contents; <ins> let fragment = if fragment_layout.size == Size::ZERO { // Fragment is a ZST, so does not represent anything. continue; } else if fragment_layout.size == var_layout.size { // Fragment covers entire variable, so as far as // DWARF is concerned, it's not really a fragment. None } else { Some(fragment_start..fragment_start + fragment_layout.size) }; </ins> per_local[place.local].push(PerLocalVarDebugInfo { name: var.name, source_info: var.source_info, dbg_var, <del> fragment: if fragment_layout.size == var_layout.size { // Fragment covers entire variable, so as far as // DWARF is concerned, it's not really a fragment. None } else { Some(fragment_start..fragment_start + fragment_layout.size) }, </del> <ins> fragment, </ins> projection: place.projection, }); }

<ins> // compile-flags: -g -Zmir-opt-level=0 -Zmir-enable-passes=+ScalarReplacementOfAggregates // compile-flags: -Cno-prepopulate-passes // // Tested offsets are only correct for x86_64. // only-x86_64 #![crate_type = "lib"] pub struct ExtraSlice<'input> { slice: &'input [u8], extra: u32, } #[no_mangle] pub fn extra(s: &[u8]) { // CHECK: void @extra( // CHECK: %slice.dbg.spill1 = alloca i32, // CHECK: %slice.dbg.spill = alloca { ptr, i64 }, // CHECK: %s.dbg.spill = alloca { ptr, i64 }, // CHECK: call void @llvm.dbg.declare(metadata ptr %s.dbg.spill, metadata ![[S_EXTRA:.*]], metadata !DIExpression()), // CHECK: call void @llvm.dbg.declare(metadata ptr %slice.dbg.spill, metadata ![[SLICE_EXTRA:.*]], metadata !DIExpression(DW_OP_LLVM_fragment, 0, 128)), // CHECK: call void @llvm.dbg.declare(metadata ptr %slice.dbg.spill1, metadata ![[SLICE_EXTRA]], metadata !DIExpression(DW_OP_LLVM_fragment, 128, 32)), let slice = ExtraSlice { slice: s, extra: s.len() as u32 }; } struct Zst; pub struct ZstSlice<'input> { slice: &'input [u8], extra: Zst, } #[no_mangle] pub fn zst(s: &[u8]) { // The field `extra` is a ZST. The fragment for the field `slice` encompasses the whole // variable, so is not a fragment. In that case, the variable must have no fragment. // CHECK: void @zst( // CHECK-NOT: call void @llvm.dbg.declare(metadata ptr %slice.dbg.spill, metadata !{}, metadata !DIExpression(DW_OP_LLVM_fragment, // CHECK: call void @llvm.dbg.declare(metadata ptr %{{.*}}, metadata ![[SLICE_ZST:.*]], metadata !DIExpression()), // CHECK-NOT: call void @llvm.dbg.declare(metadata ptr %{{.*}}, metadata ![[SLICE_ZST]], let slice = ZstSlice { slice: s, extra: Zst }; } // CHECK: ![[S_EXTRA]] = !DILocalVariable(name: "s", // CHECK: ![[SLICE_EXTRA]] = !DILocalVariable(name: "slice", </ins>

<ins> // Verify that we do not trigger a LLVM assertion by creating zero-sized DWARF fragments. // // build-pass // compile-flags: -g -Zmir-opt-level=0 -Zmir-enable-passes=+ScalarReplacementOfAggregates // compile-flags: -Cno-prepopulate-passes #![crate_type = "lib"] pub struct ExtraSlice<'input> { slice: &'input [u8], extra: u32, } #[no_mangle] pub fn extra(s: &[u8]) { let slice = ExtraSlice { slice: s, extra: s.len() as u32 }; } struct Zst; pub struct ZstSlice<'input> { slice: &'input [u8], extra: Zst, } #[no_mangle] pub fn zst(s: &[u8]) { // The field `extra` is a ZST. The fragment for the field `slice` encompasses the whole // variable, so is not a fragment. In that case, the variable must have no fragment. let slice = ZstSlice { slice: s, extra: Zst }; } </ins>