Add version to Binding deprecation warnings

This allows displaying a hint in which the version a binding may be
removed in. It helps to signal how urgent a package update may be to
package authors.
This commit is contained in:
tinger 2025-07-16 11:53:46 +02:00
parent 7897e86bcc
commit 3cb06baa98
3 changed files with 25 additions and 7 deletions

View File

@ -234,18 +234,23 @@ impl From<SyntaxError> for SourceDiagnostic {
/// Destination for a deprecation message when accessing a deprecated value. /// Destination for a deprecation message when accessing a deprecated value.
pub trait DeprecationSink { pub trait DeprecationSink {
/// Emits the given deprecation message into this sink. /// Emits the given deprecation message into this sink alongside a version
fn emit(self, message: &str); /// in which the deprecated item is planned to be removed.
fn emit(self, message: &str, until: Option<&str>);
} }
impl DeprecationSink for () { impl DeprecationSink for () {
fn emit(self, _: &str) {} fn emit(self, _: &str, _: Option<&str>) {}
} }
impl DeprecationSink for (&mut Engine<'_>, Span) { impl DeprecationSink for (&mut Engine<'_>, Span) {
/// Emits the deprecation message as a warning. /// Emits the deprecation message as a warning.
fn emit(self, message: &str) { fn emit(self, message: &str, version: Option<&str>) {
self.0.sink.warn(SourceDiagnostic::warning(self.1, message)); self.0.sink.warn(
SourceDiagnostic::warning(self.1, message).with_hints(
version.map(|v| eco_format!("this will be removed in {}", v)),
),
);
} }
} }

View File

@ -255,6 +255,10 @@ pub struct Binding {
category: Option<Category>, category: Option<Category>,
/// A deprecation message for the definition. /// A deprecation message for the definition.
deprecation: Option<&'static str>, deprecation: Option<&'static str>,
/// A version in which the deprecated binding is planned to be removed.
///
/// This is ignored if `deprecation` is `None`.
until: Option<&'static str>,
} }
/// The different kinds of slots. /// The different kinds of slots.
@ -275,6 +279,7 @@ impl Binding {
kind: BindingKind::Normal, kind: BindingKind::Normal,
category: None, category: None,
deprecation: None, deprecation: None,
until: None,
} }
} }
@ -289,6 +294,14 @@ impl Binding {
self self
} }
/// Set the version in which the binding is planned to be removed.
///
/// This is ignored if [`Binding::deprecated`] isn't also set.
pub fn until(&mut self, version: &'static str) -> &mut Self {
self.until = Some(version);
self
}
/// Read the value. /// Read the value.
pub fn read(&self) -> &Value { pub fn read(&self) -> &Value {
&self.value &self.value
@ -301,7 +314,7 @@ impl Binding {
/// - pass `(&mut engine, span)` to emit a warning into the engine. /// - pass `(&mut engine, span)` to emit a warning into the engine.
pub fn read_checked(&self, sink: impl DeprecationSink) -> &Value { pub fn read_checked(&self, sink: impl DeprecationSink) -> &Value {
if let Some(message) = self.deprecation { if let Some(message) = self.deprecation {
sink.emit(message); sink.emit(message, self.until);
} }
&self.value &self.value
} }

View File

@ -151,7 +151,7 @@ impl Symbol {
modifiers.best_match_in(list.variants().map(|(m, _, d)| (m, d))) modifiers.best_match_in(list.variants().map(|(m, _, d)| (m, d)))
{ {
if let Some(message) = deprecation { if let Some(message) = deprecation {
sink.emit(message) sink.emit(message, None)
} }
return Ok(self); return Ok(self);
} }