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

Note where implicit Sized requirement comes from #27964

Closed
kornelski opened this issue Aug 23, 2015 · 7 comments · Fixed by #73261
Closed

Note where implicit Sized requirement comes from #27964

kornelski opened this issue Aug 23, 2015 · 7 comments · Fixed by #73261
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-enhancement Category: An issue proposing an enhancement or a PR with one. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@kornelski
Copy link
Contributor

I was not aware that Sized is a default requirement for type parameters, so I was very confused why this code doesn't compile:

trait OopsSized<O /* missing : ?Sized */> {
    fn foo(&self) -> Option<Box<O>>;
}

trait Unsized {}

struct Foo;

impl OopsSized<Unsized> for Foo {
    fn foo(&self) -> Option<Box<Unsized>> {
        None
    }
}

I couldn't understand why compiler insists on having Sized for the innermost type, if Box doesn't care and makes the boxed type sized.

The current explanation for E0277 doesn't cover this case specifically, and it doesn't mention the unusual ?Sized syntax. It'd help me if, for example, the hint:

note: required by OopsSized

made implied defaults explicitly spelled out:

note: required by OopsSized<O: Sized>

and/or hinted how to fix it:

note: required by OopsSized, because O by default is Sized. Try O: ?Sized.

@arielb1 arielb1 added the A-diagnostics Area: Messages for errors, warnings, and lints label Aug 31, 2015
@makoConstruct
Copy link

I second this, it's extremely confusing.

trait Reader{}
impl Reader for () {}
fn reader_for()-> Box<Reader> { Box::new(()) }

fn check_vec<R:Reader>(r:&R){} //R needs to be Reader+?Sized for some reason, but new rust programmers wont know that.

fn main() {
    check_vec(&*reader_for());
        //error: the trait `core::marker::Sized` is not implemented for the type `Reader`
        //note: `Reader` does not have a constant size known at compile-time
        //note: required by `check_vec`
}

The user will not be able to figure out why the function requires Sized when they did not define it to require Sized and when none of its functionality depends on Sized.

@steveklabnik steveklabnik removed the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Mar 9, 2017
@Mark-Simulacrum Mark-Simulacrum changed the title Improve diagnostics of "marker::Sized is not implemented" caused by default Sized Note where implicit Sized requirement comes from Jun 1, 2017
@Mark-Simulacrum Mark-Simulacrum added the C-enhancement Category: An issue proposing an enhancement or a PR with one. label Jul 22, 2017
@estebank estebank added D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Oct 4, 2019
@estebank
Copy link
Contributor

estebank commented Feb 2, 2020

The original case has had no changes.

The case in the last comment has the following output in #68377:

error[E0277]: the size for values of type `dyn Reader` cannot be known at compilation time
 --> file.rs:8:15
  |
5 | fn check_vec<R:Reader>(r:&R){} //R needs to be Reader+?Sized for some reason, but new rust programmers wont know that.
  |    --------- -       - help: consider relaxing the implicit `Sized` restriction: `+  ?Sized`
  |              |
  |              required by this bound in `check_vec`
...
8 |     check_vec(&*reader_for());
  |               ^^^^^^^^^^^^^^ doesn't have a size known at compile-time
  |
  = help: the trait `std::marker::Sized` is not implemented for `dyn Reader`
  = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>

@najamelan
Copy link
Contributor

najamelan commented Mar 2, 2020

One from the user forum, playground:

use std::error::Error;

fn library_function<F1, E1>(f1: F1) -> Result<(), E1>
where
    F1: FnOnce() -> Result<(), E1>,
    E1: Error, // <-remove this line -> compile
{
    f1()
}

fn main() -> Result<(), Box<dyn Error>> 
{
    library_function( || Ok(()) )
}

Error:

error[E0277]: the size for values of type `dyn std::error::Error` cannot be known at compilation time
  --> src/main.rs:13:5
   |
3  | fn library_function<F1, E1>(f1: F1) -> Result<(), E1>
   |    ----------------
...
6  |     E1: Error, // <-remove this line -> compile
   |         ----- required by this bound in `library_function`
...
13 |     library_function( || Ok(()) )
   |     ^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
   |
   = help: the trait `std::marker::Sized` is not implemented for `dyn std::error::Error`
   = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
   = note: required because of the requirements on the impl of `std::error::Error` for `std::boxed::Box<dyn std::error::Error>`

Analysis:
There is a blanket impl for Error on Box<T>, but not on Box<T: ?Sized>. credit to @yandros

Go figure why "library_function doesn't have a size known at compile time".

I suppose the ideal here would be something like: Box<dyn Error> does not implement Error. The following Impl where found: impl<T: Error> Error for Box<T> -> requires T: Sized

@estebank
Copy link
Contributor

estebank commented Mar 4, 2020

@najamelan could you copy that comment as a new ticket? The original report will be closed by #69709 but yours won't be addressed by that PR, sadly.

@najamelan
Copy link
Contributor

@estebank It's done. Thank you so much for working on diagnostics!

@estebank
Copy link
Contributor

estebank commented May 6, 2020

Current output:

error[E0277]: the size for values of type `(dyn Unsized + 'static)` cannot be known at compilation time
  --> src/main.rs:11:6
   |
2  | trait OopsSized<O /* missing : ?Sized */> {
   |                 - required by this bound in `OopsSized`
...
11 | impl OopsSized<Unsized> for Foo {
   |      ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
   |
   = help: the trait `std::marker::Sized` is not implemented for `(dyn Unsized + 'static)`
   = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>

@estebank
Copy link
Contributor

estebank commented Jun 17, 2020

Output with #73261:

Screen Shot 2020-06-16 at 5 27 01 PM

error[E0277]: the size for values of type `(dyn Unsized + 'static)` cannot be known at compilation time
 --> file6.rs:9:6
  |
1 | trait OopsSized<O /* missing : ?Sized */> {
  |                 - required by this bound in `OopsSized`
...
9 | impl OopsSized<Unsized> for Foo {
  |      ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
  |
  = help: the trait `std::marker::Sized` is not implemented for `(dyn Unsized + 'static)`
  = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
help: consider relaxing the implicit `Sized` restriction
  |
1 | trait OopsSized<O: ?Sized /* missing : ?Sized */> {
  |                  ^^^^^^^^

And the output when this ticket was created 😅:

<source>:9:1: 13:2 error: the trait `core::marker::Sized` is not implemented for the type `Unsized + 'static` [E0277]
<source>: 9 impl OopsSized<Unsized> for Foo {
<source>:10     fn foo(&self) -> Option<Box<Unsized>> {
<source>:11         None
<source>:12     }
<source>:13 }
<source>:9:1: 13:2 help: run `rustc --explain E0277` to see a detailed explanation
<source>:9:1: 13:2 note: `Unsized + 'static` does not have a constant size known at compile-time
<source>: 9 impl OopsSized<Unsized> for Foo {
<source>:10     fn foo(&self) -> Option<Box<Unsized>> {
<source>:11         None
<source>:12     }
<source>:13 }

Manishearth added a commit to Manishearth/rust that referenced this issue Jun 19, 2020
…akis

Suggest `?Sized` when applicable for ADTs

Address rust-lang#71790, fix rust-lang#27964.
@bors bors closed this as completed in d2b8e60 Jun 20, 2020
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-enhancement Category: An issue proposing an enhancement or a PR with one. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
7 participants