Skip to content

implement Add and Sub for Complex - #161227

Open
folkertdev wants to merge 1 commit into
rust-lang:mainfrom
folkertdev:complex-add-sub
Open

implement Add and Sub for Complex#161227
folkertdev wants to merge 1 commit into
rust-lang:mainfrom
folkertdev:complex-add-sub

Conversation

@folkertdev

Copy link
Copy Markdown
Contributor

tracking issue: #154023

Adds the Add and Sub implementations described in the tracking issue. Some notes

  • I also added a derive for Eq, which is useful for Complex<{integer}>
  • The versions that add/sub by a scalar need a Copy bound. That seems fine for most actual use cases.

Apparently num_complex will Clone in these operations https://docs.rs/num-complex/latest/num_complex/struct.Complex.html#impl-Add%3CT%3E-for-%26Complex%3CT%3E, but that seems unlike core to me. Anyhow, libs can re-litigate that later.

@folkertdev folkertdev added the F-complex_numbers `#![feature(complex_numbers)]` label Aug 17, 2026
@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Aug 17, 2026
@rustbot

rustbot commented Aug 17, 2026

Copy link
Copy Markdown
Collaborator

r? @JohnTitor

rustbot has assigned @JohnTitor.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: libs
  • libs expanded to 12 candidates
  • Random selection from JohnTitor, Mark-Simulacrum, clarfonthey, nia-e, tgross35

Comment thread library/core/src/num/complex.rs Outdated
Comment on lines +25 to +31
impl<T: Add<Output = T>> Add<Self> for Complex<T> {
type Output = Complex<T::Output>;

fn add(self, rhs: Self) -> Self::Output {
Self::new(self.re + rhs.re, self.im + rhs.im)
}
}

@beetrees beetrees Aug 17, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason to limit the RHS and Output types to T? This could be more generic based on the Add implementation of T, e.g.:

Suggested change
impl<T: Add<Output = T>> Add<Self> for Complex<T> {
type Output = Complex<T::Output>;
fn add(self, rhs: Self) -> Self::Output {
Self::new(self.re + rhs.re, self.im + rhs.im)
}
}
impl<T: Add<U>, U> Add<Complex<U>> for Complex<T> {
type Output = Complex<T::Output>;
fn add(self, rhs: Complex<U>) -> Self::Output {
Complex::new(self.re + rhs.re, self.im + rhs.im)
}
}

Similar thinking applies to the Sub<Self> implementation. The Add<T> and Sub<T> need RHS to be T to avoid overlapping trait impls, but Output doesn't need to be limited.

View changes since the review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That runs into a conflicting impl error. (it's important that Complex implements Copy for that error to show up)

https://godbolt.org/z/ExhY3oacd

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense. Just removing the <Output = T> shouldn't cause any issues since it's just an associated type (compiler explorer), so doing that seems worthwhile (e.g. this would allow usage with Add/Sub impls like those in rustc_apfloat)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, that seems fine. Fixed

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The <Output = T> on the other two impls could also be removed?

@folkertdev
folkertdev force-pushed the complex-add-sub branch 2 times, most recently from b05c4a3 to 5e3bab3 Compare August 17, 2026 19:31
@rustbot

rustbot commented Aug 17, 2026

Copy link
Copy Markdown
Collaborator

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@btnlq btnlq left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$(a + bi) + c = (a + bi) + (c + 0i) = (a+c) + bi$
See num-complex implementation

View changes since this review

Comment thread library/core/src/num/complex.rs Outdated
Comment thread library/core/src/num/complex.rs Outdated
Comment thread library/coretests/tests/num/complex.rs Outdated
Comment thread library/coretests/tests/num/complex.rs Outdated
Comment thread library/coretests/tests/num/complex.rs Outdated
Comment thread library/coretests/tests/num/complex.rs Outdated
@folkertdev

Copy link
Copy Markdown
Contributor Author

Oof, it's been a while since university I guess, thanks. That removes the Copy bound, but does re-introduce the Output = T bound because the imaginary component doesn't update and is still of type T.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

F-complex_numbers `#![feature(complex_numbers)]` S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants