diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index aea88641f82b1..489a8403c3b1f 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -763,7 +763,9 @@ pub trait LayoutCalculator { let mut size = Size::ZERO; let only_variant = &variants[FIRST_VARIANT]; for field in only_variant { - assert!(field.0.is_sized()); + if field.0.is_unsized() { + self.delay_bug("unsized field in union".to_string()); + } align = align.max(field.align()); max_repr_align = max_repr_align.max(field.max_repr_align()); diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index ef0c763ac2038..93b29d037d67e 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -1345,7 +1345,6 @@ impl Abi { /// Discard validity range information and allow undef. pub fn to_union(&self) -> Self { - assert!(self.is_sized()); match *self { Abi::Scalar(s) => Abi::Scalar(s.to_union()), Abi::ScalarPair(s1, s2) => Abi::ScalarPair(s1.to_union(), s2.to_union()), diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index ea32506fc8980..2fd42e2f56a63 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -2306,11 +2306,10 @@ mod error { pub fn buffer_error(&mut self, t: DiagnosticBuilder<'_, ErrorGuaranteed>) { if let None = self.tainted_by_errors { - self.tainted_by_errors = Some( - self.tcx - .sess - .delay_span_bug(t.span.clone(), "diagnostic buffered but not emitted"), - ) + self.tainted_by_errors = Some(self.tcx.sess.delay_span_bug( + t.span.clone_ignoring_labels(), + "diagnostic buffered but not emitted", + )) } t.buffer(&mut self.buffered); } diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 1879ece59e329..a49b842d9ffea 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -533,6 +533,14 @@ impl MultiSpan { pub fn has_span_labels(&self) -> bool { self.span_labels.iter().any(|(sp, _)| !sp.is_dummy()) } + + /// Clone this `MultiSpan` without keeping any of the span labels - sometimes a `MultiSpan` is + /// to be re-used in another diagnostic, but includes `span_labels` which have translated + /// messages. These translated messages would fail to translate without their diagnostic + /// arguments which are unlikely to be cloned alongside the `Span`. + pub fn clone_ignoring_labels(&self) -> Self { + Self { primary_spans: self.primary_spans.clone(), ..MultiSpan::new() } + } } impl From for MultiSpan { diff --git a/tests/ui/generator/issue-113279.rs b/tests/ui/generator/issue-113279.rs new file mode 100644 index 0000000000000..f69f804b716d5 --- /dev/null +++ b/tests/ui/generator/issue-113279.rs @@ -0,0 +1,27 @@ +#![feature(generators)] + +// `foo` attempts to dereference `""`, which results in an error being reported. Later, the +// generator transform for `foo` then produces a union which contains a `str` type - unions should +// not contain unsized types, but this is okay because an error has been reported already. +// When const propagation happens later in compilation, it attempts to compute the layout of the +// generator (as part of checking whether something can be const propagated) and in turn attempts +// to compute the layout of `str` in the context of a union - where this caused an ICE. This test +// makes sure that doesn't happen again. + +fn foo() { + let _y = static || { + let x = &mut 0; + *{ + yield; + x + } += match { *"" }.len() { + //~^ ERROR cannot move a value of type `str` [E0161] + //~^^ ERROR cannot move out of a shared reference [E0507] + _ => 0, + }; + }; +} + +fn main() { + foo() +} diff --git a/tests/ui/generator/issue-113279.stderr b/tests/ui/generator/issue-113279.stderr new file mode 100644 index 0000000000000..cc9b64ef9ac2f --- /dev/null +++ b/tests/ui/generator/issue-113279.stderr @@ -0,0 +1,16 @@ +error[E0161]: cannot move a value of type `str` + --> $DIR/issue-113279.rs:17:20 + | +LL | } += match { *"" }.len() { + | ^^^^^^^ the size of `str` cannot be statically determined + +error[E0507]: cannot move out of a shared reference + --> $DIR/issue-113279.rs:17:22 + | +LL | } += match { *"" }.len() { + | ^^^ move occurs because value has type `str`, which does not implement the `Copy` trait + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0161, E0507. +For more information about an error, try `rustc --explain E0161`.