Skip to content

Rollup of 6 pull requests #110994

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Apr 29, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.lock
Original file line number Diff line number Diff line change
@@ -2370,9 +2370,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"

[[package]]
name = "openssl-sys"
version = "0.9.84"
version = "0.9.87"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a20eace9dc2d82904039cb76dcf50fb1a0bba071cfd1629720b5d6f1ddba0fa"
checksum = "8e17f59264b2809d77ae94f0e1ebabc434773f370d6ca667bd223ea10e06cc7e"
dependencies = [
"cc",
"libc",
42 changes: 31 additions & 11 deletions compiler/rustc_arena/src/lib.rs
Original file line number Diff line number Diff line change
@@ -20,6 +20,7 @@
#![feature(rustc_attrs)]
#![cfg_attr(test, feature(test))]
#![feature(strict_provenance)]
#![deny(unsafe_op_in_unsafe_fn)]
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
#![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> {
#[inline]
unsafe fn new(capacity: usize) -> ArenaChunk<T> {
ArenaChunk {
storage: NonNull::new_unchecked(Box::into_raw(Box::new_uninit_slice(capacity))),
storage: NonNull::from(Box::leak(Box::new_uninit_slice(capacity))),
entries: 0,
}
}

/// Destroys this arena chunk.
///
/// # Safety
///
/// The caller must ensure that `len` elements of this chunk have been initialized.
#[inline]
unsafe fn destroy(&mut self, len: usize) {
// The branch on needs_drop() is an -O1 performance optimization.
// Without the branch, dropping TypedArena<u8> takes linear time.
// Without the branch, dropping TypedArena<T> takes linear time.
if mem::needs_drop::<T>() {
let slice = self.storage.as_mut();
ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(&mut slice[..len]));
// SAFETY: The caller must ensure that `len` elements of this chunk have
// been initialized.
unsafe {
let slice = self.storage.as_mut();
ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(&mut slice[..len]));
}
}
}

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

let start_ptr = self.ptr.get();
self.ptr.set(start_ptr.add(len));
// SAFETY: `self.ensure_capacity` makes sure that there is enough space
// for `len` elements.
unsafe { self.ptr.set(start_ptr.add(len)) };
start_ptr
}

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

/// # Safety
///
/// The caller must ensure that `mem` is valid for writes up to
/// `size_of::<T>() * len`.
#[inline]
unsafe fn write_from_iter<T, I: Iterator<Item = T>>(
&self,
@@ -494,13 +509,18 @@ impl DroplessArena {
// Use a manual loop since LLVM manages to optimize it better for
// slice iterators
loop {
let value = iter.next();
if i >= len || value.is_none() {
// We only return as many items as the iterator gave us, even
// though it was supposed to give us `len`
return slice::from_raw_parts_mut(mem, i);
// SAFETY: The caller must ensure that `mem` is valid for writes up to
// `size_of::<T>() * len`.
unsafe {
match iter.next() {
Some(value) if i < len => mem.add(i).write(value),
Some(_) | None => {
// We only return as many items as the iterator gave us, even
// though it was supposed to give us `len`
return slice::from_raw_parts_mut(mem, i);
}
}
}
ptr::write(mem.add(i), value.unwrap());
i += 1;
}
}
35 changes: 29 additions & 6 deletions src/bootstrap/bootstrap.py
Original file line number Diff line number Diff line change
@@ -19,7 +19,10 @@
except ImportError:
lzma = None

if sys.platform == 'win32':
def platform_is_win32():
return sys.platform == 'win32'

if platform_is_win32():
EXE_SUFFIX = ".exe"
else:
EXE_SUFFIX = ""
@@ -78,15 +81,14 @@ def _download(path, url, probably_big, verbose, exception):
if probably_big or verbose:
print("downloading {}".format(url))

platform_is_win32 = sys.platform == 'win32'
try:
if probably_big or verbose:
option = "-#"
else:
option = "-s"
# If curl is not present on Win32, we should not sys.exit
# but raise `CalledProcessError` or `OSError` instead
require(["curl", "--version"], exception=platform_is_win32)
require(["curl", "--version"], exception=platform_is_win32())
with open(path, "wb") as outfile:
run(["curl", option,
"-L", # Follow redirect.
@@ -99,8 +101,8 @@ def _download(path, url, probably_big, verbose, exception):
)
except (subprocess.CalledProcessError, OSError, RuntimeError):
# see http://serverfault.com/questions/301128/how-to-download
if platform_is_win32:
run(["PowerShell.exe", "/nologo", "-Command",
if platform_is_win32():
run_powershell([
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12;",
"(New-Object System.Net.WebClient).DownloadFile('{}', '{}')".format(url, path)],
verbose=verbose,
@@ -174,6 +176,10 @@ def run(args, verbose=False, exception=False, is_bootstrap=False, **kwargs):
else:
sys.exit(err)

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


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

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

@@ -434,6 +440,23 @@ def download_toolchain(self):
(not os.path.exists(self.rustc()) or
self.program_out_of_date(self.rustc_stamp(), key)):
if os.path.exists(bin_root):
# HACK: On Windows, we can't delete rust-analyzer-proc-macro-server while it's
# running. Kill it.
if platform_is_win32():
print("Killing rust-analyzer-proc-macro-srv before deleting stage0 toolchain")
regex = '{}\\\\(host|{})\\\\stage0\\\\libexec'.format(
os.path.basename(self.build_dir),
self.build
)
script = (
# NOTE: can't use `taskkill` or `Get-Process -Name` because they error if
# the server isn't running.
'Get-Process | ' +
'Where-Object {$_.Name -eq "rust-analyzer-proc-macro-srv"} |' +
'Where-Object {{$_.Path -match "{}"}} |'.format(regex) +
'Stop-Process'
)
run_powershell([script])
shutil.rmtree(bin_root)
tarball_suffix = '.tar.gz' if lzma is None else '.tar.xz'
filename = "rust-std-{}-{}{}".format(
38 changes: 38 additions & 0 deletions src/doc/rustdoc/src/lints.md
Original file line number Diff line number Diff line change
@@ -374,3 +374,41 @@ warning: this URL is not a hyperlink

warning: 2 warnings emitted
```

## `unescaped_backticks`

This lint is **allowed by default**. It detects backticks (\`) that are not escaped.
This usually means broken inline code. For example:

```rust
#![warn(rustdoc::unescaped_backticks)]

/// `add(a, b) is the same as `add(b, a)`.
pub fn add(a: i32, b: i32) -> i32 { a + b }
```

Which will give:

```text
warning: unescaped backtick
--> src/lib.rs:3:41
|
3 | /// `add(a, b) is the same as `add(b, a)`.
| ^
|
note: the lint level is defined here
--> src/lib.rs:1:9
|
1 | #![warn(rustdoc::unescaped_backticks)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: a previous inline code might be longer than expected
|
3 | /// `add(a, b)` is the same as `add(b, a)`.
| +
help: if you meant to use a literal backtick, escape it
|
3 | /// `add(a, b) is the same as `add(b, a)\`.
| +

warning: 1 warning emitted
```
18 changes: 12 additions & 6 deletions src/librustdoc/html/render/mod.rs
Original file line number Diff line number Diff line change
@@ -1155,10 +1155,10 @@ fn render_assoc_items_inner(
let (non_trait, traits): (Vec<_>, _) = v.iter().partition(|i| i.inner_impl().trait_.is_none());
if !non_trait.is_empty() {
let mut tmp_buf = Buffer::html();
let (render_mode, id) = match what {
let (render_mode, id, class_html) = match what {
AssocItemRender::All => {
write_impl_section_heading(&mut tmp_buf, "Implementations", "implementations");
(RenderMode::Normal, "implementations-list".to_owned())
(RenderMode::Normal, "implementations-list".to_owned(), "")
}
AssocItemRender::DerefFor { trait_, type_, deref_mut_ } => {
let id =
@@ -1175,7 +1175,11 @@ fn render_assoc_items_inner(
),
&id,
);
(RenderMode::ForDeref { mut_: deref_mut_ }, cx.derive_id(id))
(
RenderMode::ForDeref { mut_: deref_mut_ },
cx.derive_id(id),
r#" class="impl-items""#,
)
}
};
let mut impls_buf = Buffer::html();
@@ -1199,7 +1203,7 @@ fn render_assoc_items_inner(
}
if !impls_buf.is_empty() {
write!(w, "{}", tmp_buf.into_inner()).unwrap();
write!(w, "<div id=\"{}\">", id).unwrap();
write!(w, "<div id=\"{id}\"{class_html}>").unwrap();
write!(w, "{}", impls_buf.into_inner()).unwrap();
w.write_str("</div>").unwrap();
}
@@ -1788,12 +1792,14 @@ fn render_impl(
.into_string()
);
}
if !default_impl_items.is_empty() || !impl_items.is_empty() {
w.write_str("<div class=\"impl-items\">");
close_tags.insert_str(0, "</div>");
}
}
if !default_impl_items.is_empty() || !impl_items.is_empty() {
w.write_str("<div class=\"impl-items\">");
w.push_buffer(default_impl_items);
w.push_buffer(impl_items);
close_tags.insert_str(0, "</div>");
}
w.write_str(&close_tags);
}
11 changes: 6 additions & 5 deletions src/librustdoc/lib.rs
Original file line number Diff line number Diff line change
@@ -7,14 +7,15 @@
#![feature(assert_matches)]
#![feature(box_patterns)]
#![feature(drain_filter)]
#![feature(impl_trait_in_assoc_type)]
#![feature(iter_intersperse)]
#![feature(lazy_cell)]
#![feature(let_chains)]
#![feature(test)]
#![feature(never_type)]
#![feature(lazy_cell)]
#![feature(type_ascription)]
#![feature(iter_intersperse)]
#![feature(round_char_boundary)]
#![feature(test)]
#![feature(type_alias_impl_trait)]
#![feature(impl_trait_in_assoc_type)]
#![feature(type_ascription)]
#![recursion_limit = "256"]
#![warn(rustc::internal)]
#![allow(clippy::collapsible_if, clippy::collapsible_else_if)]
12 changes: 12 additions & 0 deletions src/librustdoc/lint.rs
Original file line number Diff line number Diff line change
@@ -174,6 +174,17 @@ declare_rustdoc_lint! {
"codeblock could not be parsed as valid Rust or is empty"
}

declare_rustdoc_lint! {
/// The `unescaped_backticks` lint detects unescaped backticks (\`), which usually
/// mean broken inline code. This is a `rustdoc` only lint, see the documentation
/// in the [rustdoc book].
///
/// [rustdoc book]: ../../../rustdoc/lints.html#unescaped_backticks
UNESCAPED_BACKTICKS,
Allow,
"detects unescaped backticks in doc comments"
}

pub(crate) static RUSTDOC_LINTS: Lazy<Vec<&'static Lint>> = Lazy::new(|| {
vec![
BROKEN_INTRA_DOC_LINKS,
@@ -185,6 +196,7 @@ pub(crate) static RUSTDOC_LINTS: Lazy<Vec<&'static Lint>> = Lazy::new(|| {
INVALID_HTML_TAGS,
BARE_URLS,
MISSING_CRATE_LEVEL_DOCS,
UNESCAPED_BACKTICKS,
]
});

2 changes: 2 additions & 0 deletions src/librustdoc/passes/lint.rs
Original file line number Diff line number Diff line change
@@ -4,6 +4,7 @@
mod bare_urls;
mod check_code_block_syntax;
mod html_tags;
mod unescaped_backticks;

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

self.visit_item_recur(item)
}
Loading