diff --git a/crates/hir_ty/src/tests.rs b/crates/hir_ty/src/tests.rs index c953925ecb5..91c9d38c52c 100644 --- a/crates/hir_ty/src/tests.rs +++ b/crates/hir_ty/src/tests.rs @@ -8,7 +8,7 @@ mod method_resolution; mod macros; mod display_source_code; -use std::sync::Arc; +use std::{env, sync::Arc}; use base_db::{fixture::WithFixture, FileRange, SourceDatabase, SourceDatabaseExt}; use expect::Expect; @@ -22,12 +22,14 @@ use hir_def::{ AssocItemId, DefWithBodyId, LocalModuleId, Lookup, ModuleDefId, }; use hir_expand::{db::AstDatabase, InFile}; -use stdx::format_to; +use stdx::{format_to, RacyFlag}; use syntax::{ algo, ast::{self, AstNode}, SyntaxNode, }; +use tracing_subscriber::{layer::SubscriberExt, EnvFilter, Registry}; +use tracing_tree::HierarchicalLayer; use crate::{ db::HirDatabase, display::HirDisplay, infer::TypeMismatch, test_db::TestDB, InferenceResult, Ty, @@ -37,9 +39,12 @@ use crate::{ // against snapshots of the expected results using expect. Use // `env UPDATE_EXPECT=1 cargo test -p hir_ty` to update the snapshots. -fn setup_tracing() -> tracing::subscriber::DefaultGuard { - use tracing_subscriber::{layer::SubscriberExt, EnvFilter, Registry}; - use tracing_tree::HierarchicalLayer; +fn setup_tracing() -> Option { + static ENABLE: RacyFlag = RacyFlag::new(); + if !ENABLE.get(|| env::var("CHALK_DEBUG").is_ok()) { + return None; + } + let filter = EnvFilter::from_env("CHALK_DEBUG"); let layer = HierarchicalLayer::default() .with_indent_lines(true) @@ -47,7 +52,7 @@ fn setup_tracing() -> tracing::subscriber::DefaultGuard { .with_indent_amount(2) .with_writer(std::io::stderr); let subscriber = Registry::default().with(filter).with(layer); - tracing::subscriber::set_default(subscriber) + Some(tracing::subscriber::set_default(subscriber)) } fn check_types(ra_fixture: &str) { diff --git a/crates/stdx/src/lib.rs b/crates/stdx/src/lib.rs index 265d192883e..5d60f02190c 100644 --- a/crates/stdx/src/lib.rs +++ b/crates/stdx/src/lib.rs @@ -1,5 +1,8 @@ //! Missing batteries for standard libraries. -use std::time::Instant; +use std::{ + sync::atomic::{AtomicUsize, Ordering}, + time::Instant, +}; mod macros; @@ -134,6 +137,31 @@ where left } +pub struct RacyFlag(AtomicUsize); + +impl RacyFlag { + pub const fn new() -> RacyFlag { + RacyFlag(AtomicUsize::new(0)) + } + + pub fn get(&self, init: impl FnMut() -> bool) -> bool { + let mut init = Some(init); + self.get_impl(&mut || init.take().map_or(false, |mut f| f())) + } + + fn get_impl(&self, init: &mut dyn FnMut() -> bool) -> bool { + match self.0.load(Ordering::Relaxed) { + 0 => false, + 1 => true, + _ => { + let res = init(); + self.0.store(if res { 1 } else { 0 }, Ordering::Relaxed); + res + } + } + } +} + #[cfg(test)] mod tests { use super::*;