Skip to content

implement Add and Sub for Complex - #161227

Merged
rust-bors[bot] merged 1 commit into
rust-lang:mainfrom
folkertdev:complex-add-sub
Sep 4, 2026
Merged

implement Add and Sub for Complex#161227
rust-bors[bot] merged 1 commit into
rust-lang:mainfrom
folkertdev:complex-add-sub

Conversation

@folkertdev

@folkertdev folkertdev commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

View all comments

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

This comment has been minimized.

@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.

@rustbot

rustbot commented Aug 20, 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.

@folkertdev

Copy link
Copy Markdown
Contributor Author

I believe you wanted more review work

r? nia-e

@rustbot rustbot assigned nia-e and unassigned JohnTitor Aug 25, 2026
Comment on lines +25 to +31
impl<T: Add> Add<Self> for Complex<T> {
type Output = Complex<T::Output>;

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

@scottmcm scottmcm Aug 27, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This really seems like it should be

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

since I see no reason to restrict it to T: Add<T>.

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 does not work because it conflicts with the implementation of add with a scalar right below

#[unstable(feature = "complex_numbers", issue = "154023")]
impl<T: Add<Output = T>> Add<T> for Complex<T> {
    type Output = Complex<T::Output>;

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

@folkertdev

Copy link
Copy Markdown
Contributor Author

I'd quite like to build on top of this, it's all unstable surface area that can be re-litigated later, so I'd appreciate a review from someone here.

@nia-e

nia-e commented Aug 31, 2026

Copy link
Copy Markdown
Member

eek, i've been a bit busy. I should be able to get to this in a day or two but if you need a faster review feel free to r? someone else

@rustbot

This comment was marked as off-topic.

@nia-e

nia-e commented Sep 3, 2026

Copy link
Copy Markdown
Member

@bors r+

@rust-bors

rust-bors Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

📌 Commit d48bdef has been approved by nia-e

It is now in the queue for this repository.

@rust-bors rust-bors Bot added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Sep 3, 2026
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Sep 3, 2026
implement `Add` and `Sub` for `Complex`

tracking issue: rust-lang#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.
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Sep 3, 2026
implement `Add` and `Sub` for `Complex`

tracking issue: rust-lang#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.
rust-bors Bot pushed a commit that referenced this pull request Sep 3, 2026
…uwer

Rollup of 12 pull requests

Successful merges:

 - #161227 (implement `Add` and `Sub` for `Complex`)
 - #161280 (make target feature ABI check a hard error on ARM)
 - #161893 (Add custom allocator support to `(try_)map` on `UniqueArc` and `UniqueRc`)
 - #162154 (fix[154166]: closure debug capture print)
 - #161951 (Windows: add fallback if `canonicalize` fails)
 - #162173 (fix supposedly unreachable `bug!` being reachable)
 - #162180 (remove outdated next-solver handling)
 - #162191 (core: mark float `ClampBounds` methods as `#[inline]`)
 - #162195 (docs(time): clarify exact seconds for week and day)
 - #162199 (docs(time): clarify exact seconds for hour and minute)
 - #162222 (coverage: Small cleanups in `extract_hir_info`)
 - #162230 (Pass -Z merge-functions=disabled in tests/codegen-llvm/intrinsics/unchecked_math.rs)
rust-bors Bot pushed a commit that referenced this pull request Sep 4, 2026
…uwer

Rollup of 12 pull requests

Successful merges:

 - #161227 (implement `Add` and `Sub` for `Complex`)
 - #161280 (make target feature ABI check a hard error on ARM)
 - #161893 (Add custom allocator support to `(try_)map` on `UniqueArc` and `UniqueRc`)
 - #162154 (fix[154166]: closure debug capture print)
 - #161951 (Windows: add fallback if `canonicalize` fails)
 - #162173 (fix supposedly unreachable `bug!` being reachable)
 - #162180 (remove outdated next-solver handling)
 - #162191 (core: mark float `ClampBounds` methods as `#[inline]`)
 - #162195 (docs(time): clarify exact seconds for week and day)
 - #162199 (docs(time): clarify exact seconds for hour and minute)
 - #162222 (coverage: Small cleanups in `extract_hir_info`)
 - #162230 (Pass -Z merge-functions=disabled in tests/codegen-llvm/intrinsics/unchecked_math.rs)
@rust-bors
rust-bors Bot merged commit 93b5d3f into rust-lang:main Sep 4, 2026
13 checks passed
rust-bors Bot pushed a commit that referenced this pull request Sep 4, 2026
Rollup merge of #161227 - folkertdev:complex-add-sub, r=nia-e

implement `Add` and `Sub` for `Complex`

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.
@rustbot rustbot added this to the 1.100.0 milestone Sep 4, 2026
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-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. 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.

7 participants