Skip to content

we find a issue, I don't konw is there a bug? #49865

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

Closed
driftluo opened this issue Apr 11, 2018 · 9 comments
Closed

we find a issue, I don't konw is there a bug? #49865

driftluo opened this issue Apr 11, 2018 · 9 comments

Comments

@driftluo
Copy link

the function like this is ok:

fn test() -> bool {
    let a = {true} && true;
    a 
}

but when is become this, there is an error:

fn test() -> bool {
    {
    // this is some thing return bool
    true
    } && true
}

the error is:

error[E0308]: mismatched types
 --> src/main.rs:4:5
  |
4 |     true
  |     ^^^^ expected (), found bool
  |
  = note: expected type `()`
             found type `bool`

error[E0308]: mismatched types
 --> src/main.rs:6:7
  |
1 | fn test() -> bool {
  |              ---- expected `bool` because of return type
...
6 |     } && true
  |       ^^^^^^^ expected bool, found &&bool
  |
  = note: expected type `bool`
             found type `&&bool`

error: aborting due to 2 previous errors
@ZhangHanDong
Copy link

ZhangHanDong commented Apr 11, 2018

       {true}       &&      {true}

the code will be parse two expressions by rustc parser:

  • { true }
  • &&{true}

the follwing code can work:

  true && {true}

or

(true) && {true}

or

( {true} && {true} )

I don't think it's a Bug

@KiChjang
Copy link
Member

So, I think I found where the problem is:

pub fn parse_assoc_expr_with(&mut self,
min_prec: usize,
lhs: LhsExpr)
-> PResult<'a, P<Expr>> {
let mut lhs = if let LhsExpr::AlreadyParsed(expr) = lhs {
expr
} else {
let attrs = match lhs {
LhsExpr::AttributesParsed(attrs) => Some(attrs),
_ => None,
};
if [token::DotDot, token::DotDotDot, token::DotDotEq].contains(&self.token) {
return self.parse_prefix_range_expr(attrs);
} else {
self.parse_prefix_expr(attrs)?
}
};
if self.expr_is_complete(&lhs) {
// Semi-statement forms are odd. See https://github.com/rust-lang/rust/issues/29071
return Ok(lhs);
}

In particular, it's the call to expr_is_complete. @nagisa even left a comment there saying that semi-statement forms are odd, and I believe this is one of them, since we regard a {true} block as a complete statement, whereas if you change it to (true), it would not be seen as complete, and will continue on to parse the && correctly as a binary operator.

@petrochenkov
Copy link
Contributor

Yep, this is expected behavior.
Disambiguation is done in favor of two statements to support things like this

if cond {
    stmts;
}

*ptr = val; // Not multiplication!

Yes, there are false positives, but the opposite disambiguation has even more false positives.

@driftluo
Copy link
Author

I think you didn't understand what I mean.

let foo = { true };  // it means foo is bool
let foo = { true; };  // it means foo is ()
``

so why `{ true } && true` is  &&bool

@petrochenkov
Copy link
Contributor

@driftluo
Because it's interpreted as two statements

// Statement 1
{
    true
}

// Statement 2
&&true // Take address of address of `true`, the result has type `&&bool`

@driftluo
Copy link
Author

This means that if there is a braces block, it will be interpreted as a single statement regardless of what follows.
If I want it to a expression, I should use () to tell rustc, it is expression.

@crlf0710
Copy link
Member

@petrochenkov while the decision is understandable, the diagnostics is far from satisfying... Any chance to improve it somehow?

@ZhangHanDong
Copy link

@crlf0710 Agree

@KiChjang
Copy link
Member

This issue has been discussed in #29071.

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

5 participants