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

Spurious 'help: store this in the heap' on error involving &Box<dyn SomeTrait> #82446

Closed
Aaron1011 opened this issue Feb 23, 2021 · 3 comments · Fixed by #95989
Closed

Spurious 'help: store this in the heap' on error involving &Box<dyn SomeTrait> #82446

Aaron1011 opened this issue Feb 23, 2021 · 3 comments · Fixed by #95989
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-bug Category: This is a bug. D-incorrect Diagnostics: A diagnostic that is giving misleading or incorrect information. D-invalid-suggestion Diagnostics: A structured suggestion resulting in incorrect code. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@Aaron1011
Copy link
Member

Aaron1011 commented Feb 23, 2021

The following code:

trait MyTrait {}

struct Foo {
    val: Box<dyn MyTrait>
}

fn make_it(val: &Box<dyn MyTrait>) {
    Foo {
        val
    };
}

produces the following error:

error[E0308]: mismatched types
 --> src/lib.rs:9:9
  |
9 |         val
  |         ^^^
  |         |
  |         expected struct `Box`, found reference
  |         help: store this in the heap by calling `Box::new`: `Box::new(val)`
  |
  = note: expected struct `Box<(dyn MyTrait + 'static)>`
          found reference `&Box<(dyn MyTrait + 'static)>`
  = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html

error: aborting due to previous error

val is a &Box<dyn MyTrait>, so writing Box::new(val) would produce a Box<&Box<dyn MyTrait>>. This is very unlikely to be what the user wants - and in this case, it won't even work, since there are no impls for MyTrait.

Meta

Tested on rustc 1.52.0-nightly 2021-02-22

@Aaron1011 Aaron1011 added A-diagnostics Area: Messages for errors, warnings, and lints C-bug Category: This is a bug. D-invalid-suggestion Diagnostics: A structured suggestion resulting in incorrect code. D-incorrect Diagnostics: A diagnostic that is giving misleading or incorrect information. labels Feb 23, 2021
@estebank estebank added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Feb 24, 2021
@0yoyoyo
Copy link
Contributor

0yoyoyo commented Feb 28, 2021

@rustbot claim

@0yoyoyo
Copy link
Contributor

0yoyoyo commented Mar 18, 2021

This problem occurs not only when val 's type is &Box<dyn MyTrait>, but also i32 and other types. This help message will be emitted if Box<val's type> could coerce to Box<dyn MyTrait>.

But I think this is weird. This coercion should be based on CoerceUnsized, and to coerce, we need implementation of Unsize<dyn MyTrait> for val's type. In other words, it seems that all types have implementation of Unsize<dyn MyTrait>. This behavior should be incorrect also from the doc of Unsize.

I'm going to check why the compiler provides above implementation.

@0yoyoyo
Copy link
Contributor

0yoyoyo commented May 8, 2021

This suggestion uses can_coerce to determine whether to emit the message. And can_coerce then calls coerce_unsized.

coerce_unsized execute trait selection. Even if a type T needs Unsize<dyn Trait> implementation, trait selection does not check T: Trait, just push T: Trait to nested. However, coerce_unsized also does not check nested unless it is Unsize or CoerceUnsized. As a result, can_coerce does not check whether val's type has implementation of MyTrait.

But, I have no idea how to fix this. I'll leave this issue.

@0yoyoyo 0yoyoyo removed their assignment May 8, 2021
Dylan-DPC added a commit to Dylan-DPC/rust that referenced this issue Apr 13, 2022
…compiler-errors

diagnostics: regression test for spurrious "help: store this in the heap"

Closes rust-lang#82446
Dylan-DPC added a commit to Dylan-DPC/rust that referenced this issue Apr 13, 2022
…compiler-errors

diagnostics: regression test for spurrious "help: store this in the heap"

Closes rust-lang#82446
Dylan-DPC added a commit to Dylan-DPC/rust that referenced this issue Apr 13, 2022
…compiler-errors

diagnostics: regression test for spurrious "help: store this in the heap"

Closes rust-lang#82446
@bors bors closed this as completed in 7228e9b Apr 13, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-bug Category: This is a bug. D-incorrect Diagnostics: A diagnostic that is giving misleading or incorrect information. D-invalid-suggestion Diagnostics: A structured suggestion resulting in incorrect code. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants