Skip to content

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

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # 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.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants