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

Very confusing error on attempt to pass path::Path by value #23286

Closed
kmcallister opened this issue Mar 11, 2015 · 39 comments · Fixed by #74228
Closed

Very confusing error on attempt to pass path::Path by value #23286

kmcallister opened this issue Mar 11, 2015 · 39 comments · Fixed by #74228
Assignees
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-enhancement Category: An issue proposing an enhancement or a PR with one. D-confusing Diagnostics: Confusing error or lint that should be reworked. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. E-hard Call for participation: Hard difficulty. Experience needed to fix: A lot. E-help-wanted Call for participation: Help is requested to fix this issue. P-medium Medium priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@kmcallister
Copy link
Contributor

use std::path::Path;

fn f(p: Path) { }

produces

foo.rs:3:6: 3:7 error: the trait `core::marker::Sized` is not implemented for the type `[u8]` [E0277]
foo.rs:3 fn f(p: Path) { }
              ^
foo.rs:3:6: 3:7 note: `[u8]` does not have a constant size known at compile-time
foo.rs:3 fn f(p: Path) { }
              ^

We should give an explicit hint that Path should be passed by reference. Also the error does not mention Path and the type u8 does not appear in the program.

UPDATE: The message now includes a full stack trace of types, but it would be better to start out with the type the user knows about (Path, in this case) and only discuss [u8] last. -- @nikomatsakis

@kmcallister kmcallister added the A-diagnostics Area: Messages for errors, warnings, and lints label Mar 11, 2015
@brson
Copy link
Contributor

brson commented Mar 13, 2015

I've hit this too and was completely baffled about what the compiler was saying.

@Byron
Copy link
Member

Byron commented Apr 13, 2015

Same here, this was my code:

pub fn assure_config_dir_exists(dir: &str) -> Result<Path, ArgumentError> {
    Ok(Path::new(dir))
}

This works. Something that I didn't expect is that Path::new(...) returns a borrow.

pub fn assure_config_dir_exists(dir: &str) -> Result<&Path, ArgumentError> {
    Ok(Path::new(dir))
}

@marcusklaas
Copy link
Contributor

Can confirm that this behaviour is still present in rustc 1.2.0-nightly (9cb7b3ffb 2015-06-01) (built 2015-06-01).

@fcourchesne
Copy link

Confirmed in rustc 1.0 and 1.2.0-nightly (613e57b 2015-06-01) (built 2015-06-02).

@luke-gru
Copy link

I just hit this and was confused as well. rustc 1.2.0-nightly (c6b148337 2015-06-12)

@aturon aturon added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Jun 18, 2015
@aturon
Copy link
Member

aturon commented Jun 18, 2015

Nominating. This seems like an important error to try to improve.

triage: I-nominated

@arielb1
Copy link
Contributor

arielb1 commented Jun 23, 2015

The issue here is how we report errors on trait-matching in the presence of nested obligations - we report the predicate that failed to shallowly match and not the original obligation. We essentially have:

struct Path([u8]);

unsafe impl Sized for Path where foreach_field!(_: T in Struct, T: Sized) {}
// expanded:
unsafe impl Sized for Path where [u8]: Sized {}

and we require that Path: Sized - which then requires [u8]: Sized, which doesn't hold.

@nikomatsakis
Copy link
Contributor

All right, I'll give it P-high. I've been thinking of tackling this issue that @arielb1 is describing as part of another change. This is kind of a dup but I'm going to keep it separate.

triage: P-high

@rust-highfive rust-highfive added P-high High priority and removed I-nominated labels Jul 9, 2015
@liigo
Copy link
Contributor

liigo commented Jul 9, 2015

Does #26617 fix this issue?

@arielb1
Copy link
Contributor

arielb1 commented Aug 9, 2015

@liigo

No it doesn't

@arielb1
Copy link
Contributor

arielb1 commented Aug 9, 2015

On the other hand, just calling note_obligation_cause after displaying the report_on_unimplemented error gives this nice error:

test.rs:3:6: 3:7 error: the trait `core::marker::Sized` is not implemented for the type `[u8]` [E0277]
test.rs:3 fn f(p: Path) {}
               ^
test.rs:3:6: 3:7 help: run `rustc --explain E0277` to see a detailed explanation
test.rs:3:6: 3:7 note: `[u8]` does not have a constant size known at compile-time
test.rs:3 fn f(p: Path) {}
               ^
test.rs:3:6: 3:7 note: required because it appears within the type `std::sys::os_str::Slice`
test.rs:3 fn f(p: Path) {}
               ^
test.rs:3:6: 3:7 note: required because it appears within the type `std::ffi::os_str::OsStr`
test.rs:3 fn f(p: Path) {}
               ^
test.rs:3:6: 3:7 note: required because it appears within the type `std::path::Path`
test.rs:3 fn f(p: Path) {}
               ^
test.rs:3:6: 3:7 note: all local variables must have a statically known size
test.rs:3 fn f(p: Path) {}
               ^

I am semi-worried about a deep chain of types filling the screen with an error, not sure what to do about that.

@Diggsey
Copy link
Contributor

Diggsey commented Aug 10, 2015

Here's a possible set of rules to follow which would fix the problem:

  1. Is the !Sized type derived from a type parameter? If so, treat the type parameter as the source of the error.
  2. Is the !Sized field accessible? If so, treat the field as the source of the error (as it does currently)
  3. Otherwise, treat the entire type as an opaque, !Sized type which is the source of the error.

This avoids breaking encapsulation: outside its own module it becomes impossible to tell from an error message that a Path is represented as a [u8] - for all intents and purposes it's a new unsized type, unrelated to any others.

arielb1 added a commit to arielb1/rust that referenced this issue Sep 13, 2015
new error style:
```
path.rs:4:6: 4:7 error: the trait `core::marker::Sized` is not implemented for the type `[u8]` [E0277]
path.rs:4 fn f(p: Path) {}
               ^
path.rs:4:6: 4:7 help: run `rustc --explain E0277` to see a detailed explanation
path.rs:4:6: 4:7 note: `[u8]` does not have a constant size known at compile-time
path.rs:4:6: 4:7 note: required because it appears within the type `std::sys::os_str::Slice`
path.rs:4:6: 4:7 note: required because it appears within the type `std::ffi::os_str::OsStr`
path.rs:4:6: 4:7 note: required because it appears within the type `std::path::Path`
path.rs:4:6: 4:7 note: all local variables must have a statically known size
path.rs:7:5: 7:36 error: the trait `core::marker::Send` is not implemented for the type `alloc::rc::Rc<()>` [E0277]
path.rs:7     foo::<BTreeMap<Rc<()>, Rc<()>>>();
              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
path.rs:7:5: 7:36 help: run `rustc --explain E0277` to see a detailed explanation
path.rs:7:5: 7:36 note: `alloc::rc::Rc<()>` cannot be sent between threads safely
path.rs:7:5: 7:36 note: required because it appears within the type `collections::btree::node::Node<alloc::rc::Rc<()>, alloc::rc::Rc<()>>`
path.rs:7:5: 7:36 note: required because it appears within the type `collections::btree::map::BTreeMap<alloc::rc::Rc<()>, alloc::rc::Rc<()>>`
path.rs:7:5: 7:36 note: required by `foo`
error: aborting due to 2 previous errors
```

This improves the rust-lang#21793/rust-lang#23286 situation
bors added a commit that referenced this issue Sep 15, 2015
…sakis

