From 60d69804bacb47875bb691ffc97b25e92f0b98fd Mon Sep 17 00:00:00 2001 From: xizheyin Date: Wed, 23 Jul 2025 23:17:54 +0800 Subject: [PATCH 1/9] Inline some methods in rustc_span hygiene Signed-off-by: xizheyin --- compiler/rustc_span/src/hygiene.rs | 16 ++++++++++++++++ compiler/rustc_span/src/lib.rs | 1 + 2 files changed, 17 insertions(+) diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs index c3080875da803..97d1d9c2d2a12 100644 --- a/compiler/rustc_span/src/hygiene.rs +++ b/compiler/rustc_span/src/hygiene.rs @@ -322,6 +322,7 @@ impl ExpnId { /// `expn_id.outer_expn_is_descendant_of(ctxt)` is equivalent to but faster than /// `expn_id.is_descendant_of(ctxt.outer_expn())`. + #[inline] pub fn outer_expn_is_descendant_of(self, ctxt: SyntaxContext) -> bool { HygieneData::with(|data| data.is_descendant_of(self, data.outer_expn(ctxt))) } @@ -394,6 +395,7 @@ impl HygieneData { } } + #[inline] fn with(f: impl FnOnce(&mut HygieneData) -> R) -> R { with_session_globals(|session_globals| f(&mut session_globals.hygiene_data.borrow_mut())) } @@ -406,6 +408,7 @@ impl HygieneData { } } + #[inline] fn local_expn_data(&self, expn_id: LocalExpnId) -> &ExpnData { self.local_expn_data[expn_id].as_ref().expect("no expansion data for an expansion ID") } @@ -437,23 +440,28 @@ impl HygieneData { } } + #[inline] fn normalize_to_macros_2_0(&self, ctxt: SyntaxContext) -> SyntaxContext { self.syntax_context_data[ctxt.0 as usize].opaque } + #[inline] fn normalize_to_macro_rules(&self, ctxt: SyntaxContext) -> SyntaxContext { self.syntax_context_data[ctxt.0 as usize].opaque_and_semiopaque } + #[inline] fn outer_expn(&self, ctxt: SyntaxContext) -> ExpnId { self.syntax_context_data[ctxt.0 as usize].outer_expn } + #[inline] fn outer_mark(&self, ctxt: SyntaxContext) -> (ExpnId, Transparency) { let data = &self.syntax_context_data[ctxt.0 as usize]; (data.outer_expn, data.outer_transparency) } + #[inline] fn parent_ctxt(&self, ctxt: SyntaxContext) -> SyntaxContext { self.syntax_context_data[ctxt.0 as usize].parent } @@ -718,11 +726,13 @@ impl SyntaxContext { SyntaxContext(raw as u32) } + #[inline] fn from_usize(raw: usize) -> SyntaxContext { SyntaxContext(u32::try_from(raw).unwrap()) } /// Extend a syntax context with a given expansion and transparency. + #[inline] pub fn apply_mark(self, expn_id: ExpnId, transparency: Transparency) -> SyntaxContext { HygieneData::with(|data| data.apply_mark(self, expn_id, transparency)) } @@ -743,10 +753,12 @@ impl SyntaxContext { /// of g (call it g1), calling remove_mark will result in the SyntaxContext for the /// invocation of f that created g1. /// Returns the mark that was removed. + #[inline] pub fn remove_mark(&mut self) -> ExpnId { HygieneData::with(|data| data.remove_mark(self).0) } + #[inline] pub fn marks(self) -> Vec<(ExpnId, Transparency)> { HygieneData::with(|data| data.marks(self)) } @@ -776,11 +788,13 @@ impl SyntaxContext { /// ``` /// This returns the expansion whose definition scope we use to privacy check the resolution, /// or `None` if we privacy check as usual (i.e., not w.r.t. a macro definition scope). + #[inline] pub fn adjust(&mut self, expn_id: ExpnId) -> Option { HygieneData::with(|data| data.adjust(self, expn_id)) } /// Like `SyntaxContext::adjust`, but also normalizes `self` to macros 2.0. + #[inline] pub(crate) fn normalize_to_macros_2_0_and_adjust(&mut self, expn_id: ExpnId) -> Option { HygieneData::with(|data| { *self = data.normalize_to_macros_2_0(*self); @@ -901,10 +915,12 @@ impl SyntaxContext { HygieneData::with(|data| data.outer_mark(self)) } + #[inline] pub(crate) fn dollar_crate_name(self) -> Symbol { HygieneData::with(|data| data.syntax_context_data[self.0 as usize].dollar_crate_name) } + #[inline] pub fn edition(self) -> Edition { HygieneData::with(|data| data.expn_data(data.outer_expn(self)).edition) } diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 9b0e009b2cd37..dbc67da37b53c 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -167,6 +167,7 @@ where } } +#[inline] pub fn with_session_globals(f: F) -> R where F: FnOnce(&SessionGlobals) -> R, From e70d213275746edc2abfb1055d8bd6dda2d59749 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 20 Jul 2025 15:46:17 +0000 Subject: [PATCH 2/9] Add crash tests. --- tests/crashes/139872.rs | 12 ++++++++++++ tests/crashes/140332.rs | 7 +++++++ 2 files changed, 19 insertions(+) create mode 100644 tests/crashes/139872.rs create mode 100644 tests/crashes/140332.rs diff --git a/tests/crashes/139872.rs b/tests/crashes/139872.rs new file mode 100644 index 0000000000000..c3cb8e3c8d613 --- /dev/null +++ b/tests/crashes/139872.rs @@ -0,0 +1,12 @@ +//@ known-bug: #139872 + +enum E { + V16(u16), + V32(u32), +} + +static C: (E, u16, str) = (E::V16(0xDEAD), 0x600D, 0xBAD); + +pub fn main() { + let (_, n, _) = C; +} diff --git a/tests/crashes/140332.rs b/tests/crashes/140332.rs new file mode 100644 index 0000000000000..f5322fa023de8 --- /dev/null +++ b/tests/crashes/140332.rs @@ -0,0 +1,7 @@ +//@ known-bug: #140332 + +static mut S: [i8] = ["Some thing"; 1]; + +fn main() { + assert_eq!(S, [0; 1]); +} From 6b4181f1e39f2e309de6aa15e69f0b2f6889570d Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 20 Jul 2025 16:24:33 +0000 Subject: [PATCH 3/9] Do not assert layout in KnownPanicsLint. --- .../rustc_const_eval/src/interpret/operand.rs | 11 +++++++ .../rustc_const_eval/src/interpret/place.rs | 8 +++++ .../src/known_panics_lint.rs | 4 +-- tests/crashes/121176.rs | 9 ----- tests/crashes/139872.rs | 12 ------- tests/crashes/140332.rs | 7 ---- tests/ui/mir/static-by-value-dyn.rs | 14 ++++++++ tests/ui/mir/static-by-value-dyn.stderr | 19 +++++++++++ tests/ui/mir/static-by-value-slice.rs | 13 ++++++++ tests/ui/mir/static-by-value-slice.stderr | 33 +++++++++++++++++++ tests/ui/mir/static-by-value-str.rs | 17 ++++++++++ tests/ui/mir/static-by-value-str.stderr | 30 +++++++++++++++++ 12 files changed, 146 insertions(+), 31 deletions(-) delete mode 100644 tests/crashes/121176.rs delete mode 100644 tests/crashes/139872.rs delete mode 100644 tests/crashes/140332.rs create mode 100644 tests/ui/mir/static-by-value-dyn.rs create mode 100644 tests/ui/mir/static-by-value-dyn.stderr create mode 100644 tests/ui/mir/static-by-value-slice.rs create mode 100644 tests/ui/mir/static-by-value-slice.stderr create mode 100644 tests/ui/mir/static-by-value-str.rs create mode 100644 tests/ui/mir/static-by-value-str.stderr diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index 21afd082a0551..2c779489272a3 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -243,6 +243,17 @@ impl<'tcx, Prov: Provenance> std::ops::Deref for ImmTy<'tcx, Prov> { } impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> { + #[inline(always)] + pub fn try_from_immediate(imm: Immediate, layout: TyAndLayout<'tcx>) -> Option { + let matches_abi = match (imm, layout.backend_repr) { + (Immediate::Scalar(..), BackendRepr::Scalar(..)) => true, + (Immediate::ScalarPair(..), BackendRepr::ScalarPair(..)) => true, + (Immediate::Uninit, _) => layout.is_sized(), + _ => false, + }; + if matches_abi { Some(ImmTy { imm, layout }) } else { None } + } + #[inline] pub fn from_scalar(val: Scalar, layout: TyAndLayout<'tcx>) -> Self { debug_assert!(layout.backend_repr.is_scalar(), "`ImmTy::from_scalar` on non-scalar layout"); diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index e2284729efdcf..a8cfe276b49f9 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -313,6 +313,14 @@ impl<'tcx, Prov: Provenance> Projectable<'tcx, Prov> for PlaceTy<'tcx, Prov> { // These are defined here because they produce a place. impl<'tcx, Prov: Provenance> OpTy<'tcx, Prov> { + #[inline(always)] + pub fn try_as_immediate(&self) -> Option> { + match self.op() { + Operand::Indirect(_) => None, + Operand::Immediate(imm) => ImmTy::try_from_immediate(*imm, self.layout), + } + } + #[inline(always)] pub fn as_mplace_or_imm(&self) -> Either, ImmTy<'tcx, Prov>> { match self.op() { diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs index 481c794190925..cebbc40492300 100644 --- a/compiler/rustc_mir_transform/src/known_panics_lint.rs +++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs @@ -263,9 +263,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { // manually normalized. let val = self.tcx.try_normalize_erasing_regions(self.typing_env, c.const_).ok()?; - self.use_ecx(|this| this.ecx.eval_mir_constant(&val, c.span, None))? - .as_mplace_or_imm() - .right() + self.use_ecx(|this| this.ecx.eval_mir_constant(&val, c.span, None))?.try_as_immediate() } /// Returns the value, if any, of evaluating `place`. diff --git a/tests/crashes/121176.rs b/tests/crashes/121176.rs deleted file mode 100644 index 4d82e51de8f80..0000000000000 --- a/tests/crashes/121176.rs +++ /dev/null @@ -1,9 +0,0 @@ -//@ known-bug: #121176 -//@ needs-rustc-debug-assertions -use std::fmt::Debug; - -static STATIC_1: dyn Debug + Sync = *(); - -fn main() { - println!("{:?}", &STATIC_1); -} diff --git a/tests/crashes/139872.rs b/tests/crashes/139872.rs deleted file mode 100644 index c3cb8e3c8d613..0000000000000 --- a/tests/crashes/139872.rs +++ /dev/null @@ -1,12 +0,0 @@ -//@ known-bug: #139872 - -enum E { - V16(u16), - V32(u32), -} - -static C: (E, u16, str) = (E::V16(0xDEAD), 0x600D, 0xBAD); - -pub fn main() { - let (_, n, _) = C; -} diff --git a/tests/crashes/140332.rs b/tests/crashes/140332.rs deleted file mode 100644 index f5322fa023de8..0000000000000 --- a/tests/crashes/140332.rs +++ /dev/null @@ -1,7 +0,0 @@ -//@ known-bug: #140332 - -static mut S: [i8] = ["Some thing"; 1]; - -fn main() { - assert_eq!(S, [0; 1]); -} diff --git a/tests/ui/mir/static-by-value-dyn.rs b/tests/ui/mir/static-by-value-dyn.rs new file mode 100644 index 0000000000000..f1154ef08600a --- /dev/null +++ b/tests/ui/mir/static-by-value-dyn.rs @@ -0,0 +1,14 @@ +//! Regression test for #121176 +//! KnownPanicsLint used to assert ABI compatibility in the interpreter, +//! which ICEs with unsized statics. +//@ needs-rustc-debug-assertions + +use std::fmt::Debug; + +static STATIC_1: dyn Debug + Sync = *(); +//~^ ERROR the size for values of type `(dyn Debug + Sync + 'static)` cannot be known +//~| ERROR type `()` cannot be dereferenced + +fn main() { + println!("{:?}", &STATIC_1); +} diff --git a/tests/ui/mir/static-by-value-dyn.stderr b/tests/ui/mir/static-by-value-dyn.stderr new file mode 100644 index 0000000000000..25ed81326f43a --- /dev/null +++ b/tests/ui/mir/static-by-value-dyn.stderr @@ -0,0 +1,19 @@ +error[E0277]: the size for values of type `(dyn Debug + Sync + 'static)` cannot be known at compilation time + --> $DIR/static-by-value-dyn.rs:8:1 + | +LL | static STATIC_1: dyn Debug + Sync = *(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn Debug + Sync + 'static)` + = note: statics and constants must have a statically known size + +error[E0614]: type `()` cannot be dereferenced + --> $DIR/static-by-value-dyn.rs:8:37 + | +LL | static STATIC_1: dyn Debug + Sync = *(); + | ^^^ can't be dereferenced + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0277, E0614. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/mir/static-by-value-slice.rs b/tests/ui/mir/static-by-value-slice.rs new file mode 100644 index 0000000000000..d4165781eae5d --- /dev/null +++ b/tests/ui/mir/static-by-value-slice.rs @@ -0,0 +1,13 @@ +//! Regression test for #140332 +//! KnownPanicsLint used to assert ABI compatibility in the interpreter, +//! which ICEs with unsized statics. + +static mut S: [i8] = ["Some thing"; 1]; +//~^ ERROR the size for values of type `[i8]` cannot be known +//~| ERROR mismatched types +//~| ERROR mismatched types + +fn main() { + assert_eq!(S, [0; 1]); + //~^ ERROR use of mutable static is unsafe +} diff --git a/tests/ui/mir/static-by-value-slice.stderr b/tests/ui/mir/static-by-value-slice.stderr new file mode 100644 index 0000000000000..c5c760b4fe507 --- /dev/null +++ b/tests/ui/mir/static-by-value-slice.stderr @@ -0,0 +1,33 @@ +error[E0277]: the size for values of type `[i8]` cannot be known at compilation time + --> $DIR/static-by-value-slice.rs:5:1 + | +LL | static mut S: [i8] = ["Some thing"; 1]; + | ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[i8]` + = note: statics and constants must have a statically known size + +error[E0308]: mismatched types + --> $DIR/static-by-value-slice.rs:5:23 + | +LL | static mut S: [i8] = ["Some thing"; 1]; + | ^^^^^^^^^^^^ expected `i8`, found `&str` + +error[E0308]: mismatched types + --> $DIR/static-by-value-slice.rs:5:22 + | +LL | static mut S: [i8] = ["Some thing"; 1]; + | ^^^^^^^^^^^^^^^^^ expected `[i8]`, found `[i8; 1]` + +error[E0133]: use of mutable static is unsafe and requires unsafe function or block + --> $DIR/static-by-value-slice.rs:11:16 + | +LL | assert_eq!(S, [0; 1]); + | ^ use of mutable static + | + = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0133, E0277, E0308. +For more information about an error, try `rustc --explain E0133`. diff --git a/tests/ui/mir/static-by-value-str.rs b/tests/ui/mir/static-by-value-str.rs new file mode 100644 index 0000000000000..07de2a5e65c99 --- /dev/null +++ b/tests/ui/mir/static-by-value-str.rs @@ -0,0 +1,17 @@ +//! Regression test for #139872 +//! KnownPanicsLint used to assert ABI compatibility in the interpreter, +//! which ICEs with unsized statics. + +enum E { + V16(u16), + V32(u32), +} + +static C: (E, u16, str) = (E::V16(0xDEAD), 0x600D, 0xBAD); +//~^ ERROR the size for values of type `str` cannot be known +//~| ERROR the size for values of type `str` cannot be known +//~| ERROR mismatched types + +pub fn main() { + let (_, n, _) = C; +} diff --git a/tests/ui/mir/static-by-value-str.stderr b/tests/ui/mir/static-by-value-str.stderr new file mode 100644 index 0000000000000..6988c7d8857ab --- /dev/null +++ b/tests/ui/mir/static-by-value-str.stderr @@ -0,0 +1,30 @@ +error[E0277]: the size for values of type `str` cannot be known at compilation time + --> $DIR/static-by-value-str.rs:10:1 + | +LL | static C: (E, u16, str) = (E::V16(0xDEAD), 0x600D, 0xBAD); + | ^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: within `(E, u16, str)`, the trait `Sized` is not implemented for `str` + = note: required because it appears within the type `(E, u16, str)` + = note: statics and constants must have a statically known size + +error[E0308]: mismatched types + --> $DIR/static-by-value-str.rs:10:52 + | +LL | static C: (E, u16, str) = (E::V16(0xDEAD), 0x600D, 0xBAD); + | ^^^^^ expected `str`, found integer + +error[E0277]: the size for values of type `str` cannot be known at compilation time + --> $DIR/static-by-value-str.rs:10:27 + | +LL | static C: (E, u16, str) = (E::V16(0xDEAD), 0x600D, 0xBAD); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: within `(E, u16, str)`, the trait `Sized` is not implemented for `str` + = note: required because it appears within the type `(E, u16, str)` + = note: tuples must have a statically known size to be initialized + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. From 832207862a2e74ec51879b072fd0dd2599395b91 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 20 Jul 2025 21:27:41 +0000 Subject: [PATCH 4/9] Check static is sized when building MIR. --- .../rustc_const_eval/src/interpret/operand.rs | 11 ----- .../rustc_const_eval/src/interpret/place.rs | 8 ---- .../src/builder/custom/parse/instruction.rs | 4 +- .../src/builder/expr/as_constant.rs | 42 +++++++++++-------- .../src/known_panics_lint.rs | 4 +- tests/crashes/129109.rs | 10 ----- tests/crashes/130970.rs | 9 ---- tests/crashes/131347.rs | 9 ---- tests/ui/mir/unsized-extern-static.rs | 13 ++++++ tests/ui/mir/unsized-extern-static.stderr | 20 +++++++++ 10 files changed, 62 insertions(+), 68 deletions(-) delete mode 100644 tests/crashes/129109.rs delete mode 100644 tests/crashes/130970.rs delete mode 100644 tests/crashes/131347.rs create mode 100644 tests/ui/mir/unsized-extern-static.rs create mode 100644 tests/ui/mir/unsized-extern-static.stderr diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index 2c779489272a3..21afd082a0551 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -243,17 +243,6 @@ impl<'tcx, Prov: Provenance> std::ops::Deref for ImmTy<'tcx, Prov> { } impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> { - #[inline(always)] - pub fn try_from_immediate(imm: Immediate, layout: TyAndLayout<'tcx>) -> Option { - let matches_abi = match (imm, layout.backend_repr) { - (Immediate::Scalar(..), BackendRepr::Scalar(..)) => true, - (Immediate::ScalarPair(..), BackendRepr::ScalarPair(..)) => true, - (Immediate::Uninit, _) => layout.is_sized(), - _ => false, - }; - if matches_abi { Some(ImmTy { imm, layout }) } else { None } - } - #[inline] pub fn from_scalar(val: Scalar, layout: TyAndLayout<'tcx>) -> Self { debug_assert!(layout.backend_repr.is_scalar(), "`ImmTy::from_scalar` on non-scalar layout"); diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index a8cfe276b49f9..e2284729efdcf 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -313,14 +313,6 @@ impl<'tcx, Prov: Provenance> Projectable<'tcx, Prov> for PlaceTy<'tcx, Prov> { // These are defined here because they produce a place. impl<'tcx, Prov: Provenance> OpTy<'tcx, Prov> { - #[inline(always)] - pub fn try_as_immediate(&self) -> Option> { - match self.op() { - Operand::Indirect(_) => None, - Operand::Immediate(imm) => ImmTy::try_from_immediate(*imm, self.layout), - } - } - #[inline(always)] pub fn as_mplace_or_imm(&self) -> Either, ImmTy<'tcx, Prov>> { match self.op() { diff --git a/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs index 9825b947fe09a..ddb405acec74d 100644 --- a/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs +++ b/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs @@ -309,7 +309,7 @@ impl<'a, 'tcx> ParseCtxt<'a, 'tcx> { | ExprKind::ConstParam { .. } | ExprKind::ConstBlock { .. } => { Ok(Operand::Constant(Box::new( - as_constant_inner(expr, |_| None, self.tcx) + as_constant_inner(self.tcx, self.typing_env, expr, |_| None) ))) }, _ => self.parse_place(expr_id).map(Operand::Copy), @@ -393,7 +393,7 @@ impl<'a, 'tcx> ParseCtxt<'a, 'tcx> { | ExprKind::NamedConst { .. } | ExprKind::NonHirLiteral { .. } | ExprKind::ConstBlock { .. } => Ok({ - let value = as_constant_inner(expr, |_| None, self.tcx); + let value = as_constant_inner(self.tcx, self.typing_env, expr, |_| None); value.const_.eval_bits(self.tcx, self.typing_env) }), ) diff --git a/compiler/rustc_mir_build/src/builder/expr/as_constant.rs b/compiler/rustc_mir_build/src/builder/expr/as_constant.rs index 0e0c7a7fa4f0b..5eb324f4b51eb 100644 --- a/compiler/rustc_mir_build/src/builder/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/builder/expr/as_constant.rs @@ -8,7 +8,7 @@ use rustc_middle::mir::*; use rustc_middle::thir::*; use rustc_middle::ty::{ self, CanonicalUserType, CanonicalUserTypeAnnotation, Ty, TyCtxt, TypeVisitableExt as _, - UserTypeAnnotationIndex, + TypingEnv, UserTypeAnnotationIndex, }; use rustc_middle::{bug, mir, span_bug}; use tracing::{instrument, trace}; @@ -19,32 +19,27 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// Compile `expr`, yielding a compile-time constant. Assumes that /// `expr` is a valid compile-time constant! pub(crate) fn as_constant(&mut self, expr: &Expr<'tcx>) -> ConstOperand<'tcx> { - let this = self; - let tcx = this.tcx; let Expr { ty, temp_lifetime: _, span, ref kind } = *expr; match kind { ExprKind::Scope { region_scope: _, lint_level: _, value } => { - this.as_constant(&this.thir[*value]) + self.as_constant(&self.thir[*value]) } - _ => as_constant_inner( - expr, - |user_ty| { - Some(this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation { - span, - user_ty: user_ty.clone(), - inferred_ty: ty, - })) - }, - tcx, - ), + _ => as_constant_inner(self.tcx, self.typing_env(), expr, |user_ty| { + Some(self.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation { + span, + user_ty: user_ty.clone(), + inferred_ty: ty, + })) + }), } } } pub(crate) fn as_constant_inner<'tcx>( + tcx: TyCtxt<'tcx>, + typing_env: TypingEnv<'tcx>, expr: &Expr<'tcx>, push_cuta: impl FnMut(&Box>) -> Option, - tcx: TyCtxt<'tcx>, ) -> ConstOperand<'tcx> { let Expr { ty, temp_lifetime: _, span, ref kind } = *expr; match *kind { @@ -88,8 +83,19 @@ pub(crate) fn as_constant_inner<'tcx>( ConstOperand { user_ty: None, span, const_ } } ExprKind::StaticRef { alloc_id, ty, .. } => { - let const_val = ConstValue::Scalar(Scalar::from_pointer(alloc_id.into(), &tcx)); - let const_ = Const::Val(const_val, ty); + let pointee = ty.builtin_deref(true).expect("StaticRef's type must be pointer"); + let const_ = if pointee.is_sized(tcx, typing_env) { + let const_val = ConstValue::Scalar(Scalar::from_pointer(alloc_id.into(), &tcx)); + Const::Val(const_val, ty) + } else { + // Ill-formed code may produce instances where `pointee` is not `Sized`. + // This should be reported by wfcheck on the static itself. + // Still, producing a single scalar constant would be inconsistent, as pointers to + // non-`Sized` types are scalar pairs. Avoid an ICE by producing an error constant. + let guar = + tcx.dcx().span_delayed_bug(span, format!("static's type `{ty}` is not Sized")); + Const::Ty(ty, ty::Const::new_error(tcx, guar)) + }; ConstOperand { span, user_ty: None, const_ } } diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs index cebbc40492300..481c794190925 100644 --- a/compiler/rustc_mir_transform/src/known_panics_lint.rs +++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs @@ -263,7 +263,9 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { // manually normalized. let val = self.tcx.try_normalize_erasing_regions(self.typing_env, c.const_).ok()?; - self.use_ecx(|this| this.ecx.eval_mir_constant(&val, c.span, None))?.try_as_immediate() + self.use_ecx(|this| this.ecx.eval_mir_constant(&val, c.span, None))? + .as_mplace_or_imm() + .right() } /// Returns the value, if any, of evaluating `place`. diff --git a/tests/crashes/129109.rs b/tests/crashes/129109.rs deleted file mode 100644 index 0db53b98a7112..0000000000000 --- a/tests/crashes/129109.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ known-bug: rust-lang/rust#129109 -//@ compile-flags: -Zmir-enable-passes=+GVN -Zvalidate-mir - -extern "C" { - pub static mut symbol: [i8]; -} - -fn main() { - println!("C", unsafe { &symbol }); -} diff --git a/tests/crashes/130970.rs b/tests/crashes/130970.rs deleted file mode 100644 index 698c2b478e157..0000000000000 --- a/tests/crashes/130970.rs +++ /dev/null @@ -1,9 +0,0 @@ -//@ known-bug: #130970 -//@ compile-flags: -Zmir-enable-passes=+GVN -Zvalidate-mir - -fn main() { - extern "C" { - static symbol: [usize]; - } - println!("{}", symbol[0]); -} diff --git a/tests/crashes/131347.rs b/tests/crashes/131347.rs deleted file mode 100644 index 08f7d068e25af..0000000000000 --- a/tests/crashes/131347.rs +++ /dev/null @@ -1,9 +0,0 @@ -//@ known-bug: #131347 -//@ compile-flags: -Zmir-enable-passes=+GVN -Zmir-enable-passes=+Inline -Zvalidate-mir - -struct S; -static STUFF: [i8] = [0; S::N]; - -fn main() { - assert_eq!(STUFF, [0; 63]); -} diff --git a/tests/ui/mir/unsized-extern-static.rs b/tests/ui/mir/unsized-extern-static.rs new file mode 100644 index 0000000000000..386842556ba03 --- /dev/null +++ b/tests/ui/mir/unsized-extern-static.rs @@ -0,0 +1,13 @@ +//! Regression test for #129109 +//! MIR building used to produce erroneous constants when referring to statics of unsized type. +//@ compile-flags: -Zmir-enable-passes=+GVN -Zvalidate-mir + +extern "C" { + pub static mut symbol: [i8]; + //~^ ERROR the size for values of type `[i8]` +} + +fn main() { + println!("C", unsafe { &symbol }); + //~^ ERROR argument never used +} diff --git a/tests/ui/mir/unsized-extern-static.stderr b/tests/ui/mir/unsized-extern-static.stderr new file mode 100644 index 0000000000000..93aed3549d762 --- /dev/null +++ b/tests/ui/mir/unsized-extern-static.stderr @@ -0,0 +1,20 @@ +error: argument never used + --> $DIR/unsized-extern-static.rs:11:19 + | +LL | println!("C", unsafe { &symbol }); + | --- ^^^^^^^^^^^^^^^^^^ argument never used + | | + | formatting specifier missing + +error[E0277]: the size for values of type `[i8]` cannot be known at compilation time + --> $DIR/unsized-extern-static.rs:6:5 + | +LL | pub static mut symbol: [i8]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[i8]` + = note: statics and constants must have a statically known size + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. From 948c7952b8ea6052d0c753e962061e7201c331a7 Mon Sep 17 00:00:00 2001 From: Tobias Decking Date: Fri, 25 Jul 2025 17:56:10 +0200 Subject: [PATCH 5/9] Unify LLVM ctlz/cttz intrinsic generation --- compiler/rustc_codegen_llvm/src/intrinsic.rs | 28 +++++++------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index fcc0d378f0686..7b27e496986ae 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -382,26 +382,16 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { let width = size.bits(); let llty = self.type_ix(width); match name { - sym::ctlz | sym::cttz => { - let y = self.const_bool(false); - let ret = self.call_intrinsic( - format!("llvm.{name}"), - &[llty], - &[args[0].immediate(), y], - ); - - self.intcast(ret, result.layout.llvm_type(self), false) - } - sym::ctlz_nonzero => { - let y = self.const_bool(true); - let ret = - self.call_intrinsic("llvm.ctlz", &[llty], &[args[0].immediate(), y]); - self.intcast(ret, result.layout.llvm_type(self), false) - } - sym::cttz_nonzero => { - let y = self.const_bool(true); + sym::ctlz | sym::ctlz_nonzero | sym::cttz | sym::cttz_nonzero => { + let y = + self.const_bool(name == sym::ctlz_nonzero || name == sym::cttz_nonzero); + let llvm_name = if name == sym::ctlz || name == sym::ctlz_nonzero { + "llvm.ctlz" + } else { + "llvm.cttz" + }; let ret = - self.call_intrinsic("llvm.cttz", &[llty], &[args[0].immediate(), y]); + self.call_intrinsic(llvm_name, &[llty], &[args[0].immediate(), y]); self.intcast(ret, result.layout.llvm_type(self), false) } sym::ctpop => { From ec8146477e90337517b3483b84738eb5dfe53770 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Mon, 21 Jul 2025 00:11:42 +0000 Subject: [PATCH 6/9] Look at layout for completeness. --- .../src/builder/expr/as_constant.rs | 14 +++-- tests/ui/coroutine/layout-error.rs | 2 + tests/ui/coroutine/layout-error.stderr | 52 +++++++++++++++++-- 3 files changed, 60 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_mir_build/src/builder/expr/as_constant.rs b/compiler/rustc_mir_build/src/builder/expr/as_constant.rs index 5eb324f4b51eb..92935dfc97a2f 100644 --- a/compiler/rustc_mir_build/src/builder/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/builder/expr/as_constant.rs @@ -1,6 +1,6 @@ //! See docs in build/expr/mod.rs -use rustc_abi::Size; +use rustc_abi::{BackendRepr, Size}; use rustc_ast as ast; use rustc_hir::LangItem; use rustc_middle::mir::interpret::{CTFE_ALLOC_SALT, LitToConstInput, Scalar}; @@ -83,8 +83,10 @@ pub(crate) fn as_constant_inner<'tcx>( ConstOperand { user_ty: None, span, const_ } } ExprKind::StaticRef { alloc_id, ty, .. } => { - let pointee = ty.builtin_deref(true).expect("StaticRef's type must be pointer"); - let const_ = if pointee.is_sized(tcx, typing_env) { + let layout = tcx.layout_of(typing_env.as_query_input(ty)); + let const_ = if let Ok(layout) = layout + && let BackendRepr::Scalar(..) = layout.backend_repr + { let const_val = ConstValue::Scalar(Scalar::from_pointer(alloc_id.into(), &tcx)); Const::Val(const_val, ty) } else { @@ -92,8 +94,10 @@ pub(crate) fn as_constant_inner<'tcx>( // This should be reported by wfcheck on the static itself. // Still, producing a single scalar constant would be inconsistent, as pointers to // non-`Sized` types are scalar pairs. Avoid an ICE by producing an error constant. - let guar = - tcx.dcx().span_delayed_bug(span, format!("static's type `{ty}` is not Sized")); + let guar = tcx.dcx().span_delayed_bug( + span, + format!("pointer to static's type `{ty}` is not scalar"), + ); Const::Ty(ty, ty::Const::new_error(tcx, guar)) }; diff --git a/tests/ui/coroutine/layout-error.rs b/tests/ui/coroutine/layout-error.rs index 6cf32134025ca..2ee0bd8161948 100644 --- a/tests/ui/coroutine/layout-error.rs +++ b/tests/ui/coroutine/layout-error.rs @@ -17,6 +17,8 @@ impl Task { } pub type F = impl Future; +//~^ ERROR cycle detected when computing type of `F::{opaque#0}` + #[define_opaque(F)] fn foo() where diff --git a/tests/ui/coroutine/layout-error.stderr b/tests/ui/coroutine/layout-error.stderr index 91e352164357d..057ac36b849d9 100644 --- a/tests/ui/coroutine/layout-error.stderr +++ b/tests/ui/coroutine/layout-error.stderr @@ -1,9 +1,55 @@ error[E0425]: cannot find value `Foo` in this scope - --> $DIR/layout-error.rs:26:17 + --> $DIR/layout-error.rs:28:17 | LL | let a = Foo; | ^^^ not found in this scope -error: aborting due to 1 previous error +error[E0391]: cycle detected when computing type of `F::{opaque#0}` + --> $DIR/layout-error.rs:19:14 + | +LL | pub type F = impl Future; + | ^^^^^^^^^^^ + | +note: ...which requires computing type of opaque `F::{opaque#0}`... + --> $DIR/layout-error.rs:19:14 + | +LL | pub type F = impl Future; + | ^^^^^^^^^^^ +note: ...which requires borrow-checking `foo`... + --> $DIR/layout-error.rs:23:1 + | +LL | / fn foo() +LL | | where +LL | | F:, + | |_______^ +note: ...which requires promoting constants in MIR for `foo`... + --> $DIR/layout-error.rs:23:1 + | +LL | / fn foo() +LL | | where +LL | | F:, + | |_______^ +note: ...which requires checking if `foo` contains FFI-unwind calls... + --> $DIR/layout-error.rs:23:1 + | +LL | / fn foo() +LL | | where +LL | | F:, + | |_______^ +note: ...which requires building MIR for `foo`... + --> $DIR/layout-error.rs:23:1 + | +LL | / fn foo() +LL | | where +LL | | F:, + | |_______^ + = note: ...which requires computing layout of `&Task`... + = note: ...which requires normalizing `&Task`... + = note: ...which again requires computing type of `F::{opaque#0}`, completing the cycle + = note: cycle used when normalizing `Task` + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0425`. +Some errors have detailed explanations: E0391, E0425. +For more information about an error, try `rustc --explain E0391`. From 7c6496145f86133655a941e0dafd5dfa368514d4 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 25 Jul 2025 23:07:20 +0000 Subject: [PATCH 7/9] Check statics' type in type_of. --- .../rustc_hir_analysis/src/check/check.rs | 1 - .../rustc_hir_analysis/src/check/wfcheck.rs | 6 +- .../rustc_hir_analysis/src/collect/type_of.rs | 19 ++- .../src/builder/custom/parse/instruction.rs | 4 +- .../src/builder/expr/as_constant.rs | 48 +++----- tests/ui/consts/const-unsized.rs | 4 - tests/ui/consts/const-unsized.stderr | 32 +---- tests/ui/coroutine/layout-error.rs | 3 +- tests/ui/coroutine/layout-error.stderr | 70 ++++++++--- .../metadata-sufficient-for-layout.rs | 2 +- .../metadata-sufficient-for-layout.stderr | 38 ++++++ .../ui/dyn-compatibility/taint-const-eval.rs | 1 - .../dyn-compatibility/taint-const-eval.stderr | 26 +--- .../issue-36122-accessing-externed-dst.rs | 1 - .../issue-36122-accessing-externed-dst.stderr | 13 +- tests/ui/issues/issue-7364.rs | 1 - tests/ui/issues/issue-7364.stderr | 14 +-- tests/ui/layout/issue-84108.rs | 2 - tests/ui/layout/issue-84108.stderr | 21 +--- tests/ui/mir/static-by-value-slice.rs | 3 - tests/ui/mir/static-by-value-slice.stderr | 25 +--- tests/ui/mir/static-by-value-str.rs | 2 - tests/ui/mir/static-by-value-str.stderr | 21 +--- tests/ui/static/issue-24446.rs | 1 - tests/ui/static/issue-24446.stderr | 17 +-- .../bound/on-structs-and-enums-static.rs | 4 +- .../bound/on-structs-and-enums-static.stderr | 26 +--- .../type-alias-impl-trait-const.rs | 5 +- .../type-alias-impl-trait-const.stderr | 113 ++++++++++++++++++ tests/ui/wf/wf-static-type.rs | 2 - tests/ui/wf/wf-static-type.stderr | 39 +----- 31 files changed, 276 insertions(+), 288 deletions(-) create mode 100644 tests/ui/coroutine/metadata-sufficient-for-layout.stderr create mode 100644 tests/ui/type-alias-impl-trait/type-alias-impl-trait-const.stderr diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 03c026cd6c892..07ca64e61445a 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -767,7 +767,6 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), DefKind::Static { .. } => { check_static_inhabited(tcx, def_id); check_static_linkage(tcx, def_id); - res = res.and(wfcheck::check_static_item(tcx, def_id)); } DefKind::Const => res = res.and(wfcheck::check_const_item(tcx, def_id)), _ => unreachable!(), diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 14ec82ede1c5f..e8d962467b372 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1180,12 +1180,12 @@ fn check_item_fn( } #[instrument(level = "debug", skip(tcx))] -pub(super) fn check_static_item( - tcx: TyCtxt<'_>, +pub(crate) fn check_static_item<'tcx>( + tcx: TyCtxt<'tcx>, item_id: LocalDefId, + ty: Ty<'tcx>, ) -> Result<(), ErrorGuaranteed> { enter_wf_checking_ctxt(tcx, item_id, |wfcx| { - let ty = tcx.type_of(item_id).instantiate_identity(); let span = tcx.ty_span(item_id); let item_ty = wfcx.deeply_normalize(span, Some(WellFormedLoc::Ty(item_id)), ty); diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 902a2e15dffde..f84bd2a5fb3ef 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -14,6 +14,7 @@ use rustc_middle::{bug, span_bug}; use rustc_span::{DUMMY_SP, Ident, Span}; use super::{HirPlaceholderCollector, ItemCtxt, bad_placeholder}; +use crate::check::wfcheck::check_static_item; use crate::errors::TypeofReservedKeywordUsed; use crate::hir_ty_lowering::HirTyLowerer; @@ -217,7 +218,13 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ "static variable", ) } else { - icx.lower_ty(ty) + let ty = icx.lower_ty(ty); + // MIR relies on references to statics being scalars. + // Verify that here to avoid ill-formed MIR. + match check_static_item(tcx, def_id, ty) { + Ok(()) => ty, + Err(guar) => Ty::new_error(tcx, guar), + } } } ItemKind::Const(ident, _, ty, body_id) => { @@ -275,7 +282,15 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ let args = ty::GenericArgs::identity_for_item(tcx, def_id); Ty::new_fn_def(tcx, def_id.to_def_id(), args) } - ForeignItemKind::Static(t, _, _) => icx.lower_ty(t), + ForeignItemKind::Static(ty, _, _) => { + let ty = icx.lower_ty(ty); + // MIR relies on references to statics being scalars. + // Verify that here to avoid ill-formed MIR. + match check_static_item(tcx, def_id, ty) { + Ok(()) => ty, + Err(guar) => Ty::new_error(tcx, guar), + } + } ForeignItemKind::Type => Ty::new_foreign(tcx, def_id.to_def_id()), }, diff --git a/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs index ddb405acec74d..9825b947fe09a 100644 --- a/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs +++ b/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs @@ -309,7 +309,7 @@ impl<'a, 'tcx> ParseCtxt<'a, 'tcx> { | ExprKind::ConstParam { .. } | ExprKind::ConstBlock { .. } => { Ok(Operand::Constant(Box::new( - as_constant_inner(self.tcx, self.typing_env, expr, |_| None) + as_constant_inner(expr, |_| None, self.tcx) ))) }, _ => self.parse_place(expr_id).map(Operand::Copy), @@ -393,7 +393,7 @@ impl<'a, 'tcx> ParseCtxt<'a, 'tcx> { | ExprKind::NamedConst { .. } | ExprKind::NonHirLiteral { .. } | ExprKind::ConstBlock { .. } => Ok({ - let value = as_constant_inner(self.tcx, self.typing_env, expr, |_| None); + let value = as_constant_inner(expr, |_| None, self.tcx); value.const_.eval_bits(self.tcx, self.typing_env) }), ) diff --git a/compiler/rustc_mir_build/src/builder/expr/as_constant.rs b/compiler/rustc_mir_build/src/builder/expr/as_constant.rs index 92935dfc97a2f..0e0c7a7fa4f0b 100644 --- a/compiler/rustc_mir_build/src/builder/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/builder/expr/as_constant.rs @@ -1,6 +1,6 @@ //! See docs in build/expr/mod.rs -use rustc_abi::{BackendRepr, Size}; +use rustc_abi::Size; use rustc_ast as ast; use rustc_hir::LangItem; use rustc_middle::mir::interpret::{CTFE_ALLOC_SALT, LitToConstInput, Scalar}; @@ -8,7 +8,7 @@ use rustc_middle::mir::*; use rustc_middle::thir::*; use rustc_middle::ty::{ self, CanonicalUserType, CanonicalUserTypeAnnotation, Ty, TyCtxt, TypeVisitableExt as _, - TypingEnv, UserTypeAnnotationIndex, + UserTypeAnnotationIndex, }; use rustc_middle::{bug, mir, span_bug}; use tracing::{instrument, trace}; @@ -19,27 +19,32 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// Compile `expr`, yielding a compile-time constant. Assumes that /// `expr` is a valid compile-time constant! pub(crate) fn as_constant(&mut self, expr: &Expr<'tcx>) -> ConstOperand<'tcx> { + let this = self; + let tcx = this.tcx; let Expr { ty, temp_lifetime: _, span, ref kind } = *expr; match kind { ExprKind::Scope { region_scope: _, lint_level: _, value } => { - self.as_constant(&self.thir[*value]) + this.as_constant(&this.thir[*value]) } - _ => as_constant_inner(self.tcx, self.typing_env(), expr, |user_ty| { - Some(self.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation { - span, - user_ty: user_ty.clone(), - inferred_ty: ty, - })) - }), + _ => as_constant_inner( + expr, + |user_ty| { + Some(this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation { + span, + user_ty: user_ty.clone(), + inferred_ty: ty, + })) + }, + tcx, + ), } } } pub(crate) fn as_constant_inner<'tcx>( - tcx: TyCtxt<'tcx>, - typing_env: TypingEnv<'tcx>, expr: &Expr<'tcx>, push_cuta: impl FnMut(&Box>) -> Option, + tcx: TyCtxt<'tcx>, ) -> ConstOperand<'tcx> { let Expr { ty, temp_lifetime: _, span, ref kind } = *expr; match *kind { @@ -83,23 +88,8 @@ pub(crate) fn as_constant_inner<'tcx>( ConstOperand { user_ty: None, span, const_ } } ExprKind::StaticRef { alloc_id, ty, .. } => { - let layout = tcx.layout_of(typing_env.as_query_input(ty)); - let const_ = if let Ok(layout) = layout - && let BackendRepr::Scalar(..) = layout.backend_repr - { - let const_val = ConstValue::Scalar(Scalar::from_pointer(alloc_id.into(), &tcx)); - Const::Val(const_val, ty) - } else { - // Ill-formed code may produce instances where `pointee` is not `Sized`. - // This should be reported by wfcheck on the static itself. - // Still, producing a single scalar constant would be inconsistent, as pointers to - // non-`Sized` types are scalar pairs. Avoid an ICE by producing an error constant. - let guar = tcx.dcx().span_delayed_bug( - span, - format!("pointer to static's type `{ty}` is not scalar"), - ); - Const::Ty(ty, ty::Const::new_error(tcx, guar)) - }; + let const_val = ConstValue::Scalar(Scalar::from_pointer(alloc_id.into(), &tcx)); + let const_ = Const::Val(const_val, ty); ConstOperand { span, user_ty: None, const_ } } diff --git a/tests/ui/consts/const-unsized.rs b/tests/ui/consts/const-unsized.rs index e8af3323cebfe..4140563fa40e8 100644 --- a/tests/ui/consts/const-unsized.rs +++ b/tests/ui/consts/const-unsized.rs @@ -10,14 +10,10 @@ const CONST_FOO: str = *"foo"; static STATIC_1: dyn Debug + Sync = *(&1 as &(dyn Debug + Sync)); //~^ ERROR the size for values of type -//~| ERROR cannot move out of a shared reference static STATIC_BAR: str = *"bar"; //~^ ERROR the size for values of type -//~| ERROR cannot move out of a shared reference fn main() { println!("{:?} {:?} {:?} {:?}", &CONST_0, &CONST_FOO, &STATIC_1, &STATIC_BAR); - //~^ ERROR: cannot move a value of type `str` - //~| ERROR: cannot move a value of type `dyn Debug + Sync` } diff --git a/tests/ui/consts/const-unsized.stderr b/tests/ui/consts/const-unsized.stderr index c92fbc17f9cd9..a37a6df71f83c 100644 --- a/tests/ui/consts/const-unsized.stderr +++ b/tests/ui/consts/const-unsized.stderr @@ -26,7 +26,7 @@ LL | static STATIC_1: dyn Debug + Sync = *(&1 as &(dyn Debug + Sync)); = note: statics and constants must have a statically known size error[E0277]: the size for values of type `str` cannot be known at compilation time - --> $DIR/const-unsized.rs:15:1 + --> $DIR/const-unsized.rs:14:1 | LL | static STATIC_BAR: str = *"bar"; | ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -46,31 +46,7 @@ error[E0507]: cannot move out of a shared reference LL | const CONST_FOO: str = *"foo"; | ^^^^^^ move occurs because value has type `str`, which does not implement the `Copy` trait -error[E0507]: cannot move out of a shared reference - --> $DIR/const-unsized.rs:11:37 - | -LL | static STATIC_1: dyn Debug + Sync = *(&1 as &(dyn Debug + Sync)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ move occurs because value has type `dyn Debug + Sync`, which does not implement the `Copy` trait - -error[E0507]: cannot move out of a shared reference - --> $DIR/const-unsized.rs:15:26 - | -LL | static STATIC_BAR: str = *"bar"; - | ^^^^^^ move occurs because value has type `str`, which does not implement the `Copy` trait - -error[E0161]: cannot move a value of type `dyn Debug + Sync` - --> $DIR/const-unsized.rs:20:38 - | -LL | println!("{:?} {:?} {:?} {:?}", &CONST_0, &CONST_FOO, &STATIC_1, &STATIC_BAR); - | ^^^^^^^ the size of `dyn Debug + Sync` cannot be statically determined - -error[E0161]: cannot move a value of type `str` - --> $DIR/const-unsized.rs:20:48 - | -LL | println!("{:?} {:?} {:?} {:?}", &CONST_0, &CONST_FOO, &STATIC_1, &STATIC_BAR); - | ^^^^^^^^^ the size of `str` cannot be statically determined - -error: aborting due to 10 previous errors +error: aborting due to 6 previous errors -Some errors have detailed explanations: E0161, E0277, E0507. -For more information about an error, try `rustc --explain E0161`. +Some errors have detailed explanations: E0277, E0507. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/coroutine/layout-error.rs b/tests/ui/coroutine/layout-error.rs index 2ee0bd8161948..137c47490f60b 100644 --- a/tests/ui/coroutine/layout-error.rs +++ b/tests/ui/coroutine/layout-error.rs @@ -17,7 +17,6 @@ impl Task { } pub type F = impl Future; -//~^ ERROR cycle detected when computing type of `F::{opaque#0}` #[define_opaque(F)] fn foo() @@ -33,5 +32,7 @@ where // Check that statics are inhabited computes they layout. static POOL: Task = Task::new(); +//~^ ERROR cycle detected when computing type of `POOL` +//~| ERROR cycle detected when computing type of `POOL` fn main() {} diff --git a/tests/ui/coroutine/layout-error.stderr b/tests/ui/coroutine/layout-error.stderr index 057ac36b849d9..c0ededfd3fe07 100644 --- a/tests/ui/coroutine/layout-error.stderr +++ b/tests/ui/coroutine/layout-error.stderr @@ -1,55 +1,97 @@ error[E0425]: cannot find value `Foo` in this scope - --> $DIR/layout-error.rs:28:17 + --> $DIR/layout-error.rs:27:17 | LL | let a = Foo; | ^^^ not found in this scope -error[E0391]: cycle detected when computing type of `F::{opaque#0}` - --> $DIR/layout-error.rs:19:14 +error[E0391]: cycle detected when computing type of `POOL` + --> $DIR/layout-error.rs:34:14 | -LL | pub type F = impl Future; - | ^^^^^^^^^^^ +LL | static POOL: Task = Task::new(); + | ^^^^^^^ | + = note: ...which requires evaluating trait selection obligation `Task: core::marker::Sync`... note: ...which requires computing type of opaque `F::{opaque#0}`... --> $DIR/layout-error.rs:19:14 | LL | pub type F = impl Future; | ^^^^^^^^^^^ note: ...which requires borrow-checking `foo`... - --> $DIR/layout-error.rs:23:1 + --> $DIR/layout-error.rs:22:1 | LL | / fn foo() LL | | where LL | | F:, | |_______^ note: ...which requires promoting constants in MIR for `foo`... - --> $DIR/layout-error.rs:23:1 + --> $DIR/layout-error.rs:22:1 | LL | / fn foo() LL | | where LL | | F:, | |_______^ note: ...which requires checking if `foo` contains FFI-unwind calls... - --> $DIR/layout-error.rs:23:1 + --> $DIR/layout-error.rs:22:1 | LL | / fn foo() LL | | where LL | | F:, | |_______^ note: ...which requires building MIR for `foo`... - --> $DIR/layout-error.rs:23:1 + --> $DIR/layout-error.rs:22:1 + | +LL | / fn foo() +LL | | where +LL | | F:, + | |_______^ +note: ...which requires match-checking `foo`... + --> $DIR/layout-error.rs:22:1 + | +LL | / fn foo() +LL | | where +LL | | F:, + | |_______^ +note: ...which requires type-checking `foo`... + --> $DIR/layout-error.rs:22:1 | LL | / fn foo() LL | | where LL | | F:, | |_______^ - = note: ...which requires computing layout of `&Task`... - = note: ...which requires normalizing `&Task`... - = note: ...which again requires computing type of `F::{opaque#0}`, completing the cycle - = note: cycle used when normalizing `Task` + = note: ...which again requires computing type of `POOL`, completing the cycle +note: cycle used when checking that `POOL` is well-formed + --> $DIR/layout-error.rs:34:1 + | +LL | static POOL: Task = Task::new(); + | ^^^^^^^^^^^^^^^^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information + +error[E0391]: cycle detected when computing type of `POOL` + --> $DIR/layout-error.rs:34:14 + | +LL | static POOL: Task = Task::new(); + | ^^^^^^^ + | + = note: ...which requires evaluating trait selection obligation `Task: core::marker::Sync`... +note: ...which requires computing type of opaque `F::{opaque#0}`... + --> $DIR/layout-error.rs:19:14 + | +LL | pub type F = impl Future; + | ^^^^^^^^^^^ +note: ...which requires computing the opaque types defined by `POOL`... + --> $DIR/layout-error.rs:34:1 + | +LL | static POOL: Task = Task::new(); + | ^^^^^^^^^^^^^^^^^^^^ + = note: ...which again requires computing type of `POOL`, completing the cycle +note: cycle used when checking that `POOL` is well-formed + --> $DIR/layout-error.rs:34:1 + | +LL | static POOL: Task = Task::new(); + | ^^^^^^^^^^^^^^^^^^^^ = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0391, E0425. For more information about an error, try `rustc --explain E0391`. diff --git a/tests/ui/coroutine/metadata-sufficient-for-layout.rs b/tests/ui/coroutine/metadata-sufficient-for-layout.rs index b7d8575c76177..0c074029faa9a 100644 --- a/tests/ui/coroutine/metadata-sufficient-for-layout.rs +++ b/tests/ui/coroutine/metadata-sufficient-for-layout.rs @@ -4,7 +4,6 @@ // Regression test for #80998. // //@ aux-build:metadata-sufficient-for-layout.rs -//@ check-pass #![feature(type_alias_impl_trait, rustc_attrs)] #![feature(coroutine_trait)] @@ -23,5 +22,6 @@ mod helper { // Static queries the layout of the coroutine. static A: Option = None; +//~^ ERROR cycle detected when computing type of `A` fn main() {} diff --git a/tests/ui/coroutine/metadata-sufficient-for-layout.stderr b/tests/ui/coroutine/metadata-sufficient-for-layout.stderr new file mode 100644 index 0000000000000..94f90098510be --- /dev/null +++ b/tests/ui/coroutine/metadata-sufficient-for-layout.stderr @@ -0,0 +1,38 @@ +error[E0391]: cycle detected when computing type of `A` + --> $DIR/metadata-sufficient-for-layout.rs:24:11 + | +LL | static A: Option = None; + | ^^^^^^^^^^^^^^^^^ + | + = note: ...which requires evaluating trait selection obligation `core::option::Option: core::marker::Sync`... +note: ...which requires computing type of opaque `helper::F::{opaque#0}`... + --> $DIR/metadata-sufficient-for-layout.rs:15:18 + | +LL | pub type F = impl Coroutine<(), Yield = (), Return = ()>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires borrow-checking `helper::f`... + --> $DIR/metadata-sufficient-for-layout.rs:18:5 + | +LL | fn f() -> F { + | ^^^^^^^^^^^ +note: ...which requires computing type of opaque `helper::F::{opaque#0}` via HIR typeck... + --> $DIR/metadata-sufficient-for-layout.rs:15:18 + | +LL | pub type F = impl Coroutine<(), Yield = (), Return = ()>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires computing the opaque types defined by `A`... + --> $DIR/metadata-sufficient-for-layout.rs:24:1 + | +LL | static A: Option = None; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: ...which again requires computing type of `A`, completing the cycle +note: cycle used when checking that `A` is well-formed + --> $DIR/metadata-sufficient-for-layout.rs:24:1 + | +LL | static A: Option = None; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0391`. diff --git a/tests/ui/dyn-compatibility/taint-const-eval.rs b/tests/ui/dyn-compatibility/taint-const-eval.rs index a5c01e1791e74..3d1b3b8fe618e 100644 --- a/tests/ui/dyn-compatibility/taint-const-eval.rs +++ b/tests/ui/dyn-compatibility/taint-const-eval.rs @@ -6,6 +6,5 @@ trait Qux { static FOO: &(dyn Qux + Sync) = "desc"; //~^ ERROR the trait `Qux` is not dyn compatible -//~| ERROR the trait `Qux` is not dyn compatible fn main() {} diff --git a/tests/ui/dyn-compatibility/taint-const-eval.stderr b/tests/ui/dyn-compatibility/taint-const-eval.stderr index 585c1f012c785..e4be9870fdc44 100644 --- a/tests/ui/dyn-compatibility/taint-const-eval.stderr +++ b/tests/ui/dyn-compatibility/taint-const-eval.stderr @@ -21,30 +21,6 @@ help: alternatively, consider constraining `bar` so it does not apply to trait o LL | fn bar() where Self: Sized; | +++++++++++++++++ -error[E0038]: the trait `Qux` is not dyn compatible - --> $DIR/taint-const-eval.rs:7:15 - | -LL | static FOO: &(dyn Qux + Sync) = "desc"; - | ^^^^^^^^^^^^^^ `Qux` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/taint-const-eval.rs:4:8 - | -LL | trait Qux { - | --- this trait is not dyn compatible... -LL | fn bar(); - | ^^^ ...because associated function `bar` has no `self` parameter - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: consider turning `bar` into a method by giving it a `&self` argument - | -LL | fn bar(&self); - | +++++ -help: alternatively, consider constraining `bar` so it does not apply to trait objects - | -LL | fn bar() where Self: Sized; - | +++++++++++++++++ - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/extern/issue-36122-accessing-externed-dst.rs b/tests/ui/extern/issue-36122-accessing-externed-dst.rs index 9fb7780e3d769..5f886ff57379a 100644 --- a/tests/ui/extern/issue-36122-accessing-externed-dst.rs +++ b/tests/ui/extern/issue-36122-accessing-externed-dst.rs @@ -3,5 +3,4 @@ fn main() { static symbol: [usize]; //~ ERROR: the size for values of type } println!("{}", symbol[0]); - //~^ ERROR: extern static is unsafe } diff --git a/tests/ui/extern/issue-36122-accessing-externed-dst.stderr b/tests/ui/extern/issue-36122-accessing-externed-dst.stderr index 8007c3f13e5bc..c617cf4e61bdf 100644 --- a/tests/ui/extern/issue-36122-accessing-externed-dst.stderr +++ b/tests/ui/extern/issue-36122-accessing-externed-dst.stderr @@ -7,15 +7,6 @@ LL | static symbol: [usize]; = help: the trait `Sized` is not implemented for `[usize]` = note: statics and constants must have a statically known size -error[E0133]: use of extern static is unsafe and requires unsafe function or block - --> $DIR/issue-36122-accessing-externed-dst.rs:5:20 - | -LL | println!("{}", symbol[0]); - | ^^^^^^ use of extern static - | - = note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0133, E0277. -For more information about an error, try `rustc --explain E0133`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/issues/issue-7364.rs b/tests/ui/issues/issue-7364.rs index 4ce9beb68cd3f..79642bd411b38 100644 --- a/tests/ui/issues/issue-7364.rs +++ b/tests/ui/issues/issue-7364.rs @@ -3,6 +3,5 @@ use std::cell::RefCell; // Regression test for issue 7364 static boxed: Box> = Box::new(RefCell::new(0)); //~^ ERROR `RefCell` cannot be shared between threads safely [E0277] -//~| ERROR cannot call non-const associated function fn main() { } diff --git a/tests/ui/issues/issue-7364.stderr b/tests/ui/issues/issue-7364.stderr index a47a90c90ce16..7371e2105de8d 100644 --- a/tests/ui/issues/issue-7364.stderr +++ b/tests/ui/issues/issue-7364.stderr @@ -11,16 +11,6 @@ note: required because it appears within the type `Box>` --> $SRC_DIR/alloc/src/boxed.rs:LL:COL = note: shared static variables must have a type that implements `Sync` -error[E0015]: cannot call non-const associated function `Box::>::new` in statics - --> $DIR/issue-7364.rs:4:37 - | -LL | static boxed: Box> = Box::new(RefCell::new(0)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0015, E0277. -For more information about an error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/layout/issue-84108.rs b/tests/ui/layout/issue-84108.rs index 974d5310f6bb8..33884617acbf8 100644 --- a/tests/ui/layout/issue-84108.rs +++ b/tests/ui/layout/issue-84108.rs @@ -14,5 +14,3 @@ const BAR: (&Path, [u8], usize) = ("hello", [], 42); static BAZ: ([u8], usize) = ([], 0); //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time -//~| ERROR the size for values of type `[u8]` cannot be known at compilation time -//~| ERROR mismatched types diff --git a/tests/ui/layout/issue-84108.stderr b/tests/ui/layout/issue-84108.stderr index e296abfc3b53b..62a6ae341fa6e 100644 --- a/tests/ui/layout/issue-84108.stderr +++ b/tests/ui/layout/issue-84108.stderr @@ -57,26 +57,7 @@ LL | const BAR: (&Path, [u8], usize) = ("hello", [], 42); = note: expected slice `[u8]` found array `[_; 0]` -error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/issue-84108.rs:15:13 - | -LL | static BAZ: ([u8], usize) = ([], 0); - | ^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `[u8]` - = note: only the last element of a tuple may have a dynamically sized type - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0308]: mismatched types - --> $DIR/issue-84108.rs:15:30 - | -LL | static BAZ: ([u8], usize) = ([], 0); - | ^^ expected `[u8]`, found `[_; 0]` - | - = note: expected slice `[u8]` - found array `[_; 0]` - -error: aborting due to 8 previous errors +error: aborting due to 6 previous errors Some errors have detailed explanations: E0277, E0308, E0412. For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/mir/static-by-value-slice.rs b/tests/ui/mir/static-by-value-slice.rs index d4165781eae5d..af98be6a74d6c 100644 --- a/tests/ui/mir/static-by-value-slice.rs +++ b/tests/ui/mir/static-by-value-slice.rs @@ -4,10 +4,7 @@ static mut S: [i8] = ["Some thing"; 1]; //~^ ERROR the size for values of type `[i8]` cannot be known -//~| ERROR mismatched types -//~| ERROR mismatched types fn main() { assert_eq!(S, [0; 1]); - //~^ ERROR use of mutable static is unsafe } diff --git a/tests/ui/mir/static-by-value-slice.stderr b/tests/ui/mir/static-by-value-slice.stderr index c5c760b4fe507..2d0592943d0b7 100644 --- a/tests/ui/mir/static-by-value-slice.stderr +++ b/tests/ui/mir/static-by-value-slice.stderr @@ -7,27 +7,6 @@ LL | static mut S: [i8] = ["Some thing"; 1]; = help: the trait `Sized` is not implemented for `[i8]` = note: statics and constants must have a statically known size -error[E0308]: mismatched types - --> $DIR/static-by-value-slice.rs:5:23 - | -LL | static mut S: [i8] = ["Some thing"; 1]; - | ^^^^^^^^^^^^ expected `i8`, found `&str` - -error[E0308]: mismatched types - --> $DIR/static-by-value-slice.rs:5:22 - | -LL | static mut S: [i8] = ["Some thing"; 1]; - | ^^^^^^^^^^^^^^^^^ expected `[i8]`, found `[i8; 1]` - -error[E0133]: use of mutable static is unsafe and requires unsafe function or block - --> $DIR/static-by-value-slice.rs:11:16 - | -LL | assert_eq!(S, [0; 1]); - | ^ use of mutable static - | - = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior - -error: aborting due to 4 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0133, E0277, E0308. -For more information about an error, try `rustc --explain E0133`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/mir/static-by-value-str.rs b/tests/ui/mir/static-by-value-str.rs index 07de2a5e65c99..88b72f9081909 100644 --- a/tests/ui/mir/static-by-value-str.rs +++ b/tests/ui/mir/static-by-value-str.rs @@ -9,8 +9,6 @@ enum E { static C: (E, u16, str) = (E::V16(0xDEAD), 0x600D, 0xBAD); //~^ ERROR the size for values of type `str` cannot be known -//~| ERROR the size for values of type `str` cannot be known -//~| ERROR mismatched types pub fn main() { let (_, n, _) = C; diff --git a/tests/ui/mir/static-by-value-str.stderr b/tests/ui/mir/static-by-value-str.stderr index 6988c7d8857ab..6e046e0055130 100644 --- a/tests/ui/mir/static-by-value-str.stderr +++ b/tests/ui/mir/static-by-value-str.stderr @@ -8,23 +8,6 @@ LL | static C: (E, u16, str) = (E::V16(0xDEAD), 0x600D, 0xBAD); = note: required because it appears within the type `(E, u16, str)` = note: statics and constants must have a statically known size -error[E0308]: mismatched types - --> $DIR/static-by-value-str.rs:10:52 - | -LL | static C: (E, u16, str) = (E::V16(0xDEAD), 0x600D, 0xBAD); - | ^^^^^ expected `str`, found integer - -error[E0277]: the size for values of type `str` cannot be known at compilation time - --> $DIR/static-by-value-str.rs:10:27 - | -LL | static C: (E, u16, str) = (E::V16(0xDEAD), 0x600D, 0xBAD); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: within `(E, u16, str)`, the trait `Sized` is not implemented for `str` - = note: required because it appears within the type `(E, u16, str)` - = note: tuples must have a statically known size to be initialized - -error: aborting due to 3 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0277, E0308. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/static/issue-24446.rs b/tests/ui/static/issue-24446.rs index 830e373c189d7..9ab952ade9cf4 100644 --- a/tests/ui/static/issue-24446.rs +++ b/tests/ui/static/issue-24446.rs @@ -2,7 +2,6 @@ fn main() { static foo: dyn Fn() -> u32 = || -> u32 { //~^ ERROR the size for values of type //~| ERROR cannot be shared between threads safely - //~| ERROR mismatched types 0 }; } diff --git a/tests/ui/static/issue-24446.stderr b/tests/ui/static/issue-24446.stderr index ed195634f12cf..359952dcf663f 100644 --- a/tests/ui/static/issue-24446.stderr +++ b/tests/ui/static/issue-24446.stderr @@ -16,19 +16,6 @@ LL | static foo: dyn Fn() -> u32 = || -> u32 { = help: the trait `Sized` is not implemented for `(dyn Fn() -> u32 + 'static)` = note: statics and constants must have a statically known size -error[E0308]: mismatched types - --> $DIR/issue-24446.rs:2:35 - | -LL | static foo: dyn Fn() -> u32 = || -> u32 { - | ___________________________________^ -... | -LL | | }; - | |_____^ expected `dyn Fn`, found closure - | - = note: expected trait object `(dyn Fn() -> u32 + 'static)` - found closure `{closure@$DIR/issue-24446.rs:2:35: 2:44}` - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0277, E0308. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/bound/on-structs-and-enums-static.rs b/tests/ui/traits/bound/on-structs-and-enums-static.rs index d734893dd7c96..61e8e2ace607e 100644 --- a/tests/ui/traits/bound/on-structs-and-enums-static.rs +++ b/tests/ui/traits/bound/on-structs-and-enums-static.rs @@ -6,9 +6,7 @@ struct Foo { x: T, } -static X: Foo = Foo { -//~^ ERROR E0277 -//~| ERROR E0277 +static X: Foo = Foo { //~ ERROR E0277 x: 1, //~ ERROR: E0277 }; diff --git a/tests/ui/traits/bound/on-structs-and-enums-static.stderr b/tests/ui/traits/bound/on-structs-and-enums-static.stderr index 42ebcc07571f1..1413422794a75 100644 --- a/tests/ui/traits/bound/on-structs-and-enums-static.stderr +++ b/tests/ui/traits/bound/on-structs-and-enums-static.stderr @@ -15,29 +15,11 @@ note: required by a bound in `Foo` LL | struct Foo { | ^^^^^ required by this bound in `Foo` -error[E0277]: the trait bound `usize: Trait` is not satisfied - --> $DIR/on-structs-and-enums-static.rs:9:11 - | -LL | static X: Foo = Foo { - | ^^^^^^^^^^ the trait `Trait` is not implemented for `usize` - | -help: this trait has no implementations, consider adding one - --> $DIR/on-structs-and-enums-static.rs:1:1 - | -LL | trait Trait { - | ^^^^^^^^^^^ -note: required by a bound in `Foo` - --> $DIR/on-structs-and-enums-static.rs:5:14 - | -LL | struct Foo { - | ^^^^^ required by this bound in `Foo` - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0277]: the trait bound `usize: Trait` is not satisfied - --> $DIR/on-structs-and-enums-static.rs:12:8 +error[E0277]: the trait bound `{integer}: Trait` is not satisfied + --> $DIR/on-structs-and-enums-static.rs:10:8 | LL | x: 1, - | ^ the trait `Trait` is not implemented for `usize` + | ^ the trait `Trait` is not implemented for `{integer}` | help: this trait has no implementations, consider adding one --> $DIR/on-structs-and-enums-static.rs:1:1 @@ -50,6 +32,6 @@ note: required by a bound in `Foo` LL | struct Foo { | ^^^^^ required by this bound in `Foo` -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs index e21627e14b098..bfe30f3706f1d 100644 --- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs +++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs @@ -1,5 +1,3 @@ -//@ check-pass - #![feature(type_alias_impl_trait)] use std::fmt::Debug; @@ -11,5 +9,8 @@ const _FOO: Foo = 5; #[define_opaque(Foo)] static _BAR: Foo = 22_i32; +//~^ ERROR cycle detected when computing type of `_BAR` +//~| ERROR cycle detected when computing type of `_BAR` +//~| ERROR cycle detected when computing type of `_BAR` fn main() {} diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-const.stderr b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-const.stderr new file mode 100644 index 0000000000000..6537f0f35a3bb --- /dev/null +++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-const.stderr @@ -0,0 +1,113 @@ +error[E0391]: cycle detected when computing type of `_BAR` + --> $DIR/type-alias-impl-trait-const.rs:11:14 + | +LL | static _BAR: Foo = 22_i32; + | ^^^ + | + = note: ...which requires evaluating trait selection obligation `Foo: core::marker::Sync`... +note: ...which requires computing type of opaque `Foo::{opaque#0}`... + --> $DIR/type-alias-impl-trait-const.rs:5:16 + | +LL | pub type Foo = impl Debug; + | ^^^^^^^^^^ +note: ...which requires borrow-checking `_FOO`... + --> $DIR/type-alias-impl-trait-const.rs:8:1 + | +LL | const _FOO: Foo = 5; + | ^^^^^^^^^^^^^^^ +note: ...which requires computing type of opaque `Foo::{opaque#0}` via HIR typeck... + --> $DIR/type-alias-impl-trait-const.rs:5:16 + | +LL | pub type Foo = impl Debug; + | ^^^^^^^^^^ +note: ...which requires computing the opaque types defined by `_BAR`... + --> $DIR/type-alias-impl-trait-const.rs:11:1 + | +LL | static _BAR: Foo = 22_i32; + | ^^^^^^^^^^^^^^^^ + = note: ...which again requires computing type of `_BAR`, completing the cycle +note: cycle used when checking that `_BAR` is well-formed + --> $DIR/type-alias-impl-trait-const.rs:11:1 + | +LL | static _BAR: Foo = 22_i32; + | ^^^^^^^^^^^^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information + +error[E0391]: cycle detected when computing type of `_BAR` + --> $DIR/type-alias-impl-trait-const.rs:11:14 + | +LL | static _BAR: Foo = 22_i32; + | ^^^ + | + = note: ...which requires evaluating trait selection obligation `Foo: core::marker::Sync`... +note: ...which requires computing type of opaque `Foo::{opaque#0}`... + --> $DIR/type-alias-impl-trait-const.rs:5:16 + | +LL | pub type Foo = impl Debug; + | ^^^^^^^^^^ +note: ...which requires borrow-checking `_FOO`... + --> $DIR/type-alias-impl-trait-const.rs:8:1 + | +LL | const _FOO: Foo = 5; + | ^^^^^^^^^^^^^^^ +note: ...which requires computing type of opaque `Foo::{opaque#0}` via HIR typeck... + --> $DIR/type-alias-impl-trait-const.rs:5:16 + | +LL | pub type Foo = impl Debug; + | ^^^^^^^^^^ +note: ...which requires type-checking `_BAR`... + --> $DIR/type-alias-impl-trait-const.rs:11:1 + | +LL | static _BAR: Foo = 22_i32; + | ^^^^^^^^^^^^^^^^ + = note: ...which again requires computing type of `_BAR`, completing the cycle +note: cycle used when checking that `_BAR` is well-formed + --> $DIR/type-alias-impl-trait-const.rs:11:1 + | +LL | static _BAR: Foo = 22_i32; + | ^^^^^^^^^^^^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information + +error[E0391]: cycle detected when computing type of `_BAR` + --> $DIR/type-alias-impl-trait-const.rs:11:14 + | +LL | static _BAR: Foo = 22_i32; + | ^^^ + | + = note: ...which requires evaluating trait selection obligation `Foo: core::marker::Sync`... +note: ...which requires computing type of opaque `Foo::{opaque#0}`... + --> $DIR/type-alias-impl-trait-const.rs:5:16 + | +LL | pub type Foo = impl Debug; + | ^^^^^^^^^^ +note: ...which requires borrow-checking `_BAR`... + --> $DIR/type-alias-impl-trait-const.rs:11:1 + | +LL | static _BAR: Foo = 22_i32; + | ^^^^^^^^^^^^^^^^ +note: ...which requires promoting constants in MIR for `_BAR`... + --> $DIR/type-alias-impl-trait-const.rs:11:1 + | +LL | static _BAR: Foo = 22_i32; + | ^^^^^^^^^^^^^^^^ +note: ...which requires const checking `_BAR`... + --> $DIR/type-alias-impl-trait-const.rs:11:1 + | +LL | static _BAR: Foo = 22_i32; + | ^^^^^^^^^^^^^^^^ +note: ...which requires building MIR for `_BAR`... + --> $DIR/type-alias-impl-trait-const.rs:11:1 + | +LL | static _BAR: Foo = 22_i32; + | ^^^^^^^^^^^^^^^^ + = note: ...which again requires computing type of `_BAR`, completing the cycle +note: cycle used when checking that `_BAR` is well-formed + --> $DIR/type-alias-impl-trait-const.rs:11:1 + | +LL | static _BAR: Foo = 22_i32; + | ^^^^^^^^^^^^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0391`. diff --git a/tests/ui/wf/wf-static-type.rs b/tests/ui/wf/wf-static-type.rs index 1980c5de40c80..1c35e1daf4499 100644 --- a/tests/ui/wf/wf-static-type.rs +++ b/tests/ui/wf/wf-static-type.rs @@ -9,8 +9,6 @@ struct NotCopy; static FOO: IsCopy> = IsCopy { t: None }; //~^ ERROR E0277 -//~| ERROR E0277 -//~| ERROR E0277 fn main() { } diff --git a/tests/ui/wf/wf-static-type.stderr b/tests/ui/wf/wf-static-type.stderr index 53b90c69960b7..2fa8ae06c459b 100644 --- a/tests/ui/wf/wf-static-type.stderr +++ b/tests/ui/wf/wf-static-type.stderr @@ -16,43 +16,6 @@ LL + #[derive(Copy)] LL | struct NotCopy; | -error[E0277]: the trait bound `NotCopy: Copy` is not satisfied - --> $DIR/wf-static-type.rs:10:13 - | -LL | static FOO: IsCopy> = IsCopy { t: None }; - | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `NotCopy` - | - = note: required for `Option` to implement `Copy` -note: required by a bound in `IsCopy` - --> $DIR/wf-static-type.rs:7:17 - | -LL | struct IsCopy { t: T } - | ^^^^ required by this bound in `IsCopy` - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: consider annotating `NotCopy` with `#[derive(Copy)]` - | -LL + #[derive(Copy)] -LL | struct NotCopy; - | - -error[E0277]: the trait bound `NotCopy: Copy` is not satisfied - --> $DIR/wf-static-type.rs:10:51 - | -LL | static FOO: IsCopy> = IsCopy { t: None }; - | ^^^^ the trait `Copy` is not implemented for `NotCopy` - | - = note: required for `Option` to implement `Copy` -note: required by a bound in `IsCopy` - --> $DIR/wf-static-type.rs:7:17 - | -LL | struct IsCopy { t: T } - | ^^^^ required by this bound in `IsCopy` -help: consider annotating `NotCopy` with `#[derive(Copy)]` - | -LL + #[derive(Copy)] -LL | struct NotCopy; - | - -error: aborting due to 3 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0277`. From bd7b023a6b8f7507ddc933060464a6f48fde3488 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Fri, 25 Jul 2025 17:06:57 +0200 Subject: [PATCH 8/9] move uefi test to run-make --- .../host-x86_64/test-various/Dockerfile | 5 +- .../test-various/uefi_qemu_test/run.py | 140 ------------------ src/tools/compiletest/src/directives.rs | 1 + src/tools/tidy/src/deps.rs | 2 +- tests/run-make/uefi-qemu/rmake.rs | 84 +++++++++++ .../uefi-qemu}/uefi_qemu_test/Cargo.lock | 0 .../uefi-qemu}/uefi_qemu_test/Cargo.toml | 0 .../uefi-qemu}/uefi_qemu_test/src/main.rs | 9 +- 8 files changed, 90 insertions(+), 151 deletions(-) delete mode 100755 src/ci/docker/host-x86_64/test-various/uefi_qemu_test/run.py create mode 100644 tests/run-make/uefi-qemu/rmake.rs rename {src/ci/docker/host-x86_64/test-various => tests/run-make/uefi-qemu}/uefi_qemu_test/Cargo.lock (100%) rename {src/ci/docker/host-x86_64/test-various => tests/run-make/uefi-qemu}/uefi_qemu_test/Cargo.toml (100%) rename {src/ci/docker/host-x86_64/test-various => tests/run-make/uefi-qemu}/uefi_qemu_test/src/main.rs (68%) diff --git a/src/ci/docker/host-x86_64/test-various/Dockerfile b/src/ci/docker/host-x86_64/test-various/Dockerfile index 4d09bea69c08d..662a26400ce9d 100644 --- a/src/ci/docker/host-x86_64/test-various/Dockerfile +++ b/src/ci/docker/host-x86_64/test-various/Dockerfile @@ -79,7 +79,6 @@ ENV MUSL_TARGETS=x86_64-unknown-linux-musl \ CXX_x86_64_unknown_linux_musl=x86_64-linux-musl-g++ ENV MUSL_SCRIPT python3 /checkout/x.py --stage 2 test --host='' --target $MUSL_TARGETS -COPY host-x86_64/test-various/uefi_qemu_test /uefi_qemu_test ENV UEFI_TARGETS=aarch64-unknown-uefi,i686-unknown-uefi,x86_64-unknown-uefi \ CC_aarch64_unknown_uefi=clang-11 \ CXX_aarch64_unknown_uefi=clang++-11 \ @@ -88,6 +87,8 @@ ENV UEFI_TARGETS=aarch64-unknown-uefi,i686-unknown-uefi,x86_64-unknown-uefi \ CC_x86_64_unknown_uefi=clang-11 \ CXX_x86_64_unknown_uefi=clang++-11 ENV UEFI_SCRIPT python3 /checkout/x.py --stage 2 build --host='' --target $UEFI_TARGETS && \ - python3 -u /uefi_qemu_test/run.py + python3 /checkout/x.py --stage 2 test tests/run-make/uefi-qemu/rmake.rs --target aarch64-unknown-uefi && \ + python3 /checkout/x.py --stage 2 test tests/run-make/uefi-qemu/rmake.rs --target i686-unknown-uefi && \ + python3 /checkout/x.py --stage 2 test tests/run-make/uefi-qemu/rmake.rs --target x86_64-unknown-uefi ENV SCRIPT $WASM_SCRIPT && $NVPTX_SCRIPT && $MUSL_SCRIPT && $UEFI_SCRIPT diff --git a/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/run.py b/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/run.py deleted file mode 100755 index 4f877389fbcfe..0000000000000 --- a/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/run.py +++ /dev/null @@ -1,140 +0,0 @@ -#!/usr/bin/env python3 - -import os -import shutil -import subprocess -import sys -import tempfile - -from pathlib import Path - -TARGET_AARCH64 = "aarch64-unknown-uefi" -TARGET_I686 = "i686-unknown-uefi" -TARGET_X86_64 = "x86_64-unknown-uefi" - - -def run(*cmd, capture=False, check=True, env=None, timeout=None): - """Print and run a command, optionally capturing the output.""" - cmd = [str(p) for p in cmd] - print(" ".join(cmd)) - return subprocess.run( - cmd, capture_output=capture, check=check, env=env, text=True, timeout=timeout - ) - - -def build_and_run(tmp_dir, target): - if target == TARGET_AARCH64: - boot_file_name = "bootaa64.efi" - ovmf_dir = Path("/usr/share/AAVMF") - ovmf_code = "AAVMF_CODE.fd" - ovmf_vars = "AAVMF_VARS.fd" - qemu = "qemu-system-aarch64" - machine = "virt" - cpu = "cortex-a72" - elif target == TARGET_I686: - boot_file_name = "bootia32.efi" - ovmf_dir = Path("/usr/share/OVMF") - ovmf_code = "OVMF32_CODE_4M.secboot.fd" - ovmf_vars = "OVMF32_VARS_4M.fd" - # The i686 target intentionally uses 64-bit qemu; the important - # difference is that the OVMF code provides a 32-bit environment. - qemu = "qemu-system-x86_64" - machine = "q35" - cpu = "qemu64" - elif target == TARGET_X86_64: - boot_file_name = "bootx64.efi" - ovmf_dir = Path("/usr/share/OVMF") - ovmf_code = "OVMF_CODE.fd" - ovmf_vars = "OVMF_VARS.fd" - qemu = "qemu-system-x86_64" - machine = "q35" - cpu = "qemu64" - else: - raise KeyError("invalid target") - - host_artifacts = Path("/checkout/obj/build/x86_64-unknown-linux-gnu") - stage0 = host_artifacts / "stage0/bin" - stage2 = host_artifacts / "stage2/bin" - - env = dict(os.environ) - env["PATH"] = "{}:{}:{}".format(stage2, stage0, env["PATH"]) - - # Copy the test create into `tmp_dir`. - test_crate = Path(tmp_dir) / "uefi_qemu_test" - shutil.copytree("/uefi_qemu_test", test_crate) - - # Build the UEFI executable. - run( - "cargo", - "build", - "--manifest-path", - test_crate / "Cargo.toml", - "--target", - target, - env=env, - ) - - # Create a mock EFI System Partition in a subdirectory. - esp = test_crate / "esp" - boot = esp / "efi/boot" - os.makedirs(boot, exist_ok=True) - - # Copy the executable into the ESP. - src_exe_path = test_crate / "target" / target / "debug/uefi_qemu_test.efi" - shutil.copy(src_exe_path, boot / boot_file_name) - print(src_exe_path, boot / boot_file_name) - - # Select the appropriate EDK2 build. - ovmf_code = ovmf_dir / ovmf_code - ovmf_vars = ovmf_dir / ovmf_vars - - # Make a writable copy of the vars file. aarch64 doesn't boot - # correctly with read-only vars. - ovmf_rw_vars = Path(tmp_dir) / "vars.fd" - shutil.copy(ovmf_vars, ovmf_rw_vars) - - # Run the executable in QEMU and capture the output. - output = run( - qemu, - "-machine", - machine, - "-cpu", - cpu, - "-display", - "none", - "-serial", - "stdio", - "-drive", - f"if=pflash,format=raw,readonly=on,file={ovmf_code}", - "-drive", - f"if=pflash,format=raw,readonly=off,file={ovmf_rw_vars}", - "-drive", - f"format=raw,file=fat:rw:{esp}", - capture=True, - check=True, - # Set a timeout to kill the VM in case something goes wrong. - timeout=60, - ).stdout - - if "Hello World!" in output: - print("VM produced expected output") - else: - print("unexpected VM output:") - print("---start---") - print(output) - print("---end---") - sys.exit(1) - - -def main(): - targets = [TARGET_AARCH64, TARGET_I686, TARGET_X86_64] - - for target in targets: - # Create a temporary directory so that we have a writeable - # workspace. - with tempfile.TemporaryDirectory() as tmp_dir: - build_and_run(tmp_dir, target) - - -if __name__ == "__main__": - main() diff --git a/src/tools/compiletest/src/directives.rs b/src/tools/compiletest/src/directives.rs index 1397c87ab075b..584f08f2c1806 100644 --- a/src/tools/compiletest/src/directives.rs +++ b/src/tools/compiletest/src/directives.rs @@ -991,6 +991,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "only-stable", "only-thumb", "only-tvos", + "only-uefi", "only-unix", "only-visionos", "only-wasm32", diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index d17ae162ab235..2373d403d0637 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -73,7 +73,6 @@ pub(crate) const WORKSPACES: &[(&str, ExceptionList, Option<(&[&str], &[&str])>, // tidy-alphabetical-start ("compiler/rustc_codegen_gcc", EXCEPTIONS_GCC, None, &[]), ("src/bootstrap", EXCEPTIONS_BOOTSTRAP, None, &[]), - ("src/ci/docker/host-x86_64/test-various/uefi_qemu_test", EXCEPTIONS_UEFI_QEMU_TEST, None, &[]), ("src/tools/cargo", EXCEPTIONS_CARGO, None, &["src/tools/cargo"]), //("src/tools/miri/test-cargo-miri", &[], None), // FIXME uncomment once all deps are vendored //("src/tools/miri/test_dependencies", &[], None), // FIXME uncomment once all deps are vendored @@ -81,6 +80,7 @@ pub(crate) const WORKSPACES: &[(&str, ExceptionList, Option<(&[&str], &[&str])>, ("src/tools/rustbook", EXCEPTIONS_RUSTBOOK, None, &["src/doc/book", "src/doc/reference"]), ("src/tools/rustc-perf", EXCEPTIONS_RUSTC_PERF, None, &["src/tools/rustc-perf"]), ("src/tools/test-float-parse", EXCEPTIONS, None, &[]), + ("tests/run-make/uefi-qemu/uefi_qemu_test", EXCEPTIONS_UEFI_QEMU_TEST, None, &[]), // tidy-alphabetical-end ]; diff --git a/tests/run-make/uefi-qemu/rmake.rs b/tests/run-make/uefi-qemu/rmake.rs new file mode 100644 index 0000000000000..55d42fba5e7ec --- /dev/null +++ b/tests/run-make/uefi-qemu/rmake.rs @@ -0,0 +1,84 @@ +//! This test builds and runs a basic UEFI application on QEMU for various targets. +//! +//! You must have the relevant OVMF or AAVMF firmware installed for this to work. +//! +//! Requires: qemu-system-x86_64, qemu-system-aarch64 +//! OVMF/AAVMF firmware +//! +//! Note: test assumes `/uefi_qemu_test` exists and is a self-contained crate. + +//@ only-uefi + +use std::path::Path; + +use run_make_support::{cargo, cmd, path, rfs}; + +fn main() { + let target = run_make_support::target(); + + let (boot_filename, ovmf_dir, ovmf_code_name, ovmf_vars_name, qemu, machine, cpu) = + match target.as_str() { + "aarch64-unknown-uefi" => ( + "bootaa64.efi", + Path::new("/usr/share/AAVMF"), + "AAVMF_CODE.fd", + "AAVMF_VARS.fd", + "qemu-system-aarch64", + "virt", + "cortex-a72", + ), + "i686-unknown-uefi" => ( + "bootia32.efi", + Path::new("/usr/share/OVMF"), + "OVMF32_CODE_4M.secboot.fd", + "OVMF32_VARS_4M.fd", + "qemu-system-x86_64", + "q35", + "qemu64", + ), + "x86_64-unknown-uefi" => ( + "bootx64.efi", + Path::new("/usr/share/OVMF"), + "OVMF_CODE_4M.fd", + "OVMF_VARS_4M.fd", + "qemu-system-x86_64", + "q35", + "qemu64", + ), + _ => panic!("unsupported target {target}"), + }; + + let tmp = std::env::temp_dir(); + let test_crate = tmp.join("uefi_qemu_test"); + rfs::copy_dir_all(path("uefi_qemu_test"), &test_crate); + + cargo().args(&["build", "--target", &target]).current_dir(&test_crate).run(); + + // Prepare ESP + let esp = test_crate.join("esp"); + let boot = esp.join("efi/boot"); + rfs::create_dir_all(&boot); + + let src_efi = test_crate.join("target").join(&target).join("debug/uefi_qemu_test.efi"); + let dst_efi = boot.join(boot_filename); + rfs::copy(&src_efi, &dst_efi); + + // Copy OVMF files + let code = ovmf_dir.join(ovmf_code_name); + let vars_src = ovmf_dir.join(ovmf_vars_name); + let vars_dst = tmp.join("vars.fd"); + rfs::copy(&vars_src, &vars_dst); + + let output = cmd(qemu) + .args(["-machine", machine]) + .args(["-cpu", cpu]) + .args(["-display", "none"]) + .args(["-serial", "stdio"]) + .args(["-drive", &format!("if=pflash,format=raw,readonly=on,file={}", code.display())]) + .args(["-drive", &format!("if=pflash,format=raw,readonly=off,file={}", vars_dst.display())]) + .args(["-drive", &format!("format=raw,file=fat:rw:{}", esp.display())]) + .run() + .stdout_utf8(); + + assert!(output.contains("Hello World!"), "invalid output for {target}:\n{output}"); +} diff --git a/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/Cargo.lock b/tests/run-make/uefi-qemu/uefi_qemu_test/Cargo.lock similarity index 100% rename from src/ci/docker/host-x86_64/test-various/uefi_qemu_test/Cargo.lock rename to tests/run-make/uefi-qemu/uefi_qemu_test/Cargo.lock diff --git a/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/Cargo.toml b/tests/run-make/uefi-qemu/uefi_qemu_test/Cargo.toml similarity index 100% rename from src/ci/docker/host-x86_64/test-various/uefi_qemu_test/Cargo.toml rename to tests/run-make/uefi-qemu/uefi_qemu_test/Cargo.toml diff --git a/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/src/main.rs b/tests/run-make/uefi-qemu/uefi_qemu_test/src/main.rs similarity index 68% rename from src/ci/docker/host-x86_64/test-various/uefi_qemu_test/src/main.rs rename to tests/run-make/uefi-qemu/uefi_qemu_test/src/main.rs index 89e4393cb5c7b..f8e1212a9f6d2 100644 --- a/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/src/main.rs +++ b/tests/run-make/uefi-qemu/uefi_qemu_test/src/main.rs @@ -15,14 +15,7 @@ fn panic_handler(_info: &panic::PanicInfo) -> ! { #[export_name = "efi_main"] pub extern "C" fn main(_h: Handle, st: *mut SystemTable) -> Status { - let s = [ - 0x0048u16, 0x0065u16, 0x006cu16, 0x006cu16, 0x006fu16, // "Hello" - 0x0020u16, // " " - 0x0057u16, 0x006fu16, 0x0072u16, 0x006cu16, 0x0064u16, // "World" - 0x0021u16, // "!" - 0x000au16, // "\n" - 0x0000u16, // NUL - ]; + let s = b"Hello World!\n\0".map(|c| u16::from(c)); // Print "Hello World!". let r = unsafe { ((*(*st).con_out).output_string)((*st).con_out, s.as_ptr() as *mut Char16) }; From 8817572b4595df352e6a7fdd56422fb07cd28d89 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sat, 26 Jul 2025 21:46:20 +0000 Subject: [PATCH 9/9] Do not check Sync during type_of. --- .../rustc_hir_analysis/src/check/check.rs | 2 + .../rustc_hir_analysis/src/check/wfcheck.rs | 5 +- .../rustc_hir_analysis/src/collect/type_of.rs | 4 +- tests/ui/coroutine/layout-error.rs | 2 - tests/ui/coroutine/layout-error.stderr | 92 +------------- .../metadata-sufficient-for-layout.rs | 2 +- .../metadata-sufficient-for-layout.stderr | 38 ------ tests/ui/issues/issue-7364.rs | 1 + tests/ui/issues/issue-7364.stderr | 14 ++- tests/ui/static/issue-24446.rs | 1 - tests/ui/static/issue-24446.stderr | 11 +- .../type-alias-impl-trait-const.rs | 5 +- .../type-alias-impl-trait-const.stderr | 113 ------------------ 13 files changed, 26 insertions(+), 264 deletions(-) delete mode 100644 tests/ui/coroutine/metadata-sufficient-for-layout.stderr delete mode 100644 tests/ui/type-alias-impl-trait/type-alias-impl-trait-const.stderr diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 07ca64e61445a..f2be2a6571667 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -767,6 +767,8 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), DefKind::Static { .. } => { check_static_inhabited(tcx, def_id); check_static_linkage(tcx, def_id); + let ty = tcx.type_of(def_id).instantiate_identity(); + res = res.and(wfcheck::check_static_item(tcx, def_id, ty, true)); } DefKind::Const => res = res.and(wfcheck::check_const_item(tcx, def_id)), _ => unreachable!(), diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index e8d962467b372..a62efed13bc79 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1184,6 +1184,7 @@ pub(crate) fn check_static_item<'tcx>( tcx: TyCtxt<'tcx>, item_id: LocalDefId, ty: Ty<'tcx>, + should_check_for_sync: bool, ) -> Result<(), ErrorGuaranteed> { enter_wf_checking_ctxt(tcx, item_id, |wfcx| { let span = tcx.ty_span(item_id); @@ -1212,9 +1213,9 @@ pub(crate) fn check_static_item<'tcx>( } // Ensure that the end result is `Sync` in a non-thread local `static`. - let should_check_for_sync = tcx.static_mutability(item_id.to_def_id()) - == Some(hir::Mutability::Not) + let should_check_for_sync = should_check_for_sync && !is_foreign_item + && tcx.static_mutability(item_id.to_def_id()) == Some(hir::Mutability::Not) && !tcx.is_thread_local_static(item_id.to_def_id()); if should_check_for_sync { diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index f84bd2a5fb3ef..68a91212e504c 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -221,7 +221,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ let ty = icx.lower_ty(ty); // MIR relies on references to statics being scalars. // Verify that here to avoid ill-formed MIR. - match check_static_item(tcx, def_id, ty) { + match check_static_item(tcx, def_id, ty, false) { Ok(()) => ty, Err(guar) => Ty::new_error(tcx, guar), } @@ -286,7 +286,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ let ty = icx.lower_ty(ty); // MIR relies on references to statics being scalars. // Verify that here to avoid ill-formed MIR. - match check_static_item(tcx, def_id, ty) { + match check_static_item(tcx, def_id, ty, false) { Ok(()) => ty, Err(guar) => Ty::new_error(tcx, guar), } diff --git a/tests/ui/coroutine/layout-error.rs b/tests/ui/coroutine/layout-error.rs index 137c47490f60b..7f6714542c1bc 100644 --- a/tests/ui/coroutine/layout-error.rs +++ b/tests/ui/coroutine/layout-error.rs @@ -32,7 +32,5 @@ where // Check that statics are inhabited computes they layout. static POOL: Task = Task::new(); -//~^ ERROR cycle detected when computing type of `POOL` -//~| ERROR cycle detected when computing type of `POOL` fn main() {} diff --git a/tests/ui/coroutine/layout-error.stderr b/tests/ui/coroutine/layout-error.stderr index c0ededfd3fe07..f3b3843de898c 100644 --- a/tests/ui/coroutine/layout-error.stderr +++ b/tests/ui/coroutine/layout-error.stderr @@ -4,94 +4,6 @@ error[E0425]: cannot find value `Foo` in this scope LL | let a = Foo; | ^^^ not found in this scope -error[E0391]: cycle detected when computing type of `POOL` - --> $DIR/layout-error.rs:34:14 - | -LL | static POOL: Task = Task::new(); - | ^^^^^^^ - | - = note: ...which requires evaluating trait selection obligation `Task: core::marker::Sync`... -note: ...which requires computing type of opaque `F::{opaque#0}`... - --> $DIR/layout-error.rs:19:14 - | -LL | pub type F = impl Future; - | ^^^^^^^^^^^ -note: ...which requires borrow-checking `foo`... - --> $DIR/layout-error.rs:22:1 - | -LL | / fn foo() -LL | | where -LL | | F:, - | |_______^ -note: ...which requires promoting constants in MIR for `foo`... - --> $DIR/layout-error.rs:22:1 - | -LL | / fn foo() -LL | | where -LL | | F:, - | |_______^ -note: ...which requires checking if `foo` contains FFI-unwind calls... - --> $DIR/layout-error.rs:22:1 - | -LL | / fn foo() -LL | | where -LL | | F:, - | |_______^ -note: ...which requires building MIR for `foo`... - --> $DIR/layout-error.rs:22:1 - | -LL | / fn foo() -LL | | where -LL | | F:, - | |_______^ -note: ...which requires match-checking `foo`... - --> $DIR/layout-error.rs:22:1 - | -LL | / fn foo() -LL | | where -LL | | F:, - | |_______^ -note: ...which requires type-checking `foo`... - --> $DIR/layout-error.rs:22:1 - | -LL | / fn foo() -LL | | where -LL | | F:, - | |_______^ - = note: ...which again requires computing type of `POOL`, completing the cycle -note: cycle used when checking that `POOL` is well-formed - --> $DIR/layout-error.rs:34:1 - | -LL | static POOL: Task = Task::new(); - | ^^^^^^^^^^^^^^^^^^^^ - = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information - -error[E0391]: cycle detected when computing type of `POOL` - --> $DIR/layout-error.rs:34:14 - | -LL | static POOL: Task = Task::new(); - | ^^^^^^^ - | - = note: ...which requires evaluating trait selection obligation `Task: core::marker::Sync`... -note: ...which requires computing type of opaque `F::{opaque#0}`... - --> $DIR/layout-error.rs:19:14 - | -LL | pub type F = impl Future; - | ^^^^^^^^^^^ -note: ...which requires computing the opaque types defined by `POOL`... - --> $DIR/layout-error.rs:34:1 - | -LL | static POOL: Task = Task::new(); - | ^^^^^^^^^^^^^^^^^^^^ - = note: ...which again requires computing type of `POOL`, completing the cycle -note: cycle used when checking that `POOL` is well-formed - --> $DIR/layout-error.rs:34:1 - | -LL | static POOL: Task = Task::new(); - | ^^^^^^^^^^^^^^^^^^^^ - = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information - -error: aborting due to 3 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0391, E0425. -For more information about an error, try `rustc --explain E0391`. +For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/coroutine/metadata-sufficient-for-layout.rs b/tests/ui/coroutine/metadata-sufficient-for-layout.rs index 0c074029faa9a..b7d8575c76177 100644 --- a/tests/ui/coroutine/metadata-sufficient-for-layout.rs +++ b/tests/ui/coroutine/metadata-sufficient-for-layout.rs @@ -4,6 +4,7 @@ // Regression test for #80998. // //@ aux-build:metadata-sufficient-for-layout.rs +//@ check-pass #![feature(type_alias_impl_trait, rustc_attrs)] #![feature(coroutine_trait)] @@ -22,6 +23,5 @@ mod helper { // Static queries the layout of the coroutine. static A: Option = None; -//~^ ERROR cycle detected when computing type of `A` fn main() {} diff --git a/tests/ui/coroutine/metadata-sufficient-for-layout.stderr b/tests/ui/coroutine/metadata-sufficient-for-layout.stderr deleted file mode 100644 index 94f90098510be..0000000000000 --- a/tests/ui/coroutine/metadata-sufficient-for-layout.stderr +++ /dev/null @@ -1,38 +0,0 @@ -error[E0391]: cycle detected when computing type of `A` - --> $DIR/metadata-sufficient-for-layout.rs:24:11 - | -LL | static A: Option = None; - | ^^^^^^^^^^^^^^^^^ - | - = note: ...which requires evaluating trait selection obligation `core::option::Option: core::marker::Sync`... -note: ...which requires computing type of opaque `helper::F::{opaque#0}`... - --> $DIR/metadata-sufficient-for-layout.rs:15:18 - | -LL | pub type F = impl Coroutine<(), Yield = (), Return = ()>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires borrow-checking `helper::f`... - --> $DIR/metadata-sufficient-for-layout.rs:18:5 - | -LL | fn f() -> F { - | ^^^^^^^^^^^ -note: ...which requires computing type of opaque `helper::F::{opaque#0}` via HIR typeck... - --> $DIR/metadata-sufficient-for-layout.rs:15:18 - | -LL | pub type F = impl Coroutine<(), Yield = (), Return = ()>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires computing the opaque types defined by `A`... - --> $DIR/metadata-sufficient-for-layout.rs:24:1 - | -LL | static A: Option = None; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: ...which again requires computing type of `A`, completing the cycle -note: cycle used when checking that `A` is well-formed - --> $DIR/metadata-sufficient-for-layout.rs:24:1 - | -LL | static A: Option = None; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0391`. diff --git a/tests/ui/issues/issue-7364.rs b/tests/ui/issues/issue-7364.rs index 79642bd411b38..4ce9beb68cd3f 100644 --- a/tests/ui/issues/issue-7364.rs +++ b/tests/ui/issues/issue-7364.rs @@ -3,5 +3,6 @@ use std::cell::RefCell; // Regression test for issue 7364 static boxed: Box> = Box::new(RefCell::new(0)); //~^ ERROR `RefCell` cannot be shared between threads safely [E0277] +//~| ERROR cannot call non-const associated function fn main() { } diff --git a/tests/ui/issues/issue-7364.stderr b/tests/ui/issues/issue-7364.stderr index 7371e2105de8d..a47a90c90ce16 100644 --- a/tests/ui/issues/issue-7364.stderr +++ b/tests/ui/issues/issue-7364.stderr @@ -11,6 +11,16 @@ note: required because it appears within the type `Box>` --> $SRC_DIR/alloc/src/boxed.rs:LL:COL = note: shared static variables must have a type that implements `Sync` -error: aborting due to 1 previous error +error[E0015]: cannot call non-const associated function `Box::>::new` in statics + --> $DIR/issue-7364.rs:4:37 + | +LL | static boxed: Box> = Box::new(RefCell::new(0)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: calls in statics are limited to constant functions, tuple structs and tuple variants + = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0015, E0277. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/static/issue-24446.rs b/tests/ui/static/issue-24446.rs index 9ab952ade9cf4..ffd6dfabc2890 100644 --- a/tests/ui/static/issue-24446.rs +++ b/tests/ui/static/issue-24446.rs @@ -1,7 +1,6 @@ fn main() { static foo: dyn Fn() -> u32 = || -> u32 { //~^ ERROR the size for values of type - //~| ERROR cannot be shared between threads safely 0 }; } diff --git a/tests/ui/static/issue-24446.stderr b/tests/ui/static/issue-24446.stderr index 359952dcf663f..497ce8ccfb6e9 100644 --- a/tests/ui/static/issue-24446.stderr +++ b/tests/ui/static/issue-24446.stderr @@ -1,12 +1,3 @@ -error[E0277]: `(dyn Fn() -> u32 + 'static)` cannot be shared between threads safely - --> $DIR/issue-24446.rs:2:17 - | -LL | static foo: dyn Fn() -> u32 = || -> u32 { - | ^^^^^^^^^^^^^^^ `(dyn Fn() -> u32 + 'static)` cannot be shared between threads safely - | - = help: the trait `Sync` is not implemented for `(dyn Fn() -> u32 + 'static)` - = note: shared static variables must have a type that implements `Sync` - error[E0277]: the size for values of type `(dyn Fn() -> u32 + 'static)` cannot be known at compilation time --> $DIR/issue-24446.rs:2:5 | @@ -16,6 +7,6 @@ LL | static foo: dyn Fn() -> u32 = || -> u32 { = help: the trait `Sized` is not implemented for `(dyn Fn() -> u32 + 'static)` = note: statics and constants must have a statically known size -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs index bfe30f3706f1d..e21627e14b098 100644 --- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs +++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs @@ -1,3 +1,5 @@ +//@ check-pass + #![feature(type_alias_impl_trait)] use std::fmt::Debug; @@ -9,8 +11,5 @@ const _FOO: Foo = 5; #[define_opaque(Foo)] static _BAR: Foo = 22_i32; -//~^ ERROR cycle detected when computing type of `_BAR` -//~| ERROR cycle detected when computing type of `_BAR` -//~| ERROR cycle detected when computing type of `_BAR` fn main() {} diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-const.stderr b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-const.stderr deleted file mode 100644 index 6537f0f35a3bb..0000000000000 --- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-const.stderr +++ /dev/null @@ -1,113 +0,0 @@ -error[E0391]: cycle detected when computing type of `_BAR` - --> $DIR/type-alias-impl-trait-const.rs:11:14 - | -LL | static _BAR: Foo = 22_i32; - | ^^^ - | - = note: ...which requires evaluating trait selection obligation `Foo: core::marker::Sync`... -note: ...which requires computing type of opaque `Foo::{opaque#0}`... - --> $DIR/type-alias-impl-trait-const.rs:5:16 - | -LL | pub type Foo = impl Debug; - | ^^^^^^^^^^ -note: ...which requires borrow-checking `_FOO`... - --> $DIR/type-alias-impl-trait-const.rs:8:1 - | -LL | const _FOO: Foo = 5; - | ^^^^^^^^^^^^^^^ -note: ...which requires computing type of opaque `Foo::{opaque#0}` via HIR typeck... - --> $DIR/type-alias-impl-trait-const.rs:5:16 - | -LL | pub type Foo = impl Debug; - | ^^^^^^^^^^ -note: ...which requires computing the opaque types defined by `_BAR`... - --> $DIR/type-alias-impl-trait-const.rs:11:1 - | -LL | static _BAR: Foo = 22_i32; - | ^^^^^^^^^^^^^^^^ - = note: ...which again requires computing type of `_BAR`, completing the cycle -note: cycle used when checking that `_BAR` is well-formed - --> $DIR/type-alias-impl-trait-const.rs:11:1 - | -LL | static _BAR: Foo = 22_i32; - | ^^^^^^^^^^^^^^^^ - = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information - -error[E0391]: cycle detected when computing type of `_BAR` - --> $DIR/type-alias-impl-trait-const.rs:11:14 - | -LL | static _BAR: Foo = 22_i32; - | ^^^ - | - = note: ...which requires evaluating trait selection obligation `Foo: core::marker::Sync`... -note: ...which requires computing type of opaque `Foo::{opaque#0}`... - --> $DIR/type-alias-impl-trait-const.rs:5:16 - | -LL | pub type Foo = impl Debug; - | ^^^^^^^^^^ -note: ...which requires borrow-checking `_FOO`... - --> $DIR/type-alias-impl-trait-const.rs:8:1 - | -LL | const _FOO: Foo = 5; - | ^^^^^^^^^^^^^^^ -note: ...which requires computing type of opaque `Foo::{opaque#0}` via HIR typeck... - --> $DIR/type-alias-impl-trait-const.rs:5:16 - | -LL | pub type Foo = impl Debug; - | ^^^^^^^^^^ -note: ...which requires type-checking `_BAR`... - --> $DIR/type-alias-impl-trait-const.rs:11:1 - | -LL | static _BAR: Foo = 22_i32; - | ^^^^^^^^^^^^^^^^ - = note: ...which again requires computing type of `_BAR`, completing the cycle -note: cycle used when checking that `_BAR` is well-formed - --> $DIR/type-alias-impl-trait-const.rs:11:1 - | -LL | static _BAR: Foo = 22_i32; - | ^^^^^^^^^^^^^^^^ - = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information - -error[E0391]: cycle detected when computing type of `_BAR` - --> $DIR/type-alias-impl-trait-const.rs:11:14 - | -LL | static _BAR: Foo = 22_i32; - | ^^^ - | - = note: ...which requires evaluating trait selection obligation `Foo: core::marker::Sync`... -note: ...which requires computing type of opaque `Foo::{opaque#0}`... - --> $DIR/type-alias-impl-trait-const.rs:5:16 - | -LL | pub type Foo = impl Debug; - | ^^^^^^^^^^ -note: ...which requires borrow-checking `_BAR`... - --> $DIR/type-alias-impl-trait-const.rs:11:1 - | -LL | static _BAR: Foo = 22_i32; - | ^^^^^^^^^^^^^^^^ -note: ...which requires promoting constants in MIR for `_BAR`... - --> $DIR/type-alias-impl-trait-const.rs:11:1 - | -LL | static _BAR: Foo = 22_i32; - | ^^^^^^^^^^^^^^^^ -note: ...which requires const checking `_BAR`... - --> $DIR/type-alias-impl-trait-const.rs:11:1 - | -LL | static _BAR: Foo = 22_i32; - | ^^^^^^^^^^^^^^^^ -note: ...which requires building MIR for `_BAR`... - --> $DIR/type-alias-impl-trait-const.rs:11:1 - | -LL | static _BAR: Foo = 22_i32; - | ^^^^^^^^^^^^^^^^ - = note: ...which again requires computing type of `_BAR`, completing the cycle -note: cycle used when checking that `_BAR` is well-formed - --> $DIR/type-alias-impl-trait-const.rs:11:1 - | -LL | static _BAR: Foo = 22_i32; - | ^^^^^^^^^^^^^^^^ - = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0391`.