[ty] Improve diagnostics for assert_type and assert_never (#18050)

This commit is contained in:
Alex Waygood 2025-05-13 09:00:20 -04:00 committed by GitHub
parent 00f672a83b
commit 5913997c72
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 278 additions and 21 deletions

View file

@ -11,7 +11,7 @@ use crate::types::string_annotation::{
RAW_STRING_TYPE_ANNOTATION,
};
use crate::types::{protocol_class::ProtocolClassLiteral, KnownFunction, KnownInstanceType, Type};
use ruff_db::diagnostic::{Annotation, Diagnostic, Severity, Span, SubDiagnostic};
use ruff_db::diagnostic::{Annotation, Diagnostic, Severity, SubDiagnostic};
use ruff_python_ast::{self as ast, AnyNodeRef};
use ruff_text_size::{Ranged, TextRange};
use rustc_hash::FxHashSet;
@ -1543,7 +1543,7 @@ pub(super) fn report_invalid_return_type(
return;
};
let return_type_span = Span::from(context.file()).with_range(return_type_range.range());
let return_type_span = context.span(return_type_range);
let mut diag = builder.into_diagnostic("Return type does not match returned value");
diag.set_primary_message(format_args!(
@ -1849,16 +1849,13 @@ pub(crate) fn report_duplicate_bases(
),
);
sub_diagnostic.annotate(
Annotation::secondary(
Span::from(context.file()).with_range(bases_list[*first_index].range()),
)
.message(format_args!(
Annotation::secondary(context.span(&bases_list[*first_index])).message(format_args!(
"Class `{duplicate_name}` first included in bases list here"
)),
);
for index in later_indices {
sub_diagnostic.annotate(
Annotation::primary(Span::from(context.file()).with_range(bases_list[*index].range()))
Annotation::primary(context.span(&bases_list[*index]))
.message(format_args!("Class `{duplicate_name}` later repeated here")),
);
}

View file

@ -4834,12 +4834,27 @@ impl<'db> TypeInferenceBuilder<'db> {
&TYPE_ASSERTION_FAILURE,
call_expression,
) {
builder.into_diagnostic(format_args!(
"Actual type `{}` is not the same \
as asserted type `{}`",
actual_ty.display(self.db()),
asserted_ty.display(self.db()),
));
let mut diagnostic =
builder.into_diagnostic(format_args!(
"Argument does not have asserted type `{}`",
asserted_ty.display(self.db()),
));
diagnostic.annotate(
Annotation::secondary(self.context.span(
&call_expression.arguments.args[0],
))
.message(format_args!(
"Inferred type of argument is `{}`",
actual_ty.display(self.db()),
)),
);
diagnostic.info(
format_args!(
"`{asserted_type}` and `{inferred_type}` are not equivalent types",
asserted_type = asserted_ty.display(self.db()),
inferred_type = actual_ty.display(self.db()),
)
);
}
}
}
@ -4851,10 +4866,24 @@ impl<'db> TypeInferenceBuilder<'db> {
&TYPE_ASSERTION_FAILURE,
call_expression,
) {
builder.into_diagnostic(format_args!(
"Expected type `Never`, got `{}` instead",
actual_ty.display(self.db()),
));
let mut diagnostic = builder.into_diagnostic(
"Argument does not have asserted type `Never`",
);
diagnostic.annotate(
Annotation::secondary(self.context.span(
&call_expression.arguments.args[0],
))
.message(format_args!(
"Inferred type of argument is `{}`",
actual_ty.display(self.db())
)),
);
diagnostic.info(
format_args!(
"`Never` and `{inferred_type}` are not equivalent types",
inferred_type = actual_ty.display(self.db()),
)
);
}
}
}