Skip to content

Commit e32397a

Browse files
authored
Rollup merge of rust-lang#66060 - traxys:test_65401, r=michaelwoerister
Making ICEs and test them in incremental This adds: - A way to make the compiler ICE - A way to check for ICE in `cfail` tests with `should-ice` - A regression test for issue rust-lang#65401 I am not sure the attribute added `should-ice` is the best for this job
2 parents b9cf541 + e01d941 commit e32397a

31 files changed

+120
-37
lines changed

src/librustc/query/mod.rs

+6
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ use syntax_pos::symbol::Symbol;
2929
// Queries marked with `fatal_cycle` do not need the latter implementation,
3030
// as they will raise an fatal error on query cycles instead.
3131
rustc_queries! {
32+
Other {
33+
query trigger_delay_span_bug(key: DefId) -> () {
34+
desc { "trigger a delay span bug" }
35+
}
36+
}
37+
3238
Other {
3339
/// Records the type of every item.
3440
query type_of(key: DefId) -> Ty<'tcx> {

src/librustc_codegen_utils/lib.rs

+35-3
Original file line numberDiff line numberDiff line change
@@ -19,26 +19,58 @@ extern crate rustc;
1919

2020
use rustc::ty::TyCtxt;
2121
use rustc::ty::query::Providers;
22-
use rustc::hir::def_id::LOCAL_CRATE;
22+
use rustc::hir::def_id::{LOCAL_CRATE, DefId};
2323
use syntax::symbol::sym;
2424

2525
pub mod link;
2626
pub mod codegen_backend;
2727
pub mod symbol_names;
2828
pub mod symbol_names_test;
2929

30+
31+
pub fn trigger_delay_span_bug(tcx: TyCtxt<'_>, key: DefId) {
32+
tcx.sess.delay_span_bug(
33+
tcx.def_span(key),
34+
"delayed span bug triggered by #[rustc_error(delay_span_bug_from_inside_query)]"
35+
);
36+
}
37+
3038
/// check for the #[rustc_error] annotation, which forces an
3139
/// error in codegen. This is used to write compile-fail tests
3240
/// that actually test that compilation succeeds without
3341
/// reporting an error.
3442
pub fn check_for_rustc_errors_attr(tcx: TyCtxt<'_>) {
3543
if let Some((def_id, _)) = tcx.entry_fn(LOCAL_CRATE) {
36-
if tcx.has_attr(def_id, sym::rustc_error) {
37-
tcx.sess.span_fatal(tcx.def_span(def_id), "compilation successful");
44+
let attrs = &*tcx.get_attrs(def_id);
45+
for attr in attrs {
46+
if attr.check_name(sym::rustc_error) {
47+
match attr.meta_item_list() {
48+
// check if there is a #[rustc_error(delayed)]
49+
Some(list) => {
50+
if list.iter().any(|list_item| {
51+
list_item.ident().map(|i| i.name) ==
52+
Some(sym::delay_span_bug_from_inside_query)
53+
}) {
54+
tcx.ensure().trigger_delay_span_bug(def_id);
55+
}
56+
}
57+
// bare #[rustc_error]
58+
None => {
59+
tcx.sess.span_fatal(
60+
tcx.def_span(def_id),
61+
"fatal error triggered by #[rustc_error]"
62+
);
63+
}
64+
}
65+
}
3866
}
3967
}
4068
}
4169

4270
pub fn provide(providers: &mut Providers<'_>) {
4371
crate::symbol_names::provide(providers);
72+
*providers = Providers {
73+
trigger_delay_span_bug,
74+
..*providers
75+
};
4476
}

src/libsyntax/feature_gate/builtin_attrs.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -543,7 +543,10 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
543543
rustc_attr!(TEST, rustc_variance, Normal, template!(Word)),
544544
rustc_attr!(TEST, rustc_layout, Normal, template!(List: "field1, field2, ...")),
545545
rustc_attr!(TEST, rustc_regions, Normal, template!(Word)),
546-
rustc_attr!(TEST, rustc_error, Whitelisted, template!(Word)),
546+
rustc_attr!(
547+
TEST, rustc_error, Whitelisted,
548+
template!(Word, List: "delay_span_bug_from_inside_query")
549+
),
547550
rustc_attr!(TEST, rustc_dump_user_substs, Whitelisted, template!(Word)),
548551
rustc_attr!(TEST, rustc_if_this_changed, Whitelisted, template!(Word, List: "DepNode")),
549552
rustc_attr!(TEST, rustc_then_this_would_need, Whitelisted, template!(List: "DepNode")),

src/libsyntax_pos/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ symbols! {
236236
default_lib_allocator,
237237
default_type_parameter_fallback,
238238
default_type_params,
239+
delay_span_bug_from_inside_query,
239240
deny,
240241
deprecated,
241242
deref,
+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// revisions: cfail1 cfail2
2+
// should-ice
3+
// error-pattern: delayed span bug triggered by #[rustc_error(delay_span_bug_from_inside_query)]
4+
5+
#![feature(rustc_attrs)]
6+
7+
#[rustc_error(delay_span_bug_from_inside_query)]
8+
fn main() {}

src/test/ui/associated-types/bound-lifetime-constrained.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,4 @@ fn clause2<T>() where T: for<'a> Fn() -> <() as Foo<'a>>::Item {
4545
}
4646

4747
#[rustc_error]
48-
fn main() { } //[ok]~ ERROR compilation successful
48+
fn main() { } //[ok]~ ERROR fatal error triggered by #[rustc_error]

src/test/ui/associated-types/bound-lifetime-in-binding-only.ok.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: compilation successful
1+
error: fatal error triggered by #[rustc_error]
22
--> $DIR/bound-lifetime-in-binding-only.rs:71:1
33
|
44
LL | fn main() { }

src/test/ui/associated-types/bound-lifetime-in-binding-only.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,4 @@ fn ok3<T>() where for<'a> Parameterized<'a>: Foo<Item=&'a i32> {
6868
}
6969

7070
#[rustc_error]
71-
fn main() { } //[ok]~ ERROR compilation successful
71+
fn main() { } //[ok]~ ERROR fatal error triggered by #[rustc_error]

src/test/ui/associated-types/bound-lifetime-in-return-only.ok.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: compilation successful
1+
error: fatal error triggered by #[rustc_error]
22
--> $DIR/bound-lifetime-in-return-only.rs:49:1
33
|
44
LL | fn main() { }

src/test/ui/associated-types/bound-lifetime-in-return-only.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,4 @@ fn ok2(_: &dyn for<'a,'b> Fn<(&'b Parameterized<'a>,), Output=&'a i32>) {
4646
}
4747

4848
#[rustc_error]
49-
fn main() { } //[ok]~ ERROR compilation successful
49+
fn main() { } //[ok]~ ERROR fatal error triggered by #[rustc_error]

src/test/ui/associated-types/cache/project-fn-ret-contravariant.ok.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: compilation successful
1+
error: fatal error triggered by #[rustc_error]
22
--> $DIR/project-fn-ret-contravariant.rs:50:1
33
|
44
LL | fn main() { }

src/test/ui/associated-types/cache/project-fn-ret-contravariant.oneuse.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: compilation successful
1+
error: fatal error triggered by #[rustc_error]
22
--> $DIR/project-fn-ret-contravariant.rs:50:1
33
|
44
LL | fn main() { }

src/test/ui/associated-types/cache/project-fn-ret-contravariant.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -48,5 +48,5 @@ fn transmute<'a,'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) {
4848

4949
#[rustc_error]
5050
fn main() { }
51-
//[ok]~^ ERROR compilation successful
52-
//[oneuse]~^^ ERROR compilation successful
51+
//[ok]~^ ERROR fatal error triggered by #[rustc_error]
52+
//[oneuse]~^^ ERROR fatal error triggered by #[rustc_error]

src/test/ui/associated-types/cache/project-fn-ret-invariant.ok.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: compilation successful
1+
error: fatal error triggered by #[rustc_error]
22
--> $DIR/project-fn-ret-invariant.rs:59:1
33
|
44
LL | fn main() { }

src/test/ui/associated-types/cache/project-fn-ret-invariant.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,4 @@ fn transmute<'a,'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
5757

5858
#[rustc_error]
5959
fn main() { }
60-
//[ok]~^ ERROR compilation successful
60+
//[ok]~^ ERROR fatal error triggered by #[rustc_error]

src/test/ui/associated-types/higher-ranked-projection.good.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: compilation successful
1+
error: fatal error triggered by #[rustc_error]
22
--> $DIR/higher-ranked-projection.rs:24:1
33
|
44
LL | / fn main() {

src/test/ui/associated-types/higher-ranked-projection.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ fn foo<U, T>(_t: T)
2121
{}
2222

2323
#[rustc_error]
24-
fn main() { //[good]~ ERROR compilation successful
24+
fn main() { //[good]~ ERROR fatal error triggered by #[rustc_error]
2525
foo(());
2626
//[bad]~^ ERROR type mismatch
2727
}

src/test/ui/hr-subtype/hr-subtype.bound_a_vs_bound_a.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: compilation successful
1+
error: fatal error triggered by #[rustc_error]
22
--> $DIR/hr-subtype.rs:100:1
33
|
44
LL | / fn main() {

src/test/ui/hr-subtype/hr-subtype.bound_a_vs_bound_b.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: compilation successful
1+
error: fatal error triggered by #[rustc_error]
22
--> $DIR/hr-subtype.rs:100:1
33
|
44
LL | / fn main() {

src/test/ui/hr-subtype/hr-subtype.bound_co_a_vs_bound_co_b.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: compilation successful
1+
error: fatal error triggered by #[rustc_error]
22
--> $DIR/hr-subtype.rs:100:1
33
|
44
LL | / fn main() {

src/test/ui/hr-subtype/hr-subtype.bound_inv_a_vs_bound_inv_b.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: compilation successful
1+
error: fatal error triggered by #[rustc_error]
22
--> $DIR/hr-subtype.rs:100:1
33
|
44
LL | / fn main() {

src/test/ui/hr-subtype/hr-subtype.free_x_vs_free_x.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: compilation successful
1+
error: fatal error triggered by #[rustc_error]
22
--> $DIR/hr-subtype.rs:100:1
33
|
44
LL | / fn main() {

src/test/ui/hr-subtype/hr-subtype.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,9 @@ check! { bound_a_b_ret_a_vs_bound_a_ret_a: (for<'a,'b> fn(&'a u32, &'b u32) -> &
9898

9999
#[rustc_error]
100100
fn main() {
101-
//[bound_a_vs_bound_a]~^ ERROR compilation successful
102-
//[bound_a_vs_bound_b]~^^ ERROR compilation successful
103-
//[bound_inv_a_vs_bound_inv_b]~^^^ ERROR compilation successful
104-
//[bound_co_a_vs_bound_co_b]~^^^^ ERROR compilation successful
105-
//[free_x_vs_free_x]~^^^^^ ERROR compilation successful
101+
//[bound_a_vs_bound_a]~^ ERROR fatal error triggered by #[rustc_error]
102+
//[bound_a_vs_bound_b]~^^ ERROR fatal error triggered by #[rustc_error]
103+
//[bound_inv_a_vs_bound_inv_b]~^^^ ERROR fatal error triggered by #[rustc_error]
104+
//[bound_co_a_vs_bound_co_b]~^^^^ ERROR fatal error triggered by #[rustc_error]
105+
//[free_x_vs_free_x]~^^^^^ ERROR fatal error triggered by #[rustc_error]
106106
}

src/test/ui/proc-macro/no-macro-use-attr.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ extern crate test_macros;
77
//~^ WARN unused extern crate
88

99
#[rustc_error]
10-
fn main() {} //~ ERROR compilation successful
10+
fn main() {} //~ ERROR fatal error triggered by #[rustc_error]

src/test/ui/proc-macro/no-macro-use-attr.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ note: lint level defined here
1010
LL | #![warn(unused_extern_crates)]
1111
| ^^^^^^^^^^^^^^^^^^^^
1212

13-
error: compilation successful
13+
error: fatal error triggered by #[rustc_error]
1414
--> $DIR/no-macro-use-attr.rs:10:1
1515
|
1616
LL | fn main() {}

src/test/ui/rfc1445/feature-gate.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ struct Foo {
1818
const FOO: Foo = Foo { x: 0 };
1919

2020
#[rustc_error]
21-
fn main() { //[with_gate]~ ERROR compilation successful
21+
fn main() { //[with_gate]~ ERROR fatal error triggered by #[rustc_error]
2222
let y = Foo { x: 1 };
2323
match y {
2424
FOO => { }

src/test/ui/rfc1445/feature-gate.with_gate.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: compilation successful
1+
error: fatal error triggered by #[rustc_error]
22
--> $DIR/feature-gate.rs:21:1
33
|
44
LL | / fn main() {

src/test/ui/rustc-error.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22

33
#[rustc_error]
44
fn main() {
5-
//~^ ERROR compilation successful
5+
//~^ ERROR fatal error triggered by #[rustc_error]
66
}

src/test/ui/rustc-error.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: compilation successful
1+
error: fatal error triggered by #[rustc_error]
22
--> $DIR/rustc-error.rs:4:1
33
|
44
LL | / fn main() {

src/tools/compiletest/src/header.rs

+13
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,8 @@ pub struct TestProps {
375375
// If true, `rustfix` will only apply `MachineApplicable` suggestions.
376376
pub rustfix_only_machine_applicable: bool,
377377
pub assembly_output: Option<String>,
378+
// If true, the test is expected to ICE
379+
pub should_ice: bool,
378380
}
379381

380382
impl TestProps {
@@ -413,6 +415,7 @@ impl TestProps {
413415
run_rustfix: false,
414416
rustfix_only_machine_applicable: false,
415417
assembly_output: None,
418+
should_ice: false,
416419
}
417420
}
418421

@@ -463,6 +466,10 @@ impl TestProps {
463466
self.pp_exact = config.parse_pp_exact(ln, testfile);
464467
}
465468

469+
if !self.should_ice {
470+
self.should_ice = config.parse_should_ice(ln);
471+
}
472+
466473
if !self.build_aux_docs {
467474
self.build_aux_docs = config.parse_build_aux_docs(ln);
468475
}
@@ -577,6 +584,9 @@ impl TestProps {
577584
_ => 1,
578585
};
579586
}
587+
if self.should_ice {
588+
self.failure_status = 101;
589+
}
580590

581591
for key in &["RUST_TEST_NOCAPTURE", "RUST_TEST_THREADS"] {
582592
if let Ok(val) = env::var(key) {
@@ -687,6 +697,9 @@ fn iter_header(testfile: &Path, cfg: Option<&str>, it: &mut dyn FnMut(&str)) {
687697
}
688698

689699
impl Config {
700+
fn parse_should_ice(&self, line: &str) -> bool {
701+
self.parse_name_directive(line, "should-ice")
702+
}
690703
fn parse_error_pattern(&self, line: &str) -> Option<String> {
691704
self.parse_name_value_directive(line, "error-pattern")
692705
}

src/tools/compiletest/src/runtest.rs

+24-4
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,12 @@ impl<'test> TestCx<'test> {
298298
/// Code executed for each revision in turn (or, if there are no
299299
/// revisions, exactly once, with revision == None).
300300
fn run_revision(&self) {
301+
if self.props.should_ice {
302+
if self.config.mode != CompileFail &&
303+
self.config.mode != Incremental {
304+
self.fatal("cannot use should-ice in a test that is not cfail");
305+
}
306+
}
301307
match self.config.mode {
302308
CompileFail => self.run_cfail_test(),
303309
RunFail => self.run_rfail_test(),
@@ -383,7 +389,7 @@ impl<'test> TestCx<'test> {
383389
fn run_cfail_test(&self) {
384390
let proc_res = self.compile_test();
385391
self.check_if_test_should_compile(&proc_res);
386-
self.check_no_compiler_crash(&proc_res);
392+
self.check_no_compiler_crash(&proc_res, self.props.should_ice);
387393

388394
let output_to_check = self.get_output(&proc_res);
389395
let expected_errors = errors::load_errors(&self.testpaths.file, self.revision);
@@ -395,6 +401,12 @@ impl<'test> TestCx<'test> {
395401
} else {
396402
self.check_error_patterns(&output_to_check, &proc_res);
397403
}
404+
if self.props.should_ice {
405+
match proc_res.status.code() {
406+
Some(101) => (),
407+
_ => self.fatal("expected ICE"),
408+
}
409+
}
398410

399411
self.check_forbid_output(&output_to_check, &proc_res);
400412
}
@@ -1402,9 +1414,11 @@ impl<'test> TestCx<'test> {
14021414
}
14031415
}
14041416

1405-
fn check_no_compiler_crash(&self, proc_res: &ProcRes) {
1417+
fn check_no_compiler_crash(&self, proc_res: &ProcRes, should_ice: bool) {
14061418
match proc_res.status.code() {
1407-
Some(101) => self.fatal_proc_rec("compiler encountered internal error", proc_res),
1419+
Some(101) if !should_ice => {
1420+
self.fatal_proc_rec("compiler encountered internal error", proc_res)
1421+
}
14081422
None => self.fatal_proc_rec("compiler terminated by signal", proc_res),
14091423
_ => (),
14101424
}
@@ -2518,7 +2532,7 @@ impl<'test> TestCx<'test> {
25182532
self.fatal_proc_rec("compilation failed!", &proc_res);
25192533
}
25202534

2521-
self.check_no_compiler_crash(&proc_res);
2535+
self.check_no_compiler_crash(&proc_res, self.props.should_ice);
25222536

25232537
const PREFIX: &'static str = "MONO_ITEM ";
25242538
const CGU_MARKER: &'static str = "@@";
@@ -2774,8 +2788,14 @@ impl<'test> TestCx<'test> {
27742788
}
27752789

27762790
if revision.starts_with("rpass") {
2791+
if revision_cx.props.should_ice {
2792+
revision_cx.fatal("can only use should-ice in cfail tests");
2793+
}
27772794
revision_cx.run_rpass_test();
27782795
} else if revision.starts_with("rfail") {
2796+
if revision_cx.props.should_ice {
2797+
revision_cx.fatal("can only use should-ice in cfail tests");
2798+
}
27792799
revision_cx.run_rfail_test();
27802800
} else if revision.starts_with("cfail") {
27812801
revision_cx.run_cfail_test();

0 commit comments

Comments
 (0)