Skip to content

Commit 4befa2e

Browse files
committed
[WIP] Allow #[project] to be used on if let expressions
This PR would work correctly, except for the fact that rust-lang/rust#68618 causes a compilation error to be emitted before we even have a chance to run. That issue is independent of the implementation of this PR, so this PR should start working automatically once the issue is resolved.
1 parent b450354 commit 4befa2e

File tree

1 file changed

+34
-13
lines changed

1 file changed

+34
-13
lines changed

pin-project-internal/src/project.rs

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,33 @@ pub(crate) fn attribute(args: &TokenStream, input: Stmt, mutability: Mutability)
1313
.unwrap_or_else(|e| e.to_compile_error())
1414
}
1515

16-
fn parse(mut stmt: Stmt, mutability: Mutability) -> Result<TokenStream> {
17-
match &mut stmt {
16+
fn replace_stmt(stmt: &mut Stmt, mutability: Mutability) -> Result<bool> {
17+
match stmt {
1818
Stmt::Expr(Expr::Match(expr)) | Stmt::Semi(Expr::Match(expr), _) => {
19-
Context::new(mutability).replace_expr_match(expr)
19+
Context::new(mutability).replace_expr_match(expr);
20+
return Ok(true)
21+
}
22+
Stmt::Expr(Expr::If(expr_if)) => {
23+
if let Expr::Let(ref mut expr) = &mut *expr_if.cond {
24+
Context::new(mutability).replace_expr_let(expr);
25+
return Ok(true);
26+
}
2027
}
2128
Stmt::Local(local) => Context::new(mutability).replace_local(local)?,
22-
Stmt::Item(Item::Fn(item)) => replace_item_fn(item, mutability)?,
23-
Stmt::Item(Item::Impl(item)) => replace_item_impl(item, mutability),
24-
Stmt::Item(Item::Use(item)) => replace_item_use(item, mutability)?,
2529
_ => {}
2630
}
31+
Ok(false)
32+
}
33+
34+
fn parse(mut stmt: Stmt, mutability: Mutability) -> Result<TokenStream> {
35+
if !replace_stmt(&mut stmt, mutability)? {
36+
match &mut stmt {
37+
Stmt::Item(Item::Fn(item)) => replace_item_fn(item, mutability)?,
38+
Stmt::Item(Item::Impl(item)) => replace_item_impl(item, mutability),
39+
Stmt::Item(Item::Use(item)) => replace_item_use(item, mutability)?,
40+
_ => {}
41+
}
42+
}
2743

2844
Ok(stmt.into_token_stream())
2945
}
@@ -73,6 +89,10 @@ impl Context {
7389
Ok(())
7490
}
7591

92+
fn replace_expr_let(&mut self, expr: &mut ExprLet) {
93+
self.replace_pat(&mut expr.pat, true)
94+
}
95+
7696
fn replace_expr_match(&mut self, expr: &mut ExprMatch) {
7797
expr.arms.iter_mut().for_each(|Arm { pat, .. }| self.replace_pat(pat, true))
7898
}
@@ -195,17 +215,18 @@ impl FnVisitor {
195215
expr.attrs.find_remove(self.name())?
196216
}
197217
Stmt::Local(local) => local.attrs.find_remove(self.name())?,
218+
Stmt::Expr(Expr::If(expr_if)) => {
219+
if let Expr::Let(_) = &*expr_if.cond {
220+
expr_if.attrs.find_remove(self.name())?
221+
} else {
222+
None
223+
}
224+
}
198225
_ => return Ok(()),
199226
};
200227
if let Some(attr) = attr {
201228
parse_as_empty(&attr.tokens)?;
202-
match node {
203-
Stmt::Expr(Expr::Match(expr)) | Stmt::Semi(Expr::Match(expr), _) => {
204-
Context::new(self.mutability).replace_expr_match(expr)
205-
}
206-
Stmt::Local(local) => Context::new(self.mutability).replace_local(local)?,
207-
_ => unreachable!(),
208-
}
229+
replace_stmt(node, self.mutability)?;
209230
}
210231
Ok(())
211232
}

0 commit comments

Comments
 (0)