Skip to content

Commit 765eebf

Browse files
committed
Auto merge of #62253 - Centril:rollup-115uuuq, r=Centril
Rollup of 8 pull requests Successful merges: - #62062 (Use a more efficient iteration order for forward dataflow) - #62063 (Use a more efficient iteration order for backward dataflow) - #62224 (rustdoc: remove unused derives and variants) - #62228 (Extend the #[must_use] lint to boxed types) - #62235 (Extend the `#[must_use]` lint to arrays) - #62239 (Fix a typo) - #62241 (Always parse 'async unsafe fn' + properly ban in 2015) - #62248 (before_exec actually will only get deprecated with 1.37) Failed merges: r? @ghost
2 parents 5748825 + 1abbf4b commit 765eebf

27 files changed

+359
-119
lines changed

RELEASES.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -309,9 +309,9 @@ Misc
309309

310310
Compatibility Notes
311311
-------------------
312-
- [`Command::before_exec` is now deprecated in favor of the
313-
unsafe method `Command::pre_exec`.][58059]
314-
- [Use of `ATOMIC_{BOOL, ISIZE, USIZE}_INIT` is now deprecated.][57425] As you
312+
- [`Command::before_exec` is being replaced by the unsafe method
313+
`Command::pre_exec`][58059] and will be deprecated with Rust 1.37.0.
314+
- [Use of `ATOMIC_{BOOL, ISIZE, USIZE}_INIT` is now deprecated][57425] as you
315315
can now use `const` functions in `static` variables.
316316

317317
[58370]: https://github.com/rust-lang/rust/pull/58370/

src/libcore/char/methods.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -337,16 +337,16 @@ impl char {
337337
/// ```
338338
/// // as chars
339339
/// let eastern = '東';
340-
/// let capitol = '京';
340+
/// let capital = '京';
341341
///
342342
/// // both can be represented as three bytes
343343
/// assert_eq!(3, eastern.len_utf8());
344-
/// assert_eq!(3, capitol.len_utf8());
344+
/// assert_eq!(3, capital.len_utf8());
345345
///
346346
/// // as a &str, these two are encoded in UTF-8
347347
/// let tokyo = "東京";
348348
///
349-
/// let len = eastern.len_utf8() + capitol.len_utf8();
349+
/// let len = eastern.len_utf8() + capital.len_utf8();
350350
///
351351
/// // we can see that they take six bytes total...
352352
/// assert_eq!(6, tokyo.len());

src/librustc_lint/unused.rs

+41-7
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
4848
}
4949

5050
let ty = cx.tables.expr_ty(&expr);
51-
let type_permits_lack_of_use = check_must_use_ty(cx, ty, &expr, s.span, "");
51+
let type_permits_lack_of_use = check_must_use_ty(cx, ty, &expr, s.span, "", "", false);
5252

