diff --git a/components/salsa-macro-rules/src/macro_if.rs b/components/salsa-macro-rules/src/macro_if.rs index e7d05beff..a8dcc49c9 100644 --- a/components/salsa-macro-rules/src/macro_if.rs +++ b/components/salsa-macro-rules/src/macro_if.rs @@ -22,4 +22,12 @@ macro_rules! macro_if { (if0 $n:literal { $($t:tt)* } else { $($f:tt)*}) => { $($f)* }; + + (iftt () { $($t:tt)* } else { $($f:tt)*}) => { + $($f)* + }; + + (iftt ($($tt:tt)+) { $($t:tt)* } else { $($f:tt)*}) => { + $($t)* + }; } diff --git a/components/salsa-macro-rules/src/setup_interned_struct.rs b/components/salsa-macro-rules/src/setup_interned_struct.rs index b637586e5..9fffe1529 100644 --- a/components/salsa-macro-rules/src/setup_interned_struct.rs +++ b/components/salsa-macro-rules/src/setup_interned_struct.rs @@ -256,22 +256,58 @@ macro_rules! setup_interned_struct { ) } )* + } - /// Default debug formatting for this struct (may be useful if you define your own `Debug` impl) - pub fn default_debug_fmt(this: Self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - $zalsa::with_attached_database(|db| { - let zalsa = db.zalsa(); - let fields = $Configuration::ingredient(zalsa).fields(zalsa, this); - let mut f = f.debug_struct(stringify!($Struct)); - $( - let f = f.field(stringify!($field_id), &fields.$field_index); - )* - f.finish() - }).unwrap_or_else(|| { - f.debug_tuple(stringify!($Struct)) - .field(&$zalsa::AsId::as_id(&this)) - .finish() - }) + // Duplication can be dropped here once we no longer allow the `no_lifetime` hack + $zalsa::macro_if! { + iftt ($($db_lt_arg)?) { + impl $Struct<'_> { + /// Default debug formatting for this struct (may be useful if you define your own `Debug` impl) + pub fn default_debug_fmt(this: Self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result + where + // rustc rejects trivial bounds, but it cannot see through higher-ranked bounds + // with its check :^) + $(for<$db_lt> $field_ty: std::fmt::Debug),* + { + $zalsa::with_attached_database(|db| { + let zalsa = db.zalsa(); + let fields = $Configuration::ingredient(zalsa).fields(zalsa, this); + let mut f = f.debug_struct(stringify!($Struct)); + $( + let f = f.field(stringify!($field_id), &fields.$field_index); + )* + f.finish() + }).unwrap_or_else(|| { + f.debug_tuple(stringify!($Struct)) + .field(&$zalsa::AsId::as_id(&this)) + .finish() + }) + } + } + } else { + impl $Struct { + /// Default debug formatting for this struct (may be useful if you define your own `Debug` impl) + pub fn default_debug_fmt(this: Self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result + where + // rustc rejects trivial bounds, but it cannot see through higher-ranked bounds + // with its check :^) + $(for<$db_lt> $field_ty: std::fmt::Debug),* + { + $zalsa::with_attached_database(|db| { + let zalsa = db.zalsa(); + let fields = $Configuration::ingredient(zalsa).fields(zalsa, this); + let mut f = f.debug_struct(stringify!($Struct)); + $( + let f = f.field(stringify!($field_id), &fields.$field_index); + )* + f.finish() + }).unwrap_or_else(|| { + f.debug_tuple(stringify!($Struct)) + .field(&$zalsa::AsId::as_id(&this)) + .finish() + }) + } + } } } }; diff --git a/tests/debug_bounds.rs b/tests/debug_bounds.rs new file mode 100644 index 000000000..36fcb2331 --- /dev/null +++ b/tests/debug_bounds.rs @@ -0,0 +1,51 @@ +#![cfg(feature = "inventory")] + +//! Test that debug and non-debug structs compile correctly + +#[derive(Ord, PartialOrd, Eq, PartialEq, Copy, Clone, Hash)] +struct NotDebug; +#[derive(Ord, PartialOrd, Eq, PartialEq, Copy, Clone, Hash, Debug)] +struct Debug; + +#[salsa::input(debug)] +struct DebugInput { + field: Debug, +} + +#[salsa::input] +struct NotDebugInput { + field: NotDebug, +} + +#[salsa::interned(debug)] +struct DebugInterned { + field: Debug, +} + +#[salsa::interned] +struct NotDebugInterned { + field: NotDebug, +} + +#[salsa::interned(no_lifetime, debug)] +struct DebugInternedNoLifetime { + field: Debug, +} + +#[salsa::interned(no_lifetime)] +struct NotDebugInternedNoLifetime { + field: NotDebug, +} + +#[salsa::tracked(debug)] +struct DebugTracked<'db> { + field: Debug, +} + +#[salsa::tracked] +struct NotDebugTracked<'db> { + field: NotDebug, +} + +#[test] +fn ok() {}