diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs index 85fca68187fe6..21ffe6b895e72 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>, - [] 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>, diff --git a/src/librustc/ty/maps/plumbing.rs b/src/librustc/ty/maps/plumbing.rs index 0ab6ee1a54a9b..f02c7cbd0ea3e 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>, query_stack: RefCell)>>,