new error style:
```
path.rs:4:6: 4:7 error: the trait `core::marker::Sized` is not implemented for the type `[u8]` [E0277]
path.rs:4 fn f(p: Path) {}
               ^
path.rs:4:6: 4:7 help: run `rustc --explain E0277` to see a detailed explanation
path.rs:4:6: 4:7 note: `[u8]` does not have a constant size known at compile-time
path.rs:4:6: 4:7 note: required because it appears within the type `std::sys::os_str::Slice`
path.rs:4:6: 4:7 note: required because it appears within the type `std::ffi::os_str::OsStr`
path.rs:4:6: 4:7 note: required because it appears within the type `std::path::Path`
path.rs:4:6: 4:7 note: all local variables must have a statically known size
path.rs:7:5: 7:36 error: the trait `core::marker::Send` is not implemented for the type `alloc::rc::Rc<()>` [E0277]
path.rs:7     foo::<BTreeMap<Rc<()>, Rc<()>>>();
              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
path.rs:7:5: 7:36 help: run `rustc --explain E0277` to see a detailed explanation
path.rs:7:5: 7:36 note: `alloc::rc::Rc<()>` cannot be sent between threads safely
path.rs:7:5: 7:36 note: required because it appears within the type `collections::btree::node::Node<alloc::rc::Rc<()>, alloc::rc::Rc<()>>`
path.rs:7:5: 7:36 note: required because it appears within the type `collections::btree::map::BTreeMap<alloc::rc::Rc<()>, alloc::rc::Rc<()>>`
path.rs:7:5: 7:36 note: required by `foo`
error: aborting due to 2 previous errors
```

This improves the #21793/#23286 situation

r? @nikomatsakis
bors added a commit that referenced this issue Sep 15, 2015
…sakis

new error style:
```
path.rs:4:6: 4:7 error: the trait `core::marker::Sized` is not implemented for the type `[u8]` [E0277]
path.rs:4 fn f(p: Path) {}
               ^
path.rs:4:6: 4:7 help: run `rustc --explain E0277` to see a detailed explanation
path.rs:4:6: 4:7 note: `[u8]` does not have a constant size known at compile-time
path.rs:4:6: 4:7 note: required because it appears within the type `std::sys::os_str::Slice`
path.rs:4:6: 4:7 note: required because it appears within the type `std::ffi::os_str::OsStr`
path.rs:4:6: 4:7 note: required because it appears within the type `std::path::Path`
path.rs:4:6: 4:7 note: all local variables must have a statically known size
path.rs:7:5: 7:36 error: the trait `core::marker::Send` is not implemented for the type `alloc::rc::Rc<()>` [E0277]
path.rs:7     foo::<BTreeMap<Rc<()>, Rc<()>>>();
              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
path.rs:7:5: 7:36 help: run `rustc --explain E0277` to see a detailed explanation
path.rs:7:5: 7:36 note: `alloc::rc::Rc<()>` cannot be sent between threads safely
path.rs:7:5: 7:36 note: required because it appears within the type `collections::btree::node::Node<alloc::rc::Rc<()>, alloc::rc::Rc<()>>`
path.rs:7:5: 7:36 note: required because it appears within the type `collections::btree::map::BTreeMap<alloc::rc::Rc<()>, alloc::rc::Rc<()>>`
path.rs:7:5: 7:36 note: required by `foo`
error: aborting due to 2 previous errors
```

Fixes #21793 
Fixes #23286

r? @nikomatsakis
@marcusklaas
Copy link
Contributor

Has this really been fixed? It looks like the error was cleaned up a bit, but it still states that [u8] is unsized, instead of Path..

@Diggsey
Copy link
Contributor

Diggsey commented Sep 16, 2015

@marcusklaas It should now list all of the steps which result in the Sized bound being violated, including both Path and [u8]

@aturon
Copy link
Member

aturon commented Sep 29, 2015

This is definitely an improvement, but the order of information still seems backwards to me: I feel like I want to see first that Path isn't sized -- which is the immediate problem -- and then a kind of "backtrace" for why Path isn't sized. Starting off with the inner reason (about [u8] here) makes it very confusing at first, even if all of the needed information is there.

cc @nikomatsakis

@nikomatsakis
Copy link
Contributor

@aturon

Starting off with the inner reason (about [u8] here) makes it very confusing at first, even if all of the needed information is there.

