Skip to content

Commit eb62877

Browse files
committed
Auto merge of #110994 - matthiaskrgr:rollup-wv4u5yi, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - #105848 (rustdoc: Add a new lint for broken inline code) - #110644 (Update tests for libtest `--format json`) - #110950 (Deny the `unsafe_op_in_unsafe_fn` lint in `rustc_arena`.) - #110951 (Add support for LibreSSL 3.7.x) - #110964 (rustdoc: fix weird margins between Deref impl items) - #110979 (windows: kill rust-analyzer-proc-macro-srv before deleting stage0 directory) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 27d22d2 + 72de69e commit eb62877

30 files changed

+1952
-38
lines changed

Cargo.lock

+2-2
Original file line numberDiff line numberDiff line change
@@ -2370,9 +2370,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
23702370

23712371
[[package]]
23722372
name = "openssl-sys"
2373-
version = "0.9.84"
2373+
version = "0.9.87"
23742374
source = "registry+https://github.com/rust-lang/crates.io-index"
2375-
checksum = "3a20eace9dc2d82904039cb76dcf50fb1a0bba071cfd1629720b5d6f1ddba0fa"
2375+
checksum = "8e17f59264b2809d77ae94f0e1ebabc434773f370d6ca667bd223ea10e06cc7e"
23762376
dependencies = [
23772377
"cc",
23782378
"libc",

compiler/rustc_arena/src/lib.rs

+31-11
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#![feature(rustc_attrs)]
2121
#![cfg_attr(test, feature(test))]
2222
#![feature(strict_provenance)]
23+
#![deny(unsafe_op_in_unsafe_fn)]
2324
#![deny(rustc::untranslatable_diagnostic)]
2425
#![deny(rustc::diagnostic_outside_of_impl)]
2526
#![allow(clippy::mut_from_ref)] // Arena allocators are one of the places where this pattern is fine.
@@ -74,19 +75,27 @@ impl<T> ArenaChunk<T> {
7475
#[inline]
7576
unsafe fn new(capacity: usize) -> ArenaChunk<T> {
7677
ArenaChunk {
77-
storage: NonNull::new_unchecked(Box::into_raw(Box::new_uninit_slice(capacity))),
78+
storage: NonNull::from(Box::leak(Box::new_uninit_slice(capacity))),
7879
entries: 0,
7980
}
8081
}
8182

8283
/// Destroys this arena chunk.
84+
///
85+
/// # Safety
86+
///
87+
/// The caller must ensure that `len` elements of this chunk have been initialized.
8388
#[inline]
8489
unsafe fn destroy(&mut self, len: usize) {
8590
// The branch on needs_drop() is an -O1 performance optimization.
86-
// Without the branch, dropping TypedArena<u8> takes linear time.
91+
// Without the branch, dropping TypedArena<T> takes linear time.
8792
if mem::needs_drop::<T>() {
88-
let slice = self.storage.as_mut();
89-
ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(&mut slice[..len]));
93+
// SAFETY: The caller must ensure that `len` elements of this chunk have
94+
// been initialized.
95+
unsafe {
96+
let slice = self.storage.as_mut();
97+
ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(&mut slice[..len]));
98+
}
9099
}
91100
}
92101

@@ -255,7 +264,9 @@ impl<T> TypedArena<T> {
255264
self.ensure_capacity(len);
256265

257266
let start_ptr = self.ptr.get();
258-
self.ptr.set(start_ptr.add(len));
267+
// SAFETY: `self.ensure_capacity` makes sure that there is enough space
268+
// for `len` elements.
269+
unsafe { self.ptr.set(start_ptr.add(len)) };
259270
start_ptr
260271
}
261272

@@ -483,6 +494,10 @@ impl DroplessArena {
483494
}
484495
}
485496

497+
/// # Safety
498+
///
499+
/// The caller must ensure that `mem` is valid for writes up to
500+
/// `size_of::<T>() * len`.
486501
#[inline]
487502
unsafe fn write_from_iter<T, I: Iterator<Item = T>>(
488503
&self,
@@ -494,13 +509,18 @@ impl DroplessArena {
494509
// Use a manual loop since LLVM manages to optimize it better for
495510
// slice iterators
496511
loop {
497-
let value = iter.next();
498-
if i >= len || value.is_none() {
499-
// We only return as many items as the iterator gave us, even
500-
// though it was supposed to give us `len`
501-
return slice::from_raw_parts_mut(mem, i);
512+
// SAFETY: The caller must ensure that `mem` is valid for writes up to
513+
// `size_of::<T>() * len`.
514+
unsafe {
515+
match iter.next() {
516+
Some(value) if i < len => mem.add(i).write(value),
517+
Some(_) | None => {
518+
// We only return as many items as the iterator gave us, even
519+
// though it was supposed to give us `len`
520+
return slice::from_raw_parts_mut(mem, i);
521+
}
522+
}
502523
}
503-
ptr::write(mem.add(i), value.unwrap());
504524
i += 1;
505525
}
506526
}

src/bootstrap/bootstrap.py

+29-6
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@
1919
except ImportError:
2020
lzma = None
2121

22-
if sys.platform == 'win32':
22+
def platform_is_win32():
23+
return sys.platform == 'win32'
24+
25+
if platform_is_win32():
2326
EXE_SUFFIX = ".exe"
2427
else:
2528
EXE_SUFFIX = ""
@@ -78,15 +81,14 @@ def _download(path, url, probably_big, verbose, exception):
7881
if probably_big or verbose:
7982
print("downloading {}".format(url))
8083

81-
platform_is_win32 = sys.platform == 'win32'
8284
try:
8385
if probably_big or verbose:
8486
option = "-#"
8587
else:
8688
option = "-s"
8789
# If curl is not present on Win32, we should not sys.exit
8890
# but raise `CalledProcessError` or `OSError` instead
89-
require(["curl", "--version"], exception=platform_is_win32)
91+
require(["curl", "--version"], exception=platform_is_win32())
9092
with open(path, "wb") as outfile:
9193
run(["curl", option,
9294
"-L", # Follow redirect.
@@ -99,8 +101,8 @@ def _download(path, url, probably_big, verbose, exception):
99101
)
100102
except (subprocess.CalledProcessError, OSError, RuntimeError):
101103
# see http://serverfault.com/questions/301128/how-to-download
102-
if platform_is_win32:
103-
run(["PowerShell.exe", "/nologo", "-Command",
104+
if platform_is_win32():
105+
run_powershell([
104106
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12;",
105107
"(New-Object System.Net.WebClient).DownloadFile('{}', '{}')".format(url, path)],
106108
verbose=verbose,
@@ -174,6 +176,10 @@ def run(args, verbose=False, exception=False, is_bootstrap=False, **kwargs):
174176
else:
175177
sys.exit(err)
176178

179+
def run_powershell(script, *args, **kwargs):
180+
"""Run a powershell script"""
181+
run(["PowerShell.exe", "/nologo", "-Command"] + script, *args, **kwargs)
182+
177183

178184
def require(cmd, exit=True, exception=False):
179185
'''Run a command, returning its output.
@@ -229,7 +235,7 @@ def default_build_triple(verbose):
229235
print("pre-installed rustc not detected: {}".format(e))
230236
print("falling back to auto-detect")
231237

232-
required = sys.platform != 'win32'
238+
required = not platform_is_win32()
233239
ostype = require(["uname", "-s"], exit=required)
234240
cputype = require(['uname', '-m'], exit=required)
235241

@@ -434,6 +440,23 @@ def download_toolchain(self):
434440
(not os.path.exists(self.rustc()) or
435441
self.program_out_of_date(self.rustc_stamp(), key)):
436442
if os.path.exists(bin_root):
443+
# HACK: On Windows, we can't delete rust-analyzer-proc-macro-server while it's
444+
# running. Kill it.
445+
if platform_is_win32():
446+
print("Killing rust-analyzer-proc-macro-srv before deleting stage0 toolchain")
447+
regex = '{}\\\\(host|{})\\\\stage0\\\\libexec'.format(
448+
os.path.basename(self.build_dir),
449+
self.build
450+
)
451+
script = (
452+
# NOTE: can't use `taskkill` or `Get-Process -Name` because they error if
453+
# the server isn't running.
454+
'Get-Process | ' +
455+
'Where-Object {$_.Name -eq "rust-analyzer-proc-macro-srv"} |' +
456+
'Where-Object {{$_.Path -match "{}"}} |'.format(regex) +
457+
'Stop-Process'
458+
)
459+
run_powershell([script])
437460
shutil.rmtree(bin_root)
438461
tarball_suffix = '.tar.gz' if lzma is None else '.tar.xz'
439462
filename = "rust-std-{}-{}{}".format(

src/doc/rustdoc/src/lints.md

+38
Original file line numberDiff line numberDiff line change
@@ -374,3 +374,41 @@ warning: this URL is not a hyperlink
374374
375375
warning: 2 warnings emitted
376376
```
377+
378+
## `unescaped_backticks`
379+
380+
This lint is **allowed by default**. It detects backticks (\`) that are not escaped.
381+
This usually means broken inline code. For example:
382+
383+
```rust
384+
#![warn(rustdoc::unescaped_backticks)]
385+
386+
/// `add(a, b) is the same as `add(b, a)`.
387+
pub fn add(a: i32, b: i32) -> i32 { a + b }
388+
```
389+
390+
Which will give:
391+
392+
```text
393+
warning: unescaped backtick
394+
--> src/lib.rs:3:41
395+
|
396+
3 | /// `add(a, b) is the same as `add(b, a)`.
397+
| ^
398+
|
399+
note: the lint level is defined here
400+
--> src/lib.rs:1:9
401+
|
402+
1 | #![warn(rustdoc::unescaped_backticks)]
403+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
404+
help: a previous inline code might be longer than expected
405+
|
406+
3 | /// `add(a, b)` is the same as `add(b, a)`.
407+
| +
408+
help: if you meant to use a literal backtick, escape it
409+
|
410+
3 | /// `add(a, b) is the same as `add(b, a)\`.
411+
| +
412+
413+
warning: 1 warning emitted
414+
```

src/librustdoc/html/render/mod.rs

+12-6
Original file line numberDiff line numberDiff line change
@@ -1155,10 +1155,10 @@ fn render_assoc_items_inner(
11551155
let (non_trait, traits): (Vec<_>, _) = v.iter().partition(|i| i.inner_impl().trait_.is_none());
11561156
if !non_trait.is_empty() {
11571157
let mut tmp_buf = Buffer::html();
1158-
let (render_mode, id) = match what {
1158+
let (render_mode, id, class_html) = match what {
11591159
AssocItemRender::All => {
11601160
write_impl_section_heading(&mut tmp_buf, "Implementations", "implementations");
1161-
(RenderMode::Normal, "implementations-list".to_owned())
1161+
(RenderMode::Normal, "implementations-list".to_owned(), "")
11621162
}
11631163
AssocItemRender::DerefFor { trait_, type_, deref_mut_ } => {
11641164
let id =
@@ -1175,7 +1175,11 @@ fn render_assoc_items_inner(
11751175
),
11761176
&id,
11771177
);
1178-
(RenderMode::ForDeref { mut_: deref_mut_ }, cx.derive_id(id))
1178+
(
1179+
RenderMode::ForDeref { mut_: deref_mut_ },
1180+
cx.derive_id(id),
1181+
r#" class="impl-items""#,
1182+
)
11791183
}
11801184
};
11811185
let mut impls_buf = Buffer::html();
@@ -1199,7 +1203,7 @@ fn render_assoc_items_inner(
11991203
}
12001204
if !impls_buf.is_empty() {
12011205
write!(w, "{}", tmp_buf.into_inner()).unwrap();
1202-
write!(w, "<div id=\"{}\">", id).unwrap();
1206+
write!(w, "<div id=\"{id}\"{class_html}>").unwrap();
12031207
write!(w, "{}", impls_buf.into_inner()).unwrap();
12041208
w.write_str("</div>").unwrap();
12051209
}
@@ -1788,12 +1792,14 @@ fn render_impl(
17881792
.into_string()
17891793
);
17901794
}
1795+
if !default_impl_items.is_empty() || !impl_items.is_empty() {
1796+
w.write_str("<div class=\"impl-items\">");
1797+
close_tags.insert_str(0, "</div>");
1798+
}
17911799
}
17921800
if !default_impl_items.is_empty() || !impl_items.is_empty() {
1793-
w.write_str("<div class=\"impl-items\">");
17941801
w.push_buffer(default_impl_items);
17951802
w.push_buffer(impl_items);
1796-
close_tags.insert_str(0, "</div>");
17971803
}
17981804
w.write_str(&close_tags);
17991805
}

src/librustdoc/lib.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,15 @@
77
#![feature(assert_matches)]
88
#![feature(box_patterns)]
99
#![feature(drain_filter)]
10+
#![feature(impl_trait_in_assoc_type)]
11+
#![feature(iter_intersperse)]
12+
#![feature(lazy_cell)]
1013
#![feature(let_chains)]
11-
#![feature(test)]
1214
#![feature(never_type)]
13-
#![feature(lazy_cell)]
14-
#![feature(type_ascription)]
15-
#![feature(iter_intersperse)]
15+
#![feature(round_char_boundary)]
16+
#![feature(test)]
1617
#![feature(type_alias_impl_trait)]
17-
#![feature(impl_trait_in_assoc_type)]
18+
#![feature(type_ascription)]
1819
#![recursion_limit = "256"]
1920
#![warn(rustc::internal)]
2021
#![allow(clippy::collapsible_if, clippy::collapsible_else_if)]

src/librustdoc/lint.rs

+12
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,17 @@ declare_rustdoc_lint! {
174174
"codeblock could not be parsed as valid Rust or is empty"
175175
}
176176

177+
declare_rustdoc_lint! {
178+
/// The `unescaped_backticks` lint detects unescaped backticks (\`), which usually
179+
/// mean broken inline code. This is a `rustdoc` only lint, see the documentation
180+
/// in the [rustdoc book].
181+
///
182+
/// [rustdoc book]: ../../../rustdoc/lints.html#unescaped_backticks
183+
UNESCAPED_BACKTICKS,
184+
Allow,
185+
"detects unescaped backticks in doc comments"
186+
}
187+
177188
pub(crate) static RUSTDOC_LINTS: Lazy<Vec<&'static Lint>> = Lazy::new(|| {
178189
vec![
179190
BROKEN_INTRA_DOC_LINKS,
@@ -185,6 +196,7 @@ pub(crate) static RUSTDOC_LINTS: Lazy<Vec<&'static Lint>> = Lazy::new(|| {
185196
INVALID_HTML_TAGS,
186197
BARE_URLS,
187198
MISSING_CRATE_LEVEL_DOCS,
199+
UNESCAPED_BACKTICKS,
188200
]
189201
});
190202

src/librustdoc/passes/lint.rs

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
mod bare_urls;
55
mod check_code_block_syntax;
66
mod html_tags;
7+
mod unescaped_backticks;
78

89
use super::Pass;
910
use crate::clean::*;
@@ -27,6 +28,7 @@ impl<'a, 'tcx> DocVisitor for Linter<'a, 'tcx> {
2728
bare_urls::visit_item(self.cx, item);
2829
check_code_block_syntax::visit_item(self.cx, item);
2930
html_tags::visit_item(self.cx, item);
31+
unescaped_backticks::visit_item(self.cx, item);
3032

3133
self.visit_item_recur(item)
3234
}

0 commit comments

Comments
 (0)