Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Making ICEs and test them in incremental #66060

Merged
merged 9 commits into from
Nov 20, 2019
6 changes: 6 additions & 0 deletions src/librustc/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ use syntax_pos::symbol::InternedString;
// Queries marked with `fatal_cycle` do not need the latter implementation,
// as they will raise an fatal error on query cycles instead.
rustc_queries! {
Other {
query trigger_delay_span_bug(key: DefId) -> () {
desc { "trigger a delay span bug" }
}
}

Other {
/// Records the type of every item.
query type_of(key: DefId) -> Ty<'tcx> {
Expand Down
38 changes: 35 additions & 3 deletions src/librustc_codegen_utils/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,58 @@ extern crate rustc;

use rustc::ty::TyCtxt;
use rustc::ty::query::Providers;
use rustc::hir::def_id::LOCAL_CRATE;
use rustc::hir::def_id::{LOCAL_CRATE, DefId};
use syntax::symbol::sym;

pub mod link;
pub mod codegen_backend;
pub mod symbol_names;
pub mod symbol_names_test;


pub fn trigger_delay_span_bug(tcx: TyCtxt<'_>, key: DefId) {
tcx.sess.delay_span_bug(
tcx.def_span(key),
"delayed span bug triggered by #[rustc_error(delay_span_bug_from_inside_query)]"
);
}

/// check for the #[rustc_error] annotation, which forces an
/// error in codegen. This is used to write compile-fail tests
/// that actually test that compilation succeeds without
/// reporting an error.
pub fn check_for_rustc_errors_attr(tcx: TyCtxt<'_>) {
if let Some((def_id, _)) = tcx.entry_fn(LOCAL_CRATE) {
if tcx.has_attr(def_id, sym::rustc_error) {
tcx.sess.span_fatal(tcx.def_span(def_id), "compilation successful");
let attrs = &*tcx.get_attrs(def_id);
for attr in attrs {
if attr.check_name(sym::rustc_error) {
match attr.meta_item_list() {
// check if there is a #[rustc_error(delayed)]
Some(list) => {
if list.iter().any(|list_item| {
list_item.ident().map(|i| i.name) ==
Some(sym::delay_span_bug_from_inside_query)
}) {
tcx.ensure().trigger_delay_span_bug(def_id);
}
}
// bare #[rustc_error]
None => {
tcx.sess.span_fatal(
tcx.def_span(def_id),
"fatal error triggered by #[rustc_error]"
);
}
}
}
}
}
}

pub fn provide(providers: &mut Providers<'_>) {
crate::symbol_names::provide(providers);
*providers = Providers {
trigger_delay_span_bug,
..*providers
};
}
5 changes: 4 additions & 1 deletion src/libsyntax/feature_gate/builtin_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,10 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
rustc_attr!(TEST, rustc_variance, Normal, template!(Word)),
rustc_attr!(TEST, rustc_layout, Normal, template!(List: "field1, field2, ...")),
rustc_attr!(TEST, rustc_regions, Normal, template!(Word)),
rustc_attr!(TEST, rustc_error, Whitelisted, template!(Word)),
rustc_attr!(
TEST, rustc_error, Whitelisted,
template!(Word, List: "delay_span_bug_from_inside_query")
),
rustc_attr!(TEST, rustc_dump_user_substs, Whitelisted, template!(Word)),
rustc_attr!(TEST, rustc_if_this_changed, Whitelisted, template!(Word, List: "DepNode")),
rustc_attr!(TEST, rustc_then_this_would_need, Whitelisted, template!(List: "DepNode")),
Expand Down
1 change: 1 addition & 0 deletions src/libsyntax_pos/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ symbols! {
default_lib_allocator,
default_type_parameter_fallback,
default_type_params,
delay_span_bug_from_inside_query,
deny,
deprecated,
deref,
Expand Down
8 changes: 8 additions & 0 deletions src/test/incremental/delayed_span_bug.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// revisions: cfail1 cfail2
// should-ice
// error-pattern: delayed span bug triggered by #[rustc_error(delay_span_bug_from_inside_query)]

#![feature(rustc_attrs)]

#[rustc_error(delay_span_bug_from_inside_query)]
fn main() {}
2 changes: 1 addition & 1 deletion src/test/ui/associated-types/bound-lifetime-constrained.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,4 @@ fn clause2<T>() where T: for<'a> Fn() -> <() as Foo<'a>>::Item {
}

#[rustc_error]
fn main() { } //[ok]~ ERROR compilation successful
fn main() { } //[ok]~ ERROR fatal error triggered by #[rustc_error]
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: compilation successful
error: fatal error triggered by #[rustc_error]
--> $DIR/bound-lifetime-in-binding-only.rs:71:1
|
LL | fn main() { }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,4 @@ fn ok3<T>() where for<'a> Parameterized<'a>: Foo<Item=&'a i32> {
}

#[rustc_error]
fn main() { } //[ok]~ ERROR compilation successful
fn main() { } //[ok]~ ERROR fatal error triggered by #[rustc_error]
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: compilation successful
error: fatal error triggered by #[rustc_error]
--> $DIR/bound-lifetime-in-return-only.rs:49:1
|
LL | fn main() { }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,4 @@ fn ok2(_: &dyn for<'a,'b> Fn<(&'b Parameterized<'a>,), Output=&'a i32>) {
}

#[rustc_error]
fn main() { } //[ok]~ ERROR compilation successful
fn main() { } //[ok]~ ERROR fatal error triggered by #[rustc_error]
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: compilation successful
error: fatal error triggered by #[rustc_error]
--> $DIR/project-fn-ret-contravariant.rs:50:1
|
LL | fn main() { }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: compilation successful
error: fatal error triggered by #[rustc_error]
--> $DIR/project-fn-ret-contravariant.rs:50:1
|
LL | fn main() { }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,5 @@ fn transmute<'a,'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) {

#[rustc_error]
fn main() { }
//[ok]~^ ERROR compilation successful
//[oneuse]~^^ ERROR compilation successful
//[ok]~^ ERROR fatal error triggered by #[rustc_error]
//[oneuse]~^^ ERROR fatal error triggered by #[rustc_error]
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: compilation successful
error: fatal error triggered by #[rustc_error]
--> $DIR/project-fn-ret-invariant.rs:59:1
|
LL | fn main() { }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,4 @@ fn transmute<'a,'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {

#[rustc_error]
fn main() { }
//[ok]~^ ERROR compilation successful
//[ok]~^ ERROR fatal error triggered by #[rustc_error]
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: compilation successful
error: fatal error triggered by #[rustc_error]
--> $DIR/higher-ranked-projection.rs:24:1
|
LL | / fn main() {
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/associated-types/higher-ranked-projection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ fn foo<U, T>(_t: T)
{}

#[rustc_error]
fn main() { //[good]~ ERROR compilation successful
fn main() { //[good]~ ERROR fatal error triggered by #[rustc_error]
foo(());
//[bad]~^ ERROR type mismatch
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: compilation successful
error: fatal error triggered by #[rustc_error]
--> $DIR/hr-subtype.rs:100:1
|
LL | / fn main() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: compilation successful
error: fatal error triggered by #[rustc_error]
--> $DIR/hr-subtype.rs:100:1
|
LL | / fn main() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: compilation successful
error: fatal error triggered by #[rustc_error]
--> $DIR/hr-subtype.rs:100:1
|
LL | / fn main() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: compilation successful
error: fatal error triggered by #[rustc_error]
--> $DIR/hr-subtype.rs:100:1
|
LL | / fn main() {
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/hr-subtype/hr-subtype.free_x_vs_free_x.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: compilation successful
error: fatal error triggered by #[rustc_error]
--> $DIR/hr-subtype.rs:100:1
|
LL | / fn main() {
Expand Down
10 changes: 5 additions & 5 deletions src/test/ui/hr-subtype/hr-subtype.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,9 @@ check! { bound_a_b_ret_a_vs_bound_a_ret_a: (for<'a,'b> fn(&'a u32, &'b u32) -> &

#[rustc_error]
fn main() {
//[bound_a_vs_bound_a]~^ ERROR compilation successful
//[bound_a_vs_bound_b]~^^ ERROR compilation successful
//[bound_inv_a_vs_bound_inv_b]~^^^ ERROR compilation successful
//[bound_co_a_vs_bound_co_b]~^^^^ ERROR compilation successful
//[free_x_vs_free_x]~^^^^^ ERROR compilation successful
//[bound_a_vs_bound_a]~^ ERROR fatal error triggered by #[rustc_error]
//[bound_a_vs_bound_b]~^^ ERROR fatal error triggered by #[rustc_error]
//[bound_inv_a_vs_bound_inv_b]~^^^ ERROR fatal error triggered by #[rustc_error]
//[bound_co_a_vs_bound_co_b]~^^^^ ERROR fatal error triggered by #[rustc_error]
//[free_x_vs_free_x]~^^^^^ ERROR fatal error triggered by #[rustc_error]
}
2 changes: 1 addition & 1 deletion src/test/ui/proc-macro/no-macro-use-attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ extern crate test_macros;
//~^ WARN unused extern crate

#[rustc_error]
fn main() {} //~ ERROR compilation successful
fn main() {} //~ ERROR fatal error triggered by #[rustc_error]
2 changes: 1 addition & 1 deletion src/test/ui/proc-macro/no-macro-use-attr.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ note: lint level defined here
LL | #![warn(unused_extern_crates)]
| ^^^^^^^^^^^^^^^^^^^^

error: compilation successful
error: fatal error triggered by #[rustc_error]
--> $DIR/no-macro-use-attr.rs:10:1
|
LL | fn main() {}
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/rfc1445/feature-gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ struct Foo {
const FOO: Foo = Foo { x: 0 };

#[rustc_error]
fn main() { //[with_gate]~ ERROR compilation successful
fn main() { //[with_gate]~ ERROR fatal error triggered by #[rustc_error]
let y = Foo { x: 1 };
match y {
FOO => { }
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/rfc1445/feature-gate.with_gate.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: compilation successful
error: fatal error triggered by #[rustc_error]
--> $DIR/feature-gate.rs:21:1
|
LL | / fn main() {
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/rustc-error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@

#[rustc_error]
fn main() {
//~^ ERROR compilation successful
//~^ ERROR fatal error triggered by #[rustc_error]
}
2 changes: 1 addition & 1 deletion src/test/ui/rustc-error.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: compilation successful
error: fatal error triggered by #[rustc_error]
--> $DIR/rustc-error.rs:4:1
|
LL | / fn main() {
Expand Down
13 changes: 13 additions & 0 deletions src/tools/compiletest/src/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,8 @@ pub struct TestProps {
// If true, `rustfix` will only apply `MachineApplicable` suggestions.
pub rustfix_only_machine_applicable: bool,
pub assembly_output: Option<String>,
// If true, the test is expected to ICE
pub should_ice: bool,
}

impl TestProps {
Expand Down Expand Up @@ -414,6 +416,7 @@ impl TestProps {
run_rustfix: false,
rustfix_only_machine_applicable: false,
assembly_output: None,
should_ice: false,
}
}

Expand Down Expand Up @@ -464,6 +467,10 @@ impl TestProps {
self.pp_exact = config.parse_pp_exact(ln, testfile);
}

if !self.should_ice {
self.should_ice = config.parse_should_ice(ln);
}

if !self.build_aux_docs {
self.build_aux_docs = config.parse_build_aux_docs(ln);
}
Expand Down Expand Up @@ -578,6 +585,9 @@ impl TestProps {
_ => 1,
};
}
if self.should_ice {
self.failure_status = 101;
}

for key in &["RUST_TEST_NOCAPTURE", "RUST_TEST_THREADS"] {
if let Ok(val) = env::var(key) {
Expand Down Expand Up @@ -688,6 +698,9 @@ fn iter_header(testfile: &Path, cfg: Option<&str>, it: &mut dyn FnMut(&str)) {
}

impl Config {
fn parse_should_ice(&self, line: &str) -> bool {
self.parse_name_directive(line, "should-ice")
}
fn parse_error_pattern(&self, line: &str) -> Option<String> {
self.parse_name_value_directive(line, "error-pattern")
}
Expand Down
28 changes: 24 additions & 4 deletions src/tools/compiletest/src/runtest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,12 @@ impl<'test> TestCx<'test> {
/// Code executed for each revision in turn (or, if there are no
/// revisions, exactly once, with revision == None).
fn run_revision(&self) {
if self.props.should_ice {
if self.config.mode != CompileFail &&
self.config.mode != Incremental {
self.fatal("cannot use should-ice in a test that is not cfail");
}
}
match self.config.mode {
CompileFail => self.run_cfail_test(),
RunFail => self.run_rfail_test(),
Expand Down Expand Up @@ -383,7 +389,7 @@ impl<'test> TestCx<'test> {
fn run_cfail_test(&self) {
let proc_res = self.compile_test();
self.check_if_test_should_compile(&proc_res);
self.check_no_compiler_crash(&proc_res);
self.check_no_compiler_crash(&proc_res, self.props.should_ice);

let output_to_check = self.get_output(&proc_res);
let expected_errors = errors::load_errors(&self.testpaths.file, self.revision);
Expand All @@ -395,6 +401,12 @@ impl<'test> TestCx<'test> {
} else {
self.check_error_patterns(&output_to_check, &proc_res);
}
if self.props.should_ice {
match proc_res.status.code() {
Some(101) => (),
_ => self.fatal("expected ICE"),
}
}

self.check_forbid_output(&output_to_check, &proc_res);
}
Expand Down Expand Up @@ -1402,9 +1414,11 @@ impl<'test> TestCx<'test> {
}
}

fn check_no_compiler_crash(&self, proc_res: &ProcRes) {
fn check_no_compiler_crash(&self, proc_res: &ProcRes, should_ice: bool) {
match proc_res.status.code() {
Some(101) => self.fatal_proc_rec("compiler encountered internal error", proc_res),
Some(101) if !should_ice => {
self.fatal_proc_rec("compiler encountered internal error", proc_res)
}
None => self.fatal_proc_rec("compiler terminated by signal", proc_res),
_ => (),
}
Expand Down Expand Up @@ -2518,7 +2532,7 @@ impl<'test> TestCx<'test> {
self.fatal_proc_rec("compilation failed!", &proc_res);
}

self.check_no_compiler_crash(&proc_res);
self.check_no_compiler_crash(&proc_res, self.props.should_ice);

const PREFIX: &'static str = "MONO_ITEM ";
const CGU_MARKER: &'static str = "@@";
Expand Down Expand Up @@ -2774,8 +2788,14 @@ impl<'test> TestCx<'test> {
}

if revision.starts_with("rpass") {
if revision_cx.props.should_ice {
revision_cx.fatal("can only use should-ice in cfail tests");
}
revision_cx.run_rpass_test();
} else if revision.starts_with("rfail") {
if revision_cx.props.should_ice {
revision_cx.fatal("can only use should-ice in cfail tests");
}
revision_cx.run_rfail_test();
} else if revision.starts_with("cfail") {
revision_cx.run_cfail_test();
Expand Down