Skip to content

Commit da1da3f

Browse files
committed
Auto merge of #118618 - GuillaumeGomez:rollup-24ur21r, r=GuillaumeGomez
Rollup of 4 pull requests Successful merges: - #118508 (rustdoc: do not escape quotes in body text) - #118565 (interpret: make numeric_intrinsic accessible from Miri) - #118591 (portable-simd: fix test suite build) - #118600 ([rustdoc] Don't generate the "Fields" heading if there is no field displayed) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 0e2dac8 + baa3f96 commit da1da3f

File tree

9 files changed

+116
-56
lines changed

9 files changed

+116
-56
lines changed

Diff for: compiler/rustc_const_eval/src/interpret/intrinsics.rs

+36-46
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,22 @@
33
//! and miri.
44
55
use rustc_hir::def_id::DefId;
6-
use rustc_middle::mir::{
7-
self,
8-
interpret::{Allocation, ConstAllocation, GlobalId, InterpResult, PointerArithmetic, Scalar},
9-
BinOp, ConstValue, NonDivergingIntrinsic,
10-
};
116
use rustc_middle::ty;
127
use rustc_middle::ty::layout::{LayoutOf as _, ValidityRequirement};
138
use rustc_middle::ty::GenericArgsRef;
149
use rustc_middle::ty::{Ty, TyCtxt};
10+
use rustc_middle::{
11+
mir::{
12+
self,
13+
interpret::{
14+
Allocation, ConstAllocation, GlobalId, InterpResult, PointerArithmetic, Scalar,
15+
},
16+
BinOp, ConstValue, NonDivergingIntrinsic,
17+
},
18+
ty::layout::TyAndLayout,
19+
};
1520
use rustc_span::symbol::{sym, Symbol};
16-
use rustc_target::abi::{Abi, Primitive, Size};
21+
use rustc_target::abi::Size;
1722

1823
use super::{
1924
util::ensure_monomorphic_enough, CheckInAllocMsg, ImmTy, InterpCx, Machine, OpTy, PlaceTy,
@@ -22,23 +27,6 @@ use super::{
2227

2328
use crate::fluent_generated as fluent;
2429

25-
fn numeric_intrinsic<Prov>(name: Symbol, bits: u128, kind: Primitive) -> Scalar<Prov> {
26-
let size = match kind {
27-
Primitive::Int(integer, _) => integer.size(),
28-
_ => bug!("invalid `{}` argument: {:?}", name, bits),
29-
};
30-
let extra = 128 - u128::from(size.bits());
31-
let bits_out = match name {
32-
sym::ctpop => u128::from(bits.count_ones()),
33-
sym::ctlz => u128::from(bits.leading_zeros()) - extra,
34-
sym::cttz => u128::from((bits << extra).trailing_zeros()) - extra,
35-
sym::bswap => (bits << extra).swap_bytes(),
36-
sym::bitreverse => (bits << extra).reverse_bits(),
37-
_ => bug!("not a numeric intrinsic: {}", name),
38-
};
39-
Scalar::from_uint(bits_out, size)
40-
}
41-
4230
/// Directly returns an `Allocation` containing an absolute path representation of the given type.
4331
pub(crate) fn alloc_type_name<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ConstAllocation<'tcx> {
4432
let path = crate::util::type_name(tcx, ty);
@@ -179,30 +167,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
179167
| sym::bswap
180168
| sym::bitreverse => {
181169
let ty = instance_args.type_at(0);
182-
let layout_of = self.layout_of(ty)?;
170+
let layout = self.layout_of(ty)?;
183171
let val = self.read_scalar(&args[0])?;
184-
let bits = val.to_bits(layout_of.size)?;
185-
let kind = match layout_of.abi {
186-
Abi::Scalar(scalar) => scalar.primitive(),
187-
_ => span_bug!(
188-
self.cur_span(),
189-
"{} called on invalid type {:?}",
190-
intrinsic_name,
191-
ty
192-
),
193-
};
194-
let (nonzero, actual_intrinsic_name) = match intrinsic_name {
195-
sym::cttz_nonzero => (true, sym::cttz),
196-
sym::ctlz_nonzero => (true, sym::ctlz),
197-
other => (false, other),
198-
};
199-
if nonzero && bits == 0 {
200-
throw_ub_custom!(
201-
fluent::const_eval_call_nonzero_intrinsic,
202-
name = intrinsic_name,
203-
);
204-
}
205-
let out_val = numeric_intrinsic(actual_intrinsic_name, bits, kind);
172+
let out_val = self.numeric_intrinsic(intrinsic_name, val, layout)?;
206173
self.write_scalar(out_val, dest)?;
207174
}
208175
sym::saturating_add | sym::saturating_sub => {
@@ -493,6 +460,29 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
493460
}
494461
}
495462

463+
pub fn numeric_intrinsic(
464+
&self,
465+
name: Symbol,
466+
val: Scalar<M::Provenance>,
467+
layout: TyAndLayout<'tcx>,
468+
) -> InterpResult<'tcx, Scalar<M::Provenance>> {
469+
assert!(layout.ty.is_integral(), "invalid type for numeric intrinsic: {}", layout.ty);
470+
let bits = val.to_bits(layout.size)?;
471+
let extra = 128 - u128::from(layout.size.bits());
472+
let bits_out = match name {
473+
sym::ctpop => u128::from(bits.count_ones()),
474+
sym::ctlz_nonzero | sym::cttz_nonzero if bits == 0 => {
475+
throw_ub_custom!(fluent::const_eval_call_nonzero_intrinsic, name = name,);
476+
}
477+
sym::ctlz | sym::ctlz_nonzero => u128::from(bits.leading_zeros()) - extra,
478+
sym::cttz | sym::cttz_nonzero => u128::from((bits << extra).trailing_zeros()) - extra,
479+
sym::bswap => (bits << extra).swap_bytes(),
480+
sym::bitreverse => (bits << extra).reverse_bits(),
481+
_ => bug!("not a numeric intrinsic: {}", name),
482+
};
483+
Ok(Scalar::from_uint(bits_out, layout.size))
484+
}
485+
496486
pub fn exact_div(
497487
&mut self,
498488
a: &ImmTy<'tcx, M::Provenance>,

Diff for: library/portable-simd/crates/core_simd/tests/pointers.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#![feature(portable_simd, strict_provenance)]
1+
#![feature(portable_simd, strict_provenance, exposed_provenance)]
22

33
use core_simd::simd::{
44
ptr::{SimdConstPtr, SimdMutPtr},

Diff for: src/librustdoc/html/escape.rs

+36
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,39 @@ impl<'a> fmt::Display for Escape<'a> {
3838
Ok(())
3939
}
4040
}
41+
42+
/// Wrapper struct which will emit the HTML-escaped version of the contained
43+
/// string when passed to a format string.
44+
///
45+
/// This is only safe to use for text nodes. If you need your output to be
46+
/// safely contained in an attribute, use [`Escape`]. If you don't know the
47+
/// difference, use [`Escape`].
48+
pub(crate) struct EscapeBodyText<'a>(pub &'a str);
49+
50+
impl<'a> fmt::Display for EscapeBodyText<'a> {
51+
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
52+
// Because the internet is always right, turns out there's not that many
53+
// characters to escape: http://stackoverflow.com/questions/7381974
54+
let EscapeBodyText(s) = *self;
55+
let pile_o_bits = s;
56+
let mut last = 0;
57+
for (i, ch) in s.char_indices() {
58+
let s = match ch {
59+
'>' => "&gt;",
60+
'<' => "&lt;",
61+
'&' => "&amp;",
62+
_ => continue,
63+
};
64+
fmt.write_str(&pile_o_bits[last..i])?;
65+
fmt.write_str(s)?;
66+
// NOTE: we only expect single byte characters here - which is fine as long as we
67+
// only match single byte characters
68+
last = i + 1;
69+
}
70+
71+
if last < s.len() {
72+
fmt.write_str(&pile_o_bits[last..])?;
73+
}
74+
Ok(())
75+
}
76+
}

Diff for: src/librustdoc/html/highlight.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
//! Use the `render_with_highlighting` to highlight some rust code.
77
88
use crate::clean::PrimitiveType;
9-
use crate::html::escape::Escape;
9+
use crate::html::escape::EscapeBodyText;
1010
use crate::html::render::{Context, LinkFromSrc};
1111

