Skip to content

Commit fbce03b

Browse files
committed
Auto merge of rust-lang#129060 - matthiaskrgr:rollup-s72gpif, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - rust-lang#122884 (Optimize integer `pow` by removing the exit branch) - rust-lang#127857 (Allow to customize `// TODO:` comment for deprecated safe autofix) - rust-lang#129034 (Add `#[must_use]` attribute to `Coroutine` trait) - rust-lang#129049 (compiletest: Don't panic on unknown JSON-like output lines) - rust-lang#129050 (Emit a warning instead of an error if `--generate-link-to-definition` is used with other output formats than HTML) - rust-lang#129056 (Fix one usage of target triple in bootstrap) - rust-lang#129058 (Add mw back to review rotation) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 9859bf2 + 24a46c5 commit fbce03b

File tree

20 files changed

+219
-124
lines changed

20 files changed

+219
-124
lines changed

compiler/rustc_feature/src/builtin_attrs.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -643,8 +643,8 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
643643
through unstable paths"
644644
),
645645
rustc_attr!(
646-
rustc_deprecated_safe_2024, Normal, template!(Word), WarnFollowing,
647-
EncodeCrossCrate::Yes,
646+
rustc_deprecated_safe_2024, Normal, template!(List: r#"audit_that = "...""#),
647+
ErrorFollowing, EncodeCrossCrate::Yes,
648648
"rustc_deprecated_safe_2024 is supposed to be used in libstd only",
649649
),
650650

compiler/rustc_mir_build/messages.ftl

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ mir_build_call_to_deprecated_safe_fn_requires_unsafe =
3030
call to deprecated safe function `{$function}` is unsafe and requires unsafe block
3131
.note = consult the function's documentation for information on how to avoid undefined behavior
3232
.label = call to unsafe function
33-
.suggestion = you can wrap the call in an `unsafe` block if you can guarantee the code is only ever called from single-threaded code
33+
.suggestion = you can wrap the call in an `unsafe` block if you can guarantee {$guarantee}
3434
3535
mir_build_call_to_fn_with_requires_unsafe =
3636
call to function `{$function}` with `#[target_feature]` is unsafe and requires unsafe block

compiler/rustc_mir_build/src/check_unsafety.rs

+26-2
Original file line numberDiff line numberDiff line change
@@ -96,18 +96,42 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
9696
// from an edition before 2024.
9797
&UnsafeOpKind::CallToUnsafeFunction(Some(id))
9898
if !span.at_least_rust_2024()
99-
&& self.tcx.has_attr(id, sym::rustc_deprecated_safe_2024) =>
99+
&& let Some(attr) = self.tcx.get_attr(id, sym::rustc_deprecated_safe_2024) =>
100100
{
101+
let suggestion = attr
102+
.meta_item_list()
103+
.unwrap_or_default()
104+
.into_iter()
105+
.find(|item| item.has_name(sym::audit_that))
106+
.map(|item| {
107+
item.value_str().expect(
108+
"`#[rustc_deprecated_safe_2024(audit_that)]` must have a string value",
109+
)
110+
});
111+
101112
let sm = self.tcx.sess.source_map();
113+
let guarantee = suggestion
114+
.as_ref()
115+
.map(|suggestion| format!("that {}", suggestion))
116+
.unwrap_or_else(|| String::from("its unsafe preconditions"));
117+
let suggestion = suggestion
118+
.and_then(|suggestion| {
119+
sm.indentation_before(span).map(|indent| {
120+
format!("{}// TODO: Audit that {}.\n", indent, suggestion) // ignore-tidy-todo
121+
})
122+
})
123+
.unwrap_or_default();
124+
102125
self.tcx.emit_node_span_lint(
103126
DEPRECATED_SAFE_2024,
104127
self.hir_context,
105128
span,
106129
CallToDeprecatedSafeFnRequiresUnsafe {
107130
span,
108131
function: with_no_trimmed_paths!(self.tcx.def_path_str(id)),
132+
guarantee,
109133
sub: CallToDeprecatedSafeFnRequiresUnsafeSub {
110-
indent: sm.indentation_before(span).unwrap_or_default(),
134+
start_of_line_suggestion: suggestion,
111135
start_of_line: sm.span_extend_to_line(span).shrink_to_lo(),
112136
left: span.shrink_to_lo(),
113137
right: span.shrink_to_hi(),

compiler/rustc_mir_build/src/errors.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,16 @@ pub(crate) struct CallToDeprecatedSafeFnRequiresUnsafe {
2828
#[label]
2929
pub(crate) span: Span,
3030
pub(crate) function: String,
31+
pub(crate) guarantee: String,
3132
#[subdiagnostic]
3233
pub(crate) sub: CallToDeprecatedSafeFnRequiresUnsafeSub,
3334
}
3435

3536
#[derive(Subdiagnostic)]
3637
#[multipart_suggestion(mir_build_suggestion, applicability = "machine-applicable")]
3738
pub(crate) struct CallToDeprecatedSafeFnRequiresUnsafeSub {
38-
pub(crate) indent: String,
39-
#[suggestion_part(
40-
code = "{indent}// TODO: Audit that the environment access only happens in single-threaded code.\n" // ignore-tidy-todo
41-
)]
39+
pub(crate) start_of_line_suggestion: String,
40+
#[suggestion_part(code = "{start_of_line_suggestion}")]
4241
pub(crate) start_of_line: Span,
4342
#[suggestion_part(code = "unsafe {{ ")]
4443
pub(crate) left: Span,

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,7 @@ symbols! {
472472
attr,
473473
attr_literals,
474474
attributes,
475+
audit_that,
475476
augmented_assignments,
476477
auto_traits,
477478
automatically_derived,

library/core/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@
170170
#![feature(internal_impls_macro)]
171171
#![feature(ip)]
172172
#![feature(is_ascii_octdigit)]
173+
#![feature(is_val_statically_known)]
173174
#![feature(isqrt)]
174175
#![feature(link_cfg)]
175176
#![feature(offset_of_enum)]

library/core/src/num/int_macros.rs

+75-43
Original file line numberDiff line numberDiff line change
@@ -1496,18 +1496,17 @@ macro_rules! int_impl {
14961496
let mut base = self;
14971497
let mut acc: Self = 1;
14981498

1499-
while exp > 1 {
1499+
loop {
15001500
if (exp & 1) == 1 {
15011501
acc = try_opt!(acc.checked_mul(base));
1502+
// since exp!=0, finally the exp must be 1.
1503+
if exp == 1 {
1504+
return Some(acc);
1505+
}
15021506
}
15031507
exp /= 2;
15041508
base = try_opt!(base.checked_mul(base));
15051509
}
1506-
// since exp!=0, finally the exp must be 1.
1507-
// Deal with the final bit of the exponent separately, since
1508-
// squaring the base afterwards is not necessary and may cause a
1509-
// needless overflow.
1510-
acc.checked_mul(base)
15111510
}
15121511

15131512
/// Strict exponentiation. Computes `self.pow(exp)`, panicking if
@@ -1547,18 +1546,17 @@ macro_rules! int_impl {
15471546
let mut base = self;
15481547
let mut acc: Self = 1;
15491548

1550-
while exp > 1 {
1549+
loop {
15511550
if (exp & 1) == 1 {
15521551
acc = acc.strict_mul(base);
1552+
// since exp!=0, finally the exp must be 1.
1553+
if exp == 1 {
1554+
return acc;
1555+
}
15531556
}
15541557
exp /= 2;
15551558
base = base.strict_mul(base);
15561559
}
1557-
// since exp!=0, finally the exp must be 1.
1558-
// Deal with the final bit of the exponent separately, since
1559-
// squaring the base afterwards is not necessary and may cause a
1560-
// needless overflow.
1561-
acc.strict_mul(base)
15621560
}
15631561

15641562
/// Returns the square root of the number, rounded down.
@@ -2175,26 +2173,44 @@ macro_rules! int_impl {
21752173
#[must_use = "this returns the result of the operation, \
21762174
without modifying the original"]
21772175
#[inline]
2176+
#[rustc_allow_const_fn_unstable(is_val_statically_known)]
21782177
pub const fn wrapping_pow(self, mut exp: u32) -> Self {
21792178
if exp == 0 {
21802179
return 1;
21812180
}
21822181
let mut base = self;
21832182
let mut acc: Self = 1;
21842183

2185-
while exp > 1 {
2186-
if (exp & 1) == 1 {
2187-
acc = acc.wrapping_mul(base);
2184+
if intrinsics::is_val_statically_known(exp) {
2185+
while exp > 1 {
2186+
if (exp & 1) == 1 {
2187+
acc = acc.wrapping_mul(base);
2188+
}
2189+
exp /= 2;
2190+
base = base.wrapping_mul(base);
21882191
}
2189-
exp /= 2;
2190-
base = base.wrapping_mul(base);
2191-
}
21922192

2193-
// since exp!=0, finally the exp must be 1.
2194-
// Deal with the final bit of the exponent separately, since
2195-
// squaring the base afterwards is not necessary and may cause a
2196-
// needless overflow.
2197-
acc.wrapping_mul(base)
2193+
// since exp!=0, finally the exp must be 1.
2194+
// Deal with the final bit of the exponent separately, since
2195+
// squaring the base afterwards is not necessary.
2196+
acc.wrapping_mul(base)
2197+
} else {
2198+
// This is faster than the above when the exponent is not known
2199+
// at compile time. We can't use the same code for the constant
2200+
// exponent case because LLVM is currently unable to unroll
2201+
// this loop.
2202+
loop {
2203+
if (exp & 1) == 1 {
2204+
acc = acc.wrapping_mul(base);
2205+
// since exp!=0, finally the exp must be 1.
2206+
if exp == 1 {
2207+
return acc;
2208+
}
2209+
}
2210+
exp /= 2;
2211+
base = base.wrapping_mul(base);
2212+
}
2213+
}
21982214
}
21992215

22002216
/// Calculates `self` + `rhs`.
@@ -2690,9 +2706,14 @@ macro_rules! int_impl {
26902706
// Scratch space for storing results of overflowing_mul.
26912707
let mut r;
26922708

2693-
while exp > 1 {
2709+
loop {
26942710
if (exp & 1) == 1 {
26952711
r = acc.overflowing_mul(base);
2712+
// since exp!=0, finally the exp must be 1.
2713+
if exp == 1 {
2714+
r.1 |= overflown;
2715+
return r;
2716+
}
26962717
acc = r.0;
26972718
overflown |= r.1;
26982719
}
@@ -2701,14 +2722,6 @@ macro_rules! int_impl {
27012722
base = r.0;
27022723
overflown |= r.1;
27032724
}
2704-
2705-
// since exp!=0, finally the exp must be 1.
2706-
// Deal with the final bit of the exponent separately, since
2707-
// squaring the base afterwards is not necessary and may cause a
2708-
// needless overflow.
2709-
r = acc.overflowing_mul(base);
2710-
r.1 |= overflown;
2711-
r
27122725
}
27132726

27142727
/// Raises self to the power of `exp`, using exponentiation by squaring.
@@ -2728,26 +2741,45 @@ macro_rules! int_impl {
27282741
without modifying the original"]
27292742
#[inline]
27302743
#[rustc_inherit_overflow_checks]
2744+
#[rustc_allow_const_fn_unstable(is_val_statically_known)]
27312745
pub const fn pow(self, mut exp: u32) -> Self {
27322746
if exp == 0 {
27332747
return 1;
27342748
}
27352749
let mut base = self;
27362750
let mut acc = 1;
27372751

2738-
while exp > 1 {
2739-
if (exp & 1) == 1 {
2740-
acc = acc * base;
2752+
if intrinsics::is_val_statically_known(exp) {
2753+
while exp > 1 {
2754+
if (exp & 1) == 1 {
2755+
acc = acc * base;
2756+
}
2757+
exp /= 2;
2758+
base = base * base;
27412759
}
2742-
exp /= 2;
2743-
base = base * base;
2744-
}
27452760

2746-
// since exp!=0, finally the exp must be 1.
2747-
// Deal with the final bit of the exponent separately, since
2748-
// squaring the base afterwards is not necessary and may cause a
2749-
// needless overflow.
2750-
acc * base
2761+
// since exp!=0, finally the exp must be 1.
2762+
// Deal with the final bit of the exponent separately, since
2763+
// squaring the base afterwards is not necessary and may cause a
2764+
// needless overflow.
2765+
acc * base
2766+
} else {
2767+
// This is faster than the above when the exponent is not known
2768+
// at compile time. We can't use the same code for the constant
2769+
// exponent case because LLVM is currently unable to unroll
2770+
// this loop.
2771+
loop {
2772+
if (exp & 1) == 1 {
2773+
acc = acc * base;
2774+
// since exp!=0, finally the exp must be 1.
2775+
if exp == 1 {
2776+
return acc;
2777+
}
2778+
}
2779+
exp /= 2;
2780+
base = base * base;
2781+
}
2782+
}
27512783
}
27522784

27532785
/// Returns the square root of the number, rounded down.

0 commit comments

Comments
 (0)