Skip to content

Commit a102dc8

Browse files
committed
Auto merge of #104655 - matthiaskrgr:rollup-r5kfffy, r=matthiaskrgr
Rollup of 9 pull requests Successful merges: - #101310 (Clarify and restrict when `{Arc,Rc}::get_unchecked_mut` is allowed.) - #104461 (Fix building of `aarch64-pc-windows-gnullvm`) - #104487 (update ntapi dep to remove future-incompat warning) - #104504 (Add a detailed note for missing comma typo w/ FRU syntax) - #104581 (rustdoc: remove unused JS IIFE from main.js) - #104632 (avoid non-strict-provenance casts in libcore tests) - #104634 (move core::arch into separate file) - #104641 (replace unusual grammar) - #104643 (add examples to chunks remainder methods. ) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents a28f3c8 + 8465748 commit a102dc8

File tree

26 files changed

+310
-88
lines changed

26 files changed

+310
-88
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
hir_typeck_fru_note = this expression may have been misinterpreted as a `..` range expression
2+
hir_typeck_fru_expr = this expression does not end in a comma...
3+
hir_typeck_fru_expr2 = ... so this is interpreted as a `..` range expression, instead of functional record update syntax
4+
hir_typeck_fru_suggestion =
5+
to set the remaining fields{$expr ->
6+
[NONE]{""}
7+
*[other] {" "}from `{$expr}`
8+
}, separate the last named field with a comma

