Skip to content

Commit 7a38981

Browse files
committed
Auto merge of #155472 - jhpratt:rollup-cFOYOWJ, r=jhpratt
Rollup of 12 pull requests Successful merges: - #147811 (naked functions: respect `function-sections`) - #154935 (Add Sized supertrait for CoerceUnsized and DispatchFromDyn) - #139690 (`impl Default for RepeatN`) - #153511 (`std::any::TypeId`: remove misplaced "and" in `Unique<T>` example) - #154943 (Move recursion out of `MatchPairTree::for_pattern` helpers ) - #155295 (Fix misleading "borrowed data escapes outside of function" diagnostic) - #155427 (ptr: update text in intro text to one in with_addr doc) - #155428 (Fix ICE in borrowck mutability suggestion with multi-byte ref sigil) - #155435 (rustdoc: Fix `redundant_explicit_links` incorrectly firing (or not firing) under certain scenarios) - #155450 (Remove unnecessary safety conditions related to unchecked uint arithmetic) - #155454 (docs: Fix typo in std/src/thready/scoped.rs) - #155467 (`std::error::Request`: clean up documentation)
2 parents 2f201bc + 0bfd952 commit 7a38981

34 files changed

Lines changed: 676 additions & 181 deletions

compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1410,9 +1410,20 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
14101410
(span, " mut".to_owned(), true)
14111411
// If there is already a binding, we modify it to be `mut`.
14121412
} else if binding_exists {
1413-
// Shrink the span to just after the `&` in `&variable`.
1414-
let span = span.with_lo(span.lo() + BytePos(1)).shrink_to_lo();
1415-
(span, "mut ".to_owned(), true)
1413+
// Replace the sigil with the mutable version. We may be dealing
1414+
// with parser recovery here and cannot assume the user actually
1415+
// typed `&` or `*const`, so we compute the prefix from the snippet.
1416+
let Ok(src) = self.infcx.tcx.sess.source_map().span_to_snippet(span) else {
1417+
return;
1418+
};
1419+
let (prefix_len, replacement) = if local_decl.ty.is_ref() {
1420+
(src.chars().next().map_or(0, char::len_utf8), "&mut ")
1421+
} else {
1422+
(src.find("const").map_or(1, |i| i + "const".len()), "*mut ")
1423+
};
1424+
let ws_len = src[prefix_len..].len() - src[prefix_len..].trim_start().len();
1425+
let span = span.with_hi(span.lo() + BytePos((prefix_len + ws_len) as u32));
1426+
(span, replacement.to_owned(), true)
14161427
} else {
14171428
// Otherwise, suggest that the user annotates the binding; We provide the
14181429
// type of the local.

compiler/rustc_borrowck/src/diagnostics/region_errors.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -686,6 +686,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
686686
|| (*category == ConstraintCategory::Assignment
687687
&& self.regioncx.universal_regions().defining_ty.is_fn_def())
688688
|| self.regioncx.universal_regions().defining_ty.is_const()
689+
|| (fr_name_and_span.is_none()
690+
&& self.regioncx.universal_regions().defining_ty.is_fn_def())
689691
{
690692
return self.report_general_error(errci);
691693
}

compiler/rustc_codegen_ssa/src/mir/naked_asm.rs

Lines changed: 54 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc_middle::ty::{Instance, Ty, TyCtxt, TypeVisitableExt};
88
use rustc_middle::{bug, ty};
99
use rustc_span::sym;
1010
use rustc_target::callconv::{ArgAbi, FnAbi, PassMode};
11-
use rustc_target::spec::{Arch, BinaryFormat};
11+
use rustc_target::spec::{Arch, BinaryFormat, Env, Os};
1212

1313
use crate::common;
1414
use crate::mir::AsmCodegenMethods;
@@ -128,6 +128,8 @@ fn prefix_and_suffix<'tcx>(
128128

129129
let is_arm = tcx.sess.target.arch == Arch::Arm;
130130
let is_thumb = tcx.sess.unstable_target_features.contains(&sym::thumb_mode);
131+
let function_sections =
132+
tcx.sess.opts.unstable_opts.function_sections.unwrap_or(tcx.sess.target.function_sections);
131133

132134
// If we're compiling the compiler-builtins crate, e.g., the equivalent of
133135
// compiler-rt, then we want to implicitly compile everything with hidden
@@ -218,8 +220,6 @@ fn prefix_and_suffix<'tcx>(
218220
let mut end = String::new();
219221
match asm_binary_format {
220222
BinaryFormat::Elf => {
221-
let section = link_section.unwrap_or_else(|| format!(".text.{asm_name}"));
222-
223223
let progbits = match is_arm {
224224
true => "%progbits",
225225
false => "@progbits",
@@ -230,7 +230,13 @@ fn prefix_and_suffix<'tcx>(
230230
false => "@function",
231231
};
232232

233-
writeln!(begin, ".pushsection {section},\"ax\", {progbits}").unwrap();
233+
if let Some(section) = &link_section {
234+
writeln!(begin, ".pushsection {section},\"ax\", {progbits}").unwrap();
235+
} else if function_sections {
236+
writeln!(begin, ".pushsection .text.{asm_name},\"ax\", {progbits}").unwrap();
237+
} else {
238+
writeln!(begin, ".text").unwrap();
239+
}
234240
writeln!(begin, ".balign {align_bytes}").unwrap();
235241
write_linkage(&mut begin).unwrap();
236242
match visibility {
@@ -249,14 +255,22 @@ fn prefix_and_suffix<'tcx>(
249255
// pattern match on assembly generated by LLVM.
250256
writeln!(end, ".Lfunc_end_{asm_name}:").unwrap();
251257
writeln!(end, ".size {asm_name}, . - {asm_name}").unwrap();
252-
writeln!(end, ".popsection").unwrap();
258+
if link_section.is_some() || function_sections {
259+
writeln!(end, ".popsection").unwrap();
260+
}
253261
if !arch_suffix.is_empty() {
254262
writeln!(end, "{}", arch_suffix).unwrap();
255263
}
256264
}
257265
BinaryFormat::MachO => {
258-
let section = link_section.unwrap_or_else(|| "__TEXT,__text".to_string());
259-
writeln!(begin, ".pushsection {},regular,pure_instructions", section).unwrap();
266+
// NOTE: LLVM ignores `-Zfunction-sections` on macos. Instead the Mach-O symbol
267+
// subsection splitting feature is used, which can be enabled with the
268+
// `.subsections_via_symbols` global directive. LLVM already enables this directive.
269+
if let Some(section) = &link_section {
270+
writeln!(begin, ".pushsection {section},regular,pure_instructions").unwrap();
271+
} else {
272+
writeln!(begin, ".section __TEXT,__text,regular,pure_instructions").unwrap();
273+
}
260274
writeln!(begin, ".balign {align_bytes}").unwrap();
261275
write_linkage(&mut begin).unwrap();
262276
match visibility {
@@ -267,7 +281,9 @@ fn prefix_and_suffix<'tcx>(
267281

268282
writeln!(end).unwrap();
269283
writeln!(end, ".Lfunc_end_{asm_name}:").unwrap();
270-
writeln!(end, ".popsection").unwrap();
284+
if link_section.is_some() {
285+
writeln!(end, ".popsection").unwrap();
286+
}
271287
if !arch_suffix.is_empty() {
272288
writeln!(end, "{}", arch_suffix).unwrap();
273289
}
@@ -278,8 +294,36 @@ fn prefix_and_suffix<'tcx>(
278294
writeln!(begin, ".type 32").unwrap();
279295
writeln!(begin, ".endef").unwrap();
280296

281-
let section = link_section.unwrap_or_else(|| format!(".text.{asm_name}"));
282-
writeln!(begin, ".pushsection {},\"xr\"", section).unwrap();
297+
if let Some(section) = &link_section {
298+
writeln!(begin, ".section {section},\"xr\"").unwrap()
299+
} else if !function_sections {
300+
// Function sections are enabled by default on MSVC and windows-gnullvm,
301+
// but disabled by default on GNU.
302+
writeln!(begin, ".text").unwrap();
303+
} else {
304+
// LLVM uses an extension to the section directive to support defining multiple
305+
// sections with the same name and comdat. It adds `unique,<id>` at the end of the
306+
// `.section` directive. We have no way of generating that unique ID here, so don't
307+
// emit it.
308+
//
309+
// See https://llvm.org/docs/Extensions.html#id2.
310+
match &tcx.sess.target.options.env {
311+
Env::Gnu => {
312+
writeln!(begin, ".section .text${asm_name},\"xr\",one_only,{asm_name}")
313+
.unwrap();
314+
}
315+
Env::Msvc => {
316+
writeln!(begin, ".section .text,\"xr\",one_only,{asm_name}").unwrap();
317+
}
318+
Env::Unspecified => match &tcx.sess.target.options.os {
319+
Os::Uefi => {
320+
writeln!(begin, ".section .text,\"xr\",one_only,{asm_name}").unwrap();
321+
}
322+
_ => bug!("unexpected coff target {}", tcx.sess.target.llvm_target),
323+
},
324+
other => bug!("unexpected coff env {other:?}"),
325+
}
326+
}
283327
write_linkage(&mut begin).unwrap();
284328
writeln!(begin, ".balign {align_bytes}").unwrap();
285329
writeln!(begin, "{asm_name}:").unwrap();

compiler/rustc_mir_build/src/builder/matches/match_pair.rs

Lines changed: 65 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -12,77 +12,58 @@ use crate::builder::matches::{
1212
FlatPat, MatchPairTree, PatConstKind, PatternExtraData, SliceLenOp, TestableCase,
1313
};
1414

15-
impl<'a, 'tcx> Builder<'a, 'tcx> {
16-
/// Builds and pushes [`MatchPairTree`] subtrees, one for each pattern in
17-
/// `subpatterns`, representing the fields of a [`PatKind::Variant`] or
18-
/// [`PatKind::Leaf`].
19-
///
20-
/// Used internally by [`MatchPairTree::for_pattern`].
21-
fn field_match_pairs(
22-
&mut self,
23-
match_pairs: &mut Vec<MatchPairTree<'tcx>>,
24-
extra_data: &mut PatternExtraData<'tcx>,
25-
place: PlaceBuilder<'tcx>,
26-
subpatterns: &[FieldPat<'tcx>],
27-
) {
28-
for fieldpat in subpatterns {
29-
let place = place.clone_project(PlaceElem::Field(fieldpat.field, fieldpat.pattern.ty));
30-
MatchPairTree::for_pattern(place, &fieldpat.pattern, self, match_pairs, extra_data);
31-
}
15+
/// For an array or slice pattern's subpatterns (prefix/slice/suffix), returns a list
16+
/// of those subpatterns, each paired with a suitably-projected [`PlaceBuilder`].
17+
fn prefix_slice_suffix<'a, 'tcx>(
18+
place: &PlaceBuilder<'tcx>,
19+
array_len: Option<u64>, // Some for array patterns; None for slice patterns
20+
prefix: &'a [Pat<'tcx>],
21+
opt_slice: &'a Option<Box<Pat<'tcx>>>,
22+
suffix: &'a [Pat<'tcx>],
23+
) -> Vec<(PlaceBuilder<'tcx>, &'a Pat<'tcx>)> {
24+
let prefix_len = u64::try_from(prefix.len()).unwrap();
25+
let suffix_len = u64::try_from(suffix.len()).unwrap();
26+
27+
let mut output_pairs =
28+
Vec::with_capacity(prefix.len() + usize::from(opt_slice.is_some()) + suffix.len());
29+
30+
// For slice patterns with a `..` followed by 0 or more suffix subpatterns,
31+
// the actual slice index of those subpatterns isn't statically known, so
32+
// we have to index them relative to the end of the slice.
33+
//
34+
// For array patterns, all subpatterns are indexed relative to the start.
35+
let (min_length, is_array) = match array_len {
36+
Some(len) => (len, true),
37+
None => (prefix_len + suffix_len, false),
38+
};
39+
40+
for (offset, prefix_subpat) in (0u64..).zip(prefix) {
41+
let elem = ProjectionElem::ConstantIndex { offset, min_length, from_end: false };
42+
let subplace = place.clone_project(elem);
43+
output_pairs.push((subplace, prefix_subpat));
3244
}
3345

34-
/// Builds [`MatchPairTree`] subtrees for the prefix/middle/suffix parts of an
35-
/// array pattern or slice pattern, and adds those trees to `match_pairs`.
36-
///
37-
/// Used internally by [`MatchPairTree::for_pattern`].
38-
fn prefix_slice_suffix(
39-
&mut self,
40-
match_pairs: &mut Vec<MatchPairTree<'tcx>>,
41-
extra_data: &mut PatternExtraData<'tcx>,
42-
place: &PlaceBuilder<'tcx>,
43-
array_len: Option<u64>,
44-
prefix: &[Pat<'tcx>],
45-
opt_slice: &Option<Box<Pat<'tcx>>>,
46-
suffix: &[Pat<'tcx>],
47-
) {
48-
let prefix_len = u64::try_from(prefix.len()).unwrap();
49-
let suffix_len = u64::try_from(suffix.len()).unwrap();
50-
51-
// For slice patterns with a `..` followed by 0 or more suffix subpatterns,
52-
// the actual slice index of those subpatterns isn't statically known, so
53-
// we have to index them relative to the end of the slice.
54-
//
55-
// For array patterns, all subpatterns are indexed relative to the start.
56-
let (min_length, is_array) = match array_len {
57-
Some(len) => (len, true),
58-
None => (prefix_len + suffix_len, false),
46+
if let Some(slice_subpat) = opt_slice {
47+
let elem = PlaceElem::Subslice {
48+
from: prefix_len,
49+
to: if is_array { min_length - suffix_len } else { suffix_len },
50+
from_end: !is_array,
5951
};
52+
let subplace = place.clone_project(elem);
53+
output_pairs.push((subplace, slice_subpat));
54+
}
6055

61-
for (offset, subpattern) in (0u64..).zip(prefix) {
62-
let elem = ProjectionElem::ConstantIndex { offset, min_length, from_end: false };
63-
let place = place.clone_project(elem);
64-
MatchPairTree::for_pattern(place, subpattern, self, match_pairs, extra_data)
65-
}
66-
67-
if let Some(subslice_pat) = opt_slice {
68-
let subslice = place.clone_project(PlaceElem::Subslice {
69-
from: prefix_len,
70-
to: if is_array { min_length - suffix_len } else { suffix_len },
71-
from_end: !is_array,
72-
});
73-
MatchPairTree::for_pattern(subslice, subslice_pat, self, match_pairs, extra_data);
74-
}
75-
76-
for (end_offset, subpattern) in (1u64..).zip(suffix.iter().rev()) {
77-
let elem = ProjectionElem::ConstantIndex {
78-
offset: if is_array { min_length - end_offset } else { end_offset },
79-
min_length,
80-
from_end: !is_array,
81-
};
82-
let place = place.clone_project(elem);
83-
MatchPairTree::for_pattern(place, subpattern, self, match_pairs, extra_data)
84-
}
56+
for (offset_from_end, suffix_subpat) in (1u64..).zip(suffix.iter().rev()) {
57+
let elem = ProjectionElem::ConstantIndex {
58+
offset: if is_array { min_length - offset_from_end } else { offset_from_end },
59+
min_length,
60+
from_end: !is_array,
61+
};
62+
let subplace = place.clone_project(elem);
63+
output_pairs.push((subplace, suffix_subpat));
8564
}
65+
66+
output_pairs
8667
}
8768

8869
impl<'tcx> MatchPairTree<'tcx> {
@@ -239,15 +220,11 @@ impl<'tcx> MatchPairTree<'tcx> {
239220
_ => None,
240221
};
241222
if let Some(array_len) = array_len {
242-
cx.prefix_slice_suffix(
243-
&mut subpairs,
244-
extra_data,
245-
&place_builder,
246-
Some(array_len),
247-
prefix,
248-
slice,
249-
suffix,
250-
);
223+
for (subplace, subpat) in
224+
prefix_slice_suffix(&place_builder, Some(array_len), prefix, slice, suffix)
225+
{
226+
MatchPairTree::for_pattern(subplace, subpat, cx, &mut subpairs, extra_data);
227+
}
251228
} else {
252229
// If the array length couldn't be determined, ignore the
253230
// subpatterns and delayed-assert that compilation will fail.
@@ -263,15 +240,11 @@ impl<'tcx> MatchPairTree<'tcx> {
263240
None
264241
}
265242
PatKind::Slice { ref prefix, ref slice, ref suffix } => {
266-
cx.prefix_slice_suffix(
267-
&mut subpairs,
268-
extra_data,
269-
&place_builder,
270-
None,
271-
prefix,
272-
slice,
273-
suffix,
274-
);
243+
for (subplace, subpat) in
244+
prefix_slice_suffix(&place_builder, None, prefix, slice, suffix)
245+
{
246+
MatchPairTree::for_pattern(subplace, subpat, cx, &mut subpairs, extra_data);
247+
}
275248

276249
if prefix.is_empty() && slice.is_some() && suffix.is_empty() {
277250
// This pattern is shaped like `[..]`. It can match a slice
@@ -294,7 +267,10 @@ impl<'tcx> MatchPairTree<'tcx> {
294267

295268
PatKind::Variant { adt_def, variant_index, args: _, ref subpatterns } => {
296269
let downcast_place = place_builder.downcast(adt_def, variant_index); // `(x as Variant)`
297-
cx.field_match_pairs(&mut subpairs, extra_data, downcast_place, subpatterns);
270+
for &FieldPat { field, pattern: ref subpat } in subpatterns {
271+
let subplace = downcast_place.clone_project(PlaceElem::Field(field, subpat.ty));
272+
MatchPairTree::for_pattern(subplace, subpat, cx, &mut subpairs, extra_data);
273+
}
298274

299275
// We treat non-exhaustive enums the same independent of the crate they are
300276
// defined in, to avoid differences in the operational semantics between crates.
@@ -308,7 +284,10 @@ impl<'tcx> MatchPairTree<'tcx> {
308284
}
309285

310286
PatKind::Leaf { ref subpatterns } => {
311-
cx.field_match_pairs(&mut subpairs, extra_data, place_builder, subpatterns);
287+
for &FieldPat { field, pattern: ref subpat } in subpatterns {
288+
let subplace = place_builder.clone_project(PlaceElem::Field(field, subpat.ty));
289+
MatchPairTree::for_pattern(subplace, subpat, cx, &mut subpairs, extra_data);
290+
}
312291
None
313292
}
314293

library/core/src/any.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -666,7 +666,7 @@ impl dyn Any + Send + Sync {
666666
///
667667
/// The following is an example program that tries to use `TypeId::of` to
668668
/// implement a generic type `Unique<T>` that guarantees unique instances for each `Unique<T>`,
669-
/// that is, and for each type `T` there can be at most one value of type `Unique<T>` at any time.
669+
/// that is, for each type `T` there can be at most one value of type `Unique<T>` at any time.
670670
///
671671
/// ```
672672
/// mod unique {

library/core/src/error.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -494,37 +494,37 @@ where
494494
/// `Request` supports generic, type-driven access to data. Its use is currently restricted to the
495495
/// standard library in cases where trait authors wish to allow trait implementors to share generic
496496
/// information across trait boundaries. The motivating and prototypical use case is
497-
/// `core::error::Error` which would otherwise require a method per concrete type (eg.
497+
/// `core::error::Error` which would otherwise require a method per concrete type (e.g.
498498
/// `std::backtrace::Backtrace` instance that implementors want to expose to users).
499499
///
500500
/// # Data flow
501501
///
502502
/// To describe the intended data flow for Request objects, let's consider two conceptual users
503503
/// separated by API boundaries:
504504
///
505-
/// * Consumer - the consumer requests objects using a Request instance; eg a crate that offers
505+
/// * Consumer - the consumer requests objects using a Request instance; e.g. a crate that offers
506506
/// fancy `Error`/`Result` reporting to users wants to request a Backtrace from a given `dyn Error`.
507507
///
508-
/// * Producer - the producer provides objects when requested via Request; eg. a library with an
508+
/// * Producer - the producer provides objects when requested via Request; e.g. a library with an
509509
/// an `Error` implementation that automatically captures backtraces at the time instances are
510510
/// created.
511511
///
512-
/// The consumer only needs to know where to submit their request and are expected to handle the
512+
/// The consumer only needs to know where to submit their request and is expected to handle the
513513
/// request not being fulfilled by the use of `Option<T>` in the responses offered by the producer.
514514
///
515515
/// * A Producer initializes the value of one of its fields of a specific type. (or is otherwise
516-
/// prepared to generate a value requested). eg, `backtrace::Backtrace` or
517-
/// `std::backtrace::Backtrace`
516+
/// prepared to generate a value requested). e.g., `backtrace::Backtrace` or
517+
/// `std::backtrace::Backtrace`.
518518
/// * A Consumer requests an object of a specific type (say `std::backtrace::Backtrace`). In the
519519
/// case of a `dyn Error` trait object (the Producer), there are functions called `request_ref` and
520520
/// `request_value` to simplify obtaining an `Option<T>` for a given type.
521521
/// * The Producer, when requested, populates the given Request object which is given as a mutable
522522
/// reference.
523523
/// * The Consumer extracts a value or reference to the requested type from the `Request` object
524-
/// wrapped in an `Option<T>`; in the case of `dyn Error` the aforementioned `request_ref` and `
525-
/// request_value` methods mean that `dyn Error` users don't have to deal with the `Request` type at
524+
/// wrapped in an `Option<T>`; in the case of `dyn Error` the aforementioned `request_ref` and
525+
/// `request_value` methods mean that `dyn Error` users don't have to deal with the `Request` type at
526526
/// all (but `Error` implementors do). The `None` case of the `Option` suggests only that the
527-
/// Producer cannot currently offer an instance of the requested type, not it can't or never will.
527+
/// Producer cannot currently offer an instance of the requested type, not that it can't or never will.
528528
///
529529
/// # Examples
530530
///

0 commit comments

Comments
 (0)