Repository: astral-sh/ruff
File: crates/ty_python_semantic/src/types/infer/builder.rs (Rust)

Code before:
                                    self.context.report_lint(&INVALID_ASSIGNMENT, target)
                            {
                                let mut diagnostic = builder.into_diagnostic(format_args!(
                                    "Cannot assign to a subscript on an object of type `{}`",
                                    object_ty.display(db),
                                ));
                                attach_original_type_info(&mut diagnostic);

                                // If it's a user-defined class, suggest adding a `__setitem__` method.
                                if object_ty
                                    .as_nominal_instance()
                                    .and_then(|instance| {
                                        file_to_module(
                                            db,
                                            instance.class(db).class_literal(db).0.file(db),
                                        )
                                    })
                                    .and_then(|module| module.search_path(db))
                                    .is_some_and(crate::SearchPath::is_first_party)
                                {
                                    diagnostic.help(format_args!(
                                        "Consider adding a `__setitem__` method to `{}`.",
                                        object_ty.display(db),
                                    ));
                                } else {
                                    diagnostic.help(format_args!(
                                        "`{}` does not have a `__setitem__` method.",
                                        object_ty.display(db),
                                    ));
                                }
                            }
                            false
                        }
                    },
                }
            }
        }
    }

    /// Make sure that the attribute assignment `obj.attribute = value` is valid.
    ///
    /// `target` is the node for the left-hand side, `object_ty` is the type of `obj`, `attribute` is
    /// the name of the attribute being assigned, and `value_ty` is the type of the right-hand side of
    /// the assignment. If the assignment is invalid, emit diagnostics.
    fn validate_attribute_assignment(
        &mut self,
        target: &ast::ExprAttribute,
        object_ty: Type<'db>,
        attribute: &str,
        infer_value_ty: &mut dyn FnMut(&mut Self, TypeContext<'db>) -> Type<'db>,
        emit_diagnostics: bool,

Review comment (suggestion):
```suggestion
                                    diagnostic.info(format_args!(
```

Code after:

                                // If it's a user-defined class, suggest adding a `__setitem__` method.
                                if object_ty
                                    .as_nominal_instance()
                                    .and_then(|instance| {
                                        file_to_module(
                                            db,
                                            instance.class(db).class_literal(db).0.file(db),
                                        )
                                    })
                                    .and_then(|module| module.search_path(db))
                                    .is_some_and(crate::SearchPath::is_first_party)
                                {
                                    diagnostic.help(format_args!(
                                        "Consider adding a `__setitem__` method to `{}`.",
                                        object_ty.display(db),
                                    ));
                                } else {
                                    diagnostic.info(format_args!(
                                        "`{}` does not have a `__setitem__` method.",
                                        object_ty.display(db),
                                    ));
                                }
                            }
                            false
                        }
                    },
                }
            }
        }
    }

    /// Make sure that the attribute assignment `obj.attribute = value` is valid.
    ///
    /// `target` is the node for the left-hand side, `object_ty` is the type of `obj`, `attribute` is
    /// the name of the attribute being assigned, and `value_ty` is the type of the right-hand side of
    /// the assignment. If the assignment is invalid, emit diagnostics.
    fn validate_attribute_assignment(
        &mut self,
        target: &ast::ExprAttribute,
        object_ty: Type<'db>,
        attribute: &str,
        infer_value_ty: &mut dyn FnMut(&mut Self, TypeContext<'db>) -> Type<'db>,
        emit_diagnostics: bool,
    ) -> bool {
        let db = self.db();

        let mut first_tcx = None;

        // A wrapper over `infer_value_ty` that allows inferring the value type multiple times
        // during attribute resolution.