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

typestate sees break as applying to the outermost loop #2642

Closed
paulstansifer opened this issue Jun 18, 2012 · 14 comments
Closed

typestate sees break as applying to the outermost loop #2642

paulstansifer opened this issue Jun 18, 2012 · 14 comments
Milestone

Comments

@paulstansifer
Copy link
Contributor

The following code compiles (as expected):

fn main() {
    let _x: uint = loop { };
}

However, this code does not, as if the break were breaking out of the outer loop:

fn main() {
    let _x: uint = loop { loop { break; } };
}
@ghost ghost assigned catamorphism Jun 18, 2012
@nikomatsakis
Copy link
Contributor

this may be a liveness bug?

@catamorphism
Copy link
Contributor

Maybe, but I'm pretty sure I know what the bug is if it's in typestate. @paulstansifer , can you post the error message?

@nikomatsakis
Copy link
Contributor

actually I think this is neither liveness nor typestate but rather typeck and something off in the (rather hokey) way that it tracks the notion of "bottom".

@nikomatsakis
Copy link
Contributor

this is the error that I see:

/Users/nmatsakis/tmp/issue-2642.rs:2:19: 2:43 error: mismatched types: expected `uint` but found `()` (uint vs ())
/Users/nmatsakis/tmp/issue-2642.rs:2     let _x: uint = loop { loop { break; } };
                                                        ^~~~~~~~~~~~~~~~~~~~~~~~

@catamorphism
Copy link
Contributor

Yeah, not a typestate error. I can still take a look, though.

@nikomatsakis
Copy link
Contributor

To be honest, I am not sure that the type system ought to be in the business of tracking bottom.

@paulstansifer
Copy link
Contributor Author

Oops, sorry folks. That's the same as the error I get.

@paulstansifer
Copy link
Contributor Author

It's really useful if you want to return from inside an otherwise infinite loop, which is what led me to this bug.

@nikomatsakis
Copy link
Contributor

but why are you "assigning" the loop to a local variable in the first place?

@nikomatsakis
Copy link
Contributor

it seems to me that loops and complex constructs that may or may not be bottom should just have unit type. Something like ret or what have you can still have bottom type.

@paulstansifer
Copy link
Contributor Author

I probably should've reduced it to an example that looks more like the code I'm interested in:

fn f() -> uint {
  loop {
    if some_cond { ret 8u; }
    loop { break; }
  }
}

In this case, we need bottom to acknowledge that nothing will ever fall off the end of the outer loop, preventing the need for a dummy, dead code ret statement.

@eholk
Copy link
Contributor

eholk commented Jun 18, 2012

I think I usually just use fail if I need to convince the compiler that some code will never run.

@catamorphism
Copy link
Contributor

Yes, but the point of introducing loop was to make it possible to omit fails in some common cases... so I'm with Paul at least until I look at the typeck code and decide it's too hard to fix ;-)

@nikomatsakis
Copy link
Contributor

Paul's example is more convincing. I guess we have to make it work due to the fact that loops are expressions and can appear in tail position in a block. sigh

RalfJung pushed a commit to RalfJung/rust that referenced this issue Nov 6, 2022
…Jung

Followup for pr 2640

r? `@RalfJung`
Aaron1011 pushed a commit to Aaron1011/rust that referenced this issue Jan 6, 2023
…Jung

Followup for pr 2640

r? `@RalfJung`
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

4 participants