-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
fix: Correctly check for parentheses redundancy in remove_parentheses
assist
#13764
Conversation
crates/syntax/src/ast/prec.rs
Outdated
ast::StmtList(_) => self.needs_parens_in_stmt(None), | ||
ast::ArgList(_) => false, | ||
ast::MatchArm(_) => false, | ||
_ => unimplemented!() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like this should just be false? unimplmented seems wrong since other nodes don't make sense here right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, right. This was left from the time I was testing things out and haven't figured out possible parents.
fixed :)
return contains_exterior_struct_lit_inner(self).is_some(); | ||
|
||
fn contains_exterior_struct_lit_inner(expr: &Expr) -> Option<()> { | ||
use Expr::*; | ||
|
||
match expr { | ||
RecordExpr(..) => Some(()), | ||
|
||
// X { y: 1 } + X { y: 2 } | ||
BinExpr(e) => e | ||
.lhs() | ||
.as_ref() | ||
.and_then(contains_exterior_struct_lit_inner) | ||
.or_else(|| e.rhs().as_ref().and_then(contains_exterior_struct_lit_inner)), | ||
|
||
// `&X { y: 1 }`, `X { y: 1 }.y`, `X { y: 1 }.bar(...)`, etc | ||
IndexExpr(e) => contains_exterior_struct_lit_inner(&e.base()?), | ||
AwaitExpr(e) => contains_exterior_struct_lit_inner(&e.expr()?), | ||
PrefixExpr(e) => contains_exterior_struct_lit_inner(&e.expr()?), | ||
CastExpr(e) => contains_exterior_struct_lit_inner(&e.expr()?), | ||
FieldExpr(e) => contains_exterior_struct_lit_inner(&e.expr()?), | ||
MethodCallExpr(e) => contains_exterior_struct_lit_inner(&e.receiver()?), | ||
|
||
_ => None, | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could use a poor-mans try block aka immediately called closure
return contains_exterior_struct_lit_inner(self).is_some(); | |
fn contains_exterior_struct_lit_inner(expr: &Expr) -> Option<()> { | |
use Expr::*; | |
match expr { | |
RecordExpr(..) => Some(()), | |
// X { y: 1 } + X { y: 2 } | |
BinExpr(e) => e | |
.lhs() | |
.as_ref() | |
.and_then(contains_exterior_struct_lit_inner) | |
.or_else(|| e.rhs().as_ref().and_then(contains_exterior_struct_lit_inner)), | |
// `&X { y: 1 }`, `X { y: 1 }.y`, `X { y: 1 }.bar(...)`, etc | |
IndexExpr(e) => contains_exterior_struct_lit_inner(&e.base()?), | |
AwaitExpr(e) => contains_exterior_struct_lit_inner(&e.expr()?), | |
PrefixExpr(e) => contains_exterior_struct_lit_inner(&e.expr()?), | |
CastExpr(e) => contains_exterior_struct_lit_inner(&e.expr()?), | |
FieldExpr(e) => contains_exterior_struct_lit_inner(&e.expr()?), | |
MethodCallExpr(e) => contains_exterior_struct_lit_inner(&e.receiver()?), | |
_ => None, | |
} | |
} | |
(|| { | |
use Expr::*; | |
match expr { | |
RecordExpr(..) => Some(()), | |
// X { y: 1 } + X { y: 2 } | |
BinExpr(e) => e | |
.lhs() | |
.as_ref() | |
.and_then(contains_exterior_struct_lit_inner) | |
.or_else(|| e.rhs().as_ref().and_then(contains_exterior_struct_lit_inner)), | |
// `&X { y: 1 }`, `X { y: 1 }.y`, `X { y: 1 }.bar(...)`, etc | |
IndexExpr(e) => contains_exterior_struct_lit_inner(&e.base()?), | |
AwaitExpr(e) => contains_exterior_struct_lit_inner(&e.expr()?), | |
PrefixExpr(e) => contains_exterior_struct_lit_inner(&e.expr()?), | |
CastExpr(e) => contains_exterior_struct_lit_inner(&e.expr()?), | |
FieldExpr(e) => contains_exterior_struct_lit_inner(&e.expr()?), | |
MethodCallExpr(e) => contains_exterior_struct_lit_inner(&e.receiver()?), | |
_ => None, | |
} | |
})().is_some() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It kind of makes the code worse, since the recursive calls return bool
that needs to be converted back to Option
...
fn contains_exterior_struct_lit(&self) -> bool {
(|| {
use Expr::*;
(match self {
RecordExpr(..) => true,
// X { y: 1 } + X { y: 2 }
BinExpr(e) => {
return e
.lhs()
.as_ref()
.filter(|e| e.contains_exterior_struct_lit())
.map(drop)
.or_else(|| {
e.rhs().as_ref().filter(|e| e.contains_exterior_struct_lit()).map(drop)
})
}
// `&X { y: 1 }`, `X { y: 1 }.y`, `X { y: 1 }.bar(...)`, etc
IndexExpr(e) => e.base()?.contains_exterior_struct_lit(),
AwaitExpr(e) => e.expr()?.contains_exterior_struct_lit(),
PrefixExpr(e) => e.expr()?.contains_exterior_struct_lit(),
CastExpr(e) => e.expr()?.contains_exterior_struct_lit(),
FieldExpr(e) => e.expr()?.contains_exterior_struct_lit(),
MethodCallExpr(e) => e.receiver()?.contains_exterior_struct_lit(),
_ => return None,
})
.then(|| ())
})()
.is_some()
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh thats a good point, nvm
@bors r+ |
☀️ Test successful - checks-actions |
This is quite a bunch of code and some hacks, but I think this time it's correct.
I've added a lot of tests, most of which fail with the assist impl from #13733 :')