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

add docs for never type #206

Merged
merged 4 commits into from
Mar 16, 2018
Merged

Conversation

canndrew
Copy link
Contributor

No description provided.

src/types.md Outdated

The never type `!` is a type with no values, representing the result of
computations that never complete. Although it has size `0` the empty bit
pattern is not a valid representation. Expressions of type `!` can be coerced
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what the comment about a representation is intended to mean; since it has size 0, it has no representation, I thought?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An n-bit type has 2^n possible bit-patterns that can represent values. bool is represented as a byte, but only two of the 256 different bit-patterns are valid values: [00000000] (false) and [00000001] (true).

() is size 0 which means it has one bit-pattern: the empty array of bits []. In the case of () this represents the value ().

! is size 0 but it the empty array of bits does not represent any value.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, right, I see what you're saying. Is that actually true, though? It seems to me that it's more accurate to say that () has one value, but no representations. Rust generally doesn't try to encode a representation of (), for instance, Vec<()> is effectively just a length field.

I'd probably just drop the sentence; I don't think it adds more clarity.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, fixed.

src/types.md Outdated
The never type `!` is a type with no values, representing the result of
computations that never complete. Although it has size `0` the empty bit
pattern is not a valid representation. Expressions of type `!` can be coerced
into any other type.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think type-coercions.md should be updated too?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Done.

@matthewjasper
Copy link
Contributor

The section on diverging functions will also need some changes. At least this sentence has to be removed

https://github.com/rust-lang-nursery/reference/blob/6608583d99d33cbfa643607d48e5d12cef682134/src/items/functions.md#L111-L112

cc rust-lang/rust#47630

@canndrew
Copy link
Contributor Author

I've removed the section on diverging functions entirely since they're no longer special.

@alercah
Copy link
Contributor

alercah commented Jan 21, 2018

They're still special though, because they cause code afterward to be unreachable. The example there about using the diverging function to conclude that f will always return an i32 (the coercion from ! to any other type is not applicable there, because the statement calling my_err has type (), not !).

Copy link
Contributor

@mrhota mrhota left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the divergent functions section should stay, but it needs to be updated to account for the never type. I also think you should keep the link in the loop section to either (or both?) the divergent functions section or the new Never type section.

may terminate, and must have type compatible with the value of the `break`
expression(s).
A `loop` expression without an associated `break` expression is diverging and
so has type `!`. A `loop` expression containing associated
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you link to the new Never type section you created?

And can you rephrase the end of the first sentence to one of these?

  • "expression is divergent and has type !."
  • "expression diverges and has type !."

"and so" is redundant.

@@ -93,52 +93,6 @@ sufficient context to determine the type parameters. For example,

[path]: paths.html

## Diverging functions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why remove this? The information about what constructs produce the ! return type remains useful. Also, the new section below doesn't use "diverges", "diverge", or "divergent", though we make use of "diverges" in the section about loop {}s.

I say just keep this section in tact, with adjustments to account for new thinking about the Never Type.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's not really a good reason to have information on divergence in the function items page. Perhaps mention in the function call and method call operators that calling a function that returns ! diverges? Divergence sort of needs its own section in the Expressions page itself, I think? I haven't thought too much about whether it's a property of expressions, statements, or both? And that can be done separately from this.

It would be nice to pull the example into the Never type docs though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @Havvy here. Divergence isn't specifically a property of functions, it's its own thing entirely and really needs its own section. I don't fully understand the semantics of it though, so I'm not confident that I'd be able to write that section.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, put the information where ever you think it fits best, but I don't want to lose the information.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe someone like @arielb1 can help here. Is this an accurate-enough description of type-checking w.r.t divergence and !?

  • Expressions of type ! cause everything in the computation graph after the ! to be marked unreachable.
  • If a block ends in a statement, and the end of the block is unreachable, then the block has type !.

I know it's not exactly implemented like this in the compiler, but have I left out any relevant caveats? Do you think the reference needs a section on divergence separate from !?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll make sure that divergence information doesn't get lost before the next beta, even if this PR loses it.

@canndrew
Copy link
Contributor Author

They're still special though, because they cause code afterward to be unreachable.

That's true of any diverging expression though, not just function calls. I can do:

struct ContainsNever {
    never: !,
}

fn mk_it() -> ContainsNever  {
    panic!("aah");
}

fn main() {
    let wow: ContainsNever = mk_it();

    println!("rustc thinks this is reachable");

    let _n = wow.never;

    println!("but this is not");
}

The example there about using the diverging function to conclude that f will always return an i32 (the coercion from ! to any other type is not applicable there, because the statement calling my_err has type (), not !).

It would be more correct to say that the entire else block diverges and therefore has type !. Even though it doesn't end in an expression.

@Havvy Havvy added the S-waiting-on-stabilization Waiting for a stabilization PR to be merged in the main Rust repository label Jan 30, 2018
@canndrew
Copy link
Contributor Author

canndrew commented Feb 1, 2018

Is there anything else that needs to be done for this PR? The section on diverging functions that I removed didn't contain any information which isn't now completely redundant. All of it just boils down to "if you declare something to have type T then it must really have type T"

@@ -123,4 +123,4 @@ As non-Rust calling conventions do not support unwinding, unwinding past the end
of an extern function will cause the process to abort. In LLVM, this is
implemented by executing an illegal instruction.

[external blocks]: items/external-blocks.html
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated to this PR, but why does this keep showing up? And why this time in a file that is otherwise untouched?

@Havvy
Copy link
Contributor

Havvy commented Feb 11, 2018

In the special types and traits page, can you add the never type to the list of copy types?

@canndrew
Copy link
Contributor Author

@Havvy done.

@matthewjasper
Copy link
Contributor

! is stable now, can you fix the merge conflict so that this can be merged?

I'll make sure that divergence information doesn't get lost before the next beta, even if this PR loses it.

@Havvy are you still happy to do this?

Remove section on diverging function since they are no longer special.
Modify wording around description of `loop` accordingly.
Add `!` to any coercion to list of coercions.
@canndrew
Copy link
Contributor Author

@matthewjasper done.

@matthewjasper matthewjasper merged commit 75b8ec9 into rust-lang:master Mar 16, 2018
@matthewjasper
Copy link
Contributor

Thanks! 💟

@Havvy Havvy mentioned this pull request Mar 17, 2018
@ehuss ehuss mentioned this pull request Oct 23, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-stabilization Waiting for a stabilization PR to be merged in the main Rust repository
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants