rust-lang / rust-lang/rust

Never type fallback with integer literal without type fails to compile

Open
#161,848 12 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-associated-items A-inference C-bug D-confusing D-terse needs-triage T-types
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

Reproducible in Playground: https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=2f1b5d53850d4305ae648df91eecea91.

Background

I'm trying to create my own integer structs:

struct MyInt;
struct MyError;

and my custom operations with standard types:

struct I8Output;
struct I32Output;
// and for other standard types

trait MyDiv<Rhs> {
    type Output;

    fn try_div(self, rhs: Rhs) -> Result<Self::Output, MyError>;
}

impl MyDiv<i8> for MyInt {
    type Output = I8Output;

    fn try_div(self, _rhs: i8) -> Result<Self::Output, MyError> {
        Ok(I8Output)
    }
}

impl MyDiv<i32> for MyInt {
    type Output = I32Output;

    fn try_div(self, _rhs: i32) -> Result<Self::Output, MyError> {
        Ok(I32Output)
    }
}
// and for other standard types

Problem

The following code:

let x = MyInt.try_div(8)?;

fails to compile:

   Compiling playground v0.0.1 (/playground)
error[E0308]: `?` operator has incompatible types
  --> src/main.rs:50:13
   |
50 |     let x = MyInt.try_div(8)?;
   |             ^^^^^^^^^^^^^^^^^ expected `I32Output`, found `!`
   |
   = note: `?` operator cannot convert from `!` to `I32Output`
   = note: expected struct `I32Output`
                found type `!`

For more information about this error, try `rustc --explain E0308`.

The expected behavior is that 8 is typechecked(or "fell back") as i32, and x should be typechecked as I32Output.

I guess currently 8 is properly typechecked as i32 (since the error message says I32Output), but x fails to typecheck.

Note

The following code can be compiled.

// Typechecked if return type is given
let x: I32Output = MyInt.try_div(8)?;
// Typechecked if integer type is given
let x = MyInt.try_div(8i32)?;
// Result type itself can be typechecked
let y = MyInt.try_div(8);

Updates

  • 26/08/27: The issue is same for editions before 2024; i.e. This issue doesn't mater whether "never type fallback" fallbacks to ! or (). (Related comment)

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 with the linked Rust Playground reproducer and compare it with the three compiling variants listed under “Note,” focusing on never-type fallback and inference through the ? operator. Done means the unannotated let x = MyInt.try_div(8)?; case compiles with I32Output as expected.

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
Active
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.