1212
use std::collections::VecDeque;
@@ -189,7 +189,7 @@ impl<'a, 'tcx, F: Write> TokenHandler<'a, 'tcx, F> {
189189
&& can_merge(current_class, Some(*parent_class), "")
190190
{
191191
for (text, class) in self.pending_elems.iter() {
192-
string(self.out, Escape(text), *class, &self.href_context, false);
192+
string(self.out, EscapeBodyText(text), *class, &self.href_context, false);
193193
}
194194
} else {
195195
// We only want to "open" the tag ourselves if we have more than one pending and if the
@@ -202,7 +202,13 @@ impl<'a, 'tcx, F: Write> TokenHandler<'a, 'tcx, F> {
202202
None
203203
};
204204
for (text, class) in self.pending_elems.iter() {
205-
string(self.out, Escape(text), *class, &self.href_context, close_tag.is_none());
205+
string(
206+
self.out,
207+
EscapeBodyText(text),
208+
*class,
209+
&self.href_context,
210+
close_tag.is_none(),
211+
);
206212
}
207213
if let Some(close_tag) = close_tag {
208214
exit_span(self.out, close_tag);

Diff for: src/librustdoc/html/highlight/fixtures/dos_line.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
<span class="kw">pub fn </span>foo() {
2-
<span class="macro">println!</span>(<span class="string">&quot;foo&quot;</span>);
2+
<span class="macro">println!</span>(<span class="string">"foo"</span>);
33
}

Diff for: src/librustdoc/html/highlight/fixtures/sample.html

+4-4
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@
88
.lifetime { color: #B76514; }
99
.question-mark { color: #ff9011; }
1010
</style>
11-
<pre><code><span class="attr">#![crate_type = <span class="string">&quot;lib&quot;</span>]
11+
<pre><code><span class="attr">#![crate_type = <span class="string">"lib"</span>]
1212

1313
</span><span class="kw">use </span>std::path::{Path, PathBuf};
1414

15-
<span class="attr">#[cfg(target_os = <span class="string">&quot;linux&quot;</span>)]
16-
#[cfg(target_os = <span class="string">&quot;windows&quot;</span>)]
15+
<span class="attr">#[cfg(target_os = <span class="string">"linux"</span>)]
16+
#[cfg(target_os = <span class="string">"windows"</span>)]
1717
</span><span class="kw">fn </span>main() -&gt; () {
1818
<span class="kw">let </span>foo = <span class="bool-val">true </span>&amp;&amp; <span class="bool-val">false </span>|| <span class="bool-val">true</span>;
1919
<span class="kw">let _</span>: <span class="kw-2">*const </span>() = <span class="number">0</span>;
@@ -22,7 +22,7 @@
2222
<span class="kw">let _ </span>= <span class="kw-2">*</span>foo;
2323
<span class="macro">mac!</span>(foo, <span class="kw-2">&amp;mut </span>bar);
2424
<span class="macro">assert!</span>(<span class="self">self</span>.length &lt; N &amp;&amp; index &lt;= <span class="self">self</span>.length);
25-
::std::env::var(<span class="string">&quot;gateau&quot;</span>).is_ok();
25+
::std::env::var(<span class="string">"gateau"</span>).is_ok();
2626
<span class="attr">#[rustfmt::skip]
2727
</span><span class="kw">let </span>s:std::path::PathBuf = std::path::PathBuf::new();
2828
<span class="kw">let </span><span class="kw-2">mut </span>s = String::new();

Diff for: src/librustdoc/html/render/print_item.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -1737,7 +1737,14 @@ fn item_variants(
17371737
w.write_str("</h3></section>");
17381738

17391739
let heading_and_fields = match &variant_data.kind {
1740-
clean::VariantKind::Struct(s) => Some(("Fields", &s.fields)),
1740+
clean::VariantKind::Struct(s) => {
1741+
// If there is no field to display, no need to add the heading.
1742+
if s.fields.iter().any(|f| !f.is_doc_hidden()) {
1743+
Some(("Fields", &s.fields))
1744+
} else {
1745+
None
1746+
}
1747+
}
17411748
clean::VariantKind::Tuple(fields) => {
17421749
// Documentation on tuple variant fields is rare, so to reduce noise we only emit
17431750
// the section if at least one field is documented.

Diff for: tests/rustdoc/enum-variant-fields-heading.rs

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// This is a regression test for <https://github.com/rust-lang/rust/issues/118195>.
2+
// It ensures that the "Fields" heading is not generated if no field is displayed.
3+
4+
#![crate_name = "foo"]
5+
6+
// @has 'foo/enum.Foo.html'
7+
// @has - '//*[@id="variant.A"]' 'A'
8+
// @count - '//*[@id="variant.A.fields"]' 0
9+
// @has - '//*[@id="variant.B"]' 'B'
10+
// @count - '//*[@id="variant.B.fields"]' 0
11+
// @snapshot variants - '//*[@id="main-content"]/*[@class="variants"]'
12+
13+
pub enum Foo {
14+
/// A variant with no fields
15+
A {},
16+
/// A variant with hidden fields
17+
B { #[doc(hidden)] a: u8 },
18+
}
+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<div class="variants"><section id="variant.A" class="variant"><a href="#variant.A" class="anchor">&#167;</a><h3 class="code-header">A</h3></section><div class="docblock"><p>A variant with no fields</p>
2+
</div><section id="variant.B" class="variant"><a href="#variant.B" class="anchor">&#167;</a><h3 class="code-header">B</h3></section><div class="docblock"><p>A variant with hidden fields</p>
3+
</div></div>

0 commit comments

Comments
 (0)