Skip to content

Commit 4d941cd

Browse files
committed
Auto merge of #111452 - matthiaskrgr:rollup-uic8dgy, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - #108705 (Prevent ICE with broken borrow in closure) - #111292 (Fix mishandled `--check-cfg` arguments order) - #111382 (Isolate coverage FFI type layouts from their underlying LLVM C++ types) - #111385 (vec-shrink-panik: update expectations to work on LLVM 17) - #111389 (Add esp-idf platform-support page) - #111432 (Use visit_assign to detect SSA locals.) - #111448 (Use proper impl self type for alias impl in rustdoc) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 9a767b6 + 07af55e commit 4d941cd

File tree

21 files changed

+443
-49
lines changed

21 files changed

+443
-49
lines changed

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -680,7 +680,9 @@ pub type InlineAsmDiagHandlerTy = unsafe extern "C" fn(&SMDiagnostic, *const c_v
680680
pub mod coverageinfo {
681681
use super::coverage_map;
682682

683-
/// Aligns with [llvm::coverage::CounterMappingRegion::RegionKind](https://github.com/rust-lang/llvm-project/blob/rustc/13.0-2021-09-30/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L209-L230)
683+
/// Corresponds to enum `llvm::coverage::CounterMappingRegion::RegionKind`.
684+
///
685+
/// Must match the layout of `LLVMRustCounterMappingRegionKind`.
684686
#[derive(Copy, Clone, Debug)]
685687
#[repr(C)]
686688
pub enum RegionKind {
@@ -714,7 +716,9 @@ pub mod coverageinfo {
714716
/// array", encoded separately), and source location (start and end positions of the represented
715717
/// code region).
716718
///
717-
/// Matches LLVMRustCounterMappingRegion.
719+
/// Corresponds to struct `llvm::coverage::CounterMappingRegion`.
720+
///
721+
/// Must match the layout of `LLVMRustCounterMappingRegion`.
718722
#[derive(Copy, Clone, Debug)]
719723
#[repr(C)]
720724
pub struct CounterMappingRegion {

compiler/rustc_codegen_ssa/src/coverageinfo/ffi.rs

+11-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use rustc_middle::mir::coverage::{CounterValueReference, MappedExpressionIndex};
22

3-
/// Aligns with [llvm::coverage::Counter::CounterKind](https://github.com/rust-lang/llvm-project/blob/rustc/13.0-2021-09-30/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L95)
3+
/// Must match the layout of `LLVMRustCounterKind`.
44
#[derive(Copy, Clone, Debug)]
55
#[repr(C)]
66
pub enum CounterKind {
@@ -17,8 +17,10 @@ pub enum CounterKind {
1717
/// `instrprof.increment()`)
1818
/// * For `CounterKind::Expression`, `id` is the index into the coverage map's array of
1919
/// counter expressions.
20-
/// Aligns with [llvm::coverage::Counter](https://github.com/rust-lang/llvm-project/blob/rustc/13.0-2021-09-30/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L102-L103)
21-
/// Important: The Rust struct layout (order and types of fields) must match its C++ counterpart.
20+
///
21+
/// Corresponds to struct `llvm::coverage::Counter`.
22+
///
23+
/// Must match the layout of `LLVMRustCounter`.
2224
#[derive(Copy, Clone, Debug)]
2325
#[repr(C)]
2426
pub struct Counter {
@@ -59,17 +61,19 @@ impl Counter {
5961
}
6062
}
6163

62-
/// Aligns with [llvm::coverage::CounterExpression::ExprKind](https://github.com/rust-lang/llvm-project/blob/rustc/13.0-2021-09-30/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L150)
64+
/// Corresponds to enum `llvm::coverage::CounterExpression::ExprKind`.
65+
///
66+
/// Must match the layout of `LLVMRustCounterExprKind`.
6367
#[derive(Copy, Clone, Debug)]
6468
#[repr(C)]
6569
pub enum ExprKind {
6670
Subtract = 0,
6771
Add = 1,
6872
}
6973

70-
/// Aligns with [llvm::coverage::CounterExpression](https://github.com/rust-lang/llvm-project/blob/rustc/13.0-2021-09-30/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L151-L152)
71-
/// Important: The Rust struct layout (order and types of fields) must match its C++
72-
/// counterpart.
74+
/// Corresponds to struct `llvm::coverage::CounterExpression`.
75+
///
76+
/// Must match the layout of `LLVMRustCounterExpression`.
7377
#[derive(Copy, Clone, Debug)]
7478
#[repr(C)]
7579
pub struct CounterExpression {

compiler/rustc_interface/src/interface.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -173,12 +173,21 @@ pub fn parse_check_cfg(specs: Vec<String>) -> CheckCfg {
173173
let expected_values = check_cfg
174174
.expecteds
175175
.entry(ident.name.to_string())
176+
.and_modify(|expected_values| match expected_values {
177+
ExpectedValues::Some(_) => {}
178+
ExpectedValues::Any => {
179+
// handle the case where names(...) was done
180+
// before values by changing to a list
181+
*expected_values =
182+
ExpectedValues::Some(FxHashSet::default());
183+
}
184+
})
176185
.or_insert_with(|| {
177186
ExpectedValues::Some(FxHashSet::default())
178187
});
179188

180189
let ExpectedValues::Some(expected_values) = expected_values else {
181-
bug!("shoudn't be possible")
190+
bug!("`expected_values` should be a list a values")
182191
};
183192

184193
for val in values {

compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp

+101-8
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,100 @@
88

99
using namespace llvm;
1010

11+
// FFI equivalent of enum `llvm::coverage::Counter::CounterKind`
12+
// https://github.com/rust-lang/llvm-project/blob/ea6fa9c2/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L97-L99
13+
enum class LLVMRustCounterKind {
14+
Zero = 0,
15+
CounterValueReference = 1,
16+
Expression = 2,
17+
};
18+
19+
// FFI equivalent of struct `llvm::coverage::Counter`
20+
// https://github.com/rust-lang/llvm-project/blob/ea6fa9c2/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L94-L149
21+
struct LLVMRustCounter {
22+
LLVMRustCounterKind CounterKind;
23+
uint32_t ID;
24+
};
25+
26+
static coverage::Counter fromRust(LLVMRustCounter Counter) {
27+
switch (Counter.CounterKind) {
28+
case LLVMRustCounterKind::Zero:
29+
return coverage::Counter::getZero();
30+
case LLVMRustCounterKind::CounterValueReference:
31+
return coverage::Counter::getCounter(Counter.ID);
32+
case LLVMRustCounterKind::Expression:
33+
return coverage::Counter::getExpression(Counter.ID);
34+
}
35+
report_fatal_error("Bad LLVMRustCounterKind!");
36+
}
37+
38+
// FFI equivalent of enum `llvm::coverage::CounterMappingRegion::RegionKind`
39+
// https://github.com/rust-lang/llvm-project/blob/ea6fa9c2/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L213-L234
40+
enum class LLVMRustCounterMappingRegionKind {
41+
CodeRegion = 0,
42+
ExpansionRegion = 1,
43+
SkippedRegion = 2,
44+
GapRegion = 3,
45+
BranchRegion = 4,
46+
};
47+
48+
static coverage::CounterMappingRegion::RegionKind
49+
fromRust(LLVMRustCounterMappingRegionKind Kind) {
50+
switch (Kind) {
51+
case LLVMRustCounterMappingRegionKind::CodeRegion:
52+
return coverage::CounterMappingRegion::CodeRegion;
53+
case LLVMRustCounterMappingRegionKind::ExpansionRegion:
54+
return coverage::CounterMappingRegion::ExpansionRegion;
55+
case LLVMRustCounterMappingRegionKind::SkippedRegion:
56+
return coverage::CounterMappingRegion::SkippedRegion;
57+
case LLVMRustCounterMappingRegionKind::GapRegion:
58+
return coverage::CounterMappingRegion::GapRegion;
59+
case LLVMRustCounterMappingRegionKind::BranchRegion:
60+
return coverage::CounterMappingRegion::BranchRegion;
61+
}
62+
report_fatal_error("Bad LLVMRustCounterMappingRegionKind!");
63+
}
64+
65+
// FFI equivalent of struct `llvm::coverage::CounterMappingRegion`
66+
// https://github.com/rust-lang/llvm-project/blob/ea6fa9c2/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L211-L304
1167
struct LLVMRustCounterMappingRegion {
12-
coverage::Counter Count;
13-
coverage::Counter FalseCount;
68+
LLVMRustCounter Count;
69+
LLVMRustCounter FalseCount;
1470
uint32_t FileID;
1571
uint32_t ExpandedFileID;
1672
uint32_t LineStart;
1773
uint32_t ColumnStart;
1874
uint32_t LineEnd;
1975
uint32_t ColumnEnd;
20-
coverage::CounterMappingRegion::RegionKind Kind;
76+
LLVMRustCounterMappingRegionKind Kind;
77+
};
78+
79+
// FFI equivalent of enum `llvm::coverage::CounterExpression::ExprKind`
80+
// https://github.com/rust-lang/llvm-project/blob/ea6fa9c2/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L154
81+
enum class LLVMRustCounterExprKind {
82+
Subtract = 0,
83+
Add = 1,
2184
};
2285

86+
// FFI equivalent of struct `llvm::coverage::CounterExpression`
87+
// https://github.com/rust-lang/llvm-project/blob/ea6fa9c2/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L151-L160
88+
struct LLVMRustCounterExpression {
89+
LLVMRustCounterExprKind Kind;
90+
LLVMRustCounter LHS;
91+
LLVMRustCounter RHS;
92+
};
93+
94+
static coverage::CounterExpression::ExprKind
95+
fromRust(LLVMRustCounterExprKind Kind) {
96+
switch (Kind) {
97+
case LLVMRustCounterExprKind::Subtract:
98+
return coverage::CounterExpression::Subtract;
99+
case LLVMRustCounterExprKind::Add:
100+
return coverage::CounterExpression::Add;
101+
}
102+
report_fatal_error("Bad LLVMRustCounterExprKind!");
103+
}
104+
23105
extern "C" void LLVMRustCoverageWriteFilenamesSectionToBuffer(
24106
const char* const Filenames[],
25107
size_t FilenamesLen,
@@ -37,9 +119,9 @@ extern "C" void LLVMRustCoverageWriteFilenamesSectionToBuffer(
37119
extern "C" void LLVMRustCoverageWriteMappingToBuffer(
38120
const unsigned *VirtualFileMappingIDs,
39121
unsigned NumVirtualFileMappingIDs,
40-
const coverage::CounterExpression *Expressions,
122+
const LLVMRustCounterExpression *RustExpressions,
41123
unsigned NumExpressions,
42-
LLVMRustCounterMappingRegion *RustMappingRegions,
124+
const LLVMRustCounterMappingRegion *RustMappingRegions,
43125
unsigned NumMappingRegions,
44126
RustStringRef BufferOut) {
45127
// Convert from FFI representation to LLVM representation.
@@ -48,13 +130,24 @@ extern "C" void LLVMRustCoverageWriteMappingToBuffer(
48130
for (const auto &Region : ArrayRef<LLVMRustCounterMappingRegion>(
49131
RustMappingRegions, NumMappingRegions)) {
50132
MappingRegions.emplace_back(
51-
Region.Count, Region.FalseCount, Region.FileID, Region.ExpandedFileID,
133+
fromRust(Region.Count), fromRust(Region.FalseCount),
134+
Region.FileID, Region.ExpandedFileID,
52135
Region.LineStart, Region.ColumnStart, Region.LineEnd, Region.ColumnEnd,
53-
Region.Kind);
136+
fromRust(Region.Kind));
54137
}
138+
139+
std::vector<coverage::CounterExpression> Expressions;
140+
Expressions.reserve(NumExpressions);
141+
for (const auto &Expression :
142+
ArrayRef<LLVMRustCounterExpression>(RustExpressions, NumExpressions)) {
143+
Expressions.emplace_back(fromRust(Expression.Kind),
144+
fromRust(Expression.LHS),
145+
fromRust(Expression.RHS));
146+
}
147+
55148
auto CoverageMappingWriter = coverage::CoverageMappingWriter(
56149
ArrayRef<unsigned>(VirtualFileMappingIDs, NumVirtualFileMappingIDs),
57-
ArrayRef<coverage::CounterExpression>(Expressions, NumExpressions),
150+
Expressions,
58151
MappingRegions);
59152
RawRustStringOstream OS(BufferOut);
60153
CoverageMappingWriter.write(OS);

compiler/rustc_middle/src/query/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1016,7 +1016,7 @@ rustc_queries! {
10161016
desc { "converting literal to mir constant" }
10171017
}
10181018

1019-
query check_match(key: LocalDefId) {
1019+
query check_match(key: LocalDefId) -> Result<(), rustc_errors::ErrorGuaranteed> {
10201020
desc { |tcx| "match-checking `{}`", tcx.def_path_str(key) }
10211021
cache_on_disk_if { true }
10221022
}

compiler/rustc_mir_build/src/build/mod.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ fn mir_build(tcx: TyCtxt<'_>, def: LocalDefId) -> Body<'_> {
4242
// Ensure unsafeck and abstract const building is ran before we steal the THIR.
4343
tcx.ensure_with_value().thir_check_unsafety(def);
4444
tcx.ensure_with_value().thir_abstract_const(def);
45-
tcx.ensure_with_value().check_match(def);
45+
if let Err(e) = tcx.check_match(def) {
46+
return construct_error(tcx, def, e);
47+
}
4648

4749
let body = match tcx.thir_body(def) {
4850
Err(error_reported) => construct_error(tcx, def, error_reported),

compiler/rustc_mir_build/src/thir/pattern/check_match.rs

+14-11
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ use rustc_session::Session;
2626
use rustc_span::hygiene::DesugaringKind;
2727
use rustc_span::Span;
2828

29-
pub(crate) fn check_match(tcx: TyCtxt<'_>, def_id: LocalDefId) {
30-
let Ok((thir, expr)) = tcx.thir_body(def_id) else { return };
29+
pub(crate) fn check_match(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGuaranteed> {
30+
let (thir, expr) = tcx.thir_body(def_id)?;
3131
let thir = thir.borrow();
3232
let pattern_arena = TypedArena::default();
3333
let mut visitor = MatchVisitor {
@@ -37,13 +37,16 @@ pub(crate) fn check_match(tcx: TyCtxt<'_>, def_id: LocalDefId) {
3737
lint_level: tcx.hir().local_def_id_to_hir_id(def_id),
3838
let_source: LetSource::None,
3939
pattern_arena: &pattern_arena,
40+
error: Ok(()),
4041
};
4142
visitor.visit_expr(&thir[expr]);
43+
4244
for param in thir.params.iter() {
4345
if let Some(box ref pattern) = param.pat {
4446
visitor.check_irrefutable(pattern, "function argument", None);
4547
}
4648
}
49+
visitor.error
4750
}
4851

4952
fn create_e0004(
@@ -77,6 +80,7 @@ struct MatchVisitor<'a, 'p, 'tcx> {
7780
lint_level: HirId,
7881
let_source: LetSource,
7982
pattern_arena: &'p TypedArena<DeconstructedPat<'p, 'tcx>>,
83+
error: Result<(), ErrorGuaranteed>,
8084
}
8185

8286
impl<'a, 'tcx> Visitor<'a, 'tcx> for MatchVisitor<'a, '_, 'tcx> {
@@ -276,9 +280,9 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
276280
let [pat_field] = &subpatterns[..] else { bug!() };
277281
self.check_irrefutable(&pat_field.pattern, "`for` loop binding", None);
278282
} else {
279-
non_exhaustive_match(
283+
self.error = Err(non_exhaustive_match(
280284
&cx, self.thir, scrut_ty, scrut.span, witnesses, arms, expr_span,
281-
);
285+
));
282286
}
283287
}
284288
}
@@ -406,7 +410,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
406410
}
407411

408412
#[instrument(level = "trace", skip(self))]
409-
fn check_irrefutable(&self, pat: &Pat<'tcx>, origin: &str, sp: Option<Span>) {
413+
fn check_irrefutable(&mut self, pat: &Pat<'tcx>, origin: &str, sp: Option<Span>) {
410414
let mut cx = self.new_cx(self.lint_level, false);
411415

412416
let pattern = self.lower_pattern(&mut cx, pat);
@@ -475,7 +479,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
475479
AdtDefinedHere { adt_def_span, ty, variants }
476480
};
477481

478-
self.tcx.sess.emit_err(PatternNotCovered {
482+
self.error = Err(self.tcx.sess.emit_err(PatternNotCovered {
479483
span: pat.span,
480484
origin,
481485
uncovered: Uncovered::new(pat.span, &cx, witnesses),
@@ -486,7 +490,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
486490
let_suggestion,
487491
misc_suggestion,
488492
adt_defined_here,
489-
});
493+
}));
490494
}
491495
}
492496

@@ -628,7 +632,7 @@ fn non_exhaustive_match<'p, 'tcx>(
628632
witnesses: Vec<DeconstructedPat<'p, 'tcx>>,
629633
arms: &[ArmId],
630634
expr_span: Span,
631-
) {
635+
) -> ErrorGuaranteed {
632636
let is_empty_match = arms.is_empty();
633637
let non_empty_enum = match scrut_ty.kind() {
634638
ty::Adt(def, _) => def.is_enum() && !def.variants().is_empty(),
@@ -640,13 +644,12 @@ fn non_exhaustive_match<'p, 'tcx>(
640644
let pattern;
641645
let patterns_len;
642646
if is_empty_match && !non_empty_enum {
643-
cx.tcx.sess.emit_err(NonExhaustivePatternsTypeNotEmpty {
647+
return cx.tcx.sess.emit_err(NonExhaustivePatternsTypeNotEmpty {
644648
cx,
645649
expr_span,
646650
span: sp,
647651
ty: scrut_ty,
648652
});
649-
return;
650653
} else {
651654
// FIXME: migration of this diagnostic will require list support
652655
let joined_patterns = joined_uncovered_patterns(cx, &witnesses);
@@ -797,7 +800,7 @@ fn non_exhaustive_match<'p, 'tcx>(
797800
} else {
798801
err.help(msg);
799802
}
800-
err.emit();
803+
err.emit()
801804
}
802805

803806
pub(crate) fn joined_uncovered_patterns<'p, 'tcx>(

compiler/rustc_mir_transform/src/ssa.rs

+13-7
Original file line numberDiff line numberDiff line change
@@ -209,13 +209,6 @@ impl<'tcx> Visitor<'tcx> for SsaVisitor {
209209
match ctxt {
210210
PlaceContext::MutatingUse(MutatingUseContext::Projection)
211211
| PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection) => bug!(),
212-
PlaceContext::MutatingUse(MutatingUseContext::Store) => {
213-
self.assignments[local].insert(LocationExtended::Plain(loc));
214-
if let Set1::One(_) = self.assignments[local] {
215-
// Only record if SSA-like, to avoid growing the vector needlessly.
216-
self.assignment_order.push(local);
217-
}
218-
}
219212
// Anything can happen with raw pointers, so remove them.
220213
// We do not verify that all uses of the borrow dominate the assignment to `local`,
221214
// so we have to remove them too.
@@ -252,6 +245,19 @@ impl<'tcx> Visitor<'tcx> for SsaVisitor {
252245
self.visit_local(place.local, ctxt, loc);
253246
}
254247
}
248+
249+
fn visit_assign(&mut self, place: &Place<'tcx>, rvalue: &Rvalue<'tcx>, loc: Location) {
250+
if let Some(local) = place.as_local() {
251+
self.assignments[local].insert(LocationExtended::Plain(loc));
252+
if let Set1::One(_) = self.assignments[local] {
253+
// Only record if SSA-like, to avoid growing the vector needlessly.
254+
self.assignment_order.push(local);
255+
}
256+
} else {
257+
self.visit_place(place, PlaceContext::MutatingUse(MutatingUseContext::Store), loc);
258+
}
259+
self.visit_rvalue(rvalue, loc);
260+
}
255261
}
256262

257263
#[instrument(level = "trace", skip(ssa, body))]

0 commit comments

Comments
 (0)