[red-knot] Improved error message for attribute-assignments (#15668)

## Summary

Slightly improved error message for attribute assignments.
This commit is contained in:
David Peter
2025-01-22 12:04:38 +01:00
committed by GitHub
parent f349dab4fc
commit 13e7afca42
3 changed files with 56 additions and 24 deletions

View File

@@ -984,13 +984,13 @@ pub(super) fn report_slice_step_size_zero(context: &InferContext, node: AnyNodeR
);
}
pub(super) fn report_invalid_assignment(
fn report_invalid_assignment_with_message(
context: &InferContext,
node: AnyNodeRef,
declared_ty: Type,
assigned_ty: Type,
target_ty: Type,
message: std::fmt::Arguments,
) {
match declared_ty {
match target_ty {
Type::ClassLiteral(ClassLiteralType { class }) => {
context.report_lint(&INVALID_ASSIGNMENT, node, format_args!(
"Implicit shadowing of class `{}`; annotate to make it explicit if this is intentional",
@@ -1002,19 +1002,48 @@ pub(super) fn report_invalid_assignment(
function.name(context.db())));
}
_ => {
context.report_lint(
&INVALID_ASSIGNMENT,
node,
format_args!(
"Object of type `{}` is not assignable to `{}`",
assigned_ty.display(context.db()),
declared_ty.display(context.db()),
),
);
context.report_lint(&INVALID_ASSIGNMENT, node, message);
}
}
}
pub(super) fn report_invalid_assignment(
context: &InferContext,
node: AnyNodeRef,
target_ty: Type,
source_ty: Type,
) {
report_invalid_assignment_with_message(
context,
node,
target_ty,
format_args!(
"Object of type `{}` is not assignable to `{}`",
source_ty.display(context.db()),
target_ty.display(context.db()),
),
);
}
pub(super) fn report_invalid_attribute_assignment(
context: &InferContext,
node: AnyNodeRef,
target_ty: Type,
source_ty: Type,
attribute_name: &'_ str,
) {
report_invalid_assignment_with_message(
context,
node,
target_ty,
format_args!(
"Object of type `{}` is not assignable to attribute `{attribute_name}` of type `{}`",
source_ty.display(context.db()),
target_ty.display(context.db()),
),
);
}
pub(super) fn report_possibly_unresolved_reference(
context: &InferContext,
expr_name_node: &ast::ExprName,

View File

@@ -51,11 +51,12 @@ use crate::semantic_index::SemanticIndex;
use crate::stdlib::builtins_module_scope;
use crate::types::call::{Argument, CallArguments};
use crate::types::diagnostic::{
report_invalid_arguments_to_annotated, report_invalid_assignment, report_unresolved_module,
TypeCheckDiagnostics, CALL_NON_CALLABLE, CALL_POSSIBLY_UNBOUND_METHOD,
CONFLICTING_DECLARATIONS, CONFLICTING_METACLASS, CYCLIC_CLASS_DEFINITION, DIVISION_BY_ZERO,
DUPLICATE_BASE, INCONSISTENT_MRO, INVALID_ATTRIBUTE_ACCESS, INVALID_BASE,
INVALID_CONTEXT_MANAGER, INVALID_DECLARATION, INVALID_PARAMETER_DEFAULT, INVALID_TYPE_FORM,
report_invalid_arguments_to_annotated, report_invalid_assignment,
report_invalid_attribute_assignment, report_unresolved_module, TypeCheckDiagnostics,
CALL_NON_CALLABLE, CALL_POSSIBLY_UNBOUND_METHOD, CONFLICTING_DECLARATIONS,
CONFLICTING_METACLASS, CYCLIC_CLASS_DEFINITION, DIVISION_BY_ZERO, DUPLICATE_BASE,
INCONSISTENT_MRO, INVALID_ATTRIBUTE_ACCESS, INVALID_BASE, INVALID_CONTEXT_MANAGER,
INVALID_DECLARATION, INVALID_PARAMETER_DEFAULT, INVALID_TYPE_FORM,
INVALID_TYPE_VARIABLE_CONSTRAINTS, POSSIBLY_UNBOUND_ATTRIBUTE, POSSIBLY_UNBOUND_IMPORT,
UNDEFINED_REVEAL, UNRESOLVED_ATTRIBUTE, UNRESOLVED_IMPORT, UNSUPPORTED_OPERATOR,
};
@@ -2022,6 +2023,7 @@ impl<'db> TypeInferenceBuilder<'db> {
ast::Expr::Attribute(
lhs_expr @ ast::ExprAttribute {
ctx: ExprContext::Store,
attr,
..
},
) => {
@@ -2030,11 +2032,12 @@ impl<'db> TypeInferenceBuilder<'db> {
if let Some(assigned_ty) = assigned_ty {
if !assigned_ty.is_assignable_to(self.db(), attribute_expr_ty) {
report_invalid_assignment(
report_invalid_attribute_assignment(
&self.context,
target.into(),
attribute_expr_ty,
assigned_ty,
attr.as_str(),
);
}
}