diff options
| author | John Kåre Alsaker <john.kare.alsaker@gmail.com> | 2018-01-31 16:08:14 +0100 |
|---|---|---|
| committer | John Kåre Alsaker <john.kare.alsaker@gmail.com> | 2018-02-10 03:38:07 +0100 |
| commit | e236994c5e4c448fba3c02874f875b0844e43725 (patch) | |
| tree | ca8b3c38e30d8174c6ee16db7490a1b25688404f | |
| parent | 3bcda48a30b21e46b81a7989deb30a3ba85fb918 (diff) | |
| download | rust-e236994c5e4c448fba3c02874f875b0844e43725.tar.gz rust-e236994c5e4c448fba3c02874f875b0844e43725.zip | |
Add a `fatal_cycle` attribute for queries which indicates that they will cause a fatal error on query cycles
| -rw-r--r-- | src/librustc/ty/maps/mod.rs | 19 | ||||
| -rw-r--r-- | src/librustc/ty/maps/plumbing.rs | 17 |
2 files changed, 27 insertions, 9 deletions
diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs index 85fca68187f..21ffe6b895e 100644 --- a/src/librustc/ty/maps/mod.rs +++ b/src/librustc/ty/maps/mod.rs @@ -78,6 +78,11 @@ pub use self::on_disk_cache::OnDiskCache; // a way that memoizes and does dep-graph tracking, // wrapping around the actual chain of providers that // the driver creates (using several `rustc_*` crates). +// +// The result of query must implement Clone. They must also implement ty::maps::values::Value +// which produces an appropiate error value if the query resulted in a query cycle. +// Queries marked with `fatal_cycle` do not need that implementation +// as they will raise an fatal error on query cycles instead. define_maps! { <'tcx> /// Records the type of every item. [] fn type_of: TypeOfItem(DefId) -> Ty<'tcx>, @@ -267,13 +272,13 @@ define_maps! { <'tcx> [] fn dylib_dependency_formats: DylibDepFormats(CrateNum) -> Rc<Vec<(CrateNum, LinkagePreference)>>, - [] fn is_panic_runtime: IsPanicRuntime(CrateNum) -> bool, - [] fn is_compiler_builtins: IsCompilerBuiltins(CrateNum) -> bool, - [] fn has_global_allocator: HasGlobalAllocator(CrateNum) -> bool, - [] fn is_sanitizer_runtime: IsSanitizerRuntime(CrateNum) -> bool, - [] fn is_profiler_runtime: IsProfilerRuntime(CrateNum) -> bool, - [] fn panic_strategy: GetPanicStrategy(CrateNum) -> PanicStrategy, - [] fn is_no_builtins: IsNoBuiltins(CrateNum) -> bool, + [fatal_cycle] fn is_panic_runtime: IsPanicRuntime(CrateNum) -> bool, + [fatal_cycle] fn is_compiler_builtins: IsCompilerBuiltins(CrateNum) -> bool, + [fatal_cycle] fn has_global_allocator: HasGlobalAllocator(CrateNum) -> bool, + [fatal_cycle] fn is_sanitizer_runtime: IsSanitizerRuntime(CrateNum) -> bool, + [fatal_cycle] fn is_profiler_runtime: IsProfilerRuntime(CrateNum) -> bool, + [fatal_cycle] fn panic_strategy: GetPanicStrategy(CrateNum) -> PanicStrategy, + [fatal_cycle] fn is_no_builtins: IsNoBuiltins(CrateNum) -> bool, [] fn extern_crate: ExternCrate(DefId) -> Rc<Option<ExternCrate>>, diff --git a/src/librustc/ty/maps/plumbing.rs b/src/librustc/ty/maps/plumbing.rs index 0ab6ee1a54a..f02c7cbd0ea 100644 --- a/src/librustc/ty/maps/plumbing.rs +++ b/src/librustc/ty/maps/plumbing.rs @@ -183,6 +183,19 @@ macro_rules! profq_key { } } +macro_rules! handle_cycle_error { + ([][$this: expr]) => {{ + Value::from_cycle_error($this.global_tcx()) + }}; + ([fatal_cycle$(, $modifiers:ident)*][$this:expr]) => {{ + $this.tcx.sess.abort_if_errors(); + unreachable!(); + }}; + ([$other:ident$(, $modifiers:ident)*][$($args:tt)*]) => { + handle_cycle_error!([$($modifiers),*][$($args)*]) + }; +} + macro_rules! define_maps { (<$tcx:tt> $($(#[$attr:meta])* @@ -564,7 +577,7 @@ macro_rules! define_maps { pub fn $name(self, key: $K) -> $V { queries::$name::try_get(self.tcx, self.span, key).unwrap_or_else(|mut e| { e.emit(); - Value::from_cycle_error(self.global_tcx()) + handle_cycle_error!([$($modifiers)*][self]) }) })* } @@ -583,7 +596,7 @@ macro_rules! define_maps { macro_rules! define_map_struct { (tcx: $tcx:tt, - input: ($(([$(modifiers:tt)*] [$($attr:tt)*] [$name:ident]))*)) => { + input: ($(([$($modifiers:tt)*] [$($attr:tt)*] [$name:ident]))*)) => { pub struct Maps<$tcx> { providers: IndexVec<CrateNum, Providers<$tcx>>, query_stack: RefCell<Vec<(Span, Query<$tcx>)>>, |
