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

Type inference of a diverging function is weird #20172

Closed
nodakai opened this issue Dec 23, 2014 · 3 comments · Fixed by #22130
Closed

Type inference of a diverging function is weird #20172

nodakai opened this issue Dec 23, 2014 · 3 comments · Fixed by #22130
Labels
A-type-system Area: Type system

Comments

@nodakai
Copy link
Contributor

nodakai commented Dec 23, 2014

These two codes compile fine:

fn main() {
    panic!();
    panic!() //  warning: unreachable expression, #[warn(unreachable_code)] on by default
}
fn f<R>() -> R {
    panic!()
}

fn main() {
    println!("hello");
    f()
}

but this does not (note the semicolon after f()):

fn f<R>() -> R {
    panic!()
}

fn main() {
    println!("hello");
    f(); // error: unable to infer enough type information about `_`; type annotations required
}

Though the Rust language reference seems to say there's an (inhabitable) type called the "bottom type," the behavior of rustc is almost as if the bottom type does not really exist in Rust. These examples gave me an impression that a type equation involving a diverging function is simply discarded (otherwise R in the last example should correctly be inferred as the bottom type and there should be no difference between foo(); and panic();,) though I'm aware librustc/middle/infer/combine.rs does consistency check of FnDiverigng...

See also #20105 which was originally filed as a complaint for not allowing this code:

fn g<F, R>(_: F) where F: Fn<(), R> {
}

fn main() {
    g(|| panic!()); // error: unable to infer enough type information about `_`; type annotations required
}
@pnkfelix
Copy link
Member

There is no longer a bottom type; it was removed (see issue #14973), replaced with treating a function returning ! as a distinct type-constructor from a function returning some actual type.

It is not clear to me from the issue description whether the problem here is merely one of documentation needing updating, or if there is some more fundamental issue that needs to be addressed.

@nodakai
Copy link
Contributor Author

nodakai commented Dec 23, 2014

@pnkfelix Oh, I didn't know it had already been removed. Then these statements should at least be updated accordingly:

The ! annotation does not denote a type. Rather, the result type of a diverging function is a special type called $\bot$ ("bottom") that unifies with any type. Rust has no syntax for $\bot$.

The way I understood your explanation is: "diverging-ness" of a function is specific to each function marked with -> !. That's fine with me (as long as it's clearly explained so in the language reference and we don't call it the "bottom type".)

But then, I think f() in the second example should be rejected by type check because a type variable R remains undetermined.

@kmcallister kmcallister added A-type-system Area: Type system A-docs labels Jan 16, 2015
@arielb1
Copy link
Contributor

arielb1 commented Feb 6, 2015

@nodakai

The semicolon example not compiling doesn't have anything to do with bottom. f has type for<T> ->T, and there are no constraints on T, but without the semicolon, T is constrained to be ().

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-type-system Area: Type system
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants