rust-lang / rust-lang/rust

rustc decides variable is of unsized type even when it is clear later it's not

Open
#118,572 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-inference C-bug T-compiler
Dominant language
Rust
Stars
119k
Forks
16.2k
PR merge metrics
PR metrics pending

Description

I tried this code:

fn any<T>() -> T { loop {} }

fn foo() {
    let v = any();
    let r: &[i32] = &v;
    let _: [i32; 1] = v;
}

Playground.

I expected to see this happen: compiles successfully, with v deduced to be [i32; 1]

Instead, this happened:

error: mismatched types
 --> src/lib.rs:6:23
  |
5 |     let r: &[i32] = &v;
  |                      - here the type of `v` is inferred to be `[i32]`
6 |     let _: [i32; 1] = v;
  |            --------   ^ expected `[i32; 1]`, found `[i32]`
  |            |
  |            expected due to this

error: the size for values of type `[i32]` cannot be known at compilation time
 --> src/lib.rs:4:9
  |
4 |     let v = any();
  |         ^ doesn't have a size known at compile-time
  |
  = help: the trait `Sized` is not implemented for `[i32]`
  = note: all local variables must have a statically known size
  = help: unsized locals are gated as an unstable feature

error: the size for values of type `[i32]` cannot be known at compilation time
 --> src/lib.rs:4:13
  |
4 |     let v = any();
  |             ^^^ doesn't have a size known at compile-time
  |
  = help: the trait `Sized` is not implemented for `[i32]`
note: required by a bound in `any`
 --> src/lib.rs:1:8
  |
1 | fn any<T>() -> T { loop {} }
  |        ^ required by this bound in `any`
help: consider relaxing the implicit `Sized` restriction
  |
1 | fn any<T: ?Sized>() -> T { loop {} }
  |         ++++++++

rustc assumes v: [i32], and then fails both because it's an unsized type and because it can't match with let _: [i32; 1] = v;.

Strangely enough, it does compile with trait objects:

fn any<T>() -> T { loop {} }

fn foo() {
    let v = any();
    let r: &dyn std::fmt::Debug = &v;
    let _: [i32; 1] = v;
}

Playground.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by compiling the examples in the issue, using the slice and trait-object variants as comparisons. Trace how rustc infers the type of v across any(), &v, and the later array assignment in foo; done means the slice example compiles with v inferred as [i32; 1] without regressing the trait-object case.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
39/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.