Skip to content

Commit 144b9c5

Browse files
committed
Auto merge of #125817 - jieyouxu:rollup-ak8rrn1, r=jieyouxu
Rollup of 6 pull requests Successful merges: - #125652 (Revert propagation of drop-live information from Polonius) - #125730 (Apply `x clippy --fix` and `x fmt` on Rustc) - #125752 (run-make: enforce `#[must_use]` and arm command wrappers with drop bombs) - #125756 (coverage: Optionally instrument the RHS of lazy logical operators) - #125796 (Also InstSimplify `&raw*`) - #125816 (Don't build the `rust-demangler` binary for coverage tests) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 2a2c29a + 7082681 commit 144b9c5

File tree

58 files changed

+846
-190
lines changed

Some content is hidden

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

58 files changed

+846
-190
lines changed

compiler/rustc_borrowck/src/type_check/liveness/mod.rs

+3-8
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ use std::rc::Rc;
1414
use crate::{
1515
constraints::OutlivesConstraintSet,
1616
facts::{AllFacts, AllFactsExt},
17-
location::LocationTable,
1817
region_infer::values::LivenessValues,
1918
universal_regions::UniversalRegions,
2019
};
@@ -39,7 +38,6 @@ pub(super) fn generate<'mir, 'tcx>(
3938
elements: &Rc<DenseLocationMap>,
4039
flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'mir, 'tcx>>,
4140
move_data: &MoveData<'tcx>,
42-
location_table: &LocationTable,
4341
use_polonius: bool,
4442
) {
4543
debug!("liveness::generate");
@@ -53,11 +51,9 @@ pub(super) fn generate<'mir, 'tcx>(
5351
compute_relevant_live_locals(typeck.tcx(), &free_regions, body);
5452
let facts_enabled = use_polonius || AllFacts::enabled(typeck.tcx());
5553

56-
let polonius_drop_used = facts_enabled.then(|| {
57-
let mut drop_used = Vec::new();
58-
polonius::populate_access_facts(typeck, body, location_table, move_data, &mut drop_used);
59-
drop_used
60-
});
54+
if facts_enabled {
55+
polonius::populate_access_facts(typeck, body, move_data);
56+
};
6157

6258
trace::trace(
6359
typeck,
@@ -67,7 +63,6 @@ pub(super) fn generate<'mir, 'tcx>(
6763
move_data,
6864
relevant_live_locals,
6965
boring_locals,
70-
polonius_drop_used,
7166
);
7267

7368
// Mark regions that should be live where they appear within rvalues or within a call: like

compiler/rustc_borrowck/src/type_check/liveness/polonius.rs

+1-8
Original file line numberDiff line numberDiff line change
@@ -85,13 +85,10 @@ impl<'a, 'tcx> Visitor<'tcx> for UseFactsExtractor<'a, 'tcx> {
8585
pub(super) fn populate_access_facts<'a, 'tcx>(
8686
typeck: &mut TypeChecker<'a, 'tcx>,
8787
body: &Body<'tcx>,
88-
location_table: &LocationTable,
8988
move_data: &MoveData<'tcx>,
90-
//FIXME: this is not mutated, but expected to be modified as
91-
// out param, bug?
92-
dropped_at: &mut Vec<(Local, Location)>,
9389
) {
9490
debug!("populate_access_facts()");
91+
let location_table = typeck.borrowck_context.location_table;
9592

9693
if let Some(facts) = typeck.borrowck_context.all_facts.as_mut() {
9794
let mut extractor = UseFactsExtractor {
@@ -104,10 +101,6 @@ pub(super) fn populate_access_facts<'a, 'tcx>(
104101
};
105102
extractor.visit_body(body);
106103

107-
facts.var_dropped_at.extend(
108-
dropped_at.iter().map(|&(local, location)| (local, location_table.mid_index(location))),
109-
);
110-
111104
for (local, local_decl) in body.local_decls.iter_enumerated() {
112105
debug!(
113106
"add use_of_var_derefs_origin facts - local={:?}, type={:?}",

compiler/rustc_borrowck/src/type_check/liveness/trace.rs

+25-10
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use rustc_mir_dataflow::impls::MaybeInitializedPlaces;
1616
use rustc_mir_dataflow::move_paths::{HasMoveData, MoveData, MovePathIndex};
1717
use rustc_mir_dataflow::ResultsCursor;
1818

19+
use crate::location::RichLocation;
1920
use crate::{
2021
region_infer::values::{self, LiveLoans},
2122
type_check::liveness::local_use_map::LocalUseMap,
@@ -46,7 +47,6 @@ pub(super) fn trace<'mir, 'tcx>(
4647
move_data: &MoveData<'tcx>,
4748
relevant_live_locals: Vec<Local>,
4849
boring_locals: Vec<Local>,
49-
polonius_drop_used: Option<Vec<(Local, Location)>>,
5050
) {
5151
let local_use_map = &LocalUseMap::build(&relevant_live_locals, elements, body);
5252

@@ -93,9 +93,7 @@ pub(super) fn trace<'mir, 'tcx>(
9393

9494
let mut results = LivenessResults::new(cx);
9595

96-
if let Some(drop_used) = polonius_drop_used {
97-
results.add_extra_drop_facts(drop_used, relevant_live_locals.iter().copied().collect())
98-
}
96+
results.add_extra_drop_facts(&relevant_live_locals);
9997

10098
results.compute_for_all_locals(relevant_live_locals);
10199

@@ -218,21 +216,38 @@ impl<'me, 'typeck, 'flow, 'tcx> LivenessResults<'me, 'typeck, 'flow, 'tcx> {
218216
///
219217
/// Add facts for all locals with free regions, since regions may outlive
220218
/// the function body only at certain nodes in the CFG.
221-
fn add_extra_drop_facts(
222-
&mut self,
223-
drop_used: Vec<(Local, Location)>,
224-
relevant_live_locals: FxIndexSet<Local>,
225-
) {
219+
fn add_extra_drop_facts(&mut self, relevant_live_locals: &[Local]) -> Option<()> {
220+
let drop_used = self
221+
.cx
222+
.typeck
223+
.borrowck_context
224+
.all_facts
225+
.as_ref()
226+
.map(|facts| facts.var_dropped_at.clone())?;
227+
228+
let relevant_live_locals: FxIndexSet<_> = relevant_live_locals.iter().copied().collect();
229+
226230
let locations = IntervalSet::new(self.cx.elements.num_points());
227231

228-
for (local, location) in drop_used {
232+
for (local, location_index) in drop_used {
229233
if !relevant_live_locals.contains(&local) {
230234
let local_ty = self.cx.body.local_decls[local].ty;
231235
if local_ty.has_free_regions() {
236+
let location = match self
237+
.cx
238+
.typeck
239+
.borrowck_context
240+
.location_table
241+
.to_location(location_index)
242+
{
243+
RichLocation::Start(l) => l,
244+
RichLocation::Mid(l) => l,
245+
};
232246
self.cx.add_drop_live_facts_for(local, local_ty, &[location], &locations);
233247
}
234248
}
235249
}
250+
Some(())
236251
}
237252

238253
/// Clear the value of fields that are "per local variable".

compiler/rustc_borrowck/src/type_check/mod.rs

+1-9
Original file line numberDiff line numberDiff line change
@@ -188,15 +188,7 @@ pub(crate) fn type_check<'mir, 'tcx>(
188188
checker.equate_inputs_and_outputs(body, universal_regions, &normalized_inputs_and_output);
189189
checker.check_signature_annotation(body);
190190

191-
liveness::generate(
192-
&mut checker,
193-
body,
194-
elements,
195-
flow_inits,
196-
move_data,
197-
location_table,
198-
use_polonius,
199-
);
191+
liveness::generate(&mut checker, body, elements, flow_inits, move_data, use_polonius);
200192

201193
translate_outlives_facts(&mut checker);
202194
let opaque_type_values = infcx.take_opaque_types();

compiler/rustc_data_structures/src/graph/dominators/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ fn dominators_impl<G: ControlFlowGraph>(graph: &G) -> Inner<G::Node> {
9393
// These are all done here rather than through one of the 'standard'
9494
// graph traversals to help make this fast.
9595
'recurse: while let Some(frame) = stack.last_mut() {
96-
while let Some(successor) = frame.iter.next() {
96+
for successor in frame.iter.by_ref() {
9797
if real_to_pre_order[successor].is_none() {
9898
let pre_order_idx = pre_order_to_real.push(successor);
9999
real_to_pre_order[successor] = Some(pre_order_idx);

compiler/rustc_data_structures/src/graph/iterate/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ fn post_order_walk<G: DirectedGraph + Successors>(
4848
let node = frame.node;
4949
visited[node] = true;
5050

51-
while let Some(successor) = frame.iter.next() {
51+
for successor in frame.iter.by_ref() {
5252
if !visited[successor] {
5353
stack.push(PostOrderFrame { node: successor, iter: graph.successors(successor) });
5454
continue 'recurse;
@@ -112,7 +112,7 @@ where
112112
/// This is equivalent to just invoke `next` repeatedly until
113113
/// you get a `None` result.
114114
pub fn complete_search(&mut self) {
115-
while let Some(_) = self.next() {}
115+
for _ in self.by_ref() {}
116116
}
117117

118118
/// Returns true if node has been visited thus far.

compiler/rustc_data_structures/src/graph/scc/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ pub struct SccData<S: Idx> {
4040
}
4141

4242
impl<N: Idx, S: Idx + Ord> Sccs<N, S> {
43-
pub fn new(graph: &(impl DirectedGraph<Node = N> + Successors)) -> Self {
43+
pub fn new(graph: &impl Successors<Node = N>) -> Self {
4444
SccsConstruction::construct(graph)
4545
}
4646

compiler/rustc_data_structures/src/profiling.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -562,7 +562,7 @@ impl SelfProfiler {
562562
// ASLR is disabled and the heap is otherwise deterministic.
563563
let pid: u32 = process::id();
564564
let filename = format!("{crate_name}-{pid:07}.rustc_profile");
565-
let path = output_directory.join(&filename);
565+
let path = output_directory.join(filename);
566566
let profiler =
567567
Profiler::with_counter(&path, measureme::counters::Counter::by_name(counter_name)?)?;
568568

compiler/rustc_data_structures/src/sorted_map.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -125,13 +125,13 @@ impl<K: Ord, V> SortedMap<K, V> {
125125

126126
/// Iterate over the keys, sorted
127127
#[inline]
128-
pub fn keys(&self) -> impl Iterator<Item = &K> + ExactSizeIterator + DoubleEndedIterator {
128+
pub fn keys(&self) -> impl ExactSizeIterator<Item = &K> + DoubleEndedIterator {
129129
self.data.iter().map(|(k, _)| k)
130130
}
131131

132132
/// Iterate over values, sorted by key
133133
#[inline]
134-
pub fn values(&self) -> impl Iterator<Item = &V> + ExactSizeIterator + DoubleEndedIterator {
134+
pub fn values(&self) -> impl ExactSizeIterator<Item = &V> + DoubleEndedIterator {
135135
self.data.iter().map(|(_, v)| v)
136136
}
137137

compiler/rustc_data_structures/src/sync/lock.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ mod maybe_sync {
6969
match self.mode {
7070
Mode::NoSync => {
7171
let cell = unsafe { &self.lock.mode_union.no_sync };
72-
debug_assert_eq!(cell.get(), true);
72+
debug_assert!(cell.get());
7373
cell.set(false);
7474
}
7575
// SAFETY (unlock): We know that the lock is locked as this type is a proof of that.

compiler/rustc_mir_build/src/build/coverageinfo.rs

+57
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,63 @@ impl BranchInfoBuilder {
157157
}
158158

159159
impl<'tcx> Builder<'_, 'tcx> {
160+
/// If condition coverage is enabled, inject extra blocks and marker statements
161+
/// that will let us track the value of the condition in `place`.
162+
pub(crate) fn visit_coverage_standalone_condition(
163+
&mut self,
164+
mut expr_id: ExprId, // Expression giving the span of the condition
165+
place: mir::Place<'tcx>, // Already holds the boolean condition value
166+
block: &mut BasicBlock,
167+
) {
168+
// Bail out if condition coverage is not enabled for this function.
169+
let Some(branch_info) = self.coverage_branch_info.as_mut() else { return };
170+
if !self.tcx.sess.instrument_coverage_condition() {
171+
return;
172+
};
173+
174+
// Remove any wrappers, so that we can inspect the real underlying expression.
175+
while let ExprKind::Use { source: inner } | ExprKind::Scope { value: inner, .. } =
176+
self.thir[expr_id].kind
177+
{
178+
expr_id = inner;
179+
}
180+
// If the expression is a lazy logical op, it will naturally get branch
181+
// coverage as part of its normal lowering, so we can disregard it here.
182+
if let ExprKind::LogicalOp { .. } = self.thir[expr_id].kind {
183+
return;
184+
}
185+
186+
let source_info = SourceInfo { span: self.thir[expr_id].span, scope: self.source_scope };
187+
188+
// Using the boolean value that has already been stored in `place`, set up
189+
// control flow in the shape of a diamond, so that we can place separate
190+
// marker statements in the true and false blocks. The coverage MIR pass
191+
// will use those markers to inject coverage counters as appropriate.
192+
//
193+
// block
194+
// / \
195+
// true_block false_block
196+
// (marker) (marker)
197+
// \ /
198+
// join_block
199+
200+
let true_block = self.cfg.start_new_block();
201+
let false_block = self.cfg.start_new_block();
202+
self.cfg.terminate(
203+
*block,
204+
source_info,
205+
mir::TerminatorKind::if_(mir::Operand::Copy(place), true_block, false_block),
206+
);
207+
208+
branch_info.add_two_way_branch(&mut self.cfg, source_info, true_block, false_block);
209+
210+
let join_block = self.cfg.start_new_block();
211+
self.cfg.goto(true_block, source_info, join_block);
212+
self.cfg.goto(false_block, source_info, join_block);
213+
// Any subsequent codegen in the caller should use the new join block.
214+
*block = join_block;
215+
}
216+
160217
/// If branch coverage is enabled, inject marker statements into `then_block`
161218
/// and `else_block`, and record their IDs in the table of branch spans.
162219
pub(crate) fn visit_coverage_branch_condition(

compiler/rustc_mir_build/src/build/expr/into.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -183,9 +183,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
183183
const_: Const::from_bool(this.tcx, constant),
184184
},
185185
);
186-
let rhs = unpack!(this.expr_into_dest(destination, continuation, rhs));
186+
let mut rhs_block = unpack!(this.expr_into_dest(destination, continuation, rhs));
187+
// Instrument the lowered RHS's value for condition coverage.
188+
// (Does nothing if condition coverage is not enabled.)
189+
this.visit_coverage_standalone_condition(rhs, destination, &mut rhs_block);
190+
187191
let target = this.cfg.start_new_block();
188-
this.cfg.goto(rhs, source_info, target);
192+
this.cfg.goto(rhs_block, source_info, target);
189193
this.cfg.goto(short_circuit, source_info, target);
190194
target.unit()
191195
}

compiler/rustc_mir_transform/src/instsimplify.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> {
123123

124124
/// Transform `&(*a)` ==> `a`.
125125
fn simplify_ref_deref(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) {
126-
if let Rvalue::Ref(_, _, place) = rvalue {
126+
if let Rvalue::Ref(_, _, place) | Rvalue::AddressOf(_, place) = rvalue {
127127
if let Some((base, ProjectionElem::Deref)) = place.as_ref().last_projection() {
128128
if rvalue.ty(self.local_decls, self.tcx) != base.ty(self.local_decls, self.tcx).ty {
129129
return;

compiler/rustc_parse_format/src/lib.rs

+8-10
Original file line numberDiff line numberDiff line change
@@ -286,13 +286,11 @@ impl<'a> Iterator for Parser<'a> {
286286
lbrace_byte_pos.to(InnerOffset(rbrace_byte_pos.0 + width)),
287287
);
288288
}
289-
} else {
290-
if let Some(&(_, maybe)) = self.cur.peek() {
291-
match maybe {
292-
'?' => self.suggest_format_debug(),
293-
'<' | '^' | '>' => self.suggest_format_align(maybe),
294-
_ => self.suggest_positional_arg_instead_of_captured_arg(arg),
295-
}
289+
} else if let Some(&(_, maybe)) = self.cur.peek() {
290+
match maybe {
291+
'?' => self.suggest_format_debug(),
292+
'<' | '^' | '>' => self.suggest_format_align(maybe),
293+
_ => self.suggest_positional_arg_instead_of_captured_arg(arg),
296294
}
297295
}
298296
Some(NextArgument(Box::new(arg)))
@@ -1028,7 +1026,7 @@ fn find_width_map_from_snippet(
10281026
if next_c == '{' {
10291027
// consume up to 6 hexanumeric chars
10301028
let digits_len =
1031-
s.clone().take(6).take_while(|(_, c)| c.is_digit(16)).count();
1029+
s.clone().take(6).take_while(|(_, c)| c.is_ascii_hexdigit()).count();
10321030

10331031
let len_utf8 = s
10341032
.as_str()
@@ -1047,14 +1045,14 @@ fn find_width_map_from_snippet(
10471045
width += required_skips + 2;
10481046

10491047
s.nth(digits_len);
1050-
} else if next_c.is_digit(16) {
1048+
} else if next_c.is_ascii_hexdigit() {
10511049
width += 1;
10521050

10531051
// We suggest adding `{` and `}` when appropriate, accept it here as if
10541052
// it were correct
10551053
let mut i = 0; // consume up to 6 hexanumeric chars
10561054
while let (Some((_, c)), _) = (s.next(), i < 6) {
1057-
if c.is_digit(16) {
1055+
if c.is_ascii_hexdigit() {
10581056
width += 1;
10591057
} else {
10601058
break;

compiler/rustc_serialize/src/serialize.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ impl<S: Encoder> Encodable<S> for () {
252252
}
253253

254254
impl<D: Decoder> Decodable<D> for () {
255-
fn decode(_: &mut D) -> () {}
255+
fn decode(_: &mut D) {}
256256
}
257257

258258
impl<S: Encoder, T> Encodable<S> for PhantomData<T> {

compiler/rustc_session/src/config.rs

+17-1
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,23 @@ pub enum CoverageLevel {
159159
Block,
160160
/// Also instrument branch points (includes block coverage).
161161
Branch,
162-
/// Instrument for MC/DC. Mostly a superset of branch coverage, but might
162+
/// Same as branch coverage, but also adds branch instrumentation for
163+
/// certain boolean expressions that are not directly used for branching.
164+
///
165+
/// For example, in the following code, `b` does not directly participate
166+
/// in a branch, but condition coverage will instrument it as its own
167+
/// artificial branch:
168+
/// ```
169+
/// # let (a, b) = (false, true);
170+
/// let x = a && b;
171+
/// // ^ last operand
172+
/// ```
173+
///
174+
/// This level is mainly intended to be a stepping-stone towards full MC/DC
175+
/// instrumentation, so it might be removed in the future when MC/DC is
176+
/// sufficiently complete, or if it is making MC/DC changes difficult.
177+
Condition,
178+
/// Instrument for MC/DC. Mostly a superset of condition coverage, but might
163179
/// differ in some corner cases.
164180
Mcdc,
165181
}

0 commit comments

Comments
 (0)