5353
let mut fn_warned = false;
5454
let mut op_warned = false;
@@ -133,23 +133,39 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
133133
ty: Ty<'tcx>,
134134
expr: &hir::Expr,
135135
span: Span,
136-
descr_post_path: &str,
136+
descr_pre: &str,
137+
descr_post: &str,
138+
plural: bool,
137139
) -> bool {
138140
if ty.is_unit() || cx.tcx.is_ty_uninhabited_from(
139141
cx.tcx.hir().get_module_parent(expr.hir_id), ty)
140142
{
141143
return true;
142144
}
143145

146+
let plural_suffix = if plural { "s" } else { "" };
147+
144148
match ty.sty {
145-
ty::Adt(def, _) => check_must_use_def(cx, def.did, span, "", descr_post_path),
149+
ty::Adt(..) if ty.is_box() => {
150+
let boxed_ty = ty.boxed_ty();
151+
let descr_pre = &format!("{}boxed ", descr_pre);
152+
check_must_use_ty(cx, boxed_ty, expr, span, descr_pre, descr_post, plural)
153+
}
154+
ty::Adt(def, _) => {
155+
check_must_use_def(cx, def.did, span, descr_pre, descr_post)
156+
}
146157
ty::Opaque(def, _) => {
147158
let mut has_emitted = false;
148159
for (predicate, _) in &cx.tcx.predicates_of(def).predicates {
149160
if let ty::Predicate::Trait(ref poly_trait_predicate) = predicate {
150161
let trait_ref = poly_trait_predicate.skip_binder().trait_ref;
151162
let def_id = trait_ref.def_id;
152-
if check_must_use_def(cx, def_id, span, "implementer of ", "") {
163+
let descr_pre = &format!(
164+
"{}implementer{} of ",
165+
descr_pre,
166+
plural_suffix,
167+
);
168+
if check_must_use_def(cx, def_id, span, descr_pre, descr_post) {
153169
has_emitted = true;
154170
break;
155171
}
@@ -162,7 +178,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
162178
for predicate in binder.skip_binder().iter() {
163179
if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate {
164180
let def_id = trait_ref.def_id;
165-
if check_must_use_def(cx, def_id, span, "", " trait object") {
181+
let descr_post = &format!(
182+
" trait object{}{}",
183+
plural_suffix,
184+
descr_post,
185+
);
186+
if check_must_use_def(cx, def_id, span, descr_pre, descr_post) {
166187
has_emitted = true;
167188
break;
168189
}
@@ -179,14 +200,27 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
179200
vec![]
180201
};
181202
for (i, ty) in tys.iter().map(|k| k.expect_ty()).enumerate() {
182-
let descr_post_path = &format!(" in tuple element {}", i);
203+
let descr_post = &format!(" in tuple element {}", i);
183204
let span = *spans.get(i).unwrap_or(&span);
184-
if check_must_use_ty(cx, ty, expr, span, descr_post_path) {
205+
if check_must_use_ty(cx, ty, expr, span, descr_pre, descr_post, plural) {
185206
has_emitted = true;
186207
}
187208
}
188209
has_emitted
189210
}
211+
ty::Array(ty, len) => match len.assert_usize(cx.tcx) {
212+
// If the array is definitely non-empty, we can do `#[must_use]` checking.
213+
Some(n) if n != 0 => {
214+
let descr_pre = &format!(
215+
"{}array{} of ",
216+
descr_pre,
217+
plural_suffix,
218+
);
219+
check_must_use_ty(cx, ty, expr, span, descr_pre, descr_post, true)
220+
}
221+
// Otherwise, we don't lint, to avoid false positives.
222+
_ => false,
223+
}
190224
_ => false,
191225
}
192226
}

src/librustc_mir/dataflow/mod.rs

+18-2
Original file line numberDiff line numberDiff line change
@@ -228,9 +228,25 @@ where
228228
BD: BitDenotation<'tcx>,
229229
{
230230
fn walk_cfg(&mut self, in_out: &mut BitSet<BD::Idx>) {
231-
let mut dirty_queue: WorkQueue<mir::BasicBlock> =
232-
WorkQueue::with_all(self.builder.body.basic_blocks().len());
233231
let body = self.builder.body;
232+
233+
// Initialize the dirty queue in reverse post-order. This makes it more likely that the
234+
// entry state for each basic block will have the effects of its predecessors applied
235+
// before it is processed. In fact, for CFGs without back edges, this guarantees that
236+
// dataflow will converge in exactly `N` iterations, where `N` is the number of basic
237+
// blocks.
238+
let mut dirty_queue: WorkQueue<mir::BasicBlock> =
239+
WorkQueue::with_none(body.basic_blocks().len());
240+
for (bb, _) in traversal::reverse_postorder(body) {
241+
dirty_queue.insert(bb);
242+
}
243+
244+
// Add blocks which are not reachable from START_BLOCK to the work queue. These blocks will
245+
// be processed after the ones added above.
246+
for bb in body.basic_blocks().indices() {
247+
dirty_queue.insert(bb);
248+
}
249+
234250
while let Some(bb) = dirty_queue.pop() {
235251
let (on_entry, trans) = self.builder.flow_state.sets.get_mut(bb.index());
236252
debug_assert!(in_out.words().len() == on_entry.words().len());

src/librustc_mir/util/liveness.rs

+18-3
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,24 @@ pub fn liveness_of_locals<'tcx>(
7575

7676
let mut bits = LiveVarSet::new_empty(num_live_vars);
7777

78-
// queue of things that need to be re-processed, and a set containing
79-
// the things currently in the queue
80-
let mut dirty_queue: WorkQueue<BasicBlock> = WorkQueue::with_all(body.basic_blocks().len());
78+
// The dirty queue contains the set of basic blocks whose entry sets have changed since they
79+
// were last processed. At the start of the analysis, we initialize the queue in post-order to
80+
// make it more likely that the entry set for a given basic block will have the effects of all
81+
// its successors in the CFG applied before it is processed.
82+
//
83+
// FIXME(ecstaticmorse): Reverse post-order on the reverse CFG may generate a better iteration
84+
// order when cycles are present, but the overhead of computing the reverse CFG may outweigh
85+
// any benefits. Benchmark this and find out.
86+
let mut dirty_queue: WorkQueue<BasicBlock> = WorkQueue::with_none(body.basic_blocks().len());
87+
for (bb, _) in traversal::postorder(body) {
88+
dirty_queue.insert(bb);
89+
}
90+
91+
// Add blocks which are not reachable from START_BLOCK to the work queue. These blocks will
92+
// be processed after the ones added above.
93+
for bb in body.basic_blocks().indices() {
94+
dirty_queue.insert(bb);
95+
}
8196

8297
let predecessors = body.predecessors();
8398

src/librustc_passes/ast_validation.rs

-7
Original file line numberDiff line numberDiff line change
@@ -837,13 +837,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
837837
the relevant `fold_*()` method in `PlaceholderExpander`?");
838838
}
839839

840-
fn visit_fn_header(&mut self, header: &'a FnHeader) {
841-
if header.asyncness.node.is_async() && self.session.rust_2015() {
842-
struct_span_err!(self.session, header.asyncness.span, E0670,
843-
"`async fn` is not permitted in the 2015 edition").emit();
844-
}
845-
}
846-
847840
fn visit_impl_item(&mut self, ii: &'a ImplItem) {
848841
match ii.node {
849842
ImplItemKind::Method(ref sig, _) => {

src/librustdoc/clean/cfg.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use syntax_pos::Span;
1616

1717
use crate::html::escape::Escape;
1818

19-
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, PartialEq, Eq, Hash)]
19+
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2020
pub enum Cfg {
2121
/// Accepts all configurations.
2222
True,

0 commit comments

Comments
 (0)