about summary refs log tree commit diff
diff options
context:
space:
mode:
authorQuentin Boyer <qbsecond@gmail.com>2019-11-03 16:44:19 +0100
committerQuentin Boyer <qbsecond@gmail.com>2019-11-03 16:44:19 +0100
commit32f3fe7a6d9b11ec029be3655da854514cb0a1db (patch)
treefe22a1e1b1e30871600fbea804e08a9174b2a16b
parent6299c3302216174de41a24ca44033f978cd64666 (diff)
downloadrust-32f3fe7a6d9b11ec029be3655da854514cb0a1db.tar.gz
rust-32f3fe7a6d9b11ec029be3655da854514cb0a1db.zip
add rustc_error(delay_span_bug_from_inside_query) attribute
-rw-r--r--src/librustc/query/mod.rs6
-rw-r--r--src/librustc_codegen_utils/lib.rs32
-rw-r--r--src/libsyntax/feature_gate/builtin_attrs.rs5
-rw-r--r--src/libsyntax_pos/symbol.rs1
4 files changed, 40 insertions, 4 deletions
diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs
index c95652f274e..2bc4b59962b 100644
--- a/src/librustc/query/mod.rs
+++ b/src/librustc/query/mod.rs
@@ -30,6 +30,12 @@ use syntax_pos::symbol::InternedString;
 // 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> {
             cache_on_disk_if { key.is_local() }
diff --git a/src/librustc_codegen_utils/lib.rs b/src/librustc_codegen_utils/lib.rs
index 66920342ff6..bfc70b0d875 100644
--- a/src/librustc_codegen_utils/lib.rs
+++ b/src/librustc_codegen_utils/lib.rs
@@ -19,7 +19,7 @@ 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;
@@ -27,18 +27,44 @@ 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), "compilation successful");
+}
+
 /// 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), "compilation successful");
+                    }
+                }
+            }
         }
     }
 }
 
 pub fn provide(providers: &mut Providers<'_>) {
     crate::symbol_names::provide(providers);
+    *providers = Providers {
+        trigger_delay_span_bug,
+        ..*providers
+    };
 }
diff --git a/src/libsyntax/feature_gate/builtin_attrs.rs b/src/libsyntax/feature_gate/builtin_attrs.rs
index ab1620b9524..e9eef1c9d6b 100644
--- a/src/libsyntax/feature_gate/builtin_attrs.rs
+++ b/src/libsyntax/feature_gate/builtin_attrs.rs
@@ -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")),
diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs
index c37efde9923..6ff9ee03e19 100644
--- a/src/libsyntax_pos/symbol.rs
+++ b/src/libsyntax_pos/symbol.rs
@@ -234,6 +234,7 @@ symbols! {
         default_lib_allocator,
         default_type_parameter_fallback,
         default_type_params,
+        delay_span_bug_from_inside_query,
         deny,
         deprecated,
         deref,