Skip to content

type inference failure confusing diagnostic let Some(x) = None for [u8] #141336

@midnightveil

Description

@midnightveil

Code

fn func(x: &[u8]) {
    std::hint::black_box(x);
}

fn test() {
    if let Some(path) = None {
        func(&path);
    }
}

Current output

Compiling playground v0.0.1 (/playground)
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
 --> src/lib.rs:6:17
  |
6 |     if let Some(path) = None {
  |                 ^^^^ doesn't have a size known at compile-time
  |
  = help: the trait `Sized` is not implemented for `[u8]`
  = note: all local variables must have a statically known size
  = help: unsized locals are gated as an unstable feature

error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
   --> src/lib.rs:6:12
    |
6   |     if let Some(path) = None {
    |            ^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `[u8]`
note: required by a bound in `Some`
   --> /playground/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/option.rs:589:17
    |
589 | pub enum Option<T> {
    |                 ^ required by this bound in `Some`
...
597 |     Some(#[stable(feature = "rust1", since = "1.0.0")] T),
    |     ---- required by a bound in this tuple variant

error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
   --> src/lib.rs:6:25
    |
6   |     if let Some(path) = None {
    |                         ^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `[u8]`
note: required by a bound in `None`
   --> /playground/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/option.rs:589:17
    |
589 | pub enum Option<T> {
    |                 ^ required by this bound in `None`
...
593 |     None,
    |     ---- required by a bound in this unit variant

For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground` (lib) due to 3 previous errors

Desired output

I'm not sure; but the issue is not that path doesn't have a size known at compile time but more that we can't infer an appropriate type for path

Rationale and extra context

No response

Other cases

Rust Version

nightly: 2025-05-20 bc821528634632b4ff8d from rust playground

Anything else?

https://play.rust-lang.org/?version=nightly&mode=debug&edition=2024&gist=ac6219162fb8bfab6a527be73b0db480

Activity

added
A-diagnosticsArea: Messages for errors, warnings, and lints
T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
on May 21, 2025
workingjubilee

workingjubilee commented on May 21, 2025

@workingjubilee
Member

The error is correct. The obvious inference is that the arg to fn(&T), if passed as f(&arg), is itself T, which would be a [u8].

workingjubilee

workingjubilee commented on May 21, 2025

@workingjubilee
Member

There could be an improvement to be had here but it doesn't seem obvious from the initial report. Could you explain more about why you find it confusing?

midnightveil

midnightveil commented on May 21, 2025

@midnightveil
Author

The error is correct. The obvious inference is that the arg to fn(&T), if passed as f(&arg), is itself T, which would be a [u8].

Yes, I know :)

Could you explain more about why you find it confusing?

The fact that we are warned about a type having a non-compile time size when we didn't write that type, and instead it was inferred. I would think it'd be clearer if instead the error was that explicit type annotations were needed.

The issue is the error emitted by the compiler is not a direct consequence of the code that was entered, but instead a consequence of the type inference performed by the compiler (secondary, indrect). I'm not opposed to this message being output as reason why the type couldn't be inferred, but it's not the direct cause of the error.

workingjubilee

workingjubilee commented on May 21, 2025

@workingjubilee
Member

I'm still slightly perplexed because obviously, the type can be inferred!

Maybe in this case we should just notice we are trying to match Some(_) against None and bail?

added
D-confusingDiagnostics: Confusing error or lint that should be reworked.
on May 21, 2025
midnightveil

midnightveil commented on May 21, 2025

@midnightveil
Author

I'm still slightly perplexed because obviously, the type can be inferred!

I mean, it depends? Is [u8] considered to be a full type or does it need to be [u8; ]. I intuitionistically go towards the second, the first by nature of being dynamically sized I don't think* can be used without & etc.

But even so, it would be good to note that "[u8]" is inferred because XYZ in this error; I mean here sure it's probably valid to treat Some(x) = None specially but one could surely have this for other types and situations too?

Here's it's also true that the inferred type is somewhat obvious but I don't know if that's true more generally.

workingjubilee

workingjubilee commented on May 22, 2025

@workingjubilee
Member

Yes, it's a complete type, because you can implement things on it.

workingjubilee

workingjubilee commented on May 22, 2025

@workingjubilee
Member

It's just a useless type for most "actual" code, because you kind of need a size to do much with types. In that we are in perfect agreement.

workingjubilee

workingjubilee commented on May 22, 2025

@workingjubilee
Member

Anyways, thank you for this discussion, it's made it clearer what you want. I'm not sure what we'll do. Yes, maybe we can consider the "code fails because of type" and then backtrack to the type inference, but I don't know if we record enough information to capture that decision (off the top of my head, anyways).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsA-inferenceArea: Type inferenceD-confusingDiagnostics: Confusing error or lint that should be reworked.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @fmease@workingjubilee@midnightveil

        Issue actions

          type inference failure confusing diagnostic let Some(x) = None for [u8] · Issue #141336 · rust-lang/rust