Hmm, I see your point. The current message reflects more how the compiler operators internally than the mental model of the user. We could invert the message, I imagine, though what I'd really prefer to do is to keep more information than we have now (which @jroesch has been working on) in terms of keeping the full "obligation stack". But in any case that if we wanted to invert the stack trace I imagine we could, with a little bit of legwork. I'd be happy to mentor this. I'll re-open for now.

@nikomatsakis nikomatsakis reopened this Sep 30, 2015
alexcrichton added a commit to alexcrichton/rust that referenced this issue Dec 20, 2016
Point out the known type when field doesn't satisfy bound

For file

```rust
use std::path::Path;

fn f(p: Path) { }
```

provide the following error

```nocode
error[E0277]: the trait bound `[u8]: std::marker::Sized` is not satisfied in `std::path::Path`
 --> file.rs:3:6
  |
3 | fn f(p: Path) { }
  |      ^ within `std::path::Path`, the trait `std::marker::Sized` is not implemented for `[u8]`
  |
  = note: `[u8]` does not have a constant size known at compile-time
  = note: required because it appears within the type `std::path::Path`
  = note: all local variables must have a statically known size
```

Fix rust-lang#23286.
@suesslin
Copy link

With the latest version of Rust.

error[E0277]: the trait bound `[u8]: std::marker::Sized` is not satisfied
 --> src/logic.rs:5:5
  |
5 |     product_path: Path,
  |     ^^^^^^^^^^^^^^^^^^ the trait `std::marker::Sized` is not implemented for `[u8]`
  |
  = note: `[u8]` does not have a constant size known at compile-time
  = note: required because it appears within the type `std::path::Path`
  = note: only the last field of a struct may have a dynamically sized type

@VersBinarii
Copy link

+1
This still appears to be an issue:

error[E0277]: the trait bound `[u8]: std::marker::Sized` is not satisfied in `std::path::Path`
 --> src/main.rs:8:5
  |
8 |     scan_dir: Path,
  |     ^^^^^^^^^^^^^^ `[u8]` does not have a constant size known at compile-time
  |
  = help: within `std::path::Path`, the trait `std::marker::Sized` is not implemented for `[u8]`
  = note: required because it appears within the type `std::path::Path`
  = note: only the last field of a struct may have a dynamically sized type

@estebank estebank reopened this Feb 25, 2018
@estebank
Copy link
Contributor

Reopening as the output is still confusing.

@XAMPPRocky XAMPPRocky added the C-enhancement Category: An issue proposing an enhancement or a PR with one. label Feb 26, 2018
@sourcepirate
Copy link

Is there any updates on this one ?

@estebank
Copy link
Contributor

@sourcepirate I do not believe anyone has tried to address this recently.

kennytm added a commit to kennytm/rust that referenced this issue Oct 18, 2018
Custom E0277 diagnostic for `Path`

r? @nikomatsakis we have a way to target `Path` exclusively, we need to identify the correct text to show to consider rust-lang#23286 fixed.
bors added a commit that referenced this issue Oct 18, 2018
Custom E0277 diagnostic for `Path`

r? @nikomatsakis we have a way to target `Path` exclusively, we need to identify the correct text to show to consider #23286 fixed.
@estebank
Copy link
Contributor

Current output

error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
 --> src/lib.rs:3:6
  |
3 | fn f(p: Path) { }
  |      ^ borrow the `Path` instead
  |
  = help: within `std::path::Path`, the trait `std::marker::Sized` is not implemented for `[u8]`
  = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
  = note: required because it appears within the type `std::path::Path`
  = note: all local variables must have a statically known size
  = help: unsized locals are gated as an unstable feature

@marcusklaas
Copy link
Contributor

The current output looks pretty great. Explains what the error is, where it's coming from and how to fix it.

