Skip to content

Commit a32d4a0

Browse files
committed
Auto merge of #129370 - matthiaskrgr:rollup-g9117ee, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - #128727 (bump conflicting_repr_hints lint to be shown in dependencies) - #129232 (Fix `thread::sleep` Duration-handling for ESP-IDF) - #129321 (Change neutral element of <fNN as iter::Sum> to neg_zero) - #129353 (llvm-wrapper: adapt for LLVM 20 API changes) - #129363 (Force `LC_ALL=C` for all run-make tests) - #129364 (safe transmute: gracefully bubble-up layout errors) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 6b678c5 + 00e109f commit a32d4a0

File tree

19 files changed

+250
-58
lines changed

19 files changed

+250
-58
lines changed

compiler/rustc_lint_defs/src/builtin.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ declare_lint! {
251251
Deny,
252252
"conflicts between `#[repr(..)]` hints that were previously accepted and used in practice",
253253
@future_incompatible = FutureIncompatibleInfo {
254-
reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps,
254+
reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps,
255255
reference: "issue #68585 <https://github.com/rust-lang/rust/issues/68585>",
256256
};
257257
}

compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp

+11
Original file line numberDiff line numberDiff line change
@@ -1607,8 +1607,13 @@ extern "C" void LLVMRustComputeLTOCacheKey(RustStringRef KeyOut,
16071607
const auto &ExportList = Data->ExportLists.lookup(ModId);
16081608
const auto &ResolvedODR = Data->ResolvedODR.lookup(ModId);
16091609
const auto &DefinedGlobals = Data->ModuleToDefinedGVSummaries.lookup(ModId);
1610+
#if LLVM_VERSION_GE(20, 0)
1611+
DenseSet<GlobalValue::GUID> CfiFunctionDefs;
1612+
DenseSet<GlobalValue::GUID> CfiFunctionDecls;
1613+
#else
16101614
std::set<GlobalValue::GUID> CfiFunctionDefs;
16111615
std::set<GlobalValue::GUID> CfiFunctionDecls;
1616+
#endif
16121617

16131618
// Based on the 'InProcessThinBackend' constructor in LLVM
16141619
for (auto &Name : Data->Index.cfiFunctionDefs())
@@ -1618,9 +1623,15 @@ extern "C" void LLVMRustComputeLTOCacheKey(RustStringRef KeyOut,
16181623
CfiFunctionDecls.insert(
16191624
GlobalValue::getGUID(GlobalValue::dropLLVMManglingEscape(Name)));
16201625

1626+
#if LLVM_VERSION_GE(20, 0)
1627+
Key = llvm::computeLTOCacheKey(conf, Data->Index, ModId, ImportList,
1628+
ExportList, ResolvedODR, DefinedGlobals,
1629+
CfiFunctionDefs, CfiFunctionDecls);
1630+
#else
16211631
llvm::computeLTOCacheKey(Key, conf, Data->Index, ModId, ImportList,
16221632
ExportList, ResolvedODR, DefinedGlobals,
16231633
CfiFunctionDefs, CfiFunctionDecls);
1634+
#endif
16241635

16251636
LLVMRustStringWriteImpl(KeyOut, Key.c_str(), Key.size());
16261637
}

compiler/rustc_transmute/src/layout/tree.rs

+7-11
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ pub(crate) mod rustc {
179179
};
180180

181181
use super::Tree;
182-
use crate::layout::rustc::{Def, Ref};
182+
use crate::layout::rustc::{layout_of, Def, Ref};
183183

184184
#[derive(Debug, Copy, Clone)]
185185
pub(crate) enum Err {
@@ -206,7 +206,7 @@ pub(crate) mod rustc {
206206
impl<'tcx> Tree<Def<'tcx>, Ref<'tcx>> {
207207
pub fn from_ty(ty: Ty<'tcx>, cx: LayoutCx<'tcx, TyCtxt<'tcx>>) -> Result<Self, Err> {
208208
use rustc_target::abi::HasDataLayout;
209-
let layout = ty_layout(cx, ty);
209+
let layout = layout_of(cx, ty)?;
210210

211211
if let Err(e) = ty.error_reported() {
212212
return Err(Err::TypeError(e));
@@ -239,7 +239,7 @@ pub(crate) mod rustc {
239239
let FieldsShape::Array { stride, count } = &layout.fields else {
240240
return Err(Err::NotYetSupported);
241241
};
242-
let inner_layout = ty_layout(cx, *inner_ty);
242+
let inner_layout = layout_of(cx, *inner_ty)?;
243243
assert_eq!(*stride, inner_layout.size);
244244
let elt = Tree::from_ty(*inner_ty, cx)?;
245245
Ok(std::iter::repeat(elt)
@@ -254,7 +254,7 @@ pub(crate) mod rustc {
254254
},
255255

256256
ty::Ref(lifetime, ty, mutability) => {
257-
let layout = ty_layout(cx, *ty);
257+
let layout = layout_of(cx, *ty)?;
258258
let align = layout.align.abi.bytes_usize();
259259
let size = layout.size.bytes_usize();
260260
Ok(Tree::Ref(Ref {
@@ -280,7 +280,7 @@ pub(crate) mod rustc {
280280
FieldsShape::Primitive => {
281281
assert_eq!(members.len(), 1);
282282
let inner_ty = members[0];
283-
let inner_layout = ty_layout(cx, inner_ty);
283+
let inner_layout = layout_of(cx, inner_ty)?;
284284
Self::from_ty(inner_ty, cx)
285285
}
286286
FieldsShape::Arbitrary { offsets, .. } => {
@@ -413,7 +413,7 @@ pub(crate) mod rustc {
413413
let padding = Self::padding(padding_needed.bytes_usize());
414414

415415
let field_ty = ty_field(cx, (ty, layout), field_idx);
416-
let field_layout = ty_layout(cx, field_ty);
416+
let field_layout = layout_of(cx, field_ty)?;
417417
let field_tree = Self::from_ty(field_ty, cx)?;
418418

419419
struct_tree = struct_tree.then(padding).then(field_tree);
@@ -471,7 +471,7 @@ pub(crate) mod rustc {
471471
|fields, (idx, field_def)| {
472472
let field_def = Def::Field(field_def);
473473
let field_ty = ty_field(cx, (ty, layout), idx);
474-
let field_layout = ty_layout(cx, field_ty);
474+
let field_layout = layout_of(cx, field_ty)?;
475475
let field = Self::from_ty(field_ty, cx)?;
476476
let trailing_padding_needed = layout.size - field_layout.size;
477477
let trailing_padding = Self::padding(trailing_padding_needed.bytes_usize());
@@ -484,10 +484,6 @@ pub(crate) mod rustc {
484484
}
485485
}
486486

487-
pub(crate) fn ty_layout<'tcx>(cx: LayoutCx<'tcx, TyCtxt<'tcx>>, ty: Ty<'tcx>) -> Layout<'tcx> {
488-
crate::layout::rustc::layout_of(cx, ty).unwrap()
489-
}
490-
491487
fn ty_field<'tcx>(
492488
cx: LayoutCx<'tcx, TyCtxt<'tcx>>,
493489
(ty, layout): (Ty<'tcx>, Layout<'tcx>),

compiler/rustc_transmute/src/maybe_transmutable/mod.rs

+3-10
Original file line numberDiff line numberDiff line change
@@ -44,18 +44,11 @@ mod rustc {
4444
let Self { src, dst, assume, context } = self;
4545

4646
let layout_cx = LayoutCx { tcx: context, param_env: ParamEnv::reveal_all() };
47-
let layout_of = |ty| {
48-
crate::layout::rustc::layout_of(layout_cx, ty)
49-
.map_err(|_| Err::NotYetSupported)
50-
.and_then(|_| Tree::from_ty(ty, layout_cx))
51-
};
5247

5348
// Convert `src` and `dst` from their rustc representations, to `Tree`-based
54-
// representations. If these conversions fail, conclude that the transmutation is
55-
// unacceptable; the layouts of both the source and destination types must be
56-
// well-defined.
57-
let src = layout_of(src);
58-
let dst = layout_of(dst);
49+
// representations.
50+
let src = Tree::from_ty(src, layout_cx);
51+
let dst = Tree::from_ty(dst, layout_cx);
5952

6053
match (src, dst) {
6154
(Err(Err::TypeError(_)), _) | (_, Err(Err::TypeError(_))) => {

library/core/src/iter/traits/accum.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ macro_rules! float_sum_product {
104104
impl Sum for $a {
105105
fn sum<I: Iterator<Item=Self>>(iter: I) -> Self {
106106
iter.fold(
107-
0.0,
107+
-0.0,
108108
#[rustc_inherit_overflow_checks]
109109
|a, b| a + b,
110110
)
@@ -126,7 +126,7 @@ macro_rules! float_sum_product {
126126
impl<'a> Sum<&'a $a> for $a {
127127
fn sum<I: Iterator<Item=&'a Self>>(iter: I) -> Self {
128128
iter.fold(
129-
0.0,
129+
-0.0,
130130
#[rustc_inherit_overflow_checks]
131131
|a, b| a + b,
132132
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#[test]
2+
fn f32_ref() {
3+
let x: f32 = -0.0;
4+
let still_x: f32 = [x].iter().sum();
5+
assert_eq!(1. / x, 1. / still_x)
6+
}
7+
8+
#[test]
9+
fn f32_own() {
10+
let x: f32 = -0.0;
11+
let still_x: f32 = [x].into_iter().sum();
12+
assert_eq!(1. / x, 1. / still_x)
13+
}
14+
15+
#[test]
16+
fn f64_ref() {
17+
let x: f64 = -0.0;
18+
let still_x: f64 = [x].iter().sum();
19+
assert_eq!(1. / x, 1. / still_x)
20+
}
21+
22+
#[test]
23+
fn f64_own() {
24+
let x: f64 = -0.0;
25+
let still_x: f64 = [x].into_iter().sum();
26+
assert_eq!(1. / x, 1. / still_x)
27+
}

library/core/tests/num/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ mod int_log;
3030
mod ops;
3131
mod wrapping;
3232

33+
mod float_iter_sum_identity;
3334
mod ieee754;
3435
mod nan;
3536

library/std/src/sys/pal/unix/thread.rs

+24-6
Original file line numberDiff line numberDiff line change
@@ -267,14 +267,32 @@ impl Thread {
267267

268268
#[cfg(target_os = "espidf")]
269269
pub fn sleep(dur: Duration) {
270-
let mut micros = dur.as_micros();
271-
unsafe {
272-
while micros > 0 {
273-
let st = if micros > u32::MAX as u128 { u32::MAX } else { micros as u32 };
270+
// ESP-IDF does not have `nanosleep`, so we use `usleep` instead.
271+
// As per the documentation of `usleep`, it is expected to support
272+
// sleep times as big as at least up to 1 second.
273+
//
274+
// ESP-IDF does support almost up to `u32::MAX`, but due to a potential integer overflow in its
275+
// `usleep` implementation
276+
// (https://github.com/espressif/esp-idf/blob/d7ca8b94c852052e3bc33292287ef4dd62c9eeb1/components/newlib/time.c#L210),
277+
// we limit the sleep time to the maximum one that would not cause the underlying `usleep` implementation to overflow
278+
// (`portTICK_PERIOD_MS` can be anything between 1 to 1000, and is 10 by default).
279+
const MAX_MICROS: u32 = u32::MAX - 1_000_000 - 1;
280+
281+
// Add any nanoseconds smaller than a microsecond as an extra microsecond
282+
// so as to comply with the `std::thread::sleep` contract which mandates
283+
// implementations to sleep for _at least_ the provided `dur`.
284+
// We can't overflow `micros` as it is a `u128`, while `Duration` is a pair of
285+
// (`u64` secs, `u32` nanos), where the nanos are strictly smaller than 1 second
286+
// (i.e. < 1_000_000_000)
287+
let mut micros = dur.as_micros() + if dur.subsec_nanos() % 1_000 > 0 { 1 } else { 0 };
288+
289+
while micros > 0 {
290+
let st = if micros > MAX_MICROS as u128 { MAX_MICROS } else { micros as u32 };
291+
unsafe {
274292
libc::usleep(st);
275-
276-
micros -= st as u128;
277293
}
294+
295+
micros -= st as u128;
278296
}
279297
}
280298

src/tools/run-make-support/src/run.rs

+2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ fn run_common(name: &str, args: Option<&[&str]>) -> Command {
2929
}
3030
env::join_paths(paths.iter()).unwrap()
3131
});
32+
cmd.env("LC_ALL", "C"); // force english locale
3233

3334
if is_windows() {
3435
let mut paths = vec![];
@@ -84,5 +85,6 @@ pub fn run_fail(name: &str) -> CompletedProcess {
8485
pub fn cmd<S: AsRef<OsStr>>(program: S) -> Command {
8586
let mut command = Command::new(program);
8687
set_host_rpath(&mut command);
88+
command.env("LC_ALL", "C"); // force english locale
8789
command
8890
}

tests/ui/feature-gates/feature-gate-repr-simd.stderr

+14
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,17 @@ error: aborting due to 3 previous errors
3535

3636
Some errors have detailed explanations: E0566, E0658.
3737
For more information about an error, try `rustc --explain E0566`.
38+
Future incompatibility report: Future breakage diagnostic:
39+
error[E0566]: conflicting representation hints
40+
--> $DIR/feature-gate-repr-simd.rs:4:8
41+
|
42+
LL | #[repr(C)]
43+
| ^
44+
LL |
45+
LL | #[repr(simd)]
46+
| ^^^^
47+
|
48+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
49+
= note: for more information, see issue #68585 <https://github.com/rust-lang/rust/issues/68585>
50+
= note: `#[deny(conflicting_repr_hints)]` on by default
51+

tests/ui/issues/issue-47094.stderr

+25
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,28 @@ LL | #[repr(u8)]
2323
error: aborting due to 2 previous errors
2424

2525
For more information about this error, try `rustc --explain E0566`.
26+
Future incompatibility report: Future breakage diagnostic:
27+
error[E0566]: conflicting representation hints
28+
--> $DIR/issue-47094.rs:1:8
29+
|
30+
LL | #[repr(C, u8)]
31+
| ^ ^^
32+
|
33+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
34+
= note: for more information, see issue #68585 <https://github.com/rust-lang/rust/issues/68585>
35+
= note: `#[deny(conflicting_repr_hints)]` on by default
36+
37+
Future breakage diagnostic:
38+
error[E0566]: conflicting representation hints
39+
--> $DIR/issue-47094.rs:8:8
40+
|
41+
LL | #[repr(C)]
42+
| ^
43+
LL |
44+
LL | #[repr(u8)]
45+
| ^^
46+
|
47+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
48+
= note: for more information, see issue #68585 <https://github.com/rust-lang/rust/issues/68585>
49+
= note: `#[deny(conflicting_repr_hints)]` on by default
50+

tests/ui/repr/conflicting-repr-hints.stderr

+22
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,25 @@ error: aborting due to 12 previous errors
8181

8282
Some errors have detailed explanations: E0566, E0587, E0634.
8383
For more information about an error, try `rustc --explain E0566`.
84+
Future incompatibility report: Future breakage diagnostic:
85+
error[E0566]: conflicting representation hints
86+
--> $DIR/conflicting-repr-hints.rs:13:8
87+
|
88+
LL | #[repr(C, u64)]
89+
| ^ ^^^
90+
|
91+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
92+
= note: for more information, see issue #68585 <https://github.com/rust-lang/rust/issues/68585>
93+
= note: `#[deny(conflicting_repr_hints)]` on by default
94+
95+
Future breakage diagnostic:
96+
error[E0566]: conflicting representation hints
97+
--> $DIR/conflicting-repr-hints.rs:19:8
98+
|
99+
LL | #[repr(u32, u64)]
100+
| ^^^ ^^^
101+
|
102+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
103+
= note: for more information, see issue #68585 <https://github.com/rust-lang/rust/issues/68585>
104+
= note: `#[deny(conflicting_repr_hints)]` on by default
105+

tests/ui/transmutability/arrays/huge-len.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0277]: `()` cannot be safely transmuted into `ExplicitlyPadded`
22
--> $DIR/huge-len.rs:21:41
33
|
44
LL | assert::is_maybe_transmutable::<(), ExplicitlyPadded>();
5-
| ^^^^^^^^^^^^^^^^ analyzing the transmutability of `ExplicitlyPadded` is not yet supported
5+
| ^^^^^^^^^^^^^^^^ values of the type `ExplicitlyPadded` are too big for the current architecture
66
|
77
note: required by a bound in `is_maybe_transmutable`
88
--> $DIR/huge-len.rs:8:14
@@ -17,7 +17,7 @@ error[E0277]: `ExplicitlyPadded` cannot be safely transmuted into `()`
1717
--> $DIR/huge-len.rs:24:55
1818
|
1919
LL | assert::is_maybe_transmutable::<ExplicitlyPadded, ()>();
20-
| ^^ analyzing the transmutability of `ExplicitlyPadded` is not yet supported
20+
| ^^ values of the type `ExplicitlyPadded` are too big for the current architecture
2121
|
2222
note: required by a bound in `is_maybe_transmutable`
2323
--> $DIR/huge-len.rs:8:14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// An unknown destination type should be gracefully handled.
2+
3+
#![crate_type = "lib"]
4+
#![feature(transmutability)]
5+
#![allow(incomplete_features)]
6+
7+
mod assert {
8+
use std::mem::BikeshedIntrinsicFrom;
9+
10+
pub fn is_transmutable<Src, Dst>()
11+
where
12+
Dst: BikeshedIntrinsicFrom<Src>
13+
{}
14+
}
15+
16+
fn should_gracefully_handle_unknown_dst_field() {
17+
#[repr(C)] struct Src;
18+
#[repr(C)] struct Dst(Missing); //~ cannot find type
19+
assert::is_transmutable::<Src, Dst>(); //~ ERROR cannot be safely transmuted
20+
}
21+
22+
fn should_gracefully_handle_unknown_dst_ref_field() {
23+
#[repr(C)] struct Src(&'static Src);
24+
#[repr(C)] struct Dst(&'static Missing); //~ cannot find type
25+
assert::is_transmutable::<Src, Dst>(); //~ ERROR cannot be safely transmuted
26+
}

0 commit comments

Comments
 (0)