Change:
return Ok(None); }; <del> // FIXME (#26403, #27023): We should be adding padding // to `sized_size` (to accommodate the `unsized_align` // required of the unsized field that follows) before // summing it with `sized_size`. (Note that since #26403 // is unfixed, we do not yet add the necessary padding // here. But this is where the add would go.) // Return the sum of sizes and max of aligns. let size = sized_size + unsized_size; // `Size` addition </del> <ins> // # First compute the dynamic alignment </ins> <del> // Packed types ignore the alignment of their fields. </del> <ins> // Packed type alignment needs to be capped. </ins> if let ty::Adt(def, _) = layout.ty.kind() { <del> if def.repr().packed() { unsized_align = sized_align; </del> <ins> if let Some(packed) = def.repr().pack { unsized_align = unsized_align.min(packed); </ins> } } // Choose max of two known alignments (combined value must // be aligned according to more restrictive of the two). <del> let align = sized_align.max(unsized_align); </del> <ins> let full_align = sized_align.max(unsized_align); // # Then compute the dynamic size </ins> <del> // Issue #27023: must add any necessary padding to `size` // (to make it a multiple of `align`) before returning it. let size = size.align_to(align); </del> <ins> let unsized_offset_adjusted = unsized_offset_unadjusted.align_to(unsized_align); let full_size = (unsized_offset_adjusted + unsized_size).align_to(full_align); // Just for our sanitiy's sake, assert that this is equal to what codegen would compute. assert_eq!( full_size, (unsized_offset_unadjusted + unsized_size).align_to(full_align) ); </ins> // Check if this brought us over the size limit. <del> if size > self.max_size_of_val() { </del> <ins> if full_size > self.max_size_of_val() { </ins> throw_ub!(InvalidMeta(InvalidMetaKind::TooBig)); } <del> Ok(Some((size, align))) </del> <ins> Ok(Some((full_size, full_align))) </ins> } ty::Dynamic(_, _, ty::Dyn) => { let vtable = metadata.unwrap_meta().to_pointer(self)?;

Discussion:
Execute with Miri: The problem is that and do not take the reduced field alignment into account and calculate the offset as-if the standard alignment was in place.
The labels are incorrect. Neither does this require nightly, nor is it related to const-eval. This is I-unsound on stable.
label I-prioritize (Looks like can't set .)
Error: Label can only be set by Rust team members Please let know if you're having trouble with this bot.
Error: Parsing relabel command in failed: ...'const-eval' ' "I-unsoun'... Please let know if you're having trouble with this bot.
Assigning as discussed as part of the and removing .
label -I-prioritize +P-medium
labels -T-types Discussed in types team on-site -- we think this is a MIR building bug, in any case, not part of T-types. Throwing hot back to compiler team.
It was actually a bug in the codegen backend, introduced when support for was -- the existing code has logic that assumed "if it is packed then alignment is 1", and that was never re-visited.
Ah, scratch that -- there was a different related bug (the sizeofval / alignofval computation for packed structs with tail was wrong), caused by what I said above. This here was caused by the codegen backend just never considering packed types when computing the offset of the unsized field. Almost always this happened to work since the unsized field is a slice/str and so its alignment (and therefore its offset) is dynamically known, but when dyn trait tails are involved this starts to go wrong. This got fixed by ; will add a test.