Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Copy not implemented for (u32, u32) error #88047

Closed
leonardo-m opened this issue Aug 15, 2021 · 8 comments
Closed

Copy not implemented for (u32, u32) error #88047

leonardo-m opened this issue Aug 15, 2021 · 8 comments
Labels
C-bug Category: This is a bug.

Comments

@leonardo-m
Copy link

const fn foo<T: Copy, const N: usize>(a: [T; N]) -> [T; N] {
    a
}
fn main() {
    const SPAM: [(u32, u32); 1] = foo([(1, 1)]);
}

Using the last Nightly (this error didn't happen with the Nightly of the precedent day):

rustc 1.56.0-nightly (8007b506a 2021-08-14)
binary: rustc
commit-hash: 8007b506ac5da629f223b755f5a5391edd5f6d01
commit-date: 2021-08-14
host: x86_64-pc-windows-gnu
release: 1.56.0-nightly
LLVM version: 12.0.1

Gives:

error[E0277]: the trait bound `(u32, u32): Copy` is not satisfied
 --> C:\lavoro\bugs\test.rs:5:39
  |
1 | const fn foo<T: Copy, const N: usize>(a: [T; N]) -> [T; N] {
  |                 ---- required by this bound in `foo`
...
5 |     const SPAM: [(u32, u32); 1] = foo([(1, 1)]);
  |                                       ^^^^^^^^ the trait `Copy` is not implemented for `(u32, u32)`
  |
help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement
  |
4 | fn main() where (u32, u32): Copy {
  |           ++++++++++++++++++++++
@leonardo-m leonardo-m added the C-bug Category: This is a bug. label Aug 15, 2021
@ibraheemdev
Copy link
Member

This seems to be a const issue, because this compiles:

fn foo<T: Copy, const N: usize>(a: [T; N]) -> [T; N] {
    a
}
fn main() {
    let SPAM: [(u32, u32); 1] = foo([(1, 1)]);
}

@Aaron1011
Copy link
Member

I think this was caused by #87375 - cc @fee1-dead

@nbdd0121
Copy link
Contributor

This works:

#![feature(const_fn_trait_bound)]
#![feature(const_trait_bound_opt_out)]

const fn foo<T: ?const Copy, const N: usize>(a: [T; N]) -> [T; N] {
    a
}
fn main() {
    const SPAM: [(u32, u32); 1] = foo([(1, 1)]);
}

@Aaron1011
Copy link
Member

As a side note - all Copy impls can be const impls, since Copy doesn't have any associated items. I don't know if it's worth encoding this into the language in some way, or if we should require everyone to change impl Copy to impl const Copy as the need arises.

@nbdd0121
Copy link
Contributor

As a side note - all Copy impls can be const impls, since Copy doesn't have any associated items. I don't know if it's worth encoding this into the language in some way, or if we should require everyone to change impl Copy to impl const Copy as the need arises.

What's the implication on Clone impls if all Copy impls are const? E.g.

const fn foo2<T: Clone>(x: &T) {}
const fn foo<T: Copy>(x: &T) {
    foo2(x)
}

This currently is forbidden (with a very non-intuitive error message of Clone is not implemented for T). I am not sure if this is intended.

@ibraheemdev
Copy link
Member

Copy would have to be special-cased for that to work I believe.

@fee1-dead
Copy link
Member

I remember some discussion around super traits in the RFC PR. It is undecided, for trait A: B whether we enforce

  • Ty: const B or just
  • Ty: B

with impl const A for Ty.

With that, I can't come up with a trivial fix for this issue. ?const Copy should be used for now, and it will get replaced by const Drop in the future.

@leonardo-m
Copy link
Author

It seems this isn't a bug, and nbdd0121 has fixed my code, so should we close this issue down?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug.
Projects
None yet
Development

No branches or pull requests

5 participants