compiler/rustc_error_messages/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ fluent_messages! {
5151
errors => "../locales/en-US/errors.ftl",
5252
expand => "../locales/en-US/expand.ftl",
5353
hir_analysis => "../locales/en-US/hir_analysis.ftl",
54+
hir_typeck => "../locales/en-US/hir_typeck.ftl",
5455
infer => "../locales/en-US/infer.ftl",
5556
interface => "../locales/en-US/interface.ftl",
5657
lint => "../locales/en-US/lint.ftl",

compiler/rustc_errors/src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,9 @@ pub enum StashKey {
467467
/// When an invalid lifetime e.g. `'2` should be reinterpreted
468468
/// as a char literal in the parser
469469
LifetimeIsChar,
470+
/// Maybe there was a typo where a comma was forgotten before
471+
/// FRU syntax
472+
MaybeFruTypo,
470473
}
471474

472475
fn default_track_diagnostic(_: &Diagnostic) {}

compiler/rustc_hir_typeck/src/errors.rs

+39
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
//! Errors emitted by `rustc_hir_analysis`.
2+
use rustc_errors::{AddToDiagnostic, Applicability, Diagnostic, MultiSpan, SubdiagnosticMessage};
23
use rustc_macros::{Diagnostic, Subdiagnostic};
34
use rustc_middle::ty::Ty;
45
use rustc_span::{symbol::Ident, Span};
@@ -133,3 +134,41 @@ pub struct OpMethodGenericParams {
133134
pub span: Span,
134135
pub method_name: String,
135136
}
137+
138+
pub struct TypeMismatchFruTypo {
139+
/// Span of the LHS of the range
140+
pub expr_span: Span,
141+
/// Span of the `..RHS` part of the range
142+
pub fru_span: Span,
143+
/// Rendered expression of the RHS of the range
144+
pub expr: Option<String>,
145+
}
146+
147+
impl AddToDiagnostic for TypeMismatchFruTypo {
148+
fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
149+
where
150+
F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
151+
{
152+
diag.set_arg("expr", self.expr.as_deref().unwrap_or("NONE"));
153+
154+
// Only explain that `a ..b` is a range if it's split up
155+
if self.expr_span.between(self.fru_span).is_empty() {
156+
diag.span_note(
157+
self.expr_span.to(self.fru_span),
158+
rustc_errors::fluent::hir_typeck_fru_note,
159+
);
160+
} else {
161+
let mut multispan: MultiSpan = vec![self.expr_span, self.fru_span].into();
162+
multispan.push_span_label(self.expr_span, rustc_errors::fluent::hir_typeck_fru_expr);
163+
multispan.push_span_label(self.fru_span, rustc_errors::fluent::hir_typeck_fru_expr2);
164+
diag.span_note(multispan, rustc_errors::fluent::hir_typeck_fru_note);
165+
}
166+
167+
diag.span_suggestion(
168+
self.expr_span.shrink_to_hi(),
169+
rustc_errors::fluent::hir_typeck_fru_suggestion,
170+
", ",
171+
Applicability::MaybeIncorrect,
172+
);
173+
}
174+
}

compiler/rustc_hir_typeck/src/expr.rs

+39-12
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use crate::cast;
66
use crate::coercion::CoerceMany;
77
use crate::coercion::DynamicCoerceMany;
8+
use crate::errors::TypeMismatchFruTypo;
89
use crate::errors::{AddressOfTemporaryTaken, ReturnStmtOutsideOfFnBody, StructExprNonExhaustive};
910
use crate::errors::{
1011
FieldMultiplySpecifiedInInitializer, FunctionalRecordUpdateOnNonStruct,
@@ -1616,10 +1617,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
16161617
self.demand_coerce_diag(&field.expr, ty, field_type, None, AllowTwoPhase::No);
16171618

16181619
if let Some(mut diag) = diag {
1619-
if idx == ast_fields.len() - 1 && remaining_fields.is_empty() {
1620-
self.suggest_fru_from_range(field, variant, substs, &mut diag);
1620+
if idx == ast_fields.len() - 1 {
1621+
if remaining_fields.is_empty() {
1622+
self.suggest_fru_from_range(field, variant, substs, &mut diag);
1623+
diag.emit();
1624+
} else {
1625+
diag.stash(field.span, StashKey::MaybeFruTypo);
1626+
}
1627+
} else {
1628+
diag.emit();
16211629
}
1622-
diag.emit();
16231630
}
16241631
}
16251632

@@ -1877,19 +1884,39 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
18771884
.map(|adt| adt.did())
18781885
!= range_def_id
18791886
{
1880-
let instead = self
1887+
// Suppress any range expr type mismatches
1888+
if let Some(mut diag) = self
1889+
.tcx
1890+
.sess
1891+
.diagnostic()
1892+
.steal_diagnostic(last_expr_field.span, StashKey::MaybeFruTypo)
1893+
{
1894+
diag.delay_as_bug();
1895+
}
1896+
1897+
// Use a (somewhat arbitrary) filtering heuristic to avoid printing
1898+
// expressions that are either too long, or have control character
1899+
//such as newlines in them.
1900+
let expr = self
18811901
.tcx
18821902
.sess
18831903
.source_map()
18841904
.span_to_snippet(range_end.expr.span)
1885-
.map(|s| format!(" from `{s}`"))
1886-
.unwrap_or_default();
1887-
err.span_suggestion(
1888-
range_start.span.shrink_to_hi(),
1889-
&format!("to set the remaining fields{instead}, separate the last named field with a comma"),
1890-
",",
1891-
Applicability::MaybeIncorrect,
1892-
);
1905+
.ok()
1906+
.filter(|s| s.len() < 25 && !s.contains(|c: char| c.is_control()));
1907+
1908+
let fru_span = self
1909+
.tcx
1910+
.sess
1911+
.source_map()
1912+
.span_extend_while(range_start.span, |c| c.is_whitespace())
1913+
.unwrap_or(range_start.span).shrink_to_hi().to(range_end.span);
1914+
1915+
err.subdiagnostic(TypeMismatchFruTypo {
1916+
expr_span: range_start.span,
1917+
fru_span,
1918+
expr,
1919+
});
18931920
}
18941921
}
18951922

library/alloc/src/collections/btree/map.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ pub(super) const MIN_LEN: usize = node::MIN_LEN_AFTER_SPLIT;
4646
/// is done is *very* inefficient for modern computer architectures. In particular, every element
4747
/// is stored in its own individually heap-allocated node. This means that every single insertion
4848
/// triggers a heap-allocation, and every single comparison should be a cache-miss. Since these
49-
/// are both notably expensive things to do in practice, we are forced to at very least reconsider
50-
/// the BST strategy.
49+
/// are both notably expensive things to do in practice, we are forced to, at the very least,
50+
/// reconsider the BST strategy.
5151
///
5252
/// A B-Tree instead makes each node contain B-1 to 2B-1 elements in a contiguous array. By doing
5353
/// this, we reduce the number of allocations by a factor of B, and improve cache efficiency in

library/alloc/src/rc.rs

+37-4
Original file line numberDiff line numberDiff line change
@@ -1091,10 +1091,11 @@ impl<T: ?Sized> Rc<T> {
10911091
///
10921092
/// # Safety
10931093
///
1094-
/// Any other `Rc` or [`Weak`] pointers to the same allocation must not be dereferenced
1095-
/// for the duration of the returned borrow.
1096-
/// This is trivially the case if no such pointers exist,
1097-
/// for example immediately after `Rc::new`.
1094+
/// If any other `Rc` or [`Weak`] pointers to the same allocation exist, then
1095+
/// they must be must not be dereferenced or have active borrows for the duration
1096+
/// of the returned borrow, and their inner type must be exactly the same as the
1097+
/// inner type of this Rc (including lifetimes). This is trivially the case if no
1098+
/// such pointers exist, for example immediately after `Rc::new`.
10981099
///
10991100
/// # Examples
11001101
///
@@ -1109,6 +1110,38 @@ impl<T: ?Sized> Rc<T> {
11091110
/// }
11101111
/// assert_eq!(*x, "foo");
11111112
/// ```
1113+
/// Other `Rc` pointers to the same allocation must be to the same type.
1114+
/// ```no_run
1115+
/// #![feature(get_mut_unchecked)]
1116+
///
1117+
/// use std::rc::Rc;
1118+
///
1119+
/// let x: Rc<str> = Rc::from("Hello, world!");
1120+
/// let mut y: Rc<[u8]> = x.clone().into();
1121+
/// unsafe {
1122+
/// // this is Undefined Behavior, because x's inner type is str, not [u8]
1123+
/// Rc::get_mut_unchecked(&mut y).fill(0xff); // 0xff is invalid in UTF-8
1124+
/// }
1125+
/// println!("{}", &*x); // Invalid UTF-8 in a str
1126+
/// ```
1127+
/// Other `Rc` pointers to the same allocation must be to the exact same type, including lifetimes.
1128+
/// ```no_run
1129+
/// #![feature(get_mut_unchecked)]
1130+
///
1131+
/// use std::rc::Rc;
1132+
///
1133+
/// let x: Rc<&str> = Rc::new("Hello, world!");
1134+
/// {
1135+
/// let s = String::from("Oh, no!");
1136+
/// let mut y: Rc<&str> = x.clone().into();
1137+
/// unsafe {
1138+
/// // this is Undefined Behavior, because x's inner type
1139+
/// // is &'long str, not &'short str
1140+
/// *Rc::get_mut_unchecked(&mut y) = &s;
1141+
/// }
1142+
/// }
1143+
/// println!("{}", &*x); // Use-after-free
1144+
/// ```
11121145
#[inline]
11131146
#[unstable(feature = "get_mut_unchecked", issue = "63292")]
11141147
pub unsafe fn get_mut_unchecked(this: &mut Self) -> &mut T {

library/alloc/src/sync.rs

+37-4
Original file line numberDiff line numberDiff line change
@@ -1587,10 +1587,11 @@ impl<T: ?Sized> Arc<T> {
15871587
///
15881588
/// # Safety
15891589
///
1590-
/// Any other `Arc` or [`Weak`] pointers to the same allocation must not be dereferenced
1591-
/// for the duration of the returned borrow.
1592-
/// This is trivially the case if no such pointers exist,
1593-
/// for example immediately after `Arc::new`.
1590+
/// If any other `Arc` or [`Weak`] pointers to the same allocation exist, then
1591+
/// they must be must not be dereferenced or have active borrows for the duration
1592+
/// of the returned borrow, and their inner type must be exactly the same as the
1593+
/// inner type of this Rc (including lifetimes). This is trivially the case if no
1594+
/// such pointers exist, for example immediately after `Arc::new`.
15941595
///
15951596
/// # Examples
15961597
///
@@ -1605,6 +1606,38 @@ impl<T: ?Sized> Arc<T> {
16051606
/// }
16061607
/// assert_eq!(*x, "foo");
16071608
/// ```
1609+
/// Other `Arc` pointers to the same allocation must be to the same type.
1610+
/// ```no_run
1611+
/// #![feature(get_mut_unchecked)]
1612+
///
1613+
/// use std::sync::Arc;
1614+
///
1615+
/// let x: Arc<str> = Arc::from("Hello, world!");
1616+
/// let mut y: Arc<[u8]> = x.clone().into();
1617+
/// unsafe {
1618+
/// // this is Undefined Behavior, because x's inner type is str, not [u8]
1619+
/// Arc::get_mut_unchecked(&mut y).fill(0xff); // 0xff is invalid in UTF-8
1620+
/// }
1621+
/// println!("{}", &*x); // Invalid UTF-8 in a str
1622+
/// ```
1623+
/// Other `Arc` pointers to the same allocation must be to the exact same type, including lifetimes.
1624+
/// ```no_run
1625+
/// #![feature(get_mut_unchecked)]
1626+
///
1627+
/// use std::sync::Arc;
1628+
///
1629+
/// let x: Arc<&str> = Arc::new("Hello, world!");
1630+
/// {
1631+
/// let s = String::from("Oh, no!");
1632+
/// let mut y: Arc<&str> = x.clone().into();
1633+
/// unsafe {
1634+
/// // this is Undefined Behavior, because x's inner type
1635+
/// // is &'long str, not &'short str
1636+
/// *Arc::get_mut_unchecked(&mut y) = &s;
1637+
/// }
1638+
/// }
1639+
/// println!("{}", &*x); // Use-after-free
1640+
/// ```
16081641
#[inline]
16091642
#[unstable(feature = "get_mut_unchecked", issue = "63292")]
16101643
pub unsafe fn get_mut_unchecked(this: &mut Self) -> &mut T {

library/core/src/arch.rs

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#![doc = include_str!("../../stdarch/crates/core_arch/src/core_arch_docs.md")]
2+
3+
#[stable(feature = "simd_arch", since = "1.27.0")]
4+
pub use crate::core_arch::arch::*;
5+
6+
/// Inline assembly.
7+
///
8+
/// Refer to [rust by example] for a usage guide and the [reference] for
9+
/// detailed information about the syntax and available options.
10+
///
11+
/// [rust by example]: https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html
12+
/// [reference]: https://doc.rust-lang.org/nightly/reference/inline-assembly.html
13+
#[stable(feature = "asm", since = "1.59.0")]
14+
#[rustc_builtin_macro]
15+
pub macro asm("assembly template", $(operands,)* $(options($(option),*))?) {
16+
/* compiler built-in */
17+
}
18+
19+
/// Module-level inline assembly.
20+
///
21+
/// Refer to [rust by example] for a usage guide and the [reference] for
22+
/// detailed information about the syntax and available options.
23+
///
24+
/// [rust by example]: https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html
25+
/// [reference]: https://doc.rust-lang.org/nightly/reference/inline-assembly.html
26+
#[stable(feature = "global_asm", since = "1.59.0")]
27+
#[rustc_builtin_macro]
28+
pub macro global_asm("assembly template", $(operands,)* $(options($(option),*))?) {
29+
/* compiler built-in */
30+
}

library/core/src/lib.rs

+3-31
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
// Lints:
9090
#![deny(rust_2021_incompatible_or_patterns)]
9191
#![deny(unsafe_op_in_unsafe_fn)]
92+
#![deny(fuzzy_provenance_casts)]
9293
#![warn(deprecated_in_future)]
9394
#![warn(missing_debug_implementations)]
9495
#![warn(missing_docs)]
@@ -162,6 +163,7 @@
162163
#![feature(slice_ptr_get)]
163164
#![feature(slice_split_at_unchecked)]
164165
#![feature(str_internals)]
166+
#![feature(strict_provenance)]
165167
#![feature(utf16_extra)]
166168
#![feature(utf16_extra_const)]
167169
#![feature(variant_count)]
@@ -392,38 +394,8 @@ pub mod primitive;
392394
#[unstable(feature = "stdsimd", issue = "48556")]
393395
mod core_arch;
394396

395-
#[doc = include_str!("../../stdarch/crates/core_arch/src/core_arch_docs.md")]
396397
#[stable(feature = "simd_arch", since = "1.27.0")]
397-
pub mod arch {
398-
#[stable(feature = "simd_arch", since = "1.27.0")]
399-
pub use crate::core_arch::arch::*;
400-
401-
/// Inline assembly.
402-
///
403-
/// Refer to [rust by example] for a usage guide and the [reference] for
404-
/// detailed information about the syntax and available options.
405-
///
406-
/// [rust by example]: https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html
407-
/// [reference]: https://doc.rust-lang.org/nightly/reference/inline-assembly.html
408-
#[stable(feature = "asm", since = "1.59.0")]
409-
#[rustc_builtin_macro]
410-
pub macro asm("assembly template", $(operands,)* $(options($(option),*))?) {
411-
/* compiler built-in */
412-
}
413-
414-
/// Module-level inline assembly.
415-
///
416-
/// Refer to [rust by example] for a usage guide and the [reference] for
417-
/// detailed information about the syntax and available options.
418-
///
419-
/// [rust by example]: https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html
420-
/// [reference]: https://doc.rust-lang.org/nightly/reference/inline-assembly.html
421-
#[stable(feature = "global_asm", since = "1.59.0")]
422-
#[rustc_builtin_macro]
423-
pub macro global_asm("assembly template", $(operands,)* $(options($(option),*))?) {
424-
/* compiler built-in */
425-
}
426-
}
398+
pub mod arch;
427399

428400
// Pull in the `core_simd` crate directly into libcore. The contents of
429401
// `core_simd` are in a different repository: rust-lang/portable-simd.

library/core/src/ptr/const_ptr.rs

+1
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ impl<T: ?Sized> *const T {
140140
/// assert_eq!(<*const u8>::from_bits(1), dangling);
141141
/// ```
142142
#[unstable(feature = "ptr_to_from_bits", issue = "91126")]
143+
#[allow(fuzzy_provenance_casts)] // this is an unstable and semi-deprecated cast function
143144
pub fn from_bits(bits: usize) -> Self
144145
where
145146
T: Sized,

library/core/src/ptr/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,7 @@ pub const fn invalid_mut<T>(addr: usize) -> *mut T {
616616
#[inline]
617617
#[unstable(feature = "strict_provenance", issue = "95228")]
618618
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
619+
#[allow(fuzzy_provenance_casts)] // this *is* the strict provenance API one should use instead
619620
pub fn from_exposed_addr<T>(addr: usize) -> *const T
620621
where
621622
T: Sized,
@@ -653,6 +654,7 @@ where
653654
#[inline]
654655
#[unstable(feature = "strict_provenance", issue = "95228")]
655656
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
657+
#[allow(fuzzy_provenance_casts)] // this *is* the strict provenance API one should use instead
656658
pub fn from_exposed_addr_mut<T>(addr: usize) -> *mut T
657659
where
658660
T: Sized,

library/core/src/ptr/mut_ptr.rs

+1
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ impl<T: ?Sized> *mut T {
146146
/// assert_eq!(<*mut u8>::from_bits(1), dangling);
147147
/// ```
148148
#[unstable(feature = "ptr_to_from_bits", issue = "91126")]
149+
#[allow(fuzzy_provenance_casts)] // this is an unstable and semi-deprecated cast function
149150
pub fn from_bits(bits: usize) -> Self
150151
where
151152
T: Sized,

0 commit comments

Comments
 (0)