Skip to content

Commit de10abf

Browse files
committed
Auto merge of #75016 - Manishearth:rollup-x553g7j, r=Manishearth
Rollup of 6 pull requests Successful merges: - #74977 (Clean up E0741 error explanation) - #74981 (Some fixes for `plugin.md` in unstable-book) - #74983 (Replace a recursive algorithm with an iterative one and a stack.) - #74995 (Update the WASI libc build to LLVM 10.) - #74996 (submodules: update cargo from 974eb438d to 2d5c2381e) - #75007 (Clean up E0743 explanation) Failed merges: r? @ghost
2 parents cfdf9d3 + 2e53ac5 commit de10abf

File tree

6 files changed

+74
-56
lines changed

6 files changed

+74
-56
lines changed

src/ci/docker/host-x86_64/dist-various-2/build-wasi-toolchain.sh

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44

55
set -ex
66

7-
# Originally from https://releases.llvm.org/9.0.0/clang+llvm-9.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz
8-
curl https://ci-mirrors.rust-lang.org/rustc/clang%2Bllvm-9.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz | \
7+
# Originally from https://github.com/llvm/llvm-project/releases/download/llvmorg-10.0.0/clang+llvm-10.0.0-x86_64-linux-gnu-ubuntu-18.04.tar.xz
8+
curl https://ci-mirrors.rust-lang.org/rustc/clang%2Bllvm-10.0.0-x86_64-linux-gnu-ubuntu-18.04.tar.xz | \
99
tar xJf -
10-
export PATH=`pwd`/clang+llvm-9.0.0-x86_64-linux-gnu-ubuntu-14.04/bin:$PATH
10+
export PATH=`pwd`/clang+llvm-10.0.0-x86_64-linux-gnu-ubuntu-18.04/bin:$PATH
1111

1212
git clone https://github.com/WebAssembly/wasi-libc
1313

src/doc/unstable-book/src/language-features/plugin.md

+14-16
Original file line numberDiff line numberDiff line change
@@ -45,42 +45,40 @@ that warns about any item named `lintme`.
4545
extern crate rustc_ast;
4646
4747
// Load rustc as a plugin to get macros
48-
#[macro_use]
49-
extern crate rustc;
5048
extern crate rustc_driver;
49+
#[macro_use]
50+
extern crate rustc_lint;
51+
#[macro_use]
52+
extern crate rustc_session;
5153
52-
use rustc::lint::{EarlyContext, LintContext, LintPass, EarlyLintPass,
53-
EarlyLintPassObject, LintArray};
5454
use rustc_driver::plugin::Registry;
55+
use rustc_lint::{EarlyContext, EarlyLintPass, LintArray, LintContext, LintPass};
5556
use rustc_ast::ast;
56-
5757
declare_lint!(TEST_LINT, Warn, "Warn about items named 'lintme'");
5858
59-
struct Pass;
60-
61-
impl LintPass for Pass {
62-
fn get_lints(&self) -> LintArray {
63-
lint_array!(TEST_LINT)
64-
}
65-
}
59+
declare_lint_pass!(Pass => [TEST_LINT]);
6660
6761
impl EarlyLintPass for Pass {
6862
fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) {
69-
if it.ident.as_str() == "lintme" {
70-
cx.span_lint(TEST_LINT, it.span, "item is named 'lintme'");
63+
if it.ident.name.as_str() == "lintme" {
64+
cx.lint(TEST_LINT, |lint| {
65+
lint.build("item is named 'lintme'").set_span(it.span).emit()
66+
});
7167
}
7268
}
7369
}
7470
7571
#[plugin_registrar]
7672
pub fn plugin_registrar(reg: &mut Registry) {
77-
reg.register_early_lint_pass(box Pass as EarlyLintPassObject);
73+
reg.lint_store.register_lints(&[&TEST_LINT]);
74+
reg.lint_store.register_early_pass(|| box Pass);
7875
}
7976
```
8077

8178
Then code like
8279

8380
```rust,ignore
81+
#![feature(plugin)]
8482
#![plugin(lint_plugin_test)]
8583
8684
fn lintme() { }
@@ -107,7 +105,7 @@ The components of a lint plugin are:
107105

