Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
10 changes: 10 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 @@ -688,6 +695,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
23 changes: 18 additions & 5 deletions src/tools/compiletest/src/runtest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,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 +395,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 @@ -428,7 +434,12 @@ impl<'test> TestCx<'test> {
}

fn check_correct_failure_status(&self, proc_res: &ProcRes) {
let expected_status = Some(self.props.failure_status);
let expected_status =
if self.props.should_ice {
Some(101)
} else {
Some(self.props.failure_status)
};
let received_status = proc_res.status.code();

if expected_status != received_status {
Expand Down Expand Up @@ -1402,9 +1413,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 +2531,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