Never type fallback with integer literal without type fails to compile
Nobody has claimed this yet.
- 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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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