@estebank estebank removed the E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. label May 24, 2019
@oli-obk oli-obk added the E-hard Call for participation: Hard difficulty. Experience needed to fix: A lot. label May 24, 2019
@estebank estebank added D-confusing Diagnostics: Confusing error or lint that should be reworked. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. labels Oct 10, 2019
Manishearth added a commit to Manishearth/rust that referenced this issue Jul 13, 2020
Provide structured suggestion on unsized fields and fn params

* Suggest borrowing or boxing unsized fields
* Suggest borrowing fn parameters
* Remove some verbosity of unsized errors
* Remove `on_unimplemented` note from `trait Sized`

Fix rust-lang#23286, fix rust-lang#28653.

r? @davidtwco
@bors bors closed this as completed in a364c0a Jul 14, 2020
@erayerdin
Copy link

The issue is still present. I have a simple struct as below:

pub struct Paths {
    home_config_path: Path,  // "Path" is underlined red
    local_config_path: Path,
    log_path: Path,
}

I use VSCode with rust-analyzer and it complains saying:

the size for values of type `[u8]` cannot be known at compilation time
within `Path`, the trait `Sized` is not implemented for `[u8]`
required because it appears within the type `Path`
only the last field of a struct may have a dynamically sized type
change the field's type to have a statically known sizerustcE0277
app.rs(42, 23): borrowed types always have a statically known size
app.rs(42, 23): the `Box` type always has a statically known size and allocates its contents in the heap

If you prefer screenshot:

error in vscode

cargo build --workspace also fails saying below:

error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
  --> altbinutils_core/src/app.rs:42:23
   |
42 |     home_config_path: Path,
   |                       ^^^^ doesn't have a size known at compile-time
   |
   = help: within `Path`, the trait `Sized` is not implemented for `[u8]`
   = note: required because it appears within the type `Path`
   = note: only the last field of a struct may have a dynamically sized type
   = help: change the field's type to have a statically known size
help: borrowed types always have a statically known size
   |
42 |     home_config_path: &Path,
   |                       ^
help: the `Box` type always has a statically known size and allocates its contents in the heap
   |
42 |     home_config_path: Box<Path>,
   |                       ^^^^    ^

error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
   --> altbinutils_core/src/app.rs:47:6
    |
47  | impl From<Metadata> for Paths {
    |      ^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    | 
   ::: /home/erayerdin/snap/rustup/common/rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/convert/mod.rs:373:20
    |
373 | pub trait From<T>: Sized {
    |                    ----- required by this bound in `From`
    |
    = help: within `Paths`, the trait `Sized` is not implemented for `[u8]`
    = note: required because it appears within the type `Paths`

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0277`.
error: could not compile `altbinutils_core`

To learn more, run the command again with --verbose.

(Yes, I have a From implementation.)


Environment

  • rustc 1.49.0
  • cargo 1.49.0
  • VSCode 1.52.1

Unfortunately, I have no way to tell the rust-analyzer version because the extension downloads it itself. It's safe to assume it is the latest version at the time I write this reply.

If relevant:

  • Kubuntu 20.04.2

Possible Questions

Why do I think this is not related to rust-analyzer?

It's because cargo build --workspace also fails. Therefore, I think this is related to this thread.

@estebank
Copy link
Contributor

estebank commented Feb 3, 2021

help: borrowed types always have a statically known size
   |
42 |     home_config_path: &Path,
   |                       ^
help: the `Box` type always has a statically known size and allocates its contents in the heap
   |
42 |     home_config_path: Box<Path>,
   |                       ^^^^    ^

Are neither of these suggestions applicable for your case? Should their wording be made clearer or more prominent?

@erayerdin
Copy link

@estebank Actually using PathBuf instead of Path solved my issue.

brainstorm added a commit to umccr/crypt4gh-rust that referenced this issue Aug 14, 2023
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-confusing Diagnostics: Confusing error or lint that should be reworked. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. E-hard Call for participation: Hard difficulty. Experience needed to fix: A lot. E-help-wanted Call for participation: Help is requested to fix this issue. P-medium Medium priority 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.