108106
Lint passes are syntax traversals, but they run at a late stage of compilation
109107
where type information is available. `rustc`'s [built-in
110-
lints](https://github.com/rust-lang/rust/blob/master/src/librustc/lint/builtin.rs)
108+
lints](https://github.com/rust-lang/rust/blob/master/src/librustc_session/lint/builtin.rs)
111109
mostly use the same infrastructure as lint plugins, and provide examples of how
112110
to access type information.
113111

src/librustc_error_codes/error_codes/E0741.md

+8-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
Only structural-match types (that is, types that derive `PartialEq` and `Eq`)
2-
may be used as the types of const generic parameters.
1+
A non-structural-match type was used as the type of a const generic parameter.
2+
3+
Erroneous code example:
34

45
```compile_fail,E0741
56
#![feature(const_generics)]
@@ -9,12 +10,15 @@ struct A;
910
struct B<const X: A>; // error!
1011
```
1112

12-
To fix this example, we derive `PartialEq` and `Eq`.
13+
Only structural-match types (that is, types that derive `PartialEq` and `Eq`)
14+
may be used as the types of const generic parameters.
15+
16+
To fix the previous code example, we derive `PartialEq` and `Eq`:
1317

1418
```
1519
#![feature(const_generics)]
1620
17-
#[derive(PartialEq, Eq)]
21+
#[derive(PartialEq, Eq)] // We derive both traits here.
1822
struct A;
1923
2024
struct B<const X: A>; // ok!

src/librustc_error_codes/error_codes/E0743.md

+5-6
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,9 @@ Erroneous code example:
88
fn foo2(x: u8, y: &...) {} // error!
99
```
1010

11-
Only foreign functions can use the C-variadic type (`...`).
12-
In such functions, `...` may only occur non-nested.
13-
That is, `y: &'a ...` is not allowed.
11+
Only foreign functions can use the C-variadic type (`...`). In such functions,
12+
`...` may only occur non-nested. That is, `y: &'a ...` is not allowed.
1413

15-
A C-variadic type is used to give an undefined number
16-
of parameters to a given function (like `printf` in C).
17-
The equivalent in Rust would be to use macros directly.
14+
A C-variadic type is used to give an undefined number of parameters to a given
15+
function (like `printf` in C). The equivalent in Rust would be to use macros
16+
directly (like `println!` for example).

src/librustc_mir/transform/simplify.rs

+43-26
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ use rustc_index::vec::{Idx, IndexVec};
3333
use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Visitor};
3434
use rustc_middle::mir::*;
3535
use rustc_middle::ty::TyCtxt;
36+
use smallvec::SmallVec;
3637
use std::borrow::Cow;
3738

3839
pub struct SimplifyCfg {
@@ -172,9 +173,12 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> {
172173
}
173174
}
174175

175-
// Collapse a goto chain starting from `start`
176-
fn collapse_goto_chain(&mut self, start: &mut BasicBlock, changed: &mut bool) {
177-
let mut terminator = match self.basic_blocks[*start] {
176+
/// This function will return `None` if
177+
/// * the block has statements
178+
/// * the block has a terminator other than `goto`
179+
/// * the block has no terminator (meaning some other part of the current optimization stole it)
180+
fn take_terminator_if_simple_goto(&mut self, bb: BasicBlock) -> Option<Terminator<'tcx>> {
181+
match self.basic_blocks[bb] {
178182
BasicBlockData {
179183
ref statements,
180184
terminator:
@@ -183,32 +187,45 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> {
183187
} if statements.is_empty() => terminator.take(),
184188
// if `terminator` is None, this means we are in a loop. In that
185189
// case, let all the loop collapse to its entry.
186-
_ => return,
187-
};
188-
189-
let target = match terminator {
190-
Some(Terminator { kind: TerminatorKind::Goto { ref mut target }, .. }) => {
191-
self.collapse_goto_chain(target, changed);
192-
*target
193-
}
194-
_ => unreachable!(),
195-
};
196-
self.basic_blocks[*start].terminator = terminator;
197-
198-
debug!("collapsing goto chain from {:?} to {:?}", *start, target);
199-
200-
*changed |= *start != target;
190+
_ => None,
191+
}
192+
}
201193

202-
if self.pred_count[*start] == 1 {
203-
// This is the last reference to *start, so the pred-count to
204-
// to target is moved into the current block.
205-
self.pred_count[*start] = 0;
206-
} else {
207-
self.pred_count[target] += 1;
208-
self.pred_count[*start] -= 1;
194+
/// Collapse a goto chain starting from `start`
195+
fn collapse_goto_chain(&mut self, start: &mut BasicBlock, changed: &mut bool) {
196+
// Using `SmallVec` here, because in some logs on libcore oli-obk saw many single-element
197+
// goto chains. We should probably benchmark different sizes.
198+
let mut terminators: SmallVec<[_; 1]> = Default::default();
199+
let mut current = *start;
200+
while let Some(terminator) = self.take_terminator_if_simple_goto(current) {
201+
let target = match terminator {
202+
Terminator { kind: TerminatorKind::Goto { target }, .. } => target,
203+
_ => unreachable!(),
204+
};
205+
terminators.push((current, terminator));
206+
current = target;
209207
}
208+
let last = current;
209+
*start = last;
210+
while let Some((current, mut terminator)) = terminators.pop() {
211+
let target = match terminator {
212+
Terminator { kind: TerminatorKind::Goto { ref mut target }, .. } => target,
213+
_ => unreachable!(),
214+
};
215+
*target = last;
216+
debug!("collapsing goto chain from {:?} to {:?}", current, target);
210217

211-
*start = target;
218+
if self.pred_count[current] == 1 {
219+
// This is the last reference to current, so the pred-count to
220+
// to target is moved into the current block.
221+
self.pred_count[current] = 0;
222+
} else {
223+
self.pred_count[*target] += 1;
224+
self.pred_count[current] -= 1;
225+
}
226+
*changed = true;
227+
self.basic_blocks[current].terminator = Some(terminator);
228+
}
212229
}
213230

214231
// merge a block with 1 `goto` predecessor to its parent

0 commit comments

Comments
 (0)