From 8193ff9a3902ec84e232b9c35ff735eea615be51 Mon Sep 17 00:00:00 2001 From: Dhruv Manilawala Date: Wed, 22 Nov 2023 09:44:21 -0600 Subject: [PATCH] Implement `PartialEq` for `ConcatenatedStringLiteral` As highlighted in the review: > If you have two `ConcatenatedStringLiteral` values where both have > equivalent values for `strings` but where one has `value` initialized > and the other does not, would you expect them to compare equal? > Semantically I think I would, since the alternative is that equality is > dependent on whether `as_str()` has been called, which seems incidental. https://github.com/astral-sh/ruff/pull/7927#discussion_r1401998304 --- crates/ruff_python_ast/src/nodes.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/crates/ruff_python_ast/src/nodes.rs b/crates/ruff_python_ast/src/nodes.rs index afc80960bccfc..e0bc5b4730686 100644 --- a/crates/ruff_python_ast/src/nodes.rs +++ b/crates/ruff_python_ast/src/nodes.rs @@ -1306,7 +1306,7 @@ impl From for Expr { /// An internal representation of [`StringLiteral`] that represents an /// implicitly concatenated string. -#[derive(Clone, PartialEq)] +#[derive(Clone)] struct ConcatenatedStringLiteral { /// Each string literal that makes up the concatenated string. strings: Vec, @@ -1322,6 +1322,19 @@ impl ConcatenatedStringLiteral { } } +impl PartialEq for ConcatenatedStringLiteral { + fn eq(&self, other: &Self) -> bool { + if self.strings.len() != other.strings.len() { + return false; + } + // The `zip` here is safe because we have checked the length of both parts. + self.strings + .iter() + .zip(other.strings.iter()) + .all(|(s1, s2)| s1 == s2) + } +} + impl Debug for ConcatenatedStringLiteral { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("ConcatenatedStringLiteral")