Skip to content

Commit c9cd707

Browse files
committed
Auto merge of rust-lang#139229 - Zalathar:rollup-5cs3f4d, r=Zalathar
Rollup of 14 pull requests Successful merges: - rust-lang#135295 (Check empty SIMD vector in inline asm) - rust-lang#138003 (Add the new `amx` target features and the `movrs` target feature) - rust-lang#138823 (rustc_target: RISC-V: add base `I`-related important extensions) - rust-lang#138913 (Remove even more instances of `@ts-expect-error` from search.js) - rust-lang#138941 (Do not mix normalized and unnormalized caller bounds when constructing param-env for `receiver_is_dispatchable`) - rust-lang#139060 (replace commit placeholder in vendor status with actual commit) - rust-lang#139102 (coverage: Avoid splitting spans during span extraction/refinement) - rust-lang#139191 (small opaque type/borrowck cleanup) - rust-lang#139200 (Skip suggest impl or dyn when poly trait is not a real trait) - rust-lang#139208 (fix dead link netbsd.md) - rust-lang#139210 (chore: remove redundant backtick) - rust-lang#139212 (Update mdbook to 0.4.48) - rust-lang#139214 (Tell rustfmt to use the 2024 edition in ./x.py fmt) - rust-lang#139225 (move autodiff from EnzymeAD/Enzyme to our rust-lang/Enzyme soft-fork) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 70dab5a + ea51a1c commit c9cd707

File tree

117 files changed

+760
-583
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

117 files changed

+760
-583
lines changed

.gitmodules

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
shallow = true
4646
[submodule "src/tools/enzyme"]
4747
path = src/tools/enzyme
48-
url = https://github.com/EnzymeAD/Enzyme.git
48+
url = https://github.com/rust-lang/Enzyme.git
4949
shallow = true
5050
[submodule "src/gcc"]
5151
path = src/gcc

compiler/rustc_borrowck/src/consumers.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! This file provides API for compiler consumers.
22
33
use rustc_hir::def_id::LocalDefId;
4-
use rustc_index::{IndexSlice, IndexVec};
4+
use rustc_index::IndexVec;
55
use rustc_middle::mir::{Body, Promoted};
66
use rustc_middle::ty::TyCtxt;
77

@@ -100,8 +100,5 @@ pub fn get_body_with_borrowck_facts(
100100
def: LocalDefId,
101101
options: ConsumerOptions,
102102
) -> BodyWithBorrowckFacts<'_> {
103-
let (input_body, promoted) = tcx.mir_promoted(def);
104-
let input_body: &Body<'_> = &input_body.borrow();
105-
let promoted: &IndexSlice<_, _> = &promoted.borrow();
106-
*super::do_mir_borrowck(tcx, input_body, promoted, Some(options)).1.unwrap()
103+
*super::do_mir_borrowck(tcx, def, Some(options)).1.unwrap()
107104
}

compiler/rustc_borrowck/src/lib.rs

+9-10
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,8 @@ pub fn provide(providers: &mut Providers) {
103103
}
104104

105105
fn mir_borrowck(tcx: TyCtxt<'_>, def: LocalDefId) -> &BorrowCheckResult<'_> {
106-
let (input_body, promoted) = tcx.mir_promoted(def);
107-
debug!("run query mir_borrowck: {}", tcx.def_path_str(def));
108-
106+
let (input_body, _) = tcx.mir_promoted(def);
109107
let input_body: &Body<'_> = &input_body.borrow();
110-
111108
if input_body.should_skip() || input_body.tainted_by_errors.is_some() {
112109
debug!("Skipping borrowck because of injected body or tainted body");
113110
// Let's make up a borrowck result! Fun times!
@@ -120,7 +117,7 @@ fn mir_borrowck(tcx: TyCtxt<'_>, def: LocalDefId) -> &BorrowCheckResult<'_> {
120117
return tcx.arena.alloc(result);
121118
}
122119

123-
let borrowck_result = do_mir_borrowck(tcx, input_body, &*promoted.borrow(), None).0;
120+
let borrowck_result = do_mir_borrowck(tcx, def, None).0;
124121
debug!("mir_borrowck done");
125122

126123
tcx.arena.alloc(borrowck_result)
@@ -131,15 +128,16 @@ fn mir_borrowck(tcx: TyCtxt<'_>, def: LocalDefId) -> &BorrowCheckResult<'_> {
131128
/// Use `consumer_options: None` for the default behavior of returning
132129
/// [`BorrowCheckResult`] only. Otherwise, return [`BodyWithBorrowckFacts`] according
133130
/// to the given [`ConsumerOptions`].
134-
#[instrument(skip(tcx, input_body, input_promoted), fields(id=?input_body.source.def_id()), level = "debug")]
131+
#[instrument(skip(tcx), level = "debug")]
135132
fn do_mir_borrowck<'tcx>(
136133
tcx: TyCtxt<'tcx>,
137-
input_body: &Body<'tcx>,
138-
input_promoted: &IndexSlice<Promoted, Body<'tcx>>,
134+
def: LocalDefId,
139135
consumer_options: Option<ConsumerOptions>,
140136
) -> (BorrowCheckResult<'tcx>, Option<Box<BodyWithBorrowckFacts<'tcx>>>) {
141-
let def = input_body.source.def_id().expect_local();
142137
let infcx = BorrowckInferCtxt::new(tcx, def);
138+
let (input_body, promoted) = tcx.mir_promoted(def);
139+
let input_body: &Body<'_> = &input_body.borrow();
140+
let input_promoted: &IndexSlice<_, _> = &promoted.borrow();
143141
if let Some(e) = input_body.tainted_by_errors {
144142
infcx.set_tainted_by_errors(e);
145143
}
@@ -499,7 +497,8 @@ impl<'tcx> BorrowckInferCtxt<'tcx> {
499497
)
500498
});
501499

502-
self.inject_new_hidden_type_unchecked(key, hidden_ty);
500+
let prev = self.register_hidden_type_in_storage(key, hidden_ty);
501+
assert_eq!(prev, None);
503502
}
504503
}
505504
}

compiler/rustc_codegen_cranelift/example/gen_block_iterate.rs

+12-4
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,25 @@
66
#![feature(gen_blocks)]
77

88
fn foo() -> impl Iterator<Item = u32> {
9-
gen { yield 42; for x in 3..6 { yield x } }
9+
gen {
10+
yield 42;
11+
for x in 3..6 {
12+
yield x
13+
}
14+
}
1015
}
1116

1217
fn moved() -> impl Iterator<Item = u32> {
1318
let mut x = "foo".to_string();
1419
gen move {
1520
yield 42;
16-
if x == "foo" { return }
21+
if x == "foo" {
22+
return;
23+
}
1724
x.clear();
18-
for x in 3..6 { yield x }
25+
for x in 3..6 {
26+
yield x
27+
}
1928
}
2029
}
2130

@@ -32,5 +41,4 @@ fn main() {
3241
let mut iter = moved();
3342
assert_eq!(iter.next(), Some(42));
3443
assert_eq!(iter.next(), None);
35-
3644
}

compiler/rustc_codegen_cranelift/rustfmt.toml

-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
ignore = [
2-
"example/gen_block_iterate.rs", # uses edition 2024
3-
]
4-
51
# Matches rustfmt.toml of rustc
62
style_edition = "2024"
73
use_small_heuristics = "Max"

compiler/rustc_codegen_llvm/src/llvm_util.rs

+7
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,13 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option<LLVMFea
300300
("sparc", "v8plus") if get_version().0 == 19 => Some(LLVMFeature::new("v9")),
301301
("sparc", "v8plus") if get_version().0 < 19 => None,
302302
("powerpc", "power8-crypto") => Some(LLVMFeature::new("crypto")),
303+
// These new `amx` variants and `movrs` were introduced in LLVM20
304+
("x86", "amx-avx512" | "amx-fp8" | "amx-movrs" | "amx-tf32" | "amx-transpose")
305+
if get_version().0 < 20 =>
306+
{
307+
None
308+
}
309+
("x86", "movrs") if get_version().0 < 20 => None,
303310
(_, s) => Some(LLVMFeature::new(s)),
304311
}
305312
}

compiler/rustc_feature/src/unstable.rs

+1
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,7 @@ declare_features! (
324324
(unstable, loongarch_target_feature, "1.73.0", Some(44839)),
325325
(unstable, m68k_target_feature, "1.85.0", Some(134328)),
326326
(unstable, mips_target_feature, "1.27.0", Some(44839)),
327+
(unstable, movrs_target_feature, "CURRENT_RUSTC_VERSION", Some(137976)),
327328
(unstable, powerpc_target_feature, "1.27.0", Some(44839)),
328329
(unstable, prfchw_target_feature, "1.78.0", Some(44839)),
329330
(unstable, riscv_target_feature, "1.45.0", Some(44839)),

compiler/rustc_hir_analysis/src/check/intrinsicck.rs

+8
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ enum NonAsmTypeReason<'tcx> {
2929
Invalid(Ty<'tcx>),
3030
InvalidElement(DefId, Ty<'tcx>),
3131
NotSizedPtr(Ty<'tcx>),
32+
EmptySIMDArray(Ty<'tcx>),
3233
}
3334

3435
impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
@@ -102,6 +103,9 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
102103
}
103104
ty::Adt(adt, args) if adt.repr().simd() => {
104105
let fields = &adt.non_enum_variant().fields;
106+
if fields.is_empty() {
107+
return Err(NonAsmTypeReason::EmptySIMDArray(ty));
108+
}
105109
let field = &fields[FieldIdx::ZERO];
106110
let elem_ty = field.ty(self.tcx(), args);
107111

@@ -226,6 +230,10 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
226230
can be used as arguments for inline assembly",
227231
).emit();
228232
}
233+
NonAsmTypeReason::EmptySIMDArray(ty) => {
234+
let msg = format!("use of empty SIMD vector `{ty}`");
235+
self.infcx.dcx().struct_span_err(expr.span, msg).emit();
236+
}
229237
}
230238
return None;
231239
}

compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs

+1
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
8686
"expected a type, found a trait"
8787
);
8888
if self_ty.span.can_be_used_for_suggestions()
89+
&& poly_trait_ref.trait_ref.trait_def_id().is_some()
8990
&& !self.maybe_suggest_impl_trait(self_ty, &mut diag)
9091
&& !self.maybe_suggest_dyn_trait(self_ty, sugg, &mut diag)
9192
{

compiler/rustc_infer/src/infer/opaque_types/mod.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -198,13 +198,12 @@ impl<'tcx> InferCtxt<'tcx> {
198198
/// it hasn't previously been defined. This does not emit any
199199
/// constraints and it's the responsibility of the caller to make
200200
/// sure that the item bounds of the opaque are checked.
201-
pub fn inject_new_hidden_type_unchecked(
201+
pub fn register_hidden_type_in_storage(
202202
&self,
203203
opaque_type_key: OpaqueTypeKey<'tcx>,
204204
hidden_ty: OpaqueHiddenType<'tcx>,
205-
) {
206-
let prev = self.inner.borrow_mut().opaque_types().register(opaque_type_key, hidden_ty);
207-
assert_eq!(prev, None);
205+
) -> Option<Ty<'tcx>> {
206+
self.inner.borrow_mut().opaque_types().register(opaque_type_key, hidden_ty)
208207
}
209208

210209
/// Insert a hidden type into the opaque type storage, equating it

compiler/rustc_mir_transform/src/coverage/mappings.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ pub(super) fn extract_all_mapping_info_from_mir<'tcx>(
9696
}
9797
} else {
9898
// Extract coverage spans from MIR statements/terminators as normal.
99-
extract_refined_covspans(mir_body, hir_info, graph, &mut code_mappings);
99+
extract_refined_covspans(tcx, mir_body, hir_info, graph, &mut code_mappings);
100100
}
101101

102102
branch_pairs.extend(extract_branch_pairs(mir_body, hir_info, graph));

compiler/rustc_mir_transform/src/coverage/spans.rs

+30-77
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
use std::collections::VecDeque;
2+
use std::iter;
23

34
use rustc_data_structures::fx::FxHashSet;
45
use rustc_middle::mir;
6+
use rustc_middle::ty::TyCtxt;
57
use rustc_span::{DesugaringKind, ExpnKind, MacroKind, Span};
68
use tracing::{debug, debug_span, instrument};
79

@@ -11,8 +13,9 @@ use crate::coverage::{ExtractedHirInfo, mappings, unexpand};
1113

1214
mod from_mir;
1315

14-
pub(super) fn extract_refined_covspans(
15-
mir_body: &mir::Body<'_>,
16+
pub(super) fn extract_refined_covspans<'tcx>(
17+
tcx: TyCtxt<'tcx>,
18+
mir_body: &mir::Body<'tcx>,
1619
hir_info: &ExtractedHirInfo,
1720
graph: &CoverageGraph,
1821
code_mappings: &mut impl Extend<mappings::CodeMapping>,
@@ -50,7 +53,7 @@ pub(super) fn extract_refined_covspans(
5053
// First, perform the passes that need macro information.
5154
covspans.sort_by(|a, b| graph.cmp_in_dominator_order(a.bcb, b.bcb));
5255
remove_unwanted_expansion_spans(&mut covspans);
53-
split_visible_macro_spans(&mut covspans);
56+
shrink_visible_macro_spans(tcx, &mut covspans);
5457

5558
// We no longer need the extra information in `SpanFromMir`, so convert to `Covspan`.
5659
let mut covspans = covspans.into_iter().map(SpanFromMir::into_covspan).collect::<Vec<_>>();
@@ -83,9 +86,7 @@ pub(super) fn extract_refined_covspans(
8386
// Split the covspans into separate buckets that don't overlap any holes.
8487
let buckets = divide_spans_into_buckets(covspans, &holes);
8588

86-
for mut covspans in buckets {
87-
// Make sure each individual bucket is internally sorted.
88-
covspans.sort_by(compare_covspans);
89+
for covspans in buckets {
8990
let _span = debug_span!("processing bucket", ?covspans).entered();
9091

9192
let mut covspans = remove_unwanted_overlapping_spans(covspans);
@@ -129,82 +130,50 @@ fn remove_unwanted_expansion_spans(covspans: &mut Vec<SpanFromMir>) {
129130
}
130131

131132
/// When a span corresponds to a macro invocation that is visible from the
132-
/// function body, split it into two parts. The first part covers just the
133-
/// macro name plus `!`, and the second part covers the rest of the macro
134-
/// invocation. This seems to give better results for code that uses macros.
135-
fn split_visible_macro_spans(covspans: &mut Vec<SpanFromMir>) {
136-
let mut extra_spans = vec![];
137-
138-
covspans.retain(|covspan| {
139-
let Some(ExpnKind::Macro(MacroKind::Bang, visible_macro)) = covspan.expn_kind else {
140-
return true;
141-
};
142-
143-
let split_len = visible_macro.as_str().len() as u32 + 1;
144-
let (before, after) = covspan.span.split_at(split_len);
145-
if !covspan.span.contains(before) || !covspan.span.contains(after) {
146-
// Something is unexpectedly wrong with the split point.
147-
// The debug assertion in `split_at` will have already caught this,
148-
// but in release builds it's safer to do nothing and maybe get a
149-
// bug report for unexpected coverage, rather than risk an ICE.
150-
return true;
133+
/// function body, truncate it to just the macro name plus `!`.
134+
/// This seems to give better results for code that uses macros.
135+
fn shrink_visible_macro_spans(tcx: TyCtxt<'_>, covspans: &mut Vec<SpanFromMir>) {
136+
let source_map = tcx.sess.source_map();
137+
138+
for covspan in covspans {
139+
if matches!(covspan.expn_kind, Some(ExpnKind::Macro(MacroKind::Bang, _))) {
140+
covspan.span = source_map.span_through_char(covspan.span, '!');
151141
}
152-
153-
extra_spans.push(SpanFromMir::new(before, covspan.expn_kind.clone(), covspan.bcb));
154-
extra_spans.push(SpanFromMir::new(after, covspan.expn_kind.clone(), covspan.bcb));
155-
false // Discard the original covspan that we just split.
156-
});
157-
158-
// The newly-split spans are added at the end, so any previous sorting
159-
// is not preserved.
160-
covspans.extend(extra_spans);
142+
}
161143
}
162144

163145
/// Uses the holes to divide the given covspans into buckets, such that:
164-
/// - No span in any hole overlaps a bucket (truncating the spans if necessary).
146+
/// - No span in any hole overlaps a bucket (discarding spans if necessary).
165147
/// - The spans in each bucket are strictly after all spans in previous buckets,
166148
/// and strictly before all spans in subsequent buckets.
167149
///
168-
/// The resulting buckets are sorted relative to each other, but might not be
169-
/// internally sorted.
150+
/// The lists of covspans and holes must be sorted.
151+
/// The resulting buckets are sorted relative to each other, and each bucket's
152+
/// contents are sorted.
170153
#[instrument(level = "debug")]
171154
fn divide_spans_into_buckets(input_covspans: Vec<Covspan>, holes: &[Hole]) -> Vec<Vec<Covspan>> {
172155
debug_assert!(input_covspans.is_sorted_by(|a, b| compare_spans(a.span, b.span).is_le()));
173156
debug_assert!(holes.is_sorted_by(|a, b| compare_spans(a.span, b.span).is_le()));
174157

175-
// Now we're ready to start carving holes out of the initial coverage spans,
176-
// and grouping them in buckets separated by the holes.
158+
// Now we're ready to start grouping spans into buckets separated by holes.
177159

178160
let mut input_covspans = VecDeque::from(input_covspans);
179-
let mut fragments = vec![];
180161

181162
// For each hole:
182163
// - Identify the spans that are entirely or partly before the hole.
183-
// - Put those spans in a corresponding bucket, truncated to the start of the hole.
184-
// - If one of those spans also extends after the hole, put the rest of it
185-
// in a "fragments" vector that is processed by the next hole.
164+
// - Discard any that overlap with the hole.
165+
// - Add the remaining identified spans to the corresponding bucket.
186166
let mut buckets = (0..holes.len()).map(|_| vec![]).collect::<Vec<_>>();
187167
for (hole, bucket) in holes.iter().zip(&mut buckets) {
188-
let fragments_from_prev = std::mem::take(&mut fragments);
189-
190-
// Only inspect spans that precede or overlap this hole,
191-
// leaving the rest to be inspected by later holes.
192-
// (This relies on the spans and holes both being sorted.)
193-
let relevant_input_covspans =
194-
drain_front_while(&mut input_covspans, |c| c.span.lo() < hole.span.hi());
195-
196-
for covspan in fragments_from_prev.into_iter().chain(relevant_input_covspans) {
197-
let (before, after) = covspan.split_around_hole_span(hole.span);
198-
bucket.extend(before);
199-
fragments.extend(after);
200-
}
168+
bucket.extend(
169+
drain_front_while(&mut input_covspans, |c| c.span.lo() < hole.span.hi())
170+
.filter(|c| !c.span.overlaps(hole.span)),
171+
);
201172
}
202173

203-
// After finding the spans before each hole, any remaining fragments/spans
204-
// form their own final bucket, after the final hole.
174+
// Any remaining spans form their own final bucket, after the final hole.
205175
// (If there were no holes, this will just be all of the initial spans.)
206-
fragments.extend(input_covspans);
207-
buckets.push(fragments);
176+
buckets.push(Vec::from(input_covspans));
208177

209178
buckets
210179
}
@@ -215,7 +184,7 @@ fn drain_front_while<'a, T>(
215184
queue: &'a mut VecDeque<T>,
216185
mut pred_fn: impl FnMut(&T) -> bool,
217186
) -> impl Iterator<Item = T> {
218-
std::iter::from_fn(move || if pred_fn(queue.front()?) { queue.pop_front() } else { None })
187+
iter::from_fn(move || queue.pop_front_if(|x| pred_fn(x)))
219188
}
220189

221190
/// Takes one of the buckets of (sorted) spans extracted from MIR, and "refines"
@@ -258,22 +227,6 @@ struct Covspan {
258227
}
259228

260229
impl Covspan {
261-
/// Splits this covspan into 0-2 parts:
262-
/// - The part that is strictly before the hole span, if any.
263-
/// - The part that is strictly after the hole span, if any.
264-
fn split_around_hole_span(&self, hole_span: Span) -> (Option<Self>, Option<Self>) {
265-
let before = try {
266-
let span = self.span.trim_end(hole_span)?;
267-
Self { span, ..*self }
268-
};
269-
let after = try {
270-
let span = self.span.trim_start(hole_span)?;
271-
Self { span, ..*self }
272-
};
273-
274-
(before, after)
275-
}
276-
277230
/// If `self` and `other` can be merged (i.e. they have the same BCB),
278231
/// mutates `self.span` to also include `other.span` and returns true.
279232
///

0 commit comments

Comments
 (0)