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

inflexibility with diverging functions #10352

Closed
thestinger opened this issue Nov 8, 2013 · 6 comments
Closed

inflexibility with diverging functions #10352

thestinger opened this issue Nov 8, 2013 · 6 comments

Comments

@thestinger
Copy link
Contributor

The following code compiles, since the return type is inferred to be Option<()>:

fn main() {
    Some(5).map(|_| ());
}

However, this will not compile because rustc cannot infer a type:

fn main() {
    Some(5).map(|_| fail!());
}

If we used something like Void instead of !, the return type would obviously be Option<Void> here. However, since ! isn't allowed anywhere but a function signature this is a pain.

@thestinger
Copy link
Contributor Author

#7680 was rejected, but this presents a good reason for changing how we handle this

@Kimundi
Copy link
Member

Kimundi commented Nov 8, 2013

Maybe we could just make ! default to () or Void in case where inference fails?

@thestinger
Copy link
Contributor Author

In that case it probably makes more sense just to use an uninhabited enum with a lang item called something like Fail with consistent usage everywhere. The return type should really contain an uninhabited enum rather than () or it will still be a pain elsewhere.

@nikomatsakis
Copy link
Contributor

I don't consider this a bug. The type of fail! is correct as is and allows a number of important use cases. The compiler is not wrong to say that there is no constraint on that type. The correct answer is to supply a manual type hint or just not call map -- adding a function like apply would do just as well, or creating a wrapper around fail! that hides the fact that it fails (which is what you are looking to do):

fn fail(s: ~str) { fail!(s); }
my_opt.map(|s| fail(format!(...)); )

@nikomatsakis
Copy link
Contributor

As an example of the kind of code that having fail! have bottom type enables:

let x = match ... {
   case1 => 1,
   case2 => 2,
   case3 => fail!("Impossible!")
};

Another possible fix would be to say that all unconstrained type variables are arbitrarily assigned unit. We did this for a while and reverted it due to bugs I think, and possibly some surprising interactions. I'm inclined not to change the inference rules, personally, partially because I'm not too happy with our inference scheme and I don't want to get locked into defaults we might want to change.

@thestinger
Copy link
Contributor Author

Okay, I'm convinced.

flip1995 pushed a commit to flip1995/rust that referenced this issue Jun 30, 2023
Add `unnecessary_literal_unwrap` lint

Add lint for more unnecessary unwraps and suggest fixes for them.

Fixes rust-lang#10352

- [x] Followed [lint naming conventions][lint_naming]
- [x] Added passing UI tests (including committed `.stderr` file)
- [x] `cargo test` passes locally
- [x] Executed `cargo dev update_lints`
- [x] Added lint documentation
- [x] Run `cargo dev fmt`

r? `@llogiq`

---

changelog: New lint [`unnecessary_literal_unwrap`]
[rust-lang#10358](rust-lang/rust-clippy#10358)
<!-- changelog_checked -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants