Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit cee62c1

Browse files
committed
Auto merge of rust-lang#75351 - JohnTitor:rollup-q9udsyx, r=JohnTitor
Rollup of 8 pull requests Successful merges: - rust-lang#74200 (Std panicking unsafe block in unsafe fn) - rust-lang#75286 (Add additional case for Path starts with) - rust-lang#75318 (Resolve `char` as a primitive even if there is a module in scope) - rust-lang#75320 (Detect likely `for foo of bar` JS syntax) - rust-lang#75328 (Cleanup E0749) - rust-lang#75344 (Rename "Important traits" to "Notable traits") - rust-lang#75348 (Move to intra-doc links in library/core/src/time.rs) - rust-lang#75350 (Do not ICE when lowering invalid extern fn with bodies) Failed merges: r? @ghost
2 parents f5fef3c + 5369619 commit cee62c1

File tree

22 files changed

+162
-60
lines changed

22 files changed

+162
-60
lines changed

library/core/src/time.rs

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,10 @@ const MICROS_PER_SEC: u64 = 1_000_000;
3030
/// nanosecond-level precision, APIs binding a system timeout will typically round up
3131
/// the number of nanoseconds.
3232
///
33-
/// `Duration`s implement many common traits, including [`Add`], [`Sub`], and other
34-
/// [`ops`] traits. It implements `Default` by returning a zero-length `Duration`.
33+
/// [`Duration`]s implement many common traits, including [`Add`], [`Sub`], and other
34+
/// [`ops`] traits. It implements [`Default`] by returning a zero-length `Duration`.
3535
///
36-
/// [`Add`]: ../../std/ops/trait.Add.html
37-
/// [`Sub`]: ../../std/ops/trait.Sub.html
38-
/// [`ops`]: ../../std/ops/index.html
36+
/// [`ops`]: crate::ops
3937
///
4038
/// # Examples
4139
///
@@ -293,7 +291,7 @@ impl Duration {
293291
/// + duration.subsec_nanos() as f64 * 1e-9);
294292
/// ```
295293
///
296-
/// [`subsec_nanos`]: #method.subsec_nanos
294+
/// [`subsec_nanos`]: Duration::subsec_nanos
297295
#[stable(feature = "duration", since = "1.3.0")]
298296
#[rustc_const_stable(feature = "duration", since = "1.32.0")]
299297
#[inline]
@@ -421,8 +419,6 @@ impl Duration {
421419
/// Checked `Duration` addition. Computes `self + other`, returning [`None`]
422420
/// if overflow occurred.
423421
///
424-
/// [`None`]: ../../std/option/enum.Option.html#variant.None
425-
///
426422
/// # Examples
427423
///
428424
/// Basic usage:
@@ -457,8 +453,6 @@ impl Duration {
457453
/// Checked `Duration` subtraction. Computes `self - other`, returning [`None`]
458454
/// if the result would be negative or if overflow occurred.
459455
///
460-
/// [`None`]: ../../std/option/enum.Option.html#variant.None
461-
///
462456
/// # Examples
463457
///
464458
/// Basic usage:
@@ -494,8 +488,6 @@ impl Duration {
494488
/// Checked `Duration` multiplication. Computes `self * other`, returning
495489
/// [`None`] if overflow occurred.
496490
///
497-
/// [`None`]: ../../std/option/enum.Option.html#variant.None
498-
///
499491
/// # Examples
500492
///
501493
/// Basic usage:
@@ -526,8 +518,6 @@ impl Duration {
526518
/// Checked `Duration` division. Computes `self / other`, returning [`None`]
527519
/// if `other == 0`.
528520
///
529-
/// [`None`]: ../../std/option/enum.Option.html#variant.None
530-
///
531521
/// # Examples
532522
///
533523
/// Basic usage:

library/std/src/panicking.rs

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
//! * Executing a panic up to doing the actual implementation
88
//! * Shims around "try"
99
10+
#![deny(unsafe_op_in_unsafe_fn)]
11+
1012
use core::panic::{BoxMeUp, Location, PanicInfo};
1113

1214
use crate::any::Any;
@@ -322,25 +324,48 @@ pub unsafe fn r#try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<dyn Any + Send>>
322324
let mut data = Data { f: ManuallyDrop::new(f) };
323325

324326
let data_ptr = &mut data as *mut _ as *mut u8;
325-
return if intrinsics::r#try(do_call::<F, R>, data_ptr, do_catch::<F, R>) == 0 {
326-
Ok(ManuallyDrop::into_inner(data.r))
327-
} else {
328-
Err(ManuallyDrop::into_inner(data.p))
329-
};
327+
// SAFETY:
328+
//
329+
// Access to the union's fields: this is `std` and we know that the `r#try`
330+
// intrinsic fills in the `r` or `p` union field based on its return value.
331+
//
332+
// The call to `intrinsics::r#try` is made safe by:
333+
// - `do_call`, the first argument, can be called with the initial `data_ptr`.
334+
// - `do_catch`, the second argument, can be called with the `data_ptr` as well.
335+
// See their safety preconditions for more informations
336+
unsafe {
337+
return if intrinsics::r#try(do_call::<F, R>, data_ptr, do_catch::<F, R>) == 0 {
338+
Ok(ManuallyDrop::into_inner(data.r))
339+
} else {
340+
Err(ManuallyDrop::into_inner(data.p))
341+
};
342+
}
330343

331344
// We consider unwinding to be rare, so mark this function as cold. However,
332345
// do not mark it no-inline -- that decision is best to leave to the
333346
// optimizer (in most cases this function is not inlined even as a normal,
334347
// non-cold function, though, as of the writing of this comment).
335348
#[cold]
336349
unsafe fn cleanup(payload: *mut u8) -> Box<dyn Any + Send + 'static> {
337-
let obj = Box::from_raw(__rust_panic_cleanup(payload));
350+
// SAFETY: The whole unsafe block hinges on a correct implementation of
351+
// the panic handler `__rust_panic_cleanup`. As such we can only
352+
// assume it returns the correct thing for `Box::from_raw` to work
353+
// without undefined behavior.
354+
let obj = unsafe { Box::from_raw(__rust_panic_cleanup(payload)) };
338355
panic_count::decrease();
339356
obj
340357
}
341358

359+
// SAFETY:
360+
// data must be non-NUL, correctly aligned, and a pointer to a `Data<F, R>`
361+
// Its must contains a valid `f` (type: F) value that can be use to fill
362+
// `data.r`.
363+
//
364+
// This function cannot be marked as `unsafe` because `intrinsics::r#try`
365+
// expects normal function pointers.
342366
#[inline]
343367
fn do_call<F: FnOnce() -> R, R>(data: *mut u8) {
368+
// SAFETY: this is the responsibilty of the caller, see above.
344369
unsafe {
345370
let data = data as *mut Data<F, R>;
346371
let data = &mut (*data);
@@ -352,8 +377,21 @@ pub unsafe fn r#try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<dyn Any + Send>>
352377
// We *do* want this part of the catch to be inlined: this allows the
353378
// compiler to properly track accesses to the Data union and optimize it
354379
// away most of the time.
380+
//
381+
// SAFETY:
382+
// data must be non-NUL, correctly aligned, and a pointer to a `Data<F, R>`
383+
// Since this uses `cleanup` it also hinges on a correct implementation of
384+
// `__rustc_panic_cleanup`.
385+
//
386+
// This function cannot be marked as `unsafe` because `intrinsics::r#try`
387+
// expects normal function pointers.
355388
#[inline]
356389
fn do_catch<F: FnOnce() -> R, R>(data: *mut u8, payload: *mut u8) {
390+
// SAFETY: this is the responsibilty of the caller, see above.
391+
//
392+
// When `__rustc_panic_cleaner` is correctly implemented we can rely
393+
// on `obj` being the correct thing to pass to `data.p` (after wrapping
394+
// in `ManuallyDrop`).
357395
unsafe {
358396
let data = data as *mut Data<F, R>;
359397
let data = &mut (*data);

library/std/src/path.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2031,9 +2031,13 @@ impl Path {
20312031
/// assert!(path.starts_with("/etc"));
20322032
/// assert!(path.starts_with("/etc/"));
20332033
/// assert!(path.starts_with("/etc/passwd"));
2034-
/// assert!(path.starts_with("/etc/passwd/"));
2034+
/// assert!(path.starts_with("/etc/passwd/")); // extra slash is okay
2035+
/// assert!(path.starts_with("/etc/passwd///")); // multiple extra slashes are okay
20352036
///
20362037
/// assert!(!path.starts_with("/e"));
2038+
/// assert!(!path.starts_with("/etc/passwd.txt"));
2039+
///
2040+
/// assert!(!Path::new("/etc/foo.rs").starts_with("/etc/foo"));
20372041
/// ```
20382042
#[stable(feature = "rust1", since = "1.0.0")]
20392043
pub fn starts_with<P: AsRef<Path>>(&self, base: P) -> bool {

library/std/src/thread/local.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,11 @@ macro_rules! __thread_local_inner {
172172
static __KEY: $crate::thread::__OsLocalKeyInner<$t> =
173173
$crate::thread::__OsLocalKeyInner::new();
174174

175-
__KEY.get(__init)
175+
// FIXME: remove the #[allow(...)] marker when macros don't
176+
// raise warning for missing/extraneous unsafe blocks anymore.
177+
// See https://github.com/rust-lang/rust/issues/74838.
178+
#[allow(unused_unsafe)]
179+
unsafe { __KEY.get(__init) }
176180
}
177181

178182
unsafe {

src/librustc_ast_lowering/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
573573
.resolver
574574
.trait_map()
575575
.iter()
576-
.map(|(&k, v)| (self.node_id_to_hir_id[k].unwrap(), v.clone()))
576+
.filter_map(|(&k, v)| {
577+
self.node_id_to_hir_id.get(k).and_then(|id| id.as_ref()).map(|id| (*id, v.clone()))
578+
})
577579
.collect();
578580

579581
let mut def_id_to_hir_id = IndexVec::default();
Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,19 @@
1-
Negative impls are not allowed to have any items. Negative impls
2-
declare that a trait is **not** implemented (and never will be) and
3-
hence there is no need to specify the values for trait methods or
4-
other items.
1+
An item was added on a negative impl.
2+
3+
Erroneous code example:
4+
5+
```compile_fail,E0749
6+
# #![feature(negative_impls)]
7+
trait MyTrait {
8+
type Foo;
9+
}
10+
11+
impl !MyTrait for u32 {
12+
type Foo = i32; // error!
13+
}
14+
# fn main() {}
15+
```
16+
17+
Negative impls are not allowed to have any items. Negative impls declare that a
18+
trait is **not** implemented (and never will be) and hence there is no need to
19+
specify the values for trait methods or other items.

src/librustc_parse/parser/expr.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1733,13 +1733,20 @@ impl<'a> Parser<'a> {
17331733
Ok(self.mk_expr(lo.to(self.prev_token.span), kind, attrs))
17341734
}
17351735

1736-
fn error_missing_in_for_loop(&self) {
1737-
let in_span = self.prev_token.span.between(self.token.span);
1738-
self.struct_span_err(in_span, "missing `in` in `for` loop")
1736+
fn error_missing_in_for_loop(&mut self) {
1737+
let (span, msg, sugg) = if self.token.is_ident_named(sym::of) {
1738+
// Possibly using JS syntax (#75311).
1739+
let span = self.token.span;
1740+
self.bump();
1741+
(span, "try using `in` here instead", "in")
1742+
} else {
1743+
(self.prev_token.span.between(self.token.span), "try adding `in` here", " in ")
1744+
};
1745+
self.struct_span_err(span, "missing `in` in `for` loop")
17391746
.span_suggestion_short(
1740-
in_span,
1741-
"try adding `in` here",
1742-
" in ".into(),
1747+
span,
1748+
msg,
1749+
sugg.into(),
17431750
// Has been misleading, at least in the past (closed Issue #48492).
17441751
Applicability::MaybeIncorrect,
17451752
)

src/librustc_span/symbol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,7 @@ symbols! {
737737
not,
738738
note,
739739
object_safe_for_dispatch,
740+
of,
740741
offset,
741742
omit_gdb_pretty_printer_section,
742743
on,

src/librustdoc/html/render/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3450,7 +3450,7 @@ fn spotlight_decl(decl: &clean::FnDecl) -> String {
34503450
if impl_.trait_.def_id().map_or(false, |d| c.traits[&d].is_spotlight) {
34513451
if out.is_empty() {
34523452
out.push_str(&format!(
3453-
"<h3 class=\"important\">Important traits for {}</h3>\
3453+
"<h3 class=\"notable\">Notable traits for {}</h3>\
34543454
<code class=\"content\">",
34553455
impl_.for_.print()
34563456
));
@@ -3485,7 +3485,7 @@ fn spotlight_decl(decl: &clean::FnDecl) -> String {
34853485
if !out.is_empty() {
34863486
out.insert_str(
34873487
0,
3488-
"<span class=\"important-traits\"><span class=\"important-traits-tooltip\">ⓘ<div class='important-traits-tooltiptext'><span class=\"docblock\">"
3488+
"<span class=\"notable-traits\"><span class=\"notable-traits-tooltip\">ⓘ<div class='notable-traits-tooltiptext'><span class=\"docblock\">"
34893489

34903490
);
34913491
out.push_str("</code></span></div></span></span>");

src/librustdoc/html/static/main.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2636,9 +2636,9 @@ function defocusSearchBar() {
26362636
});
26372637
}());
26382638

2639-
onEachLazy(document.getElementsByClassName("important-traits"), function(e) {
2639+
onEachLazy(document.getElementsByClassName("notable-traits"), function(e) {
26402640
e.onclick = function() {
2641-
this.getElementsByClassName('important-traits-tooltiptext')[0]
2641+
this.getElementsByClassName('notable-traits-tooltiptext')[0]
26422642
.classList.toggle("force-tooltip");
26432643
};
26442644
});

0 commit comments

Comments
 (0)