red_knot_python_semantic: make the guards implement DerefMut

This is the payoff from removing a bit of indirection. The types still
exist, but now callers don't need to do builder -> reporter ->
diagnostic. They can just conceptually think of it as builder ->
diagnostic.
This commit is contained in:
Andrew Gallant 2025-04-11 10:03:59 -04:00 committed by Andrew Gallant
parent f3cc287a40
commit a4d3c4bf8b
4 changed files with 37 additions and 32 deletions

View file

@ -1254,9 +1254,8 @@ impl<'db> BindingError<'db> {
let provided_ty_display = provided_ty.display(context.db());
let expected_ty_display = expected_ty.display(context.db());
let mut reporter = builder.build("Argument to this function is incorrect");
let diag = reporter.diagnostic();
let mut diag = builder.build("Argument to this function is incorrect");
let span = context.span(Self::get_node(node, *argument_index));
diag.annotate(Annotation::primary(span).message(format_args!(
"Expected `{expected_ty_display}`, found `{provided_ty_display}`"

View file

@ -85,8 +85,7 @@ impl<'db> InferContext<'db> {
let Some(builder) = self.report_lint(lint) else {
return;
};
let mut reporter = builder.build("");
let diag = reporter.diagnostic();
let mut diag = builder.build("");
let span = Span::from(self.file).with_range(ranged.range());
diag.annotate(Annotation::primary(span).message(message));
}
@ -240,15 +239,17 @@ pub(super) struct LintDiagnosticGuard<'db, 'ctx> {
lint_id: LintId,
}
impl LintDiagnosticGuard<'_, '_> {
/// Return a mutable borrow of the diagnostic on this reporter.
///
/// Callers may mutate the diagnostic to add new sub-diagnostics
/// or annotations.
///
/// The diagnostic is added to the typing context, if appropriate,
/// when this reporter is dropped.
pub(super) fn diagnostic(&mut self) -> &mut Diagnostic {
impl std::ops::Deref for LintDiagnosticGuard<'_, '_> {
type Target = Diagnostic;
fn deref(&self) -> &Diagnostic {
// OK because `self.diag` is only `None` within `Drop`.
self.diag.as_ref().unwrap()
}
}
impl std::ops::DerefMut for LintDiagnosticGuard<'_, '_> {
fn deref_mut(&mut self) -> &mut Diagnostic {
// OK because `self.diag` is only `None` within `Drop`.
self.diag.as_mut().unwrap()
}
@ -398,15 +399,24 @@ pub(super) struct DiagnosticGuard<'db, 'ctx> {
diag: Option<Diagnostic>,
}
impl DiagnosticGuard<'_, '_> {
/// Return a mutable borrow of the diagnostic on this reporter.
///
/// Callers may mutate the diagnostic to add new sub-diagnostics
/// or annotations.
///
/// The diagnostic is added to the typing context, if appropriate,
/// when this reporter is dropped.
pub(super) fn diagnostic(&mut self) -> &mut Diagnostic {
impl std::ops::Deref for DiagnosticGuard<'_, '_> {
type Target = Diagnostic;
fn deref(&self) -> &Diagnostic {
// OK because `self.diag` is only `None` within `Drop`.
self.diag.as_ref().unwrap()
}
}
/// Return a mutable borrow of the diagnostic on this reporter.
///
/// Callers may mutate the diagnostic to add new sub-diagnostics
/// or annotations.
///
/// The diagnostic is added to the typing context, if appropriate,
/// when this reporter is dropped.
impl std::ops::DerefMut for DiagnosticGuard<'_, '_> {
fn deref_mut(&mut self) -> &mut Diagnostic {
// OK because `self.diag` is only `None` within `Drop`.
self.diag.as_mut().unwrap()
}

View file

@ -1075,9 +1075,7 @@ pub(super) fn report_invalid_return_type(
let object_span = Span::from(context.file()).with_range(object_range.range());
let return_type_span = Span::from(context.file()).with_range(return_type_range.range());
let mut reporter = builder.build("Return type does not match returned value");
let diag = reporter.diagnostic();
let mut diag = builder.build("Return type does not match returned value");
diag.annotate(Annotation::primary(object_span).message(format_args!(
"Expected `{expected_ty}`, found `{actual_ty}`",
expected_ty = expected_ty.display(context.db()),

View file

@ -4174,14 +4174,12 @@ impl<'db> TypeInferenceBuilder<'db> {
.context
.report_diagnostic(DiagnosticId::RevealedType, Severity::Info)
{
let mut reporter = builder.build("Revealed type");
let mut diag = builder.into_diagnostic("Revealed type");
let span = self.context.span(call_expression);
reporter.diagnostic().annotate(
Annotation::primary(span).message(format_args!(
"`{}`",
revealed_type.display(self.db())
)),
);
diag.annotate(Annotation::primary(span).message(format_args!(
"`{}`",
revealed_type.display(self.db())
)